Ejemplo n.º 1
0
 /**
  * Adds a summary row to the given data table
  *
  * @param Piwik_DataTable  $table
  */
 public function filter($table)
 {
     if ($table->getRowsCount() <= $this->startRowToSummarize + 1) {
         return;
     }
     $table->filter('Sort', array($this->columnToSortByBeforeTruncating, 'desc'));
     $rows = $table->getRows();
     $count = $table->getRowsCount();
     $newRow = new Piwik_DataTable_Row();
     for ($i = $this->startRowToSummarize; $i < $count; $i++) {
         if (!isset($rows[$i])) {
             // case when the last row is a summary row, it is not indexed by $cout but by Piwik_DataTable::ID_SUMMARY_ROW
             $summaryRow = $table->getRowFromId(Piwik_DataTable::ID_SUMMARY_ROW);
             //FIXME: I'm not sure why it could return false, but it was reported in: http://forum.piwik.org/read.php?2,89324,page=1#msg-89442
             if ($summaryRow) {
                 $newRow->sumRow($summaryRow, $enableCopyMetadata = false);
             }
         } else {
             $newRow->sumRow($rows[$i], $enableCopyMetadata = false);
         }
     }
     $newRow->setColumns(array('label' => $this->labelSummaryRow) + $newRow->getColumns());
     if ($this->deleteRows) {
         $table->filter('Limit', array(0, $this->startRowToSummarize));
     }
     $table->addSummaryRow($newRow);
     unset($rows);
 }
Ejemplo n.º 2
0
 /**
  * Truncates the table after X rows and adds a summary row
  *
  * @param Piwik_DataTable  $table
  */
 public function filter($table)
 {
     $table->filter('AddSummaryRow', array($this->truncateAfter));
     $table->filter('ReplaceSummaryRowLabel');
     foreach ($table->getRows() as $row) {
         if ($row->isSubtableLoaded()) {
             $idSubTable = $row->getIdSubDataTable();
             $subTable = Piwik_DataTable_Manager::getInstance()->getTable($idSubTable);
             $subTable->filter('Truncate', array($this->truncateAfter));
         }
     }
 }
Ejemplo n.º 3
0
 /**
  * Hook called after the dataTable has been loaded from the API
  * Can be used to add, delete or modify the data freshly loaded
  */
 protected function postDataTableLoadedFromAPI()
 {
     if (empty($this->dataTable)) {
         return false;
     }
     // First, filters that delete rows
     foreach ($this->queuedFiltersPriority as $filter) {
         $filterName = $filter[0];
         $filterParameters = $filter[1];
         $this->dataTable->filter($filterName, $filterParameters);
     }
     if (0 == Piwik_Common::getRequestVar('disable_generic_filters', '0', 'string')) {
         // Second, generic filters (Sort, Limit, Replace Column Names, etc.)
         $requestString = $this->getRequestString();
         $request = Piwik_API_Request::getRequestArrayFromString($requestString);
         if (!empty($this->variablesDefault['enable_sort']) && $this->variablesDefault['enable_sort'] === 'false') {
             $request['filter_sort_column'] = $request['filter_sort_order'] = '';
         }
         $genericFilter = new Piwik_API_DataTableGenericFilter($request);
         $genericFilter->filter($this->dataTable);
     }
     // Finally, apply datatable filters that were queued (should be 'presentation' filters that do not affect the number of rows)
     foreach ($this->queuedFilters as $filter) {
         $filterName = $filter[0];
         $filterParameters = $filter[1];
         $this->dataTable->filter($filterName, $filterParameters);
     }
 }
Ejemplo n.º 4
0
 /**
  * Hook called after the dataTable has been loaded from the API
  * Can be used to add, delete or modify the data freshly loaded
  * 
  * @return bool
  */
 protected function postDataTableLoadedFromAPI()
 {
     if (empty($this->dataTable)) {
         return false;
     }
     // deal w/ table metadata
     if ($this->dataTable instanceof Piwik_DataTable) {
         $this->viewProperties['metadata'] = $this->dataTable->getAllTableMetadata();
         if (isset($this->viewProperties['metadata'][Piwik_DataTable::ARCHIVED_DATE_METADATA_NAME])) {
             $this->viewProperties['metadata'][Piwik_DataTable::ARCHIVED_DATE_METADATA_NAME] = $this->makePrettyArchivedOnText();
         }
     }
     // First, filters that delete rows
     foreach ($this->queuedFiltersPriority as $filter) {
         $filterName = $filter[0];
         $filterParameters = $filter[1];
         $this->dataTable->filter($filterName, $filterParameters);
     }
     if (!$this->areGenericFiltersDisabled()) {
         // Second, generic filters (Sort, Limit, Replace Column Names, etc.)
         $requestString = $this->getRequestString();
         $request = Piwik_API_Request::getRequestArrayFromString($requestString);
         if (!empty($this->variablesDefault['enable_sort']) && $this->variablesDefault['enable_sort'] === 'false') {
             $request['filter_sort_column'] = $request['filter_sort_order'] = '';
         }
         $genericFilter = new Piwik_API_DataTableGenericFilter($request);
         $genericFilter->filter($this->dataTable);
     }
     if (!$this->areQueuedFiltersDisabled()) {
         // Finally, apply datatable filters that were queued (should be 'presentation' filters that
         // do not affect the number of rows)
         foreach ($this->queuedFilters as $filter) {
             $filterName = $filter[0];
             $filterParameters = $filter[1];
             $this->dataTable->filter($filterName, $filterParameters);
         }
     }
     return true;
 }
Ejemplo n.º 5
0
 /**
  * Apply generic filters to the DataTable object resulting from the API Call.
  * Disable this feature by setting the parameter disable_generic_filters to 1 in the API call request.
  * 
  * @param Piwik_DataTable  $datatable
  * @return bool
  */
 protected function applyGenericFilters($datatable)
 {
     if ($datatable instanceof Piwik_DataTable_Array) {
         $tables = $datatable->getArray();
         $filterWasApplied = false;
         foreach ($tables as $table) {
             $filterWasApplied = $this->applyGenericFilters($table);
         }
         return;
     }
     $genericFilters = self::getGenericFiltersInformation();
     $filterApplied = false;
     foreach ($genericFilters as $filterName => $parameters) {
         $filterParameters = array();
         $exceptionRaised = false;
         foreach ($parameters as $name => $info) {
             // parameter type to cast to
             $type = $info[0];
             // default value if specified, when the parameter doesn't have a value
             $defaultValue = null;
             if (isset($info[1])) {
                 $defaultValue = $info[1];
             }
             // third element in the array, if it exists, overrides the name of the request variable
             $varName = $name;
             if (isset($info[2])) {
                 $varName = $info[2];
             }
             try {
                 $value = Piwik_Common::getRequestVar($name, $defaultValue, $type, $this->request);
                 settype($value, $type);
                 $filterParameters[] = $value;
             } catch (Exception $e) {
                 $exceptionRaised = true;
                 break;
             }
         }
         if (!$exceptionRaised) {
             $datatable->filter($filterName, $filterParameters);
             $filterApplied = true;
         }
     }
     return $filterApplied;
 }
Ejemplo n.º 6
0
 /**
  * Enhance a $dataTable using metadata :
  *
  * - remove metrics based on $reportMetadata['metrics']
  * - add 0 valued metrics if $dataTable doesn't provide all $reportMetadata['metrics']
  * - format metric values to a 'human readable' format
  * - extract row metadata to a separate Piwik_DataTable_Simple|Piwik_DataTable_Array : $rowsMetadata
  * - translate metric names to a separate array : $columns
  *
  * @param int $idSite enables monetary value formatting based on site currency
  * @param Piwik_DataTable|Piwik_DataTable_Array $dataTable
  * @param array $reportMetadata
  * @param boolean $hasDimension
  * @return array Piwik_DataTable_Simple|Piwik_DataTable_Array $newReport with human readable format & array $columns list of translated column names & Piwik_DataTable_Simple|Piwik_DataTable_Array $rowsMetadata
  **/
 private function handleTableReport($idSite, $dataTable, &$reportMetadata, $hasDimension)
 {
     $columns = $reportMetadata['metrics'];
     if ($hasDimension) {
         $columns = array_merge(array('label' => $reportMetadata['dimension']), $columns);
         if (isset($reportMetadata['processedMetrics'])) {
             $processedMetricsAdded = $this->getDefaultProcessedMetrics();
             foreach ($processedMetricsAdded as $processedMetricId => $processedMetricTranslation) {
                 // this processed metric can be displayed for this report
                 if (isset($reportMetadata['processedMetrics'][$processedMetricId])) {
                     $columns[$processedMetricId] = $processedMetricTranslation;
                 }
             }
         }
         // Display the global Goal metrics
         if (isset($reportMetadata['metricsGoal'])) {
             $metricsGoalDisplay = array('revenue');
             // Add processed metrics to be displayed for this report
             foreach ($metricsGoalDisplay as $goalMetricId) {
                 if (isset($reportMetadata['metricsGoal'][$goalMetricId])) {
                     $columns[$goalMetricId] = $reportMetadata['metricsGoal'][$goalMetricId];
                 }
             }
         }
         if (isset($reportMetadata['processedMetrics'])) {
             // Add processed metrics
             $dataTable->filter('AddColumnsProcessedMetrics', array($deleteRowsWithNoVisit = false));
         }
     }
     // $dataTable is an instance of Piwik_DataTable_Array when multiple periods requested
     if ($dataTable instanceof Piwik_DataTable_Array) {
         // Need a new Piwik_DataTable_Array to store the 'human readable' values
         $newReport = new Piwik_DataTable_Array();
         $newReport->setKeyName("prettyDate");
         $dataTableMetadata = $dataTable->metadata;
         $newReport->metadata = $dataTableMetadata;
         // Need a new Piwik_DataTable_Array to store report metadata
         $rowsMetadata = new Piwik_DataTable_Array();
         $rowsMetadata->setKeyName("prettyDate");
         // Process each Piwik_DataTable_Simple entry
         foreach ($dataTable->getArray() as $label => $simpleDataTable) {
             list($enhancedSimpleDataTable, $rowMetadata) = $this->handleSimpleDataTable($idSite, $simpleDataTable, $columns, $hasDimension);
             $period = $dataTableMetadata[$label]['period']->getLocalizedLongString();
             $newReport->addTable($enhancedSimpleDataTable, $period);
             $rowsMetadata->addTable($rowMetadata, $period);
         }
     } else {
         list($newReport, $rowsMetadata) = $this->handleSimpleDataTable($idSite, $dataTable, $columns, $hasDimension);
     }
     return array($newReport, $columns, $rowsMetadata);
 }
Ejemplo n.º 7
0
 /**
  * Utility function used by getAll. Performs a binary filter of two
  * DataTables in order to correctly calculate evolution metrics.
  * 
  * @param Piwik_DataTable|Piwik_DataTable_Array $currentData
  * @param Piwik_DataTable|Piwik_DataTable_Array $pastData
  * @param array $fields The array of string fields to calculate evolution
  *                      metrics for.
  */
 private function calculateEvolutionPercentages($currentData, $pastData, $fields)
 {
     if ($currentData instanceof Piwik_DataTable_Array) {
         $pastArray = $pastData->getArray();
         foreach ($currentData->getArray() as $label => $subTable) {
             $this->calculateEvolutionPercentages($subTable, current($pastArray), $fields);
             next($pastArray);
         }
     } else {
         foreach ($fields as $field) {
             $currentData->filter('Piwik_MultiSites_CalculateEvolutionFilter', array($pastData, $this->evolutionColumnNames[$field], $field, $quotientPrecision = 2));
         }
     }
 }
Ejemplo n.º 8
0
 /**
  * Returns datatable describing the number of visits for each day of the week.
  * 
  * @param string $idSite The site ID. Cannot refer to multiple sites.
  * @param string $period The period type: day, week, year, range...
  * @param string $date The start date of the period. Cannot refer to multiple dates.
  * @param string $segment The segment.
  * @return Piwik_DataTable
  */
 public function getByDayOfWeek($idSite, $period, $date, $segment = false)
 {
     Piwik::checkUserHasViewAccess($idSite);
     // disabled for multiple sites/dates
     if (Piwik_Archive::isMultipleSites($idSite)) {
         throw new Exception("VisitTime.getByDayOfWeek does not support multiple sites.");
     }
     if (Piwik_Archive::isMultiplePeriod($date, $period)) {
         throw new Exception("VisitTime.getByDayOfWeek does not support multiple dates.");
     }
     // metrics to query
     $metrics = Piwik_ArchiveProcessing::getCoreMetrics();
     // get metric data for every day within the supplied period
     $oSite = new Piwik_Site($idSite);
     $oPeriod = Piwik_Archive::makePeriodFromQueryParams($oSite, $period, $date);
     $dateRange = $oPeriod->getDateStart()->toString() . ',' . $oPeriod->getDateEnd()->toString();
     $archive = Piwik_Archive::build($idSite, 'day', $dateRange, $segment);
     $dataTable = $archive->getDataTableFromNumeric($metrics)->mergeChildren();
     // if there's no data for this report, don't bother w/ anything else
     if ($dataTable->getRowsCount() == 0) {
         return $dataTable;
     }
     // group by the day of the week (see below for dayOfWeekFromDate function)
     $dataTable->filter('GroupBy', array('label', 'Piwik_VisitTime_dayOfWeekFromDate'));
     // create new datatable w/ empty rows, then add calculated datatable
     $rows = array();
     foreach (array(1, 2, 3, 4, 5, 6, 7) as $day) {
         $rows[] = array('label' => $day, 'nb_visits' => 0);
     }
     $result = new Piwik_DataTable();
     $result->addRowsFromSimpleArray($rows);
     $result->addDataTable($dataTable);
     // set day of week integer as metadata
     $result->filter('ColumnCallbackAddMetadata', array('label', 'day_of_week'));
     // translate labels
     $result->filter('ColumnCallbackReplace', array('label', 'Piwik_VisitTime_translateDayOfWeek'));
     // set datatable metadata for period start & finish
     $result->setMetadata('date_start', $oPeriod->getDateStart());
     $result->setMetadata('date_end', $oPeriod->getDateEnd());
     return $result;
 }
Ejemplo n.º 9
0
 /**
  * Performs a binary filter of two
  * DataTables in order to correctly calculate evolution metrics.
  * 
  * @param Piwik_DataTable|Piwik_DataTable_Array $currentData
  * @param Piwik_DataTable|Piwik_DataTable_Array $pastData
  * @param array $fields The array of string fields to calculate evolution
  *                      metrics for.
  */
 private function calculateEvolutionPercentages($currentData, $pastData, $apiMetrics)
 {
     if ($currentData instanceof Piwik_DataTable_Array) {
         $pastArray = $pastData->getArray();
         foreach ($currentData->getArray() as $subTable) {
             $this->calculateEvolutionPercentages($subTable, current($pastArray), $apiMetrics);
             next($pastArray);
         }
     } else {
         foreach ($apiMetrics as $metricSettings) {
             $currentData->filter('Piwik_MultiSites_CalculateEvolutionFilter', array($pastData, $metricSettings[self::METRIC_EVOLUTION_COL_NAME_KEY], $metricSettings[self::METRIC_RECORD_NAME_KEY], $quotientPrecision = 2));
         }
     }
 }
Ejemplo n.º 10
0
 /**
  * Executes filter and removes all rows below the defined minimum
  *
  * @param Piwik_DataTable  $table
  */
 function filter($table)
 {
     $table->filter('ColumnCallbackDeleteRow', array($this->columnToFilter, array("Piwik_DataTable_Filter_ExcludeLowPopulation", "excludeLowPopulation")));
 }
Ejemplo n.º 11
0
 /**
  * Utility function. Gets row count of a set of tables grouped by the 'name' column.
  * This is the implementation of the getRowCountsAndSizeBy... functions.
  */
 private function getRowCountsByArchiveName($statuses, $getRowSizeMethod, $forceCache = false, $otherSelects = array(), $otherDataTableColumns = array())
 {
     $extraCols = '';
     if (!empty($otherSelects)) {
         $extraCols = ', ' . implode(', ', $otherSelects);
     }
     $cols = array_merge(array('row_count'), $otherDataTableColumns);
     $dataTable = new Piwik_DataTable();
     foreach ($statuses as $status) {
         $dataTableOptionName = $this->getCachedOptionName($status['Name'], 'byArchiveName');
         // if option exists && !$forceCache, use the cached data, otherwise create the
         $cachedData = Piwik_GetOption($dataTableOptionName);
         if ($cachedData !== false && !$forceCache) {
             $table = new Piwik_DataTable();
             $table->addRowsFromSerializedArray($cachedData);
         } else {
             // otherwise, create data table & cache it
             $sql = "SELECT name as 'label', COUNT(*) as 'row_count'{$extraCols} FROM {$status['Name']} GROUP BY name";
             $table = new Piwik_DataTable();
             $table->addRowsFromSimpleArray(Piwik_FetchAll($sql));
             $reduceArchiveRowName = array($this, 'reduceArchiveRowName');
             $table->filter('GroupBy', array('label', $reduceArchiveRowName));
             $serializedTables = $table->getSerialized();
             $serializedTable = reset($serializedTables);
             Piwik_SetOption($dataTableOptionName, $serializedTable);
         }
         // add estimated_size column
         $getEstimatedSize = array($this, $getRowSizeMethod);
         $table->filter('ColumnCallbackAddColumn', array($cols, 'estimated_size', $getEstimatedSize, array($status)));
         $dataTable->addDataTable($table);
         destroy($table);
     }
     return $dataTable;
 }
Ejemplo n.º 12
0
 /**
  * Removes DataTable rows referencing actions that were never the last action of a visit.
  * 
  * @param Piwik_DataTable $dataTable
  */
 private function filterNonExitActions($dataTable)
 {
     $dataTable->filter('ColumnCallbackDeleteRow', array('exit_nb_visits', 'strlen'));
 }