/** * @param Piwik_DataTable_Row $row * @param Piwik_DataTable $dataTable * @param string $date * @param string $labelPrefix * @param bool $parentLogo */ private function flattenRow(Piwik_DataTable_Row $row, Piwik_DataTable $dataTable, $date, $labelPrefix = '', $parentLogo = false) { $label = $row->getColumn('label'); if ($label !== false) { $label = trim($label); if (substr($label, 0, 1) == '/' && $this->recursiveLabelSeparator == '/') { $label = substr($label, 1); } $label = $labelPrefix . $label; $row->setColumn('label', $label); } $logo = $row->getMetadata('logo'); if ($logo === false && $parentLogo !== false) { $logo = $parentLogo; $row->setMetadata('logo', $logo); } $subTable = $this->loadSubtable($row, $date); $row->removeSubtable(); if ($subTable === null) { if ($this->includeAggregateRows) { $row->setMetadata('is_aggregate', 0); } $dataTable->addRow($row); } else { if ($this->includeAggregateRows) { $row->setMetadata('is_aggregate', 1); $dataTable->addRow($row); } $prefix = $label . $this->recursiveLabelSeparator; foreach ($subTable->getRows() as $row) { $this->flattenRow($row, $dataTable, $date, $prefix, $logo); } } }
protected function updateActionsTableWithRowQuery($query) { $rowsProcessed = 0; while ($row = $query->fetch()) { // in some unknown case, the type field is NULL, as reported in #1082 - we ignore this page view if (empty($row['type'])) { continue; } $actionExplodedNames = $this->getActionExplodedNames($row['name'], $row['type']); // we work on the root table of the given TYPE (either ACTION_URL or DOWNLOAD or OUTLINK etc.) $currentTable =& $this->actionsTablesByType[$row['type']]; // go to the level of the subcategory $end = count($actionExplodedNames) - 1; for ($level = 0; $level < $end; $level++) { $actionCategory = $actionExplodedNames[$level]; $currentTable =& $currentTable[$actionCategory]; } $actionName = $actionExplodedNames[$end]; // we are careful to prefix the page URL / name with some value // so that if a page has the same name as a category // we don't merge both entries if ($row['type'] == Piwik_Tracker_Action::TYPE_ACTION_URL) { $actionName = '/' . $actionName; } else { $actionName = ' ' . $actionName; } // currentTable is now the array element corresponding the the action // at this point we may be for example at the 4th level of depth in the hierarchy $currentTable =& $currentTable[$actionName]; // add the row to the matching sub category subtable if (!$currentTable instanceof Piwik_DataTable_Row) { if ($row['type'] == Piwik_Tracker_Action::TYPE_ACTION_NAME) { $currentTable = new Piwik_DataTable_Row(array(Piwik_DataTable_Row::COLUMNS => array('label' => (string) $actionName))); } else { $currentTable = new Piwik_DataTable_Row(array(Piwik_DataTable_Row::COLUMNS => array('label' => (string) $actionName), Piwik_DataTable_Row::METADATA => array('url' => (string) $row['name']))); } } foreach ($row as $name => $value) { // we don't add this information as itnot pertinent // name is already set as the label // and it has been cleaned from the categories and extracted from the initial string // type is used to partition the different actions type in different table. Adding the info to the row would be a duplicate. if ($name != 'name' && $name != 'type') { // in some edge cases, we have twice the same action name with 2 different idaction // this happens when 2 visitors visit the same new page at the same time, there is a SELECT and an INSERT for each new page, // and in between the two the other visitor comes. // here we handle the case where there is already a row for this action name, if this is the case we add the value if (($alreadyValue = $currentTable->getColumn($name)) !== false) { $currentTable->setColumn($name, $alreadyValue + $value); } else { $currentTable->addColumn($name, $value); } } } // if the exit_action was not recorded properly in the log_link_visit_action // there would be an error message when getting the nb_hits column // we must fake the record and add the columns if ($currentTable->getColumn('nb_hits') === false) { // to test this code: delete the entries in log_link_action_visit for // a given exit_idaction_url foreach ($this->defaultRow->getColumns() as $name => $value) { $currentTable->addColumn($name, $value); } } // simple count $rowsProcessed++; } // just to make sure php copies the last $currentTable in the $parentTable array $currentTable =& $this->actionsTablesByType; return $rowsProcessed; }
/** * Replaces the given column within given row with the given value * * @param Piwik_DataTable_Row $row * @param string $columnToFilter * @param mixed $newValue */ protected function setElementToReplace($row, $columnToFilter, $newValue) { $row->setColumn($columnToFilter, $newValue); }
/** * Add a row to the table and rebuild the index if necessary * * @param Piwik_DataTable_Row $row to add at the end of the array */ public function addRow(Piwik_DataTable_Row $row) { // if there is a upper limit on the number of allowed rows and the table is full, // add the new row to the summary row if ($this->maximumAllowedRows > 0 && $this->getRowsCount() >= $this->maximumAllowedRows - 1) { if ($this->summaryRow === null) { $this->addSummaryRow(new Piwik_DataTable_Row(array(Piwik_DataTable_Row::COLUMNS => $row->getColumns()))); $this->summaryRow->setColumn('label', self::LABEL_SUMMARY_ROW); } else { $this->summaryRow->sumRow($row, $enableCopyMetadata = false); } return $this->summaryRow; } $this->rows[] = $row; if (!$this->indexNotUpToDate && $this->rebuildIndexContinuously) { $label = $row->getColumn('label'); if ($label !== false) { $this->rowsIndexByLabel[$label] = count($this->rows) - 1; } $this->indexNotUpToDate = false; } return $row; }