public function manage() { Piwik::checkUserHasAdminAccess($this->idSite); $view = new View('@Goals/manageGoals'); $this->setGeneralVariablesView($view); $this->setEditGoalsViewVariables($view); $this->setGoalOptions($view); return $view->render(); }
/** * When tracking data in the past (using Tracking API), this function * can be used to invalidate reports for the idSites and dates where new data * was added. * DEV: If you call this API, the UI should display the data correctly, but will process * in real time, which could be very slow after large data imports. * After calling this function via REST, you can manually force all data * to be reprocessed by visiting the script as the Super User: * http://example.net/piwik/misc/cron/archive.php?token_auth=$SUPER_USER_TOKEN_AUTH_HERE * REQUIREMENTS: On large piwik setups, you will need in PHP configuration: max_execution_time = 0 * We recommend to use an hourly schedule of the script. * More information: http://piwik.org/setup-auto-archiving/ * * @param string $idSites Comma separated list of idSite that have had data imported for the specified dates * @param string $dates Comma separated list of dates to invalidate for all these websites * @param string $period If specified (one of day, week, month, year, range) it will only invalidates archives for this period. * Note: because week, month, year, range reports aggregate day reports then you need to specifically invalidate day reports to see * other periods reports processed.. * @throws Exception * @return array * @hideExceptForSuperUser */ public function invalidateArchivedReports($idSites, $dates, $period = false) { $idSites = Site::getIdSitesFromIdSitesString($idSites); if (empty($idSites)) { throw new Exception("Specify a value for &idSites= as a comma separated list of website IDs, for which your token_auth has 'admin' permission"); } Piwik::checkUserHasAdminAccess($idSites); $invalidator = new ArchiveInvalidator(); $output = $invalidator->markArchivesAsInvalidated($idSites, $dates, $period); Site::clearCache(); return $output; }
/** * When tracking data in the past (using Tracking API), this function * can be used to invalidate reports for the idSites and dates where new data * was added. * DEV: If you call this API, the UI should display the data correctly, but will process * in real time, which could be very slow after large data imports. * After calling this function via REST, you can manually force all data * to be reprocessed by visiting the script as the Super User: * http://example.net/piwik/misc/cron/archive.php?token_auth=$SUPER_USER_TOKEN_AUTH_HERE * REQUIREMENTS: On large piwik setups, you will need in PHP configuration: max_execution_time = 0 * We recommend to use an hourly schedule of the script. * More information: http://piwik.org/setup-auto-archiving/ * * @param string $idSites Comma separated list of idSite that have had data imported for the specified dates * @param string $dates Comma separated list of dates to invalidate for all these websites * @param string $period If specified (one of day, week, month, year, range) it will only invalidates archives for this period. * Note: because week, month, year, range reports aggregate day reports then you need to specifically invalidate day reports to see * other periods reports processed.. * @throws Exception * @return array * @hideExceptForSuperUser */ public function invalidateArchivedReports($idSites, $dates, $period = false) { $idSites = Site::getIdSitesFromIdSitesString($idSites); if (empty($idSites)) { throw new Exception("Specify a value for &idSites= as a comma separated list of website IDs, for which your token_auth has 'admin' permission"); } Piwik::checkUserHasAdminAccess($idSites); list($dateObjects, $invalidDates) = $this->getDatesToInvalidateFromString($dates); $invalidator = new ArchiveInvalidator(); $output = $invalidator->markArchivesAsInvalidated($idSites, $dateObjects, $period); if ($invalidDates) { $output[] = 'Warning: some of the Dates to invalidate were invalid: ' . implode(", ", $invalidDates) . ". Piwik simply ignored those and proceeded with the others."; } Site::clearCache(); return $output; }
public function getMeasurableTypeSettings() { $idSite = Common::getRequestVar('idSite', 0, 'int'); $idType = Common::getRequestVar('idType', '', 'string'); if ($idSite >= 1) { Piwik::checkUserHasAdminAccess($idSite); } else { if ($idSite === 0) { Piwik::checkUserHasSomeAdminAccess(); } else { throw new Exception('Invalid idSite parameter. IdSite has to be zero or higher'); } } $view = new View('@SitesManager/measurable_type_settings'); $propSettings = new MeasurableSettings($idSite, $idType); $view->settings = $propSettings->getSettingsForCurrentUser(); return $view->render(); }
public function save() { Piwik::checkUserHasAdminAccess($this->idSite); $typeManager = new TypeManager(); $type = $typeManager->getType($this->idType); /** * Triggered just before Measurable settings are about to be saved. You can use this event for example * to validate not only one setting but multiple ssetting. For example whether username * and password matches. * * @since Piwik 2.14.0 * @deprecated will be removed in Piwik 3.0.0 * * @param MeasurableSettings $this * @param \Piwik\Measurable\Type $type * @param int $idSite */ Piwik::postEvent('Measurable.beforeSaveSettings', array($this, $type, $this->idSite)); $this->storage->save(); }
/** * Invalidates report data, forcing it to be recomputed during the next archiving run. * * Note: This is done automatically when tracking or importing visits in the past. * * @param string $idSites Comma separated list of site IDs to invalidate reports for. * @param string $dates Comma separated list of dates of periods to invalidate reports for. * @param string|bool $period The type of period to invalidate: either 'day', 'week', 'month', 'year', 'range'. * The command will automatically cascade up, invalidating reports for parent periods as * well. So invalidating a day will invalidate the week it's in, the month it's in and the * year it's in, since those periods will need to be recomputed too. * @param string|bool $segment Optional. The segment to invalidate reports for. * @param bool $cascadeDown If true, child periods will be invalidated as well. So if it is requested to invalidate * a month, then all the weeks and days within that month will also be invalidated. But only * if this parameter is set. * @throws Exception * @return array * @hideExceptForSuperUser */ public function invalidateArchivedReports($idSites, $dates, $period = false, $segment = false, $cascadeDown = false) { $idSites = Site::getIdSitesFromIdSitesString($idSites); if (empty($idSites)) { throw new Exception("Specify a value for &idSites= as a comma separated list of website IDs, for which your token_auth has 'admin' permission"); } Piwik::checkUserHasAdminAccess($idSites); if (!empty($segment)) { $segment = new Segment($segment, $idSites); } else { $segment = null; } list($dateObjects, $invalidDates) = $this->getDatesToInvalidateFromString($dates); $invalidationResult = $this->invalidator->markArchivesAsInvalidated($idSites, $dateObjects, $period, $segment, (bool) $cascadeDown); $output = $invalidationResult->makeOutputLogs(); if ($invalidDates) { $output[] = 'Warning: some of the Dates to invalidate were invalid: ' . implode(", ", $invalidDates) . ". Piwik simply ignored those and proceeded with the others."; } Site::clearCache(); // TODO: is this needed? it shouldn't be needed... return $invalidationResult->makeOutputLogs(); }
/** * Soft deletes a given Goal. * Stats data in the archives will still be recorded, but not displayed. * * @param int $idSite * @param int $idGoal * @return void */ public function deleteGoal($idSite, $idGoal) { Piwik::checkUserHasAdminAccess($idSite); Db::query("UPDATE " . Common::prefixTable('goal') . "\n\t\t\t\t\t\t\t\t\t\tSET deleted = 1\n\t\t\t\t\t\t\t\t\t\tWHERE idsite = ?\n\t\t\t\t\t\t\t\t\t\t\tAND idgoal = ?", array($idSite, $idGoal)); Db::deleteAllRows(Common::prefixTable("log_conversion"), "WHERE idgoal = ? AND idsite = ?", "idvisit", 100000, array($idGoal, $idSite)); Cache::regenerateCacheWebsiteAttributes($idSite); }
/** * Soft deletes a given Goal. * Stats data in the archives will still be recorded, but not displayed. * * @param int $idSite * @param int $idGoal * @return void */ public function deleteGoal($idSite, $idGoal) { Piwik::checkUserHasAdminAccess($idSite); $this->getModel()->deleteGoal($idSite, $idGoal); $this->getModel()->deleteGoalConversions($idSite, $idGoal); Cache::regenerateCacheWebsiteAttributes($idSite); }
/** * Get a list of all available custom variable slots (scope + index) and which names have been used so far in * each slot since the beginning of the website. * * @param int $idSite * @return array */ public function getUsagesOfSlots($idSite) { Piwik::checkUserHasAdminAccess($idSite); $numVars = CustomVariables::getNumUsableCustomVariables(); $usedCustomVariables = array('visit' => array_fill(1, $numVars, array()), 'page' => array_fill(1, $numVars, array())); /** @var DataTable $customVarUsages */ $today = StaticContainer::get('CustomVariables.today'); $date = '2008-12-12,' . $today; $customVarUsages = Request::processRequest('CustomVariables.getCustomVariables', array('idSite' => $idSite, 'period' => 'range', 'date' => $date, 'format' => 'original')); foreach ($customVarUsages->getRows() as $row) { $slots = $row->getMetadata('slots'); if (!empty($slots)) { foreach ($slots as $slot) { $usedCustomVariables[$slot['scope']][$slot['index']][] = array('name' => $row->getColumn('label'), 'nb_visits' => $row->getColumn('nb_visits'), 'nb_actions' => $row->getColumn('nb_actions')); } } } $grouped = array(); foreach ($usedCustomVariables as $scope => $scopes) { foreach ($scopes as $index => $cvars) { $grouped[] = array('scope' => $scope, 'index' => $index, 'usages' => $cvars); } } return $grouped; }
/** * Set an access level to a given user for a list of websites ID. * * If access = 'noaccess' the current access (if any) will be deleted. * If access = 'view' or 'admin' the current access level is deleted and updated with the new value. * * @param string $userLogin The user login * @param string $access Access to grant. Must have one of the following value : noaccess, view, admin * @param int|array $idSites The array of idSites on which to apply the access level for the user. * If the value is "all" then we apply the access level to all the websites ID for which the current authentificated user has an 'admin' access. * * @throws Exception if the user doesn't exist * @throws Exception if the access parameter doesn't have a correct value * @throws Exception if any of the given website ID doesn't exist * * @return bool true on success */ public function setUserAccess($userLogin, $access, $idSites) { $this->checkAccessType($access); $this->checkUserExists($userLogin); $this->checkUserIsNotSuperUser($userLogin); if ($userLogin == 'anonymous' && $access == 'admin') { throw new Exception(Piwik::translate("UsersManager_ExceptionAdminAnonymous")); } // in case idSites is all we grant access to all the websites on which the current connected user has an 'admin' access if ($idSites === 'all') { $idSites = \Piwik\Plugins\SitesManager\API::getInstance()->getSitesIdWithAdminAccess(); } else { $idSites = Site::getIdSitesFromIdSitesString($idSites); } if (empty($idSites)) { throw new Exception('Specify at least one website ID in &idSites='); } // it is possible to set user access on websites only for the websites admin // basically an admin can give the view or the admin access to any user for the websites he manages Piwik::checkUserHasAdminAccess($idSites); $this->deleteUserAccess($userLogin, $idSites); // delete UserAccess $db = Db::get(); // if the access is noaccess then we don't save it as this is the default value // when no access are specified if ($access != 'noaccess') { foreach ($idSites as $idsite) { $db->insert(Common::prefixTable("access"), array("idsite" => $idsite, "login" => $userLogin, "access" => $access)); } } // we reload the access list which doesn't yet take in consideration this new user access Access::getInstance()->reloadAccess(); Cache::deleteTrackerCache(); }
/** * Get a list of all supported scopes that can be used in the API method * `CustomDimensions.configureNewCustomDimension`. The response also contains information whether more Custom * Dimensions can be created or not. Requires at least Admin access for the specified website. * * @param int $idSite * @return array */ public function getAvailableScopes($idSite) { Piwik::checkUserHasAdminAccess($idSite); $scopes = array(); foreach (CustomDimensions::getPublicScopes() as $scope) { $configs = $this->getConfiguration()->getCustomDimensionsHavingScope($idSite, $scope); $indexes = $this->getTracking($scope)->getInstalledIndexes(); $scopes[] = array('value' => $scope, 'name' => Piwik::translate('General_TrackingScope' . ucfirst($scope)), 'numSlotsAvailable' => count($indexes), 'numSlotsUsed' => count($configs), 'numSlotsLeft' => count($indexes) - count($configs), 'supportsExtractions' => CustomDimensions::doesScopeSupportExtractions($scope)); } return $scopes; }
public function manage() { $idSite = Common::getRequestVar('idSite'); Piwik::checkUserHasAdminAccess($idSite); return $this->renderTemplate('manage', array('title' => Piwik::translate('CustomDimensions_CustomDimensions'))); }
/** * Save the custom css and custom css file * * @param $siteId * @param null $customCss * @param null $customFile */ public function saveSite($siteId, $customCss = null, $customFile = null) { Piwik::checkUserHasAdminAccess($siteId); $query = "UPDATE " . Common::prefixTable("site") . " SET custom_css = ?, custom_css_file = ?" . " WHERE idsite = ?"; Db::query($query, array($customCss, $customFile, $siteId)); }
/** * Updates the field ts_created for the specified websites. * * @param $idSites int Id Site to update ts_created * @param $minDate Date to set as creation date. To play it safe it will substract one more day. * * @ignore */ public function updateSiteCreatedTime($idSites, Date $minDate) { $idSites = Site::getIdSitesFromIdSitesString($idSites); Piwik::checkUserHasAdminAccess($idSites); // Update piwik_site.ts_created $query = "UPDATE " . Common::prefixTable("site") . " SET ts_created = ?" . " WHERE idsite IN ( " . implode(",", $idSites) . " )\n\t\t\t\t\tAND ts_created > ?"; $minDateSql = $minDate->subDay(1)->getDatetime(); $bind = array($minDateSql, $minDateSql); Db::query($query, $bind); }
/** * Updates the field ts_created for the specified websites. * * @param $idSites int Id Site to update ts_created * @param $minDate Date to set as creation date. To play it safe it will substract one more day. * * @ignore */ public function updateSiteCreatedTime($idSites, Date $minDate) { $idSites = Site::getIdSitesFromIdSitesString($idSites); Piwik::checkUserHasAdminAccess($idSites); $minDateSql = $minDate->subDay(1)->getDatetime(); $this->getModel()->updateSiteCreatedTime($idSites, $minDateSql); }
/** * When tracking data in the past (using Tracking API), this function * can be used to invalidate reports for the idSites and dates where new data * was added. * DEV: If you call this API, the UI should display the data correctly, but will process * in real time, which could be very slow after large data imports. * After calling this function via REST, you can manually force all data * to be reprocessed by visiting the script as the Super User: * http://example.net/piwik/misc/cron/archive.php?token_auth=$SUPER_USER_TOKEN_AUTH_HERE * REQUIREMENTS: On large piwik setups, you will need in PHP configuration: max_execution_time = 0 * We recommend to use an hourly schedule of the script. * More information: http://piwik.org/setup-auto-archiving/ * * @param string $idSites Comma separated list of idSite that have had data imported for the specified dates * @param string $dates Comma separated list of dates to invalidate for all these websites * @throws Exception * @return array */ public function invalidateArchivedReports($idSites, $dates) { $idSites = Site::getIdSitesFromIdSitesString($idSites); if (empty($idSites)) { throw new Exception("Specify a value for &idSites= as a comma separated list of website IDs, for which your token_auth has 'admin' permission"); } Piwik::checkUserHasAdminAccess($idSites); // Ensure the specified dates are valid $toInvalidate = $invalidDates = array(); $dates = explode(',', trim($dates)); $dates = array_unique($dates); foreach ($dates as $theDate) { $theDate = trim($theDate); try { $date = Date::factory($theDate); } catch (Exception $e) { $invalidDates[] = $theDate; continue; } if ($date->toString() == $theDate) { $toInvalidate[] = $date; } else { $invalidDates[] = $theDate; } } // If using the feature "Delete logs older than N days"... $purgeDataSettings = PrivacyManager::getPurgeDataSettings(); $logsAreDeletedBeforeThisDate = $purgeDataSettings['delete_logs_schedule_lowest_interval']; $logsDeleteEnabled = $purgeDataSettings['delete_logs_enable']; $minimumDateWithLogs = false; if ($logsDeleteEnabled && $logsAreDeletedBeforeThisDate) { $minimumDateWithLogs = Date::factory('today')->subDay($logsAreDeletedBeforeThisDate); } // Given the list of dates, process which tables they should be deleted from $minDate = false; $warningDates = $processedDates = array(); /* @var $date Date */ foreach ($toInvalidate as $date) { // we should only delete reports for dates that are more recent than N days if ($minimumDateWithLogs && $date->isEarlier($minimumDateWithLogs)) { $warningDates[] = $date->toString(); } else { $processedDates[] = $date->toString(); } $month = $date->toString('Y_m'); // For a given date, we must invalidate in the monthly archive table $datesByMonth[$month][] = $date->toString(); // But also the year stored in January $year = $date->toString('Y_01'); $datesByMonth[$year][] = $date->toString(); // but also weeks overlapping several months stored in the month where the week is starting /* @var $week Week */ $week = Period\Factory::build('week', $date); $weekAsString = $week->getDateStart()->toString('Y_m'); $datesByMonth[$weekAsString][] = $date->toString(); // Keep track of the minimum date for each website if ($minDate === false || $date->isEarlier($minDate)) { $minDate = $date; } } if (empty($minDate)) { throw new Exception("Check the 'dates' parameter is a valid date."); } // In each table, invalidate day/week/month/year containing this date $archiveTables = ArchiveTableCreator::getTablesArchivesInstalled(); foreach ($archiveTables as $table) { // Extract Y_m from table name $suffix = ArchiveTableCreator::getDateFromTableName($table); if (!isset($datesByMonth[$suffix])) { continue; } // Dates which are to be deleted from this table $datesToDeleteInTable = $datesByMonth[$suffix]; // Build one statement to delete all dates from the given table $sql = $bind = array(); $datesToDeleteInTable = array_unique($datesToDeleteInTable); foreach ($datesToDeleteInTable as $dateToDelete) { $sql[] = '(date1 <= ? AND ? <= date2)'; $bind[] = $dateToDelete; $bind[] = $dateToDelete; } $sql = implode(" OR ", $sql); $query = "DELETE FROM {$table} " . " WHERE ( {$sql} ) " . " AND idsite IN (" . implode(",", $idSites) . ")"; Db::query($query, $bind); } \Piwik\Plugins\SitesManager\API::getInstance()->updateSiteCreatedTime($idSites, $minDate); // Force to re-process data for these websites in the next cron core:archive command run $invalidatedIdSites = self::getWebsiteIdsToInvalidate(); $invalidatedIdSites = array_merge($invalidatedIdSites, $idSites); $invalidatedIdSites = array_unique($invalidatedIdSites); $invalidatedIdSites = array_values($invalidatedIdSites); Option::set(self::OPTION_INVALIDATED_IDSITES, serialize($invalidatedIdSites)); Site::clearCache(); $output = array(); // output logs if ($warningDates) { $output[] = 'Warning: the following Dates have not been invalidated, because they are earlier than your Log Deletion limit: ' . implode(", ", $warningDates) . "\n The last day with logs is " . $minimumDateWithLogs . ". " . "\n Please disable 'Delete old Logs' or set it to a higher deletion threshold (eg. 180 days or 365 years).'."; } $output[] = "Success. The following dates were invalidated successfully: " . implode(", ", $processedDates); return $output; }
public function manage() { $idSite = Common::getRequestVar('idSite'); Piwik::checkUserHasAdminAccess($idSite); return $this->renderTemplate('manage', array()); }