/** * This method selects all DataTables that have the name $name over the period. * It calls the appropriate methods that sum all these tables together. * The resulting DataTable is returned. * * @param string $name * @param array $invalidSummedColumnNameToRenamedName columns in the array (old name, new name) to be renamed as the sum operation is not valid on them (eg. nb_uniq_visitors->sum_daily_nb_uniq_visitors) * @return Piwik_DataTable */ protected function getRecordDataTableSum($name, $invalidSummedColumnNameToRenamedName) { $table = new Piwik_DataTable(); foreach ($this->archives as $archive) { $archive->preFetchBlob($name); $datatableToSum = $archive->getDataTable($name); $archive->loadSubDataTables($name, $datatableToSum); $table->addDataTable($datatableToSum); $archive->freeBlob($name); } if (is_null($invalidSummedColumnNameToRenamedName)) { $invalidSummedColumnNameToRenamedName = self::$invalidSummedColumnNameToRenamedName; } foreach ($invalidSummedColumnNameToRenamedName as $oldName => $newName) { $table->renameColumn($oldName, $newName); } return $table; }
/** * test add 2 different tables to the same table * * @group Core * @group DataTable */ public function testAddDataTable2times() { $idcol = Piwik_DataTable_Row::COLUMNS; $rows = array(array($idcol => array('label' => 'google', 'visits' => 1)), array($idcol => array('label' => 'ask', 'visits' => 0)), array($idcol => array('label' => '123', 'visits' => 2)), Piwik_DataTable::ID_SUMMARY_ROW => array($idcol => array('label' => Piwik_DataTable::LABEL_SUMMARY_ROW, 'visits' => 1))); $table = new Piwik_DataTable(); $table->addRowsFromArray($rows); $rows2 = array(array($idcol => array('label' => 'google2', 'visits' => -1)), array($idcol => array('label' => 'ask', 'visits' => 100)), array($idcol => array('label' => '123456', 'visits' => 1.5))); $table2 = new Piwik_DataTable(); $table2->addRowsFromArray($rows2); $rows3 = array(array($idcol => array('label' => 'google2', 'visits' => -1)), array($idcol => array('label' => 'ask', 'visits' => -10)), array($idcol => array('label' => '123ab', 'visits' => 1.5)), Piwik_DataTable::ID_SUMMARY_ROW => array($idcol => array('label' => Piwik_DataTable::LABEL_SUMMARY_ROW, 'visits' => 3))); $table3 = new Piwik_DataTable(); $table3->addRowsFromArray($rows3); // add the 2 tables $table->addDataTable($table2); $table->addDataTable($table3); $rowsExpected = array(array($idcol => array('label' => 'google', 'visits' => 1)), array($idcol => array('label' => 'ask', 'visits' => 90)), array($idcol => array('label' => '123', 'visits' => 2)), array($idcol => array('label' => 'google2', 'visits' => -2)), array($idcol => array('label' => '123456', 'visits' => 1.5)), array($idcol => array('label' => '123ab', 'visits' => 1.5)), Piwik_DataTable::ID_SUMMARY_ROW => array($idcol => array('label' => Piwik_DataTable::LABEL_SUMMARY_ROW, 'visits' => 4))); $tableExpected = new Piwik_DataTable(); $tableExpected->addRowsFromArray($rowsExpected); $this->assertTrue(Piwik_DataTable::isEqual($table, $tableExpected)); }
/** * @param Piwik_ArchiveProcessing_Day $archiveProcessing */ function archiveGeneralGoalMetrics($archiveProcessing) { // extra aggregate selects for the visits to conversion report $visitToConvExtraCols = Piwik_ArchiveProcessing_Day::buildReduceByRangeSelect('visitor_count_visits', self::$visitCountRanges, 'log_conversion', 'vcv'); // extra aggregate selects for the days to conversion report $daysToConvExtraCols = Piwik_ArchiveProcessing_Day::buildReduceByRangeSelect('visitor_days_since_first', self::$daysToConvRanges, 'log_conversion', 'vdsf'); $query = $archiveProcessing->queryConversionsByDimension(array(), '', array_merge($visitToConvExtraCols, $daysToConvExtraCols)); if ($query === false) { return; } $goals = array(); $visitsToConvReport = array(); $daysToConvReport = array(); // Get a standard empty goal row $overall = $archiveProcessing->getNewGoalRow($idGoal = 1); while ($row = $query->fetch()) { $idgoal = $row['idgoal']; if (!isset($goals[$idgoal])) { $goals[$idgoal] = $archiveProcessing->getNewGoalRow($idgoal); $visitsToConvReport[$idgoal] = new Piwik_DataTable(); $daysToConvReport[$idgoal] = new Piwik_DataTable(); } $archiveProcessing->updateGoalStats($row, $goals[$idgoal]); // We don't want to sum Abandoned cart metrics in the overall revenue/conversions/converted visits // since it is a "negative conversion" if ($idgoal != Piwik_Tracker_GoalManager::IDGOAL_CART) { $archiveProcessing->updateGoalStats($row, $overall); } // map the goal + visit number of a visitor with the # of conversions that happened on that visit $table = $archiveProcessing->getSimpleDataTableFromRow($row, Piwik_Archive::INDEX_NB_CONVERSIONS, 'vcv'); $visitsToConvReport[$idgoal]->addDataTable($table); // map the goal + day number of a visit with the # of conversion that happened on that day $table = $archiveProcessing->getSimpleDataTableFromRow($row, Piwik_Archive::INDEX_NB_CONVERSIONS, 'vdsf'); $daysToConvReport[$idgoal]->addDataTable($table); } // these data tables hold reports for every goal of a site $visitsToConvOverview = new Piwik_DataTable(); $daysToConvOverview = new Piwik_DataTable(); // Stats by goal, for all visitors foreach ($goals as $idgoal => $values) { foreach ($values as $metricId => $value) { $metricName = Piwik_Archive::$mappingFromIdToNameGoal[$metricId]; $recordName = self::getRecordName($metricName, $idgoal); $archiveProcessing->insertNumericRecord($recordName, $value); } $conversion_rate = $this->getConversionRate($values[Piwik_Archive::INDEX_GOAL_NB_VISITS_CONVERTED], $archiveProcessing); $recordName = self::getRecordName('conversion_rate', $idgoal); $archiveProcessing->insertNumericRecord($recordName, $conversion_rate); // if the goal is not a special goal (like ecommerce) add it to the overview report if ($idgoal !== Piwik_Tracker_GoalManager::IDGOAL_CART && $idgoal !== Piwik_Tracker_GoalManager::IDGOAL_ORDER) { $visitsToConvOverview->addDataTable($visitsToConvReport[$idgoal]); $daysToConvOverview->addDataTable($daysToConvReport[$idgoal]); } // visit count until conversion stats $archiveProcessing->insertBlobRecord(self::getRecordName(self::VISITS_UNTIL_RECORD_NAME, $idgoal), $visitsToConvReport[$idgoal]->getSerialized()); // day count until conversion stats $archiveProcessing->insertBlobRecord(self::getRecordName(self::DAYS_UNTIL_CONV_RECORD_NAME, $idgoal), $daysToConvReport[$idgoal]->getSerialized()); } // archive overview reports $archiveProcessing->insertBlobRecord(self::getRecordName(self::VISITS_UNTIL_RECORD_NAME), $visitsToConvOverview->getSerialized()); $archiveProcessing->insertBlobRecord(self::getRecordName(self::DAYS_UNTIL_CONV_RECORD_NAME), $daysToConvOverview->getSerialized()); // Stats for all goals $totalAllGoals = array(self::getRecordName('conversion_rate') => $this->getConversionRate($archiveProcessing->getNumberOfVisitsConverted(), $archiveProcessing), self::getRecordName('nb_conversions') => $overall[Piwik_Archive::INDEX_GOAL_NB_CONVERSIONS], self::getRecordName('nb_visits_converted') => $archiveProcessing->getNumberOfVisitsConverted(), self::getRecordName('revenue') => $overall[Piwik_Archive::INDEX_GOAL_REVENUE]); foreach ($totalAllGoals as $recordName => $value) { $archiveProcessing->insertNumericRecord($recordName, $value); } }
/** * 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; }
/** * This method selects all DataTables that have the name $name over the period. * It calls the appropriate methods that sum all these tables together. * The resulting DataTable is returned. * * @param string $name * @return Piwik_DataTable */ protected function getRecordDataTableSum($name) { $table = new Piwik_DataTable(); foreach ($this->archives as $archive) { $archive->preFetchBlob($name); $datatableToSum = $archive->getDataTable($name); $archive->loadSubDataTables($name, $datatableToSum); $table->addDataTable($datatableToSum); $archive->freeBlob($name); } return $table; }
/** * 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; }