update Piwik to version 2.16 (fixes #91)

This commit is contained in:
oliver 2016-04-10 18:55:57 +02:00
commit d885a4baa9
5833 changed files with 418860 additions and 226988 deletions

View file

@ -1,6 +1,6 @@
<?php
/**
* Piwik - Open source web analytics
* Piwik - free/libre analytics platform
*
* @link http://piwik.org
* @license http://www.gnu.org/licenses/gpl-3.0.html GPL v3 or later
@ -14,21 +14,25 @@ use Piwik\API\Proxy;
use Piwik\API\Request;
use Piwik\Common;
use Piwik\Config as PiwikConfig;
use Piwik\Config;
use Piwik\DataTable\Filter\CalculateEvolutionFilter;
use Piwik\Date;
use Piwik\Exception\NoPrivilegesException;
use Piwik\Exception\NoWebsiteFoundException;
use Piwik\FrontController;
use Piwik\Menu\MenuTop;
use Piwik\Menu\MenuUser;
use Piwik\NoAccessException;
use Piwik\Notification\Manager as NotificationManager;
use Piwik\NumberFormatter;
use Piwik\Period\Month;
use Piwik\Period;
use Piwik\Period\PeriodValidator;
use Piwik\Period\Range;
use Piwik\Piwik;
use Piwik\Plugins\CoreAdminHome\CustomLogo;
use Piwik\Plugins\CoreVisualizations\Visualizations\JqplotGraph\Evolution;
use Piwik\Plugins\LanguagesManager\LanguagesManager;
use Piwik\Plugins\SitesManager\API as APISitesManager;
use Piwik\Plugins\UsersManager\API as APIUsersManager;
use Piwik\Registry;
use Piwik\SettingsPiwik;
use Piwik\Site;
use Piwik\Url;
@ -38,18 +42,18 @@ use Piwik\ViewDataTable\Factory as ViewDataTableFactory;
/**
* Base class of all plugin Controllers.
*
*
* Plugins that wish to add display HTML should create a Controller that either
* extends from this class or from {@link ControllerAdmin}. Every public method in
* the controller will be exposed as a controller method and can be invoked via
* an HTTP request.
*
*
* Learn more about Piwik's MVC system [here](/guides/mvc-in-piwik).
*
*
* ### Examples
*
*
* **Defining a controller**
*
*
* class Controller extends \Piwik\Plugin\Controller
* {
* public function index()
@ -59,17 +63,17 @@ use Piwik\ViewDataTable\Factory as ViewDataTableFactory;
* return $view->render();
* }
* }
*
*
* **Linking to a controller action**
*
* <a href="?module=MyPlugin&action=index&idSite=1&period=day&date=2013-10-10">Link</a>
*
*
*/
abstract class Controller
{
/**
* The plugin name, eg. `'Referrers'`.
*
*
* @var string
* @api
*/
@ -93,7 +97,7 @@ abstract class Controller
/**
* The value of the **idSite** query parameter.
*
*
* @var int
* @api
*/
@ -101,7 +105,7 @@ abstract class Controller
/**
* The Site object created with {@link $idSite}.
*
*
* @var Site
* @api
*/
@ -109,7 +113,7 @@ abstract class Controller
/**
* Constructor.
*
*
* @api
*/
public function __construct()
@ -177,6 +181,50 @@ abstract class Controller
$this->strDate = $date->toString();
}
/**
* Returns values that are enabled for the parameter &period=
* @return array eg. array('day', 'week', 'month', 'year', 'range')
*/
protected static function getEnabledPeriodsInUI()
{
$periodValidator = new PeriodValidator();
return $periodValidator->getPeriodsAllowedForUI();
}
/**
* @return array
*/
private static function getEnabledPeriodsNames()
{
$availablePeriods = self::getEnabledPeriodsInUI();
$periodNames = array(
'day' => array(
'singular' => Piwik::translate('Intl_PeriodDay'),
'plural' => Piwik::translate('Intl_PeriodDays')
),
'week' => array(
'singular' => Piwik::translate('Intl_PeriodWeek'),
'plural' => Piwik::translate('Intl_PeriodWeeks')
),
'month' => array(
'singular' => Piwik::translate('Intl_PeriodMonth'),
'plural' => Piwik::translate('Intl_PeriodMonths')
),
'year' => array(
'singular' => Piwik::translate('Intl_PeriodYear'),
'plural' => Piwik::translate('Intl_PeriodYears')
),
// Note: plural is not used for date range
'range' => array(
'singular' => Piwik::translate('General_DateRangeInPeriodList'),
'plural' => Piwik::translate('General_DateRangeInPeriodList')
),
);
$periodNames = array_intersect_key($periodNames, array_fill_keys($availablePeriods, true));
return $periodNames;
}
/**
* Returns the name of the default method that will be called
* when visiting: index.php?module=PluginName without the action parameter.
@ -200,10 +248,60 @@ abstract class Controller
return $view->render();
}
/**
* Assigns the given variables to the template and renders it.
*
* Example:
*
* public function myControllerAction () {
* return $this->renderTemplate('index', array(
* 'answerToLife' => '42'
* ));
* }
*
* This will render the 'index.twig' file within the plugin templates folder and assign the view variable
* `answerToLife` to `42`.
*
* @param string $template The name of the template file. If only a name is given it will automatically use
* the template within the plugin folder. For instance 'myTemplate' will result in
* '@$pluginName/myTemplate.twig'. Alternatively you can include the full path:
* '@anyOtherFolder/otherTemplate'. The trailing '.twig' is not needed.
* @param array $variables For instance array('myViewVar' => 'myValue'). In template you can use {{ myViewVar }}
* @return string
* @since 2.5.0
* @api
*/
protected function renderTemplate($template, array $variables = array())
{
if (false === strpos($template, '@') || false === strpos($template, '/')) {
$template = '@' . $this->pluginName . '/' . $template;
}
$view = new View($template);
// alternatively we could check whether the templates extends either admin.twig or dashboard.twig and based on
// that call the correct method. This will be needed once we unify Controller and ControllerAdmin see
// https://github.com/piwik/piwik/issues/6151
if ($this instanceof ControllerAdmin) {
$this->setBasicVariablesView($view);
} elseif (empty($this->site) || empty($this->idSite)) {
$this->setBasicVariablesView($view);
} else {
$this->setGeneralVariablesView($view);
}
foreach ($variables as $key => $value) {
$view->$key = $value;
}
return $view->render();
}
/**
* Convenience method that creates and renders a ViewDataTable for a API method.
*
* @param string $apiAction The name of the API action (eg, `'getResolution'`).
* @param string|\Piwik\Plugin\Report $apiAction The name of the API action (eg, `'getResolution'`) or
* an instance of an report.
* @param bool $controllerAction The name of the Controller action name that is rendering the report. Defaults
* to the `$apiAction`.
* @param bool $fetch If `true`, the rendered string is returned, if `false` it is `echo`'d.
@ -214,6 +312,21 @@ abstract class Controller
*/
protected function renderReport($apiAction, $controllerAction = false)
{
if (empty($controllerAction) && is_string($apiAction)) {
$report = Report::factory($this->pluginName, $apiAction);
if (!empty($report)) {
$apiAction = $report;
}
}
if ($apiAction instanceof Report) {
$this->checkSitePermission();
$apiAction->checkIsEnabled();
return $apiAction->render();
}
$pluginName = $this->pluginName;
/** @var Proxy $apiProxy */
@ -250,7 +363,7 @@ abstract class Controller
protected function getLastUnitGraph($currentModuleName, $currentControllerAction, $apiMethod)
{
$view = ViewDataTableFactory::build(
'graphEvolution', $apiMethod, $currentModuleName . '.' . $currentControllerAction, $forceDefault = true);
Evolution::ID, $apiMethod, $currentModuleName . '.' . $currentControllerAction, $forceDefault = true);
$view->config->show_goals = false;
return $view;
}
@ -282,7 +395,7 @@ abstract class Controller
$date = Common::getRequestVar('date');
$meta = \Piwik\Plugins\API\API::getInstance()->getReportMetadata($idSite, $period, $date);
$columns = array_merge($columnsToDisplay, $selectableColumns);
$columns = array_merge($columnsToDisplay ? $columnsToDisplay : array(), $selectableColumns);
$translations = array_combine($columns, $columns);
foreach ($meta as $reportMeta) {
if ($reportMeta['action'] == 'get' && !isset($reportMeta['parameters'])) {
@ -296,6 +409,7 @@ abstract class Controller
// initialize the graph and load the data
$view = $this->getLastUnitGraph($currentModuleName, $currentControllerAction, $apiMethod);
if ($columnsToDisplay !== false) {
$view->config->columns_to_display = $columnsToDisplay;
}
@ -379,11 +493,11 @@ abstract class Controller
/**
* Returns a URL to a sparkline image for a report served by the current plugin.
*
*
* The result of this URL should be used with the [sparkline()](/api-reference/Piwik/View#twig) twig function.
*
*
* The current site ID and period will be used.
*
*
* @param string $action Method name of the controller that serves the report.
* @param array $customParameters The array of query parameter name/value pairs that
* should be set in result URL.
@ -439,9 +553,9 @@ abstract class Controller
/**
* Assigns variables to {@link Piwik\View} instances that display an entire page.
*
*
* The following variables assigned:
*
*
* **date** - The value of the **date** query parameter.
* **idSite** - The value of the **idSite** query parameter.
* **rawDate** - The value of the **date** query parameter.
@ -454,81 +568,105 @@ abstract class Controller
* **config_action_url_category_delimiter** - The value of the `[General] action_url_category_delimiter`
* INI config option.
* **topMenu** - The result of `MenuTop::getInstance()->getMenu()`.
*
*
* As well as the variables set by {@link setPeriodVariablesView()}.
*
*
* Will exit on error.
*
*
* @param View $view
* @return void
* @api
*/
protected function setGeneralVariablesView($view)
{
$view->idSite = $this->idSite;
$this->checkSitePermission();
$this->setPeriodVariablesView($view);
$view->siteName = $this->site->getName();
$view->siteMainUrl = $this->site->getMainUrl();
$siteTimezone = $this->site->getTimezone();
$datetimeMinDate = $this->site->getCreationDate()->getDatetime();
$minDate = Date::factory($datetimeMinDate, $siteTimezone);
$this->setMinDateView($minDate, $view);
$maxDate = Date::factory('now', $siteTimezone);
$this->setMaxDateView($maxDate, $view);
$rawDate = Common::getRequestVar('date');
Period::checkDateFormat($rawDate);
$periodStr = Common::getRequestVar('period');
if ($periodStr != 'range') {
$date = Date::factory($this->strDate);
$validDate = $this->getValidDate($date, $minDate, $maxDate);
$period = Period\Factory::build($periodStr, $validDate);
if ($date->toString() !== $validDate->toString()) {
// we to not always change date since it could convert a strDate "today" to "YYYY-MM-DD"
// only change $this->strDate if it was not valid before
$this->setDate($validDate);
}
} else {
$period = new Range($periodStr, $rawDate, $siteTimezone);
}
// Setting current period start & end dates, for pre-setting the calendar when "Date Range" is selected
$dateStart = $period->getDateStart();
$dateStart = $this->getValidDate($dateStart, $minDate, $maxDate);
$dateEnd = $period->getDateEnd();
$dateEnd = $this->getValidDate($dateEnd, $minDate, $maxDate);
if ($periodStr == 'range') {
// make sure we actually display the correct calendar pretty date
$newRawDate = $dateStart->toString() . ',' . $dateEnd->toString();
$period = new Range($periodStr, $newRawDate, $siteTimezone);
}
$view->date = $this->strDate;
$view->prettyDate = self::getCalendarPrettyDate($period);
$view->prettyDateLong = $period->getLocalizedLongString();
$view->rawDate = $rawDate;
$view->startDate = $dateStart;
$view->endDate = $dateEnd;
try {
$view->idSite = $this->idSite;
if (empty($this->site) || empty($this->idSite)) {
throw new Exception("The requested website idSite is not found in the request, or is invalid.
Please check that you are logged in Piwik and have permission to access the specified website.");
}
$this->setPeriodVariablesView($view);
$language = LanguagesManager::getLanguageForSession();
$view->language = !empty($language) ? $language : LanguagesManager::getLanguageCodeForCurrentUser();
$rawDate = Common::getRequestVar('date');
$periodStr = Common::getRequestVar('period');
if ($periodStr != 'range') {
$date = Date::factory($this->strDate);
$period = Period::factory($periodStr, $date);
} else {
$period = new Range($periodStr, $rawDate, $this->site->getTimezone());
}
$view->rawDate = $rawDate;
$view->prettyDate = self::getCalendarPrettyDate($period);
$this->setBasicVariablesView($view);
$view->siteName = $this->site->getName();
$view->siteMainUrl = $this->site->getMainUrl();
$view->topMenu = MenuTop::getInstance()->getMenu();
$view->userMenu = MenuUser::getInstance()->getMenu();
$datetimeMinDate = $this->site->getCreationDate()->getDatetime();
$minDate = Date::factory($datetimeMinDate, $this->site->getTimezone());
$this->setMinDateView($minDate, $view);
$maxDate = Date::factory('now', $this->site->getTimezone());
$this->setMaxDateView($maxDate, $view);
// Setting current period start & end dates, for pre-setting the calendar when "Date Range" is selected
$dateStart = $period->getDateStart();
if ($dateStart->isEarlier($minDate)) {
$dateStart = $minDate;
}
$dateEnd = $period->getDateEnd();
if ($dateEnd->isLater($maxDate)) {
$dateEnd = $maxDate;
}
$view->startDate = $dateStart;
$view->endDate = $dateEnd;
$language = LanguagesManager::getLanguageForSession();
$view->language = !empty($language) ? $language : LanguagesManager::getLanguageCodeForCurrentUser();
$this->setBasicVariablesView($view);
$view->topMenu = MenuTop::getInstance()->getMenu();
$notifications = $view->notifications;
if (empty($notifications)) {
$view->notifications = NotificationManager::getAllNotificationsToDisplay();
NotificationManager::cancelAllNonPersistent();
} catch (Exception $e) {
Piwik_ExitWithMessage($e->getMessage(), $e->getTraceAsString());
}
}
private function getValidDate(Date $date, Date $minDate, Date $maxDate)
{
if ($date->isEarlier($minDate)) {
$date = $minDate;
}
if ($date->isLater($maxDate)) {
$date = $maxDate;
}
return $date;
}
/**
* Assigns a set of generally useful variables to a {@link Piwik\View} instance.
*
*
* The following variables assigned:
*
* **debugTrackVisitsInsidePiwikUI** - The value of the `[Debug] track_visits_inside_piwik_ui`
* INI config option.
*
* **isSuperUser** - True if the current user is the Super User, false if otherwise.
* **hasSomeAdminAccess** - True if the current user has admin access to at least one site,
* false if otherwise.
@ -539,7 +677,7 @@ abstract class Controller
* **hasSVGLogo** - True if there is a SVG logo, false if otherwise.
* **enableFrames** - The value of the `[General] enable_framed_pages` INI config option. If
* true, {@link Piwik\View::setXFrameOptions()} is called on the view.
*
*
* Also calls {@link setHostValidationVariablesView()}.
*
* @param View $view
@ -548,15 +686,17 @@ abstract class Controller
protected function setBasicVariablesView($view)
{
$view->clientSideConfig = PiwikConfig::getInstance()->getClientSideOptions();
$view->debugTrackVisitsInsidePiwikUI = PiwikConfig::getInstance()->Debug['track_visits_inside_piwik_ui'];
$view->isSuperUser = Access::getInstance()->hasSuperUserAccess();
$view->hasSomeAdminAccess = Piwik::isUserHasSomeAdminAccess();
$view->hasSomeViewAccess = Piwik::isUserHasSomeViewAccess();
$view->isUserIsAnonymous = Piwik::isUserIsAnonymous();
$view->hasSuperUserAccess = Piwik::hasUserSuperUserAccess();
$customLogo = new CustomLogo();
$view->isCustomLogo = $customLogo->isEnabled();
if (!Piwik::isUserIsAnonymous()) {
$view->emailSuperUser = implode(',', Piwik::getAllSuperUserAccessEmailAddresses());
}
$this->addCustomLogoInfo($view);
$view->logoHeader = \Piwik\Plugins\API\API::getInstance()->getHeaderLogoUrl();
$view->logoLarge = \Piwik\Plugins\API\API::getInstance()->getLogoUrl();
@ -574,6 +714,13 @@ abstract class Controller
self::setHostValidationVariablesView($view);
}
protected function addCustomLogoInfo($view)
{
$customLogo = new CustomLogo();
$view->isCustomLogo = $customLogo->isEnabled();
$view->customFavicon = $customLogo->getPathUserFavicon();
}
/**
* Checks if the current host is valid and sets variables on the given view, including:
*
@ -631,7 +778,7 @@ abstract class Controller
$validHost,
'</a>'
));
} else if (Piwik::isUserIsAnonymous()) {
} elseif (Piwik::isUserIsAnonymous()) {
$view->invalidHostMessage = $warningStart . ' '
. Piwik::translate('CoreHome_InjectedHostNonSuperUserWarning', array(
"<br/><a href=\"$validUrl\">",
@ -660,7 +807,7 @@ abstract class Controller
/**
* Sets general period variables on a view, including:
*
*
* - **displayUniqueVisitors** - Whether unique visitors should be displayed for the current
* period.
* - **period** - The value of the **period** query parameter.
@ -677,33 +824,27 @@ abstract class Controller
return;
}
$periodValidator = new PeriodValidator();
$currentPeriod = Common::getRequestVar('period');
$view->displayUniqueVisitors = SettingsPiwik::isUniqueVisitorsEnabled($currentPeriod);
$availablePeriods = array('day', 'week', 'month', 'year', 'range');
if (!in_array($currentPeriod, $availablePeriods)) {
throw new Exception("Period must be one of: " . implode(",", $availablePeriods));
$availablePeriods = $periodValidator->getPeriodsAllowedForUI();
if (! $periodValidator->isPeriodAllowedForUI($currentPeriod)) {
throw new Exception("Period must be one of: " . implode(", ", $availablePeriods));
}
$periodNames = array(
'day' => array('singular' => Piwik::translate('CoreHome_PeriodDay'), 'plural' => Piwik::translate('CoreHome_PeriodDays')),
'week' => array('singular' => Piwik::translate('CoreHome_PeriodWeek'), 'plural' => Piwik::translate('CoreHome_PeriodWeeks')),
'month' => array('singular' => Piwik::translate('CoreHome_PeriodMonth'), 'plural' => Piwik::translate('CoreHome_PeriodMonths')),
'year' => array('singular' => Piwik::translate('CoreHome_PeriodYear'), 'plural' => Piwik::translate('CoreHome_PeriodYears')),
// Note: plural is not used for date range
'range' => array('singular' => Piwik::translate('General_DateRangeInPeriodList'), 'plural' => Piwik::translate('General_DateRangeInPeriodList')),
);
$found = array_search($currentPeriod, $availablePeriods);
if ($found !== false) {
unset($availablePeriods[$found]);
}
unset($availablePeriods[$found]);
$view->period = $currentPeriod;
$view->otherPeriods = $availablePeriods;
$view->periodsNames = $periodNames;
$view->periodsNames = self::getEnabledPeriodsNames();
}
/**
* Helper method used to redirect the current HTTP request to another module/action.
*
*
* This function will exit immediately after executing.
*
* @param string $moduleToRedirect The plugin to redirect to, eg. `"MultiSites"`.
@ -717,132 +858,46 @@ abstract class Controller
public function redirectToIndex($moduleToRedirect, $actionToRedirect, $websiteId = null, $defaultPeriod = null,
$defaultDate = null, $parameters = array())
{
if (empty($websiteId)) {
$websiteId = $this->getDefaultWebsiteId();
}
if (empty($defaultDate)) {
$defaultDate = $this->getDefaultDate();
}
if (empty($defaultPeriod)) {
$defaultPeriod = $this->getDefaultPeriod();
}
$parametersString = '';
if (!empty($parameters)) {
$parametersString = '&' . Url::getQueryStringFromParameters($parameters);
}
if ($websiteId) {
$url = "Location: index.php?module=" . $moduleToRedirect
. "&action=" . $actionToRedirect
. "&idSite=" . $websiteId
. "&period=" . $defaultPeriod
. "&date=" . $defaultDate
. $parametersString;
header($url);
exit;
try {
$this->doRedirectToUrl($moduleToRedirect, $actionToRedirect, $websiteId, $defaultPeriod, $defaultDate, $parameters);
} catch (Exception $e) {
// no website ID to default to, so could not redirect
}
if (Piwik::hasUserSuperUserAccess()) {
Piwik_ExitWithMessage("Error: no website was found in this Piwik installation.
<br />Check the table '" . Common::prefixTable('site') . "' in your database, it should contain your Piwik websites.", false, true);
$siteTableName = Common::prefixTable('site');
$message = "Error: no website was found in this Piwik installation.
<br />Check the table '$siteTableName' in your database, it should contain your Piwik websites.";
$ex = new NoWebsiteFoundException($message);
$ex->setIsHtmlMessage();
throw $ex;
}
$currentLogin = Piwik::getCurrentUserLogin();
if (!empty($currentLogin)
&& $currentLogin != 'anonymous'
) {
if (!Piwik::isUserIsAnonymous()) {
$currentLogin = Piwik::getCurrentUserLogin();
$emails = implode(',', Piwik::getAllSuperUserAccessEmailAddresses());
$errorMessage = sprintf(Piwik::translate('CoreHome_NoPrivilegesAskPiwikAdmin'), $currentLogin, "<br/><a href='mailto:" . $emails . "?subject=Access to Piwik for user $currentLogin'>", "</a>");
$errorMessage .= "<br /><br />&nbsp;&nbsp;&nbsp;<b><a href='index.php?module=" . Registry::get('auth')->getName() . "&amp;action=logout'>&rsaquo; " . Piwik::translate('General_Logout') . "</a></b><br />";
Piwik_ExitWithMessage($errorMessage, false, true);
$errorMessage = sprintf(Piwik::translate('CoreHome_NoPrivilegesAskPiwikAdmin'), $currentLogin, "<br/><a href='mailto:" . $emails . "?subject=Access to Piwik for user $currentLogin'>", "</a>");
$errorMessage .= "<br /><br />&nbsp;&nbsp;&nbsp;<b><a href='index.php?module=" . Piwik::getLoginPluginName() . "&amp;action=logout'>&rsaquo; " . Piwik::translate('General_Logout') . "</a></b><br />";
$ex = new NoPrivilegesException($errorMessage);
$ex->setIsHtmlMessage();
throw $ex;
}
echo FrontController::getInstance()->dispatch(Piwik::getLoginPluginName(), false);
exit;
}
/**
* Returns default site ID that Piwik should load.
*
* _Note: This value is a Piwik setting set by each user._
*
* @return bool|int
* @api
*/
protected function getDefaultWebsiteId()
{
$defaultWebsiteId = false;
// User preference: default website ID to load
$defaultReport = APIUsersManager::getInstance()->getUserPreference(Piwik::getCurrentUserLogin(), APIUsersManager::PREFERENCE_DEFAULT_REPORT);
if (is_numeric($defaultReport)) {
$defaultWebsiteId = $defaultReport;
}
if ($defaultWebsiteId && Piwik::isUserHasViewAccess($defaultWebsiteId)) {
return $defaultWebsiteId;
}
$sitesId = APISitesManager::getInstance()->getSitesIdWithAtLeastViewAccess();
if (!empty($sitesId)) {
return $sitesId[0];
}
return false;
}
/**
* Returns default date for Piwik reports.
*
* _Note: This value is a Piwik setting set by each user._
*
* @return string `'today'`, `'2010-01-01'`, etc.
* @api
*/
protected function getDefaultDate()
{
// NOTE: a change in this function might mean a change in plugins/UsersManager/javascripts/usersSettings.js as well
$userSettingsDate = APIUsersManager::getInstance()->getUserPreference(Piwik::getCurrentUserLogin(), APIUsersManager::PREFERENCE_DEFAULT_REPORT_DATE);
if ($userSettingsDate == 'yesterday') {
return $userSettingsDate;
}
// if last7, last30, etc.
if (strpos($userSettingsDate, 'last') === 0
|| strpos($userSettingsDate, 'previous') === 0
) {
return $userSettingsDate;
}
return 'today';
}
/**
* Returns default period type for Piwik reports.
*
* @return string `'day'`, `'week'`, `'month'`, `'year'` or `'range'`
* @api
*/
protected function getDefaultPeriod()
{
$userSettingsDate = APIUsersManager::getInstance()->getUserPreference(Piwik::getCurrentUserLogin(), APIUsersManager::PREFERENCE_DEFAULT_REPORT_DATE);
if ($userSettingsDate === false) {
return PiwikConfig::getInstance()->General['default_period'];
}
if (in_array($userSettingsDate, array('today', 'yesterday'))) {
return 'day';
}
if (strpos($userSettingsDate, 'last') === 0
|| strpos($userSettingsDate, 'previous') === 0
) {
return 'range';
}
return $userSettingsDate;
}
/**
* Checks that the token_auth in the URL matches the currently logged-in user's token_auth.
*
*
* This is a protection against CSRF and should be used in all controller
* methods that modify Piwik or any user settings.
*
*
* **The token_auth should never appear in the browser's address bar.**
*
* @throws \Piwik\NoAccessException If the token doesn't match.
@ -850,7 +905,14 @@ abstract class Controller
*/
protected function checkTokenInUrl()
{
if (Common::getRequestVar('token_auth', false) != Piwik::getCurrentUserTokenAuth()) {
$tokenRequest = Common::getRequestVar('token_auth', false);
$tokenUser = Piwik::getCurrentUserTokenAuth();
if (empty($tokenRequest) && empty($tokenUser)) {
return; // UI tests
}
if ($tokenRequest !== $tokenUser) {
throw new NoAccessException(Piwik::translate('General_ExceptionInvalidToken'));
}
}
@ -864,8 +926,9 @@ abstract class Controller
*/
public static function getCalendarPrettyDate($period)
{
if ($period instanceof Month) // show month name when period is for a month
{
if ($period instanceof Month) {
// show month name when period is for a month
return $period->getLocalizedLongString();
} else {
return $period->getPrettyString();
@ -881,7 +944,7 @@ abstract class Controller
*/
public static function getPrettyDate($date, $period)
{
return self::getCalendarPrettyDate(Period::factory($period, Date::factory($date)));
return self::getCalendarPrettyDate(Period\Factory::build($period, Date::factory($date)));
}
/**
@ -914,7 +977,7 @@ abstract class Controller
if ($evolutionPercent < 0) {
$class = "negative-evolution";
$img = "arrow_down.png";
} else if ($evolutionPercent == 0) {
} elseif ($evolutionPercent == 0) {
$class = "neutral-evolution";
$img = "stop.png";
} else {
@ -923,6 +986,9 @@ abstract class Controller
$titleEvolutionPercent = '+' . $titleEvolutionPercent;
}
$currentValue = NumberFormatter::getInstance()->format($currentValue);
$pastValue = NumberFormatter::getInstance()->format($pastValue);
$title = Piwik::translate('General_EvolutionSummaryGeneric', array(
Piwik::translate('General_NVisits', $currentValue),
$date,
@ -941,4 +1007,38 @@ abstract class Controller
return $result;
}
protected function checkSitePermission()
{
if (!empty($this->idSite) && empty($this->site)) {
throw new NoAccessException(Piwik::translate('General_ExceptionPrivilegeAccessWebsite', array("'view'", $this->idSite)));
} elseif (empty($this->site) || empty($this->idSite)) {
throw new Exception("The requested website idSite is not found in the request, or is invalid.
Please check that you are logged in Piwik and have permission to access the specified website.");
}
}
/**
* @param $moduleToRedirect
* @param $actionToRedirect
* @param $websiteId
* @param $defaultPeriod
* @param $defaultDate
* @param $parameters
* @throws Exception
*/
private function doRedirectToUrl($moduleToRedirect, $actionToRedirect, $websiteId, $defaultPeriod, $defaultDate, $parameters)
{
$menu = new Menu();
$parameters = array_merge(
$menu->urlForDefaultUserParams($websiteId, $defaultPeriod, $defaultDate),
$parameters
);
$queryParams = !empty($parameters) ? '&' . Url::getQueryStringFromParameters($parameters) : '';
$url = "index.php?module=%s&action=%s";
$url = sprintf($url, $moduleToRedirect, $actionToRedirect);
$url = $url . $queryParams;
Url::redirectToUrl($url);
}
}