Example #1
0
 /**
  * runTasks collects tasks defined within piwik plugins, runs them if they are scheduled and reschedules
  * the tasks that have been executed.
  *
  * @return array
  */
 public static function runTasks()
 {
     // Gets the array where rescheduled timetables are stored
     $option = Piwik_GetOption(self::TIMETABLE_OPTION_STRING);
     $timetable = self::getTimetableFromOption($option);
     if ($timetable === false) {
         return;
     }
     $forceScheduledTasks = false;
     if (isset($GLOBALS['PIWIK_TRACKER_DEBUG_FORCE_SCHEDULED_TASKS']) && $GLOBALS['PIWIK_TRACKER_DEBUG_FORCE_SCHEDULED_TASKS'] || DEBUG_FORCE_SCHEDULED_TASKS) {
         $forceScheduledTasks = true;
         $timetable = array();
     }
     // Collects tasks
     Piwik_PostEvent(self::GET_TASKS_EVENT, $tasks);
     $return = array();
     // for every priority level, starting with the highest and concluding with the lowest
     for ($priority = Piwik_ScheduledTask::HIGHEST_PRIORITY; $priority <= Piwik_ScheduledTask::LOWEST_PRIORITY; ++$priority) {
         // Loop through each task
         foreach ($tasks as $task) {
             // if the task does not have the current priority level, don't execute it yet
             if ($task->getPriority() != $priority) {
                 continue;
             }
             $scheduledTime = $task->getScheduledTime();
             $className = $task->getClassName();
             $methodName = $task->getMethodName();
             $fullyQualifiedMethodName = get_class($className) . '.' . $methodName;
             /*
              * Task has to be executed if :
              * 	- it is the first time, ie. rescheduledTime is not set
              *  - that task has already been executed and the current system time is greater than the
              *    rescheduled time.
              */
             if (!isset($timetable[$fullyQualifiedMethodName]) || isset($timetable[$fullyQualifiedMethodName]) && time() >= $timetable[$fullyQualifiedMethodName] || $forceScheduledTasks) {
                 // Updates the rescheduled time
                 $timetable[$fullyQualifiedMethodName] = $scheduledTime->getRescheduledTime();
                 Piwik_SetOption(self::TIMETABLE_OPTION_STRING, serialize($timetable));
                 self::$running = true;
                 // Run the task
                 try {
                     $timer = new Piwik_Timer();
                     call_user_func(array($className, $methodName));
                     $message = $timer->__toString();
                 } catch (Exception $e) {
                     $message = 'ERROR: ' . $e->getMessage();
                 }
                 self::$running = false;
                 $return[] = array('task' => $fullyQualifiedMethodName, 'output' => $message);
             }
         }
     }
     return $return;
 }
Example #2
0
 protected function getDeleteLogsInfo()
 {
     Piwik::checkUserIsSuperUser();
     $deleteLogsInfos = array();
     $taskScheduler = new Piwik_TaskScheduler();
     $deleteLogsInfos["config"] = Zend_Registry::get('config')->Deletelogs->toArray();
     $privacyManager = new Piwik_PrivacyManager();
     $deleteLogsInfos["deleteTables"] = implode(", ", $privacyManager->getDeleteTableLogTables());
     $scheduleTimetable = $taskScheduler->getScheduledTimeForTask("Piwik_PrivacyManager", "deleteLogTables");
     $optionTable = Piwik_GetOption(self::OPTION_LAST_DELETE_PIWIK_LOGS);
     //If task was already rescheduled, read time from taskTimetable. Else, calculate next possible runtime.
     if (!empty($scheduleTimetable) && $scheduleTimetable - time() > 0) {
         $nextPossibleSchedule = (int) $scheduleTimetable;
     } else {
         $date = Piwik_Date::factory("today");
         $nextPossibleSchedule = $date->addDay(1)->getTimestamp();
     }
     //deletion schedule did not run before
     if (empty($optionTable)) {
         $deleteLogsInfos["lastRun"] = false;
         //next run ASAP (with next schedule run)
         $date = Piwik_Date::factory("today");
         $deleteLogsInfos["nextScheduleTime"] = $nextPossibleSchedule;
     } else {
         $deleteLogsInfos["lastRun"] = $optionTable;
         $deleteLogsInfos["lastRunPretty"] = Piwik_Date::factory((int) $optionTable)->getLocalized('%day% %shortMonth% %longYear%');
         //Calculate next run based on last run + interval
         $nextScheduleRun = (int) ($deleteLogsInfos["lastRun"] + $deleteLogsInfos["config"]["delete_logs_schedule_lowest_interval"] * 24 * 60 * 60);
         //is the calculated next run in the past? (e.g. plugin was disabled in the meantime or something) -> run ASAP
         if ($nextScheduleRun - time() <= 0) {
             $deleteLogsInfos["nextScheduleTime"] = $nextPossibleSchedule;
         } else {
             $deleteLogsInfos["nextScheduleTime"] = $nextScheduleRun;
         }
     }
     $deleteLogsInfos["nextRunPretty"] = Piwik::getPrettyTimeFromSeconds($deleteLogsInfos["nextScheduleTime"] - time());
     return $deleteLogsInfos;
 }
Example #3
0
 /**
  * Tracker requests will automatically trigger the Scheduled tasks.
  * This is useful for users who don't setup the cron,
  * but still want daily/weekly/monthly PDF reports emailed automatically.
  *
  * This is similar to calling the API CoreAdminHome.runScheduledTasks (see misc/cron/archive.sh)
  *
  * @param int  $now  Current timestamp
  */
 public static function runScheduledTasks($now)
 {
     // Currently, there is no hourly tasks. When there are some,
     // this could be too agressive minimum interval (some hours would be skipped in case of low traffic)
     $minimumInterval = Piwik_Config::getInstance()->Tracker['scheduled_tasks_min_interval'];
     // If the user disabled browser archiving, he has already setup a cron
     // To avoid parallel requests triggering the Scheduled Tasks,
     // Get last time tasks started executing
     $cache = Piwik_Common::getCacheGeneral();
     if ($minimumInterval <= 0 || empty($cache['isBrowserTriggerArchivingEnabled'])) {
         printDebug("-> Scheduled tasks not running in Tracker: Browser archiving is disabled.");
         return;
     }
     $nextRunTime = $cache['lastTrackerCronRun'] + $minimumInterval;
     if (isset($GLOBALS['PIWIK_TRACKER_DEBUG_FORCE_SCHEDULED_TASKS']) && $GLOBALS['PIWIK_TRACKER_DEBUG_FORCE_SCHEDULED_TASKS'] || $cache['lastTrackerCronRun'] === false || $nextRunTime < $now) {
         $cache['lastTrackerCronRun'] = $now;
         Piwik_Common::setCacheGeneral($cache);
         Piwik_Common::initCorePiwikInTrackerMode();
         Piwik_SetOption('lastTrackerCronRun', $cache['lastTrackerCronRun']);
         printDebug('-> Scheduled Tasks: Starting...');
         // save current user privilege and temporarily assume super user privilege
         $isSuperUser = Piwik::isUserIsSuperUser();
         // Scheduled tasks assume Super User is running
         Piwik::setUserIsSuperUser();
         // While each plugins should ensure that necessary languages are loaded,
         // we ensure English translations at least are loaded
         Piwik_Translate::getInstance()->loadEnglishTranslation();
         $resultTasks = Piwik_TaskScheduler::runTasks();
         // restore original user privilege
         Piwik::setUserIsSuperUser($isSuperUser);
         printDebug($resultTasks);
         printDebug('Finished Scheduled Tasks.');
     } else {
         printDebug("-> Scheduled tasks not triggered.");
     }
     printDebug("Next run will be from: " . date('Y-m-d H:i:s', $nextRunTime) . ' UTC');
 }
Example #4
0
 /**
  * Will run all scheduled tasks due to run at this time.
  * @return void
  */
 public function runScheduledTasks()
 {
     Piwik::checkUserIsSuperUser();
     return Piwik_TaskScheduler::runTasks();
 }
Example #5
0
 private function buildDataTable($sites, $period, $date, $segment, $_restrictSitesToLogin, $enhanced)
 {
     $allWebsitesRequested = $sites == 'all';
     if ($allWebsitesRequested) {
         if (Piwik::isUserIsSuperUser() && !Piwik_TaskScheduler::isTaskBeingExecuted()) {
             Piwik_Site::setSites(Piwik_SitesManager_API::getInstance()->getAllSites());
         } else {
             Piwik_Site::setSitesFromArray(Piwik_SitesManager_API::getInstance()->getSitesWithAtLeastViewAccess($limit = false, $_restrictSitesToLogin));
         }
     }
     // build the archive type used to query archive data
     $archive = Piwik_Archive::build($sites, $period, $date, $segment, $_restrictSitesToLogin);
     // determine what data will be displayed
     $fieldsToGet = array();
     $columnNameRewrites = array();
     $apiECommerceMetrics = array();
     $apiMetrics = Piwik_MultiSites_API::getApiMetrics($enhanced);
     foreach ($apiMetrics as $metricName => $metricSettings) {
         $fieldsToGet[] = $metricSettings[self::METRIC_RECORD_NAME_KEY];
         $columnNameRewrites[$metricSettings[self::METRIC_RECORD_NAME_KEY]] = $metricName;
         if ($metricSettings[self::METRIC_IS_ECOMMERCE_KEY]) {
             $apiECommerceMetrics[$metricName] = $metricSettings;
         }
     }
     // get the data
     // $dataTable instanceOf Piwik_DataTable_Array
     $dataTable = $archive->getDataTableFromNumeric($fieldsToGet);
     // get rid of the DataTable_Array that is created by the IndexedBySite archive type
     if ($dataTable instanceof Piwik_DataTable_Array && $allWebsitesRequested) {
         $dataTable = $dataTable->mergeChildren();
     } else {
         if (!$dataTable instanceof Piwik_DataTable_Array) {
             $firstDataTableRow = $dataTable->getFirstRow();
             $firstDataTableRow->setColumn('label', $sites);
         }
     }
     // if the period isn't a range & a lastN/previousN date isn't used, we get the same
     // data for the last period to show the evolution of visits/actions/revenue
     if ($period != 'range' && !preg_match('/(last|previous)([0-9]*)/', $date, $regs)) {
         if (strpos($date, ',')) {
             $rangePeriod = new Piwik_Period_Range($period, $date);
             $lastStartDate = Piwik_Period_Range::removePeriod($period, $rangePeriod->getDateStart(), $n = 1);
             $lastEndDate = Piwik_Period_Range::removePeriod($period, $rangePeriod->getDateEnd(), $n = 1);
             $strLastDate = "{$lastStartDate},{$lastEndDate}";
         } else {
             $strLastDate = Piwik_Period_Range::removePeriod($period, Piwik_Date::factory($date), $n = 1)->toString();
         }
         $pastArchive = Piwik_Archive::build('all', $period, $strLastDate, $segment, $_restrictSitesToLogin);
         $pastData = $pastArchive->getDataTableFromNumeric($fieldsToGet);
         $pastData = $pastData->mergeChildren();
         // use past data to calculate evolution percentages
         $this->calculateEvolutionPercentages($dataTable, $pastData, $apiMetrics);
     }
     // remove eCommerce related metrics on non eCommerce Piwik sites
     // note: this is not optimal in terms of performance: those metrics should not be retrieved in the first place
     if ($enhanced) {
         // $dataTableRows instanceOf Piwik_DataTable_Row[]
         $dataTableRows = $dataTable->getRows();
         foreach ($dataTableRows as $dataTableRow) {
             $siteId = $dataTableRow->getColumn('label');
             if (!Piwik_Site::isEcommerceEnabledFor($siteId)) {
                 foreach ($apiECommerceMetrics as $metricSettings) {
                     $dataTableRow->deleteColumn($metricSettings[self::METRIC_RECORD_NAME_KEY]);
                     $dataTableRow->deleteColumn($metricSettings[self::METRIC_EVOLUTION_COL_NAME_KEY]);
                 }
             }
         }
     }
     // move the site id to a metadata column
     $dataTable->filter('ColumnCallbackAddMetadata', array('label', 'idsite'));
     // set the label of each row to the site name
     if ($allWebsitesRequested) {
         $getNameFor = array('Piwik_Site', 'getNameFor');
         $dataTable->filter('ColumnCallbackReplace', array('label', $getNameFor));
     } else {
         $dataTable->filter('ColumnDelete', array('label'));
     }
     // replace record names with user friendly metric names
     $dataTable->filter('ReplaceColumnNames', array($columnNameRewrites));
     // Ensures data set sorted, for Metadata output
     $dataTable->filter('Sort', array(self::NB_VISITS_METRIC, 'desc', $naturalSort = false));
     // filter rows without visits
     // note: if only one website is queried and there are no visits, we can not remove the row otherwise Piwik_API_ResponseBuilder throws 'Call to a member function getColumns() on a non-object'
     if ($allWebsitesRequested) {
         $dataTable->filter('ColumnCallbackDeleteRow', array(self::NB_VISITS_METRIC, create_function('$value', 'return $value != 0;')));
     }
     return $dataTable;
 }
Example #6
0
 /**
  * Returns the list of websites ID with the 'view' or 'admin' access for the current user.
  * For the superUser it returns all the websites in the database.
  * 
  * @return array list of websites ID
  */
 public function getSitesIdWithAtLeastViewAccess($_restrictSitesToLogin = false)
 {
     if (!empty($_restrictSitesToLogin) && Piwik_TaskScheduler::isTaskBeingExecuted()) {
         $accessRaw = Piwik_Access::getRawSitesWithSomeViewAccess($_restrictSitesToLogin);
         $sitesId = array();
         foreach ($accessRaw as $access) {
             $sitesId[] = $access['idsite'];
         }
         return $sitesId;
     } else {
         return Zend_Registry::get('access')->getSitesIdWithAtLeastViewAccess();
     }
 }