getIdSitesFromIdSitesString() публичный статический Метод

Checks the given string for valid site IDs and returns them as an array.
public static getIdSitesFromIdSitesString ( string | array $ids, boolean | string $_restrictSitesToLogin = false ) : array
$ids string | array Comma separated idSite list, eg, `'1,2,3,4'` or an array of IDs, eg, `array(1, 2, 3, 4)`.
$_restrictSitesToLogin boolean | string Implementation detail. Used only when running as a scheduled task.
Результат array An array of valid, unique integers.
Пример #1
0
 /**
  * Return the number of visitors that visited every site in the given list for the
  * given date range. Includes the number of visitors that visited at least one site
  * and the number that visited every site.
  *
  * This data is calculated on demand, and for very large tables can take a long time
  * to run.
  *
  * See {@link Model\DistinctMetricsAggregator} for more information.
  *
  * @param string $idSite comma separated list of site IDs, ie, `"1,2,3"`
  * @param string $period
  * @param string $date
  * @return array Metrics **nb_total_visitors** and **nb_shared_visitors**.
  * @throws Exception if $idSite references zero sites or just one site.
  */
 public function getCommonVisitors($idSite, $period, $date, $segment = false)
 {
     if (empty($idSite)) {
         throw new Exception("No sites to get common visitors for.");
     }
     $idSites = Site::getIdSitesFromIdSitesString($idSite);
     Piwik::checkUserHasViewAccess($idSites);
     $segment = new Segment($segment, $idSites);
     $period = PeriodFactory::build($period, $date);
     return $this->distinctMetricsAggregator->getCommonVisitorCount($idSites, $period->getDateStart(), $period->getDateEnd(), $segment);
 }
Пример #2
0
 /**
  * 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;
 }
Пример #3
0
 public static function checkUserHasAdminAccess($idSites)
 {
     if (!self::$superUser) {
         $websitesAccess = self::$idSitesAdmin;
     } else {
         $websitesAccess = API::getInstance()->getAllSitesId();
     }
     $idSites = PiwikSite::getIdSitesFromIdSitesString($idSites);
     foreach ($idSites as $idsite) {
         if (!in_array($idsite, $websitesAccess)) {
             throw new NoAccessException("checkUserHasAdminAccess Fake exception // string not to be tested");
         }
     }
 }
Пример #4
0
 private function getSitesToInvalidateFor(InputInterface $input)
 {
     $sites = $input->getOption('sites');
     $siteIds = Site::getIdSitesFromIdSitesString($sites);
     if (empty($siteIds)) {
         throw new \InvalidArgumentException("Invalid --sites value: '{$sites}'.");
     }
     $allSiteIds = SitesManagerAPI::getInstance()->getAllSitesId();
     foreach ($siteIds as $idSite) {
         if (!in_array($idSite, $allSiteIds)) {
             throw new \InvalidArgumentException("Invalid --sites value: '{$sites}', there are no sites with IDs = {$idSite}");
         }
     }
     return $siteIds;
 }
Пример #5
0
 public function isSiteSearchEnabled($idSites, $idSite)
 {
     $idSites = Site::getIdSitesFromIdSitesString($idSites, true);
     if (!empty($idSite)) {
         $idSites[] = $idSite;
     }
     if (empty($idSites)) {
         return false;
     }
     foreach ($idSites as $idSite) {
         if (!Site::isSiteSearchEnabledFor($idSite)) {
             return false;
         }
     }
     return true;
 }
Пример #6
0
 /**
  * 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;
 }
Пример #7
0
 public function isSiteSearchEnabled()
 {
     $idSite = Common::getRequestVar('idSite', 0, 'int');
     $idSites = Common::getRequestVar('idSites', '', 'string');
     $idSites = Site::getIdSitesFromIdSitesString($idSites, true);
     if (!empty($idSite)) {
         $idSites[] = $idSite;
     }
     if (empty($idSites)) {
         return false;
     }
     foreach ($idSites as $idSite) {
         if (!Site::isSiteSearchEnabledFor($idSite)) {
             return false;
         }
     }
     return true;
 }
Пример #8
0
 /**
  * Returns all Goals for a given website, or list of websites
  *
  * @param string|array $idSite Array or Comma separated list of website IDs to request the goals for
  * @return array Array of Goal attributes
  */
 public function getGoals($idSite)
 {
     $cacheId = self::getCacheId($idSite);
     $cache = $this->getGoalsInfoStaticCache();
     if (!$cache->contains($cacheId)) {
         $idSite = Site::getIdSitesFromIdSitesString($idSite);
         if (empty($idSite)) {
             return array();
         }
         Piwik::checkUserHasViewAccess($idSite);
         $goals = $this->getModel()->getActiveGoals($idSite);
         $cleanedGoals = array();
         foreach ($goals as &$goal) {
             $cleanedGoals[$goal['idgoal']] = $this->formatGoal($goal);
         }
         $cache->save($cacheId, $cleanedGoals);
     }
     return $cache->fetch($cacheId);
 }
Пример #9
0
 /**
  * Returns all Goals for a given website, or list of websites
  *
  * @param string|array $idSite Array or Comma separated list of website IDs to request the goals for
  * @return array Array of Goal attributes
  */
 public function getGoals($idSite)
 {
     //TODO calls to this function could be cached as static
     // would help UI at least, since some UI requests would call this 2-3 times..
     $idSite = Site::getIdSitesFromIdSitesString($idSite);
     if (empty($idSite)) {
         return array();
     }
     Piwik::checkUserHasViewAccess($idSite);
     $goals = $this->getModel()->getActiveGoals($idSite);
     $cleanedGoals = array();
     foreach ($goals as &$goal) {
         if ($goal['match_attribute'] == 'manually') {
             unset($goal['pattern']);
             unset($goal['pattern_type']);
             unset($goal['case_sensitive']);
         }
         $cleanedGoals[$goal['idgoal']] = $goal;
     }
     return $cleanedGoals;
 }
Пример #10
0
 /**
  * Returns all Goals for a given website, or list of websites
  *
  * @param string|array $idSite Array or Comma separated list of website IDs to request the goals for
  * @return array Array of Goal attributes
  */
 public function getGoals($idSite)
 {
     //TODO calls to this function could be cached as static
     // would help UI at least, since some UI requests would call this 2-3 times..
     $idSite = Site::getIdSitesFromIdSitesString($idSite);
     if (empty($idSite)) {
         return array();
     }
     Piwik::checkUserHasViewAccess($idSite);
     $goals = Db::fetchAll("SELECT *\n\t\t\t\t\t\t\t\tFROM " . Common::prefixTable('goal') . "\n\t\t\t\t\t\t\t\tWHERE idsite IN (" . implode(", ", $idSite) . ")\n\t\t\t\t\t\t\t\t\tAND deleted = 0");
     $cleanedGoals = array();
     foreach ($goals as &$goal) {
         if ($goal['match_attribute'] == 'manually') {
             unset($goal['pattern']);
             unset($goal['pattern_type']);
             unset($goal['case_sensitive']);
         }
         $cleanedGoals[$goal['idgoal']] = $goal;
     }
     return $cleanedGoals;
 }
Пример #11
0
 /**
  * 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();
 }
Пример #12
0
 /**
  * Returns all Goals for a given website, or list of websites
  *
  * @param string|array $idSite Array or Comma separated list of website IDs to request the goals for
  * @return array Array of Goal attributes
  */
 public function getGoals($idSite)
 {
     $cacheId = self::getCacheId($idSite);
     $cache = $this->getGoalsInfoStaticCache();
     if (!$cache->contains($cacheId)) {
         $idSite = Site::getIdSitesFromIdSitesString($idSite);
         if (empty($idSite)) {
             return array();
         }
         Piwik::checkUserHasViewAccess($idSite);
         $goals = $this->getModel()->getActiveGoals($idSite);
         $cleanedGoals = array();
         foreach ($goals as &$goal) {
             if ($goal['match_attribute'] == 'manually') {
                 unset($goal['pattern']);
                 unset($goal['pattern_type']);
                 unset($goal['case_sensitive']);
             }
             $cleanedGoals[$goal['idgoal']] = $goal;
         }
         $cache->save($cacheId, $cleanedGoals);
     }
     return $cache->fetch($cacheId);
 }
Пример #13
0
 /**
  * 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);
 }
Пример #14
0
 /**
  * @param int|array|string $idSites
  * @return array
  * @throws \Piwik\NoAccessException
  */
 protected function getIdSites($idSites)
 {
     if ($idSites === 'all') {
         $idSites = $this->getSitesIdWithAtLeastViewAccess();
     }
     $idSites = Site::getIdSitesFromIdSitesString($idSites);
     if (empty($idSites)) {
         throw new NoAccessException("The parameter 'idSite=' is missing from the request.");
     }
     return $idSites;
 }
Пример #15
0
 /**
  * Initializes the various parameters to the script, based on input parameters.
  *
  */
 private function initStateFromParameters()
 {
     $this->todayArchiveTimeToLive = Rules::getTodayArchiveTimeToLive();
     $this->acceptInvalidSSLCertificate = $this->getParameterFromCli("accept-invalid-ssl-certificate");
     $this->processPeriodsMaximumEverySeconds = $this->getDelayBetweenPeriodsArchives();
     $this->shouldArchiveAllSites = (bool) $this->getParameterFromCli("force-all-websites");
     $this->shouldStartProfiler = (bool) $this->getParameterFromCli("xhprof");
     $restrictToIdSites = $this->getParameterFromCli("force-idsites", true);
     $skipIdSites = $this->getParameterFromCli("skip-idsites", true);
     $this->shouldArchiveSpecifiedSites = \Piwik\Site::getIdSitesFromIdSitesString($restrictToIdSites);
     $this->shouldSkipSpecifiedSites = \Piwik\Site::getIdSitesFromIdSitesString($skipIdSites);
     $this->lastSuccessRunTimestamp = Option::get(self::OPTION_ARCHIVING_FINISHED_TS);
     $this->shouldArchiveOnlySitesWithTrafficSince = $this->isShouldArchiveAllSitesWithTrafficSince();
     $this->shouldArchiveOnlySpecificPeriods = $this->getPeriodsToProcess();
     if ($this->shouldArchiveOnlySitesWithTrafficSince === false) {
         // force-all-periods is not set here
         if (empty($this->lastSuccessRunTimestamp)) {
             // First time we run the script
             $this->shouldArchiveOnlySitesWithTrafficSince = self::ARCHIVE_SITES_WITH_TRAFFIC_SINCE;
         } else {
             // there was a previous successful run
             $this->shouldArchiveOnlySitesWithTrafficSince = time() - $this->lastSuccessRunTimestamp;
         }
     } else {
         // force-all-periods is set here
         $this->archiveAndRespectTTL = false;
         if ($this->shouldArchiveOnlySitesWithTrafficSince === true) {
             // force-all-periods without value
             $this->shouldArchiveOnlySitesWithTrafficSince = self::ARCHIVE_SITES_WITH_TRAFFIC_SINCE;
         }
     }
 }
Пример #16
0
 private function updateSiteCreatedTime($idSites, Date $minDate)
 {
     $idSites = Site::getIdSitesFromIdSitesString($idSites);
     $minDateSql = $minDate->subDay(1)->getDatetime();
     $model = new SitesManagerModel();
     $model->updateSiteCreatedTime($idSites, $minDateSql);
 }
Пример #17
0
 /**
  * Creates a UserSynchronizer using INI configuration.
  *
  * @return UserSynchronizer
  */
 public static function makeConfigured()
 {
     $result = new UserSynchronizer();
     $result->setUserMapper(UserMapper::makeConfigured());
     $result->setUsersManagerApi(UsersManagerAPI::getInstance());
     $result->setUserModel(new UserModel());
     if (Config::isAccessSynchronizationEnabled()) {
         $result->setUserAccessMapper(UserAccessMapper::makeConfigured());
         Log::debug("UserSynchronizer::%s(): Using UserAccessMapper when synchronizing users.", __FUNCTION__);
     } else {
         Log::debug("UserSynchronizer::%s(): LDAP access synchronization not enabled.", __FUNCTION__);
     }
     $defaultSitesWithViewAccess = Config::getDefaultSitesToGiveViewAccessTo();
     if (!empty($defaultSitesWithViewAccess)) {
         $siteIds = Access::doAsSuperUser(function () use($defaultSitesWithViewAccess) {
             return Site::getIdSitesFromIdSitesString($defaultSitesWithViewAccess);
         });
         if (empty($siteIds)) {
             Log::warning("UserSynchronizer::%s(): new_user_default_sites_view_access INI config option has no " . "entries. Newly synchronized users will not have any access.", __FUNCTION__);
         }
         $result->setNewUserDefaultSitesWithViewAccess($siteIds);
     }
     Log::debug("UserSynchronizer::%s: configuring with defaultSitesWithViewAccess = %s", __FUNCTION__, $defaultSitesWithViewAccess);
     return $result;
 }
Пример #18
0
 private function updateSiteCreatedTime($idSites, Date $minDate)
 {
     $idSites = Site::getIdSitesFromIdSitesString($idSites);
     $minDateSql = $minDate->subDay(1)->getDatetime();
     #$model = new SitesManagerModel();
     $model = Factory::getModel('Piwik\\Plugins\\SitesManager');
     $model->updateSiteCreatedTime($idSites, $minDateSql);
 }
Пример #19
0
 /**
  * Triggers a hook to ask plugins for available Reports.
  * Returns metadata information about each report (category, name, dimension, metrics, etc.)
  *
  * @param string $idSites Comma separated list of website Ids
  * @param bool|string $period
  * @param bool|Date $date
  * @param bool $hideMetricsDoc
  * @param bool $showSubtableReports
  * @return array
  */
 public function getReportMetadata($idSites, $period = false, $date = false, $hideMetricsDoc = false, $showSubtableReports = false)
 {
     $idSites = Site::getIdSitesFromIdSitesString($idSites);
     if (!empty($idSites)) {
         Piwik::checkUserHasViewAccess($idSites);
     }
     // as they cache key contains a lot of information there would be an even better cache result by caching parts of
     // this huge method separately but that makes it also more complicated. leaving it like this for now.
     $key = $this->buildReportMetadataCacheKey($idSites, $period, $date, $hideMetricsDoc, $showSubtableReports);
     $key = CacheId::pluginAware($key);
     $cache = PiwikCache::getTransientCache();
     if ($cache->contains($key)) {
         return $cache->fetch($key);
     }
     $parameters = array('idSites' => $idSites, 'period' => $period, 'date' => $date);
     $availableReports = array();
     foreach (Report::getAllReports() as $report) {
         $report->configureReportMetadata($availableReports, $parameters);
     }
     /**
      * Triggered when gathering metadata for all available reports.
      *
      * Plugins that define new reports should use this event to make them available in via
      * the metadata API. By doing so, the report will become available in scheduled reports
      * as well as in the Piwik Mobile App. In fact, any third party app that uses the metadata
      * API will automatically have access to the new report.
      *
      * @param string &$availableReports The list of available reports. Append to this list
      *                                  to make a report available.
      *
      *                                  Every element of this array must contain the following
      *                                  information:
      *
      *                                  - **category**: A translated string describing the report's category.
      *                                  - **name**: The translated display title of the report.
      *                                  - **module**: The plugin of the report.
      *                                  - **action**: The API method that serves the report.
      *
      *                                  The following information is optional:
      *
      *                                  - **dimension**: The report's [dimension](/guides/all-about-analytics-data#dimensions) if any.
      *                                  - **metrics**: An array mapping metric names with their display names.
      *                                  - **metricsDocumentation**: An array mapping metric names with their
      *                                                              translated documentation.
      *                                  - **processedMetrics**: The array of metrics in the report that are
      *                                                          calculated using existing metrics. Can be set to
      *                                                          `false` if the report contains no processed
      *                                                          metrics.
      *                                  - **order**: The order of the report in the list of reports
      *                                               with the same category.
      *
      * @param array $parameters Contains the values of the sites and period we are
      *                          getting reports for. Some reports depend on this data.
      *                          For example, Goals reports depend on the site IDs being
      *                          requested. Contains the following information:
      *
      *                          - **idSites**: The array of site IDs we are getting reports for.
      *                          - **period**: The period type, eg, `'day'`, `'week'`, `'month'`,
      *                                        `'year'`, `'range'`.
      *                          - **date**: A string date within the period or a date range, eg,
      *                                      `'2013-01-01'` or `'2012-01-01,2013-01-01'`.
      *
      * TODO: put dimensions section in all about analytics data
      * @deprecated since 2.5.0 Use Report Classes instead.
      * @ignore
      */
     Piwik::postEvent('API.getReportMetadata', array(&$availableReports, $parameters));
     // TODO we can remove this one once we remove API.getReportMetadata event (except hideMetricsDoc)
     foreach ($availableReports as &$availableReport) {
         // can be removed once we remove hook API.getReportMetadata
         if (!isset($availableReport['metrics'])) {
             $availableReport['metrics'] = Metrics::getDefaultMetrics();
         }
         // can be removed once we remove hook API.getReportMetadata
         if (!isset($availableReport['processedMetrics'])) {
             $availableReport['processedMetrics'] = Metrics::getDefaultProcessedMetrics();
         }
         if ($hideMetricsDoc) {
             unset($availableReport['metricsDocumentation']);
         } else {
             if (!isset($availableReport['metricsDocumentation'])) {
                 // set metric documentation to default if it's not set
                 // can be removed once we remove hook API.getReportMetadata
                 $availableReport['metricsDocumentation'] = Metrics::getDefaultMetricsDocumentation();
             }
         }
     }
     /**
      * Triggered after all available reports are collected.
      *
      * This event can be used to modify the report metadata of reports in other plugins. You
      * could, for example, add custom metrics to every report or remove reports from the list
      * of available reports.
      *
      * @param array &$availableReports List of all report metadata. Read the {@hook API.getReportMetadata}
      *                                 docs to see what this array contains.
      * @param array $parameters Contains the values of the sites and period we are
      *                          getting reports for. Some report depend on this data.
      *                          For example, Goals reports depend on the site IDs being
      *                          request. Contains the following information:
      *
      *                          - **idSites**: The array of site IDs we are getting reports for.
      *                          - **period**: The period type, eg, `'day'`, `'week'`, `'month'`,
      *                                        `'year'`, `'range'`.
      *                          - **date**: A string date within the period or a date range, eg,
      *                                      `'2013-01-01'` or `'2012-01-01,2013-01-01'`.
      */
     Piwik::postEvent('API.getReportMetadata.end', array(&$availableReports, $parameters));
     // Sort results to ensure consistent order
     usort($availableReports, array('self', 'sortReports'));
     $knownMetrics = array_merge(Metrics::getDefaultMetrics(), Metrics::getDefaultProcessedMetrics());
     $columnsToKeep = $this->getColumnsToKeep();
     $columnsToRemove = $this->getColumnsToRemove();
     foreach ($availableReports as &$availableReport) {
         // Ensure all metrics have a translation
         $metrics = $availableReport['metrics'];
         $cleanedMetrics = array();
         // TODO we can remove this once we remove the getReportMetadata event, leaving it here for backwards compatibility
         foreach ($metrics as $metricId => $metricTranslation) {
             // When simply the column name was given, ie 'metric' => array( 'nb_visits' )
             // $metricTranslation is in this case nb_visits. We look for a known translation.
             if (is_numeric($metricId) && isset($knownMetrics[$metricTranslation])) {
                 $metricId = $metricTranslation;
                 $metricTranslation = $knownMetrics[$metricTranslation];
             }
             $cleanedMetrics[$metricId] = $metricTranslation;
         }
         $availableReport['metrics'] = $cleanedMetrics;
         // if hide/show columns specified, hide/show metrics & docs
         $availableReport['metrics'] = $this->hideShowMetricsWithParams($availableReport['metrics'], $columnsToRemove, $columnsToKeep);
         if (isset($availableReport['processedMetrics'])) {
             $availableReport['processedMetrics'] = $this->hideShowMetricsWithParams($availableReport['processedMetrics'], $columnsToRemove, $columnsToKeep);
         }
         if (isset($availableReport['metricsDocumentation'])) {
             $availableReport['metricsDocumentation'] = $this->hideShowMetricsWithParams($availableReport['metricsDocumentation'], $columnsToRemove, $columnsToKeep);
         }
         // Remove array elements that are false (to clean up API output)
         foreach ($availableReport as $attributeName => $attributeValue) {
             if (empty($attributeValue)) {
                 unset($availableReport[$attributeName]);
             }
         }
         // when there are per goal metrics, don't display conversion_rate since it can differ from per goal sum
         // TODO we should remove this once we remove the getReportMetadata event, leaving it here for backwards compatibility
         if (isset($availableReport['metricsGoal'])) {
             unset($availableReport['processedMetrics']['conversion_rate']);
             unset($availableReport['metricsGoal']['conversion_rate']);
         }
         // Processing a uniqueId for each report,
         // can be used by UIs as a key to match a given report
         $uniqueId = $availableReport['module'] . '_' . $availableReport['action'];
         if (!empty($availableReport['parameters'])) {
             foreach ($availableReport['parameters'] as $key => $value) {
                 $uniqueId .= '_' . $key . '--' . $value;
             }
         }
         $availableReport['uniqueId'] = $uniqueId;
         // Order is used to order reports internally, but not meant to be used outside
         unset($availableReport['order']);
     }
     // remove subtable reports
     if (!$showSubtableReports) {
         foreach ($availableReports as $idx => $report) {
             if (isset($report['isSubtableReport']) && $report['isSubtableReport']) {
                 unset($availableReports[$idx]);
             }
         }
     }
     $actualReports = array_values($availableReports);
     $cache->save($key, $actualReports);
     return $actualReports;
     // make sure array has contiguous key values
 }
 /**
  * Returns list of int site IDs from site list found in LDAP.
  *
  * @param string $sitesSpec eg, `"1,2,3"` or `"all"`
  * @return int[]
  */
 protected function getSitesFromSitesList($sitesSpec)
 {
     return Access::doAsSuperUser(function () use($sitesSpec) {
         return Site::getIdSitesFromIdSitesString($sitesSpec);
     });
 }
Пример #21
0
 /**
  * Returns all annotations within a specific date range. The result is
  * an array that maps site IDs with arrays of annotations within the range.
  *
  * Note: The date range is inclusive.
  *
  * @see self::get for info on what attributes stored within annotations.
  *
  * @param Date|bool $startDate The start of the date range.
  * @param Date|bool $endDate The end of the date range.
  * @param array|bool|int|string $idSite IDs of the sites whose annotations to
  *                                       search through.
  * @return array Array mapping site IDs with arrays of annotations, eg:
  *               array(
  *                 '5' => array(
  *                          array(...), // annotation
  *                          array(...), // annotation
  *                          ...
  *                        ),
  *                 '6' => array(
  *                          array(...), // annotation
  *                          array(...), // annotation
  *                          ...
  *                        ),
  *               )
  */
 public function search($startDate, $endDate, $idSite = false)
 {
     if ($idSite) {
         $idSites = Site::getIdSitesFromIdSitesString($idSite);
     } else {
         $idSites = array_keys($this->annotations);
     }
     // collect annotations that are within the right date range & belong to the right
     // site
     $result = array();
     foreach ($idSites as $idSite) {
         if (!isset($this->annotations[$idSite])) {
             continue;
         }
         foreach ($this->annotations[$idSite] as $idNote => $annotation) {
             if ($startDate !== false) {
                 $annotationDate = Date::factory($annotation['date']);
                 if ($annotationDate->getTimestamp() < $startDate->getTimestamp() || $annotationDate->getTimestamp() > $endDate->getTimestamp()) {
                     continue;
                 }
             }
             $this->augmentAnnotationData($idSite, $idNote, $annotation);
             $result[$idSite][] = $annotation;
         }
         // sort by annotation date
         if (!empty($result[$idSite])) {
             uasort($result[$idSite], array($this, 'compareAnnotationDate'));
         }
     }
     return $result;
 }
Пример #22
0
 /**
  * Returns a new Archive instance that will query archive data for the given set of
  * sites and periods, using an optional Segment.
  *
  * This method uses data that is found in query parameters, so the parameters to this
  * function can be string values.
  *
  * If you want to create an Archive instance with an array of Period instances, use
  * {@link Archive::factory()}.
  *
  * @param string|int|array $idSites A single ID (eg, `'1'`), multiple IDs (eg, `'1,2,3'` or `array(1, 2, 3)`),
  *                                  or `'all'`.
  * @param string $period 'day', `'week'`, `'month'`, `'year'` or `'range'`
  * @param Date|string $strDate 'YYYY-MM-DD', magic keywords (ie, 'today'; {@link Date::factory()}
  *                             or date range (ie, 'YYYY-MM-DD,YYYY-MM-DD').
  * @param bool|false|string $segment Segment definition or false if no segment should be used. {@link Piwik\Segment}
  * @param bool|false|string $_restrictSitesToLogin Used only when running as a scheduled task.
  * @param bool $skipAggregationOfSubTables Whether the archive, when it is processed, should also aggregate all sub-tables
  * @return Archive
  */
 public static function build($idSites, $period, $strDate, $segment = false, $_restrictSitesToLogin = false, $skipAggregationOfSubTables = false)
 {
     $websiteIds = Site::getIdSitesFromIdSitesString($idSites, $_restrictSitesToLogin);
     if (Period::isMultiplePeriod($strDate, $period)) {
         $oPeriod = Factory::build($period, $strDate);
         $allPeriods = $oPeriod->getSubperiods();
     } else {
         $timezone = count($websiteIds) == 1 ? Site::getTimezoneFor($websiteIds[0]) : false;
         $oPeriod = Factory::makePeriodFromQueryParams($timezone, $period, $strDate);
         $allPeriods = array($oPeriod);
     }
     $segment = new Segment($segment, $websiteIds);
     $idSiteIsAll = $idSites == self::REQUEST_ALL_WEBSITES_FLAG;
     $isMultipleDate = Period::isMultiplePeriod($strDate, $period);
     return Archive::factory($segment, $allPeriods, $websiteIds, $idSiteIsAll, $isMultipleDate, $skipAggregationOfSubTables);
 }
Пример #23
0
 /**
  * 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);
 }
Пример #24
0
 /**
  * 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();
 }
Пример #25
0
 /**
  * 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;
 }
Пример #26
0
 /**
  * Get triggered alerts.
  *
  * @param int[] idSites
  *
  * @return array
  */
 public function getTriggeredAlerts($idSites)
 {
     if (empty($idSites)) {
         return array();
     }
     $idSites = Site::getIdSitesFromIdSitesString($idSites);
     Piwik::checkUserHasViewAccess($idSites);
     $login = Piwik::getCurrentUserLogin();
     return $this->getModel()->getTriggeredAlerts($idSites, $login);
 }
Пример #27
0
 private static function getSitesListOption(InputInterface $input, $optionName)
 {
     return Site::getIdSitesFromIdSitesString($input->getOption($optionName));
 }
 /**
  * Creates a UserSynchronizer using INI configuration.
  *
  * @return UserSynchronizer
  */
 public static function makeConfigured()
 {
     $result = new UserSynchronizer();
     $result->setUserMapper(UserMapper::makeConfigured());
     $result->setUsersManagerApi(UsersManagerAPI::getInstance());
     $result->setUserModel(new UserModel());
     /** @var LoggerInterface $logger */
     $logger = StaticContainer::get('Psr\\Log\\LoggerInterface');
     if (Config::isAccessSynchronizationEnabled()) {
         $result->setUserAccessMapper(UserAccessMapper::makeConfigured());
         $logger->debug("UserSynchronizer::{func}(): Using UserAccessMapper when synchronizing users.", array('func' => __FUNCTION__));
     } else {
         $logger->debug("UserSynchronizer::{func}(): LDAP access synchronization not enabled.", array('func' => __FUNCTION__));
     }
     $defaultSitesWithViewAccess = Config::getDefaultSitesToGiveViewAccessTo();
     if (!empty($defaultSitesWithViewAccess)) {
         $siteIds = Access::doAsSuperUser(function () use($defaultSitesWithViewAccess) {
             return Site::getIdSitesFromIdSitesString($defaultSitesWithViewAccess);
         });
         if (empty($siteIds)) {
             $logger->warning("UserSynchronizer::{func}(): new_user_default_sites_view_access INI config option has no " . "entries. Newly synchronized users will not have any access.", array('func' => __FUNCTION__));
         }
         $result->setNewUserDefaultSitesWithViewAccess($siteIds);
     }
     $logger->debug("UserSynchronizer::{func}: configuring with defaultSitesWithViewAccess = {sites}", array('func' => __FUNCTION__, 'sites' => $defaultSitesWithViewAccess));
     return $result;
 }