Ejemplo n.º 1
0
 public function getCompetitionDatatable()
 {
     $dataTable = new Piwik_DataTable();
     $row1 = new Piwik_DataTable_Row();
     $row1->setColumns(array('name' => 'piwik', 'license' => 'GPL'));
     $dataTable->addRow($row1);
     $dataTable->addRowFromSimpleArray(array('name' => 'google analytics', 'license' => 'commercial'));
     return $dataTable;
 }
Ejemplo n.º 2
0
 /** Build DataTable from array and archive it */
 private function archiveDataArray($keyword, &$data)
 {
     $dataTable = new Piwik_DataTable();
     foreach ($data as &$row) {
         $dataTable->addRow(new Piwik_SiteUsers_ExtendedDataTableRow(array(Piwik_DataTable_Row::COLUMNS => $row)));
     }
     $name = 'SiteUsers_' . $keyword;
     $this->archiveProcessing->insertBlobRecord($name, $dataTable->getSerialized());
     destroy($dataTable);
 }
Ejemplo n.º 3
0
 /**
  *
  * @group Core
  * @group DataTable
  * @group DataTable_Filter
  * @group DataTable_Filter_Truncate
  */
 public function testForInfiniteRecursion()
 {
     $dataTableBeingFiltered = new Piwik_DataTable();
     // remark: this unit test would become invalid and would need to be rewritten if
     // Truncate filter stops calling getIdSubDataTable() on rows associated with a SubDataTable
     $rowBeingFiltered = $this->getMock('Piwik_DataTable_Row', array('getIdSubDataTable'));
     $rowBeingFiltered->expects($this->never())->method('getIdSubDataTable');
     $dataTableBeingFiltered->addRow($rowBeingFiltered);
     // we simulate a legitimate but rare circular reference between a Piwik_DataTable_Row and its
     // enclosing Piwik_DataTable.
     // This can happen because identifiers are not thoroughly synchronized when the expanded parameter
     // is false.
     $rowBeingFiltered->c[Piwik_DataTable_Row::DATATABLE_ASSOCIATED] = $dataTableBeingFiltered->getId();
     $filter = new Piwik_DataTable_Filter_Truncate($dataTableBeingFiltered, 1);
     $filter->filter($dataTableBeingFiltered);
 }
Ejemplo n.º 4
0
 /**
  * Get following pages of a url.
  * This is done on the logs - not the archives!
  * 
  * Note: if you use this method via the regular API, the number of results will be limited.
  * Make sure, you set filter_limit=-1 in the request.
  */
 public function getFollowingPages($url, $idSite, $period, $date, $segment = false)
 {
     $this->authenticate($idSite);
     $url = Piwik_Tracker_Action::excludeQueryParametersFromUrl($url, $idSite);
     // we don't unsanitize $url here. it will be done in the Transitions plugin.
     $resultDataTable = new Piwik_DataTable();
     try {
         $limitBeforeGrouping = Piwik_Config::getInstance()->General['overlay_following_pages_limit'];
         $transitionsReport = Piwik_Transitions_API::getInstance()->getTransitionsForAction($url, $type = 'url', $idSite, $period, $date, $segment, $limitBeforeGrouping, $part = 'followingActions', $returnNormalizedUrls = true);
     } catch (Exception $e) {
         return $resultDataTable;
     }
     $reports = array('followingPages', 'outlinks', 'downloads');
     foreach ($reports as $reportName) {
         if (!isset($transitionsReport[$reportName])) {
             continue;
         }
         foreach ($transitionsReport[$reportName]->getRows() as $row) {
             // don't touch the row at all for performance reasons
             $resultDataTable->addRow($row);
         }
     }
     return $resultDataTable;
 }
Ejemplo n.º 5
0
 /** Build DataTable from array
  * @return Piwik_DataTable */
 private function buildDataTable(&$data)
 {
     $entryUrl = Piwik_LatestReferrers::ENTRY_URL;
     $refUrl = Piwik_LatestReferrers::REFERRER_URL;
     $dataTable = new Piwik_DataTable();
     foreach ($data as &$row) {
         // build data table row
         $rowData = array(Piwik_DataTable_Row::COLUMNS => $row);
         // add entry url
         $rowData[Piwik_DataTable_Row::METADATA]['url'] = array($entryUrl => $row[$entryUrl]);
         // add referrer url, if available
         if (isset($row[$refUrl])) {
             $rowData[Piwik_DataTable_Row::METADATA]['url'][$refUrl] = $row[$refUrl];
         }
         $dataTable->addRow(new Piwik_DataTable_Row($rowData));
     }
     return $dataTable;
 }
Ejemplo n.º 6
0
 /**
  * Enhance $simpleDataTable using metadata :
  *
  * - remove metrics based on $reportMetadata['metrics']
  * - add 0 valued metrics if $simpleDataTable doesn't provide all $reportMetadata['metrics']
  * - format metric values to a 'human readable' format
  * - extract row metadata to a separate Piwik_DataTable_Simple $rowsMetadata
  *
  * @param int $idSite enables monetary value formatting based on site currency
  * @param Piwik_DataTable_Simple $simpleDataTable
  * @param array $metadataColumns
  * @param boolean $hasDimension
  * @return array Piwik_DataTable $enhancedDataTable filtered metrics with human readable format & Piwik_DataTable_Simple $rowsMetadata
  */
 private function handleSimpleDataTable($idSite, $simpleDataTable, $metadataColumns, $hasDimension)
 {
     // new DataTable to store metadata
     $rowsMetadata = new Piwik_DataTable();
     // new DataTable to store 'human readable' values
     if ($hasDimension) {
         $enhancedDataTable = new Piwik_DataTable();
     } else {
         $enhancedDataTable = new Piwik_DataTable_Simple();
     }
     // add missing metrics
     foreach ($simpleDataTable->getRows() as $row) {
         $rowMetrics = $row->getColumns();
         foreach ($metadataColumns as $id => $name) {
             if (!isset($rowMetrics[$id])) {
                 $row->addColumn($id, 0);
             }
         }
     }
     foreach ($simpleDataTable->getRows() as $row) {
         $enhancedRow = new Piwik_DataTable_Row();
         $enhancedDataTable->addRow($enhancedRow);
         $rowMetrics = $row->getColumns();
         foreach ($rowMetrics as $columnName => $columnValue) {
             // filter metrics according to metadata definition
             if (isset($metadataColumns[$columnName])) {
                 // generate 'human readable' metric values
                 $prettyValue = Piwik::getPrettyValue($idSite, $columnName, $columnValue, false, false);
                 $enhancedRow->addColumn($columnName, $prettyValue);
             }
         }
         // If report has a dimension, extract metadata into a distinct DataTable
         if ($hasDimension) {
             $rowMetadata = $row->getMetadata();
             $idSubDataTable = $row->getIdSubDataTable();
             // Create a row metadata only if there are metadata to insert
             if (count($rowMetadata) > 0 || !is_null($idSubDataTable)) {
                 $metadataRow = new Piwik_DataTable_Row();
                 $rowsMetadata->addRow($metadataRow);
                 foreach ($rowMetadata as $metadataKey => $metadataValue) {
                     $metadataRow->addColumn($metadataKey, $metadataValue);
                 }
                 if (!is_null($idSubDataTable)) {
                     $metadataRow->addColumn('idsubdatatable', $idSubDataTable);
                 }
             }
         }
     }
     return array($enhancedDataTable, $rowsMetadata);
 }
Ejemplo n.º 7
0
 /**
  * Generates a dataTable given a multidimensional PHP array that associates LABELS to Piwik_DataTableRows
  * This is used for the "Actions" DataTable, where a line is the aggregate of all the subtables
  * Example: the category /blog has 3 visits because it has /blog/index (2 visits) + /blog/about (1 visit) 
  *
  * @param array $table
  * @return Piwik_DataTable
  */
 public static function generateDataTable($table)
 {
     $dataTableToReturn = new Piwik_DataTable();
     foreach ($table as $label => $maybeDatatableRow) {
         // case the aInfo is a subtable-like array
         // it means that we have to go recursively and process it
         // then we build the row that is an aggregate of all the children
         // and we associate this row to the subtable
         if (!$maybeDatatableRow instanceof Piwik_DataTable_Row) {
             $subTable = self::generateDataTable($maybeDatatableRow);
             $row = new Piwik_DataTable_Row_DataTableSummary($subTable);
             $row->setColumns(array('label' => $label) + $row->getColumns());
             $row->addSubtable($subTable);
         } else {
             $row = $maybeDatatableRow;
         }
         $dataTableToReturn->addRow($row);
     }
     return $dataTableToReturn;
 }
Ejemplo n.º 8
0
 /**
  * Generates a dataTable given a multidimensional PHP array that associates LABELS to Piwik_DataTableRows
  * This is used for the "Actions" DataTable, where a line is the aggregate of all the subtables
  * Example: the category /blog has 3 visits because it has /blog/index (2 visits) + /blog/about (1 visit)
  *
  * @param array  $table
  * @param array  $parents
  * @return Piwik_DataTable
  */
 public static function generateDataTable($table, $parents = array())
 {
     $dataTableToReturn = new Piwik_DataTable();
     foreach ($table as $label => $maybeDatatableRow) {
         // case the aInfo is a subtable-like array
         // it means that we have to go recursively and process it
         // then we build the row that is an aggregate of all the children
         // and we associate this row to the subtable
         if (!$maybeDatatableRow instanceof Piwik_DataTable_Row) {
             array_push($parents, array($dataTableToReturn->getId(), $label));
             $subTable = self::generateDataTable($maybeDatatableRow, $parents);
             $subTable->setParents($parents);
             $row = new Piwik_DataTable_Row_DataTableSummary($subTable);
             $row->setColumns(array('label' => $label) + $row->getColumns());
             $row->addSubtable($subTable);
             array_pop($parents);
         } else {
             $row = $maybeDatatableRow;
         }
         if ($row->getMetadata('issummaryrow') == true) {
             $row->deleteMetadata('issummaryrow');
             $dataTableToReturn->addSummaryRow($row);
         } else {
             $dataTableToReturn->addRow($row);
         }
     }
     return $dataTableToReturn;
 }
Ejemplo n.º 9
0
 /**
  * Build DataTable from array and archive it
  * @return id of the datatable
  */
 private function archiveDataArray($keyword, &$data, $addSearchTermMetaData = false, $addUrlMetaData = false)
 {
     $dataTable = new Piwik_DataTable();
     foreach ($data as &$row) {
         $rowData = array(Piwik_DataTable_Row::COLUMNS => $row);
         if ($addSearchTermMetaData) {
             $rowData[Piwik_DataTable_Row::METADATA] = array('idSearch' => $row[$addSearchTermMetaData], 'searchTerm' => $row[self::SEARCH_TERM]);
         }
         if ($addUrlMetaData) {
             $rowData[Piwik_DataTable_Row::METADATA]['url'] = $row[self::URL];
         }
         $dataTable->addRow(new Piwik_SiteSearch_ExtendedDataTableRow($rowData));
     }
     $id = $dataTable->getId();
     $name = 'SiteSearch_' . $keyword;
     $this->archiveProcessing->insertBlobRecord($name, $dataTable->getSerialized());
     destroy($dataTable);
     return $id;
 }
Ejemplo n.º 10
0
 /**
  * Load the data tables from the API and combine them into a data table
  * that can be plotted
  */
 protected function loadDataTable()
 {
     $metadata = false;
     $dataTableArrays = array();
     // load the tables for each label
     foreach ($this->labels as $rowLabelIndex => $rowLabel) {
         // TODO this used to be: $_GET['label'] = $this->label = $rowLabel;
         // is the $_GET assignment obsolete after label filter refactorings?
         $this->label = $rowLabel;
         $table = $this->doLoadDataTable();
         $dataTableArrays[$rowLabelIndex] = $table->getArray();
         if (!$metadata) {
             $metadata = $table->metadata;
         }
         $urlFound = false;
         foreach ($dataTableArrays[$rowLabelIndex] as $table) {
             if ($table->getRowsCount() > 0) {
                 $firstRow = $table->getFirstRow();
                 // in case labels were replaced in the data table (e.g. for browsers report),
                 // display the label from the table, not the one passed as filter
                 $label = $firstRow->getColumn('label');
                 if (!empty($label)) {
                     $this->labels[$rowLabelIndex] = $label;
                     // special case: websites report
                     if ($this->apiMethod == 'Referers.getWebsites') {
                         $this->labels[$rowLabelIndex] = html_entity_decode($this->labels[$rowLabelIndex]);
                         $urlFound = true;
                     }
                 }
                 // if url is available as metadata, use it (only for actions reports)
                 if (substr($this->apiMethod, 0, 7) == 'Actions' && ($url = $firstRow->getMetadata('url'))) {
                     $this->labels[$rowLabelIndex] = $url;
                     $urlFound = true;
                 }
                 break;
             }
         }
         if (!$urlFound && strpos($rowLabel, Piwik_API_DataTableLabelFilter::RECURSIVE_LABEL_SEPARATOR) !== false) {
             // if we have a recursive label and no url, use the path
             $this->labels[$rowLabelIndex] = str_replace(Piwik_API_DataTableLabelFilter::RECURSIVE_LABEL_SEPARATOR, ' - ', $rowLabel);
         }
     }
     // combine the tables
     $dataTable = new Piwik_DataTable_Array();
     $dataTable->metadata = $metadata;
     foreach (array_keys(reset($dataTableArrays)) as $dateLabel) {
         $newRow = new Piwik_DataTable_Row();
         foreach ($dataTableArrays as $rowLabelIndex => $tableArray) {
             $table = $tableArray[$dateLabel];
             if ($table->getRowsCount() == 0) {
                 $value = 0;
             } else {
                 $value = $table->getFirstRow()->getColumn($this->metric);
                 $value = floatVal(str_replace(',', '.', $value));
                 if ($value == '') {
                     $value = 0;
                 }
             }
             // keep metric in the label so that unit (%, s, ...) can be guessed correctly
             $label = $this->metric . '_' . $rowLabelIndex;
             $newRow->addColumn($label, $value);
         }
         $newTable = new Piwik_DataTable();
         $newTable->addRow($newRow);
         $dataTable->addTable($newTable, $dateLabel);
     }
     // available metrics for metrics picker
     $this->metricsForSelect = $this->availableMetrics;
     $this->availableMetrics = array();
     foreach ($this->labels as $rowLabelIndex => $label) {
         // add metric name
         $label .= ' (' . $this->metricsForSelect[$this->metric] . ')';
         $this->availableMetrics[$this->metric . '_' . $rowLabelIndex] = $label;
     }
     return $dataTable;
 }
Ejemplo n.º 11
0
 /**
  * @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);
         }
     }
 }
 /**
  * General tests that tries to test the normal behaviour of DataTable
  * 
  * We create some tables, add rows, some of the rows link to sub tables
  * 
  * Then we serialize everything, and we check that the unserialize give the same object back
  */
 function test_general()
 {
     /*
      * create some fake tables to make sure that the serialized array of the first TABLE
      * does not take in consideration those tables
      */
     $useless1 = new Piwik_DataTable();
     $useless1->addRowFromArray(array(Piwik_DataTable_Row::COLUMNS => array(13)));
     /*
      * end fake tables
      */
     /*
      * MAIN TABLE
      */
     $table = new Piwik_DataTable();
     $subtable = new Piwik_DataTable();
     $idtable = $table->getId();
     $idsubtable = $subtable->getId();
     /*
      * create some fake tables to make sure that the serialized array of the first TABLE
      * does not take in consideration those tables
      * -> we check that the DataTable_Manager is not impacting DataTable 
      */
     $useless2 = new Piwik_DataTable();
     $useless1->addRowFromArray(array(Piwik_DataTable_Row::COLUMNS => array(8487)));
     $useless3 = new Piwik_DataTable();
     $useless3->addRowFromArray(array(Piwik_DataTable_Row::COLUMNS => array(8487)));
     /*
      * end fake tables
      */
     $row = array(Piwik_DataTable_Row::COLUMNS => array(0 => 1554, 1 => 42, 2 => 657, 3 => 155744), Piwik_DataTable_Row::METADATA => array('logo' => 'test.png'));
     $row = new Piwik_DataTable_Row($row);
     $table->addRow($row);
     $table->addRowFromArray(array(Piwik_DataTable_Row::COLUMNS => array(0 => 1554, 1 => 42), Piwik_DataTable_Row::METADATA => array('url' => 'piwik.org')));
     $table->addRowFromArray(array(Piwik_DataTable_Row::COLUMNS => array(0 => 787877888787), Piwik_DataTable_Row::METADATA => array('url' => 'OUPLA ADDED'), Piwik_DataTable_Row::DATATABLE_ASSOCIATED => $subtable));
     /*
      * SUB TABLE
      */
     $row = array(Piwik_DataTable_Row::COLUMNS => array(0 => 1554), Piwik_DataTable_Row::METADATA => array('searchengine' => 'google'));
     $subtable->addRowFromArray($row);
     $row = array(Piwik_DataTable_Row::COLUMNS => array(0 => 84894), Piwik_DataTable_Row::METADATA => array('searchengine' => 'yahoo'));
     $subtable->addRowFromArray($row);
     $row = array(Piwik_DataTable_Row::COLUMNS => array(0 => 4898978989), Piwik_DataTable_Row::METADATA => array('searchengine' => 'ask'));
     $subtable->addRowFromArray($row);
     /*
      * SUB SUB TABLE
      */
     $subsubtable = new Piwik_DataTable();
     $subsubtable->addRowFromArray(array(Piwik_DataTable_Row::COLUMNS => array(245), Piwik_DataTable_Row::METADATA => array('yes' => 'subsubmetadata1')));
     $subsubtable->addRowFromArray(array(Piwik_DataTable_Row::COLUMNS => array(13), Piwik_DataTable_Row::METADATA => array('yes' => 'subsubmetadata2')));
     $row = array(Piwik_DataTable_Row::COLUMNS => array(0 => 666666666666666), Piwik_DataTable_Row::METADATA => array('url' => 'NEW ROW ADDED'), Piwik_DataTable_Row::DATATABLE_ASSOCIATED => $subsubtable);
     $subtable->addRowFromArray($row);
     $idsubsubtable = $subsubtable->getId();
     $serialized = $table->getSerialized();
     $this->assertEqual(array_keys($serialized), array($idsubsubtable, $idsubtable, 0));
     $tableAfter = new Piwik_DataTable();
     $tableAfter->addRowsFromSerializedArray($serialized[0]);
     $this->assertEqual($table->getRows(), $tableAfter->getRows());
     $subsubtableAfter = new Piwik_DataTable();
     $subsubtableAfter->addRowsFromSerializedArray($serialized[$idsubsubtable]);
     $this->assertEqual($subsubtable->getRows(), $subsubtableAfter->getRows());
     $this->assertEqual($table, Piwik_DataTable_Manager::getInstance()->getTable($idtable));
     $this->assertEqual($subsubtable, Piwik_DataTable_Manager::getInstance()->getTable($idsubsubtable));
 }
Ejemplo n.º 13
0
	/**
	 * Will search in the DataTable for a Label matching the searched string
	 * and return only the matching row, or an empty datatable
	 */
	protected function getFilterPageDatatableSearch( $callBackParameters, $search, $actionType, $table = false, $searchTree = false, $searchCurrentLevel = 0 )
	{
		if($table === false)
		{
			$table = call_user_func_array(array('Piwik_Archive', 'getDataTableFromArchive'), $callBackParameters);
		}
		if($searchTree === false)
		{
    		if($actionType == Piwik_Tracker_Action::TYPE_ACTION_NAME)
    		{
    			$searchedString = Piwik_Common::unsanitizeInputValue($search);
    		}
    		else
    		{
    			$searchedString = Piwik_Tracker_Action::excludeQueryParametersFromUrl($search, $idSite = $callBackParameters[1]);
    		}
			$searchTree = Piwik_Actions::getActionExplodedNames($searchedString, $actionType);
		}
		if(!($table instanceof Piwik_DataTable))
		{
			throw new Exception("For this API function, date=lastN or date=previousM is not supported");
		}
		$rows = $table->getRows();
		$labelSearch = $searchTree[$searchCurrentLevel];
		$isEndSearch = ((count($searchTree)-1) == $searchCurrentLevel);
		foreach($rows as $key => $row)
		{
			$found = false;
			// Found a match at this level
			$label = $row->getColumn('label');
			if($label === $labelSearch)
			{
				// Is this the end of the search tree? then we found the requested row
				if($isEndSearch)
				{
//					var_dump($label); var_dump($labelSearch); exit;
					$table = new Piwik_DataTable();
					$table->addRow($row);
					return $table;
				}
				
				// If we still need to search deeper, call search 
				$idSubTable = $row->getIdSubDataTable();
				// Update the idSubtable in the callback parameter list, to fetch this subtable from the archive
				$callBackParameters[6] = $idSubTable;
				$subTable = call_user_func_array(array('Piwik_Archive', 'getDataTableFromArchive'), $callBackParameters);
				$found = $this->getFilterPageDatatableSearch($callBackParameters, $search, $actionType, $subTable, $searchTree, $searchCurrentLevel+1);
				if($found)
				{
					return $found;
				}
			}
			if(!$found)
			{
				$table->deleteRow($key);
			}
		}
		// Case the DataTable was searched but nothing was found, @see getFilterPageDatatableSearch()
		if($searchCurrentLevel == 0)
		{
			return new Piwik_DataTable;
		}
		return false;
	}
Ejemplo n.º 14
0
    /**
     * Get information about the following actions (following pages, site searches, outlinks, downloads)
     * 
     * @param $idaction
     * @param $actionType
     * @param Piwik_ArchiveProcessing_Day $archiveProcessing
     * @param $limitBeforeGrouping
     * @param $includeLoops
     * @return array(followingPages:Piwik_DataTable, outlinks:Piwik_DataTable, downloads:Piwik_DataTable)
     */
    public function queryFollowingActions($idaction, $actionType, Piwik_ArchiveProcessing_Day $archiveProcessing, $limitBeforeGrouping = false, $includeLoops = false)
    {
        $types = array();
        $isTitle = $actionType == 'title';
        if (!$isTitle) {
            // specific setup for page urls
            $types[Piwik_Tracker_Action::TYPE_ACTION_URL] = 'followingPages';
            $dimension = 'IF( idaction_url IS NULL, idaction_name, idaction_url )';
            // site search referrers are logged with url=NULL
            // when we find one, we have to join on name
            $joinLogActionColumn = $dimension;
            $addSelect = 'log_action.name, log_action.url_prefix, log_action.type';
        } else {
            // specific setup for page titles:
            $types[Piwik_Tracker_Action::TYPE_ACTION_NAME] = 'followingPages';
            // join log_action on name and url and pick depending on url type
            // the table joined on url is log_action1
            $joinLogActionColumn = array('idaction_url', 'idaction_name');
            $dimension = '
				CASE
					' . '
					WHEN log_link_visit_action.idaction_url IS NULL THEN log_action2.idaction
					' . '
					WHEN log_action1.type = ' . Piwik_Tracker_Action::TYPE_ACTION_URL . ' THEN log_action2.idaction
					' . '
					ELSE log_action1.idaction
				END
			';
            $addSelect = '
				CASE
					' . '
					WHEN log_link_visit_action.idaction_url IS NULL THEN log_action2.name
					' . '
					WHEN log_action1.type = ' . Piwik_Tracker_Action::TYPE_ACTION_URL . ' THEN log_action2.name
					' . '
					ELSE log_action1.name
				END AS name,
				CASE
					' . '
					WHEN log_link_visit_action.idaction_url IS NULL THEN log_action2.type
					' . '
					WHEN log_action1.type = ' . Piwik_Tracker_Action::TYPE_ACTION_URL . ' THEN log_action2.type
					' . '
					ELSE log_action1.type
				END AS type,
				NULL AS url_prefix
			';
        }
        // these types are available for both titles and urls
        $types[Piwik_Tracker_Action::TYPE_SITE_SEARCH] = 'followingSiteSearches';
        $types[Piwik_Tracker_Action::TYPE_OUTLINK] = 'outlinks';
        $types[Piwik_Tracker_Action::TYPE_DOWNLOAD] = 'downloads';
        $rankingQuery = new Piwik_RankingQuery($limitBeforeGrouping ? $limitBeforeGrouping : $this->limitBeforeGrouping);
        $rankingQuery->addLabelColumn(array('name', 'url_prefix'));
        $rankingQuery->partitionResultIntoMultipleGroups('type', array_keys($types));
        $type = $this->getColumnTypeSuffix($actionType);
        $where = 'log_link_visit_action.idaction_' . $type . '_ref = ' . intval($idaction);
        if (!$includeLoops) {
            $where .= ' AND (log_link_visit_action.idaction_' . $type . ' IS NULL OR ' . 'log_link_visit_action.idaction_' . $type . ' != ' . intval($idaction) . ')';
        }
        $orderBy = '`' . Piwik_Archive::INDEX_NB_ACTIONS . '` DESC';
        $metrics = array(Piwik_Archive::INDEX_NB_ACTIONS);
        $data = $archiveProcessing->queryActionsByDimension($dimension, $where, $metrics, $orderBy, $rankingQuery, $joinLogActionColumn, $addSelect);
        $this->totalTransitionsToFollowingActions = 0;
        $dataTables = array();
        foreach ($types as $type => $recordName) {
            $dataTable = new Piwik_DataTable();
            if (isset($data[$type])) {
                foreach ($data[$type] as &$record) {
                    $actions = intval($record[Piwik_Archive::INDEX_NB_ACTIONS]);
                    $dataTable->addRow(new Piwik_DataTable_Row(array(Piwik_DataTable_Row::COLUMNS => array('label' => $this->getPageLabel($record, $isTitle), Piwik_Archive::INDEX_NB_ACTIONS => $actions))));
                    $this->totalTransitionsToFollowingActions += $actions;
                }
            }
            $dataTables[$recordName] = $dataTable;
        }
        return $dataTables;
    }
Ejemplo n.º 15
0
 /**
  * Utility function used by mergeChildren. Copies the rows from one table,
  * sets their 'label' columns to a value and adds them to another table.
  * 
  * @param Piwik_DataTable  $toTable    The table to copy rows to.
  * @param Piwik_DataTable  $fromTable  The table to copy rows from.
  * @param string           $label      The value to set the 'label' column of every copied row.
  */
 private function copyRowsAndSetLabel($toTable, $fromTable, $label)
 {
     foreach ($fromTable->getRows() as $fromRow) {
         $oldColumns = $fromRow->getColumns();
         unset($oldColumns['label']);
         $columns = array_merge(array('label' => $label), $oldColumns);
         $row = new Piwik_DataTable_Row(array(Piwik_DataTable_Row::COLUMNS => $columns, Piwik_DataTable_Row::METADATA => $fromRow->getMetadata(), Piwik_DataTable_Row::DATATABLE_ASSOCIATED => $fromRow->getIdSubDataTable()));
         $toTable->addRow($row);
     }
 }
Ejemplo n.º 16
0
 protected function doFilterPageDatatableSearch($callBackParameters, $table, $searchTree)
 {
     // filter a data table array
     if ($table instanceof Piwik_DataTable_Array) {
         foreach ($table->getArray() as $subTable) {
             $filteredSubTable = $this->doFilterPageDatatableSearch($callBackParameters, $subTable, $searchTree);
             if ($filteredSubTable->getRowsCount() > 0) {
                 // match found in a sub table, return and stop searching the others
                 return $filteredSubTable;
             }
         }
         // nothing found in all sub tables
         return new Piwik_DataTable();
     }
     // filter regular data table
     if ($table instanceof Piwik_DataTable) {
         // search for the first part of the tree search
         $search = array_shift($searchTree);
         $row = $table->getRowFromLabel($search);
         if ($row === false) {
             // not found
             return new Piwik_DataTable();
         }
         // end of tree search reached
         if (count($searchTree) == 0) {
             $table = new Piwik_DataTable();
             $table->addRow($row);
             return $table;
         }
         // match found on this level and more levels remaining: go deeper
         $idSubTable = $row->getIdSubDataTable();
         $callBackParameters[6] = $idSubTable;
         $table = call_user_func_array(array('Piwik_Archive', 'getDataTableFromArchive'), $callBackParameters);
         return $this->doFilterPageDatatableSearch($callBackParameters, $table, $searchTree);
     }
     throw new Exception("For this API function, DataTable " . get_class($table) . " is not supported");
 }
Ejemplo n.º 17
0
    /**
     * Get information about the following actions (following pages, outlinks, downloads)
     * 
     * @param $idaction
     * @param Piwik_ArchiveProcessing_Day $archiveProcessing
     * @return array(followingPages:Piwik_DataTable, outlinks:Piwik_DataTable, downloads:Piwik_DataTable)
     */
    public function queryFollowingActions($idaction, Piwik_ArchiveProcessing_Day $archiveProcessing, $limitBeforeGrouping = false)
    {
        static $types = array(Piwik_Tracker_Action::TYPE_ACTION_URL => 'followingPages', Piwik_Tracker_Action::TYPE_OUTLINK => 'outlinks', Piwik_Tracker_Action::TYPE_DOWNLOAD => 'downloads');
        $dimension = 'idaction_url';
        $rankingQuery = new Piwik_RankingQuery($limitBeforeGrouping ? $limitBeforeGrouping : $this->limitBeforeGrouping);
        $rankingQuery->addLabelColumn(array('name', 'url_prefix'));
        $rankingQuery->partitionResultIntoMultipleGroups('type', array_keys($types));
        $addSelect = 'log_action.name, log_action.url_prefix, log_action.type';
        $where = '
			log_link_visit_action.idaction_url_ref = ' . intval($idaction) . ' AND 
			log_link_visit_action.idaction_url != ' . intval($idaction);
        $orderBy = '`' . Piwik_Archive::INDEX_NB_ACTIONS . '` DESC';
        $metrics = array(Piwik_Archive::INDEX_NB_ACTIONS);
        $data = $archiveProcessing->queryActionsByDimension(array($dimension), $where, $metrics, $orderBy, $rankingQuery, $dimension, $addSelect);
        $dataTables = array();
        foreach ($types as $type => $recordName) {
            $dataTable = new Piwik_DataTable();
            if (isset($data[$type])) {
                foreach ($data[$type] as &$record) {
                    $dataTable->addRow(new Piwik_DataTable_Row(array(Piwik_DataTable_Row::COLUMNS => array('label' => $type == Piwik_Tracker_Action::TYPE_ACTION_URL ? Piwik_Tracker_Action::reconstructNormalizedUrl($record['name'], $record['url_prefix']) : $record['name'], Piwik_Archive::INDEX_NB_ACTIONS => intval($record[Piwik_Archive::INDEX_NB_ACTIONS])))));
                }
            }
            $dataTables[$recordName] = $dataTable;
        }
        return $dataTables;
    }
Ejemplo n.º 18
0
 /** Get row evolution for a multiple labels */
 private function getMultiRowEvolution($idSite, $period, $date, $apiModule, $apiAction, $labels, $segment, $column, $language = false, $idGoal = false, $legendAppendMetric = true, $labelUseAbsoluteUrl = true)
 {
     $actualLabels = $logos = array();
     $metadata = $this->getRowEvolutionMetaData($idSite, $period, $date, $apiModule, $apiAction, $language, $idGoal);
     if (!isset($metadata['metrics'][$column])) {
         // invalid column => use the first one that's available
         $metrics = array_keys($metadata['metrics']);
         $column = reset($metrics);
     }
     // load the tables for each label
     $dataTablesPerLabel = array();
     $dataTableMetadata = false;
     foreach ($labels as $labelIndex => $label) {
         $dataTable = $this->loadRowEvolutionDataFromAPI($idSite, $period, $date, $apiModule, $apiAction, $label, $segment, $idGoal);
         $dataTablesPerLabel[$labelIndex] = $dataTable->getArray();
         if (!$dataTableMetadata) {
             $dataTableMetadata = $dataTable->metadata;
         }
         $urlFound = false;
         foreach ($dataTablesPerLabel[$labelIndex] as $table) {
             if ($table->getRowsCount() > 0) {
                 $firstRow = $table->getFirstRow();
                 // in case labels were replaced in the data table (e.g. for browsers report),
                 // display the label from the table, not the one passed as filter
                 $columnLabel = $firstRow->getColumn('label');
                 if (!empty($columnLabel)) {
                     $actualLabels[$labelIndex] = $columnLabel;
                 }
                 list($actualLabel, $urlFound) = $this->cleanUrlForLabel($firstRow, $apiModule, $apiAction, $labelUseAbsoluteUrl);
                 if ($actualLabel) {
                     $actualLabels[$labelIndex] = $actualLabel;
                 }
                 // Forward the logo path to display logos in multi rows comparison
                 $logos[$labelIndex] = $firstRow->getMetadata('logo');
                 break;
             }
         }
         if (!$urlFound) {
             $actualLabels[$labelIndex] = str_replace(Piwik_API_DataTableManipulator_LabelFilter::SEPARATOR_RECURSIVE_LABEL, ' - ', $label);
         }
     }
     // combine the tables
     $dataTableMulti = new Piwik_DataTable_Array();
     $dataTableMulti->setKeyName($dataTable->getKeyName());
     $dataTableMulti->metadata = $dataTableMetadata;
     foreach (array_keys(reset($dataTablesPerLabel)) as $dateLabel) {
         $newRow = new Piwik_DataTable_Row();
         foreach ($dataTablesPerLabel as $labelIndex => $tableArray) {
             $table = $tableArray[$dateLabel];
             if ($table->getRowsCount() == 0) {
                 $value = 0;
             } else {
                 $value = $table->getFirstRow()->getColumn($column);
                 $value = floatVal(str_replace(',', '.', $value));
                 if ($value == '') {
                     $value = 0;
                 }
             }
             // keep metric in the label so that unit (%, s, ...) can be guessed correctly
             $label = $column . '_' . $labelIndex;
             $newRow->addColumn($label, $value);
         }
         $newTable = new Piwik_DataTable();
         $newTable->addRow($newRow);
         $dataTableMulti->addTable($newTable, $dateLabel);
     }
     // the available metrics for the report are returned as metadata / columns
     $metadata['columns'] = $metadata['metrics'];
     // metadata / metrics should document the rows that are compared
     // this way, UI code can be reused
     $metadata['metrics'] = array();
     foreach ($actualLabels as $labelIndex => $label) {
         if ($legendAppendMetric) {
             $label .= ' (' . $metadata['columns'][$column] . ')';
         }
         $metricName = $column . '_' . $labelIndex;
         $metadata['metrics'][$metricName] = Piwik_DataTable_Filter_SafeDecodeLabel::safeDecodeLabel($label);
         if (!empty($logos[$labelIndex])) {
             $metadata['logos'][$metricName] = $logos[$labelIndex];
         }
     }
     $this->enhanceRowEvolutionMetaData($metadata, $dataTableMulti);
     return array('column' => $column, 'reportData' => $dataTableMulti, 'metadata' => $metadata);
 }
Ejemplo n.º 19
0
 /**
  * Returns table used for the tests
  *
  * @return Piwik_DataTable
  */
 protected function getDataTableCount5()
 {
     $table = new Piwik_DataTable();
     $table->addRow($this->getRow0());
     $table->addRow($this->getRow1());
     $table->addRow($this->getRow2());
     $table->addRow($this->getRow3());
     $table->addRow($this->getRow4());
     return $table;
 }
Ejemplo n.º 20
0
 /** Get row evolution for a multiple labels */
 private function getMultiRowEvolution($idSite, $period, $date, $apiModule, $apiAction, $labels, $segment, $column, $language = false)
 {
     $actualLabels = array();
     $metadata = $this->getRowEvolutionMetaData($idSite, $period, $date, $apiModule, $apiAction, $segment, $language);
     if (!isset($metadata['metrics'][$column])) {
         // invalid column => use the first one that's available
         $column = reset(array_keys($metadata['metrics']));
     }
     // load the tables for each label
     $dataTablesPerLabel = array();
     $dataTableMetadata = false;
     foreach ($labels as $labelIndex => $label) {
         $dataTable = $this->loadRowEvolutionData($idSite, $period, $date, $apiModule, $apiAction, $label, $segment);
         $dataTablesPerLabel[$labelIndex] = $dataTable->getArray();
         if (!$dataTableMetadata) {
             $dataTableMetadata = $dataTable->metadata;
         }
         $urlFound = false;
         foreach ($dataTablesPerLabel[$labelIndex] as $table) {
             if ($table->getRowsCount() > 0) {
                 $firstRow = $table->getFirstRow();
                 // in case labels were replaced in the data table (e.g. for browsers report),
                 // display the label from the table, not the one passed as filter
                 $columnLabel = $firstRow->getColumn('label');
                 if (!empty($columnLabel)) {
                     $actualLabels[$labelIndex] = $columnLabel;
                     // TODO: confirm we need this
                     // special case: websites report
                     //if ($apiAction == 'getWebsites')
                     //{
                     //	$actualLabels[$labelIndex] = html_entity_decode($actualLabels[$labelIndex]);
                     //}
                 }
                 // if url is available as metadata, use it (only for actions reports)
                 if ($url = $firstRow->getMetadata('url')) {
                     $actualLabels[$labelIndex] = $url;
                     $urlFound = true;
                 }
                 break;
             }
         }
         if (!$urlFound) {
             // if we have a recursive label and no url, use the path
             $actualLabels[$labelIndex] = str_replace(Piwik_API_DataTableLabelFilter::SEPARATOR_RECURSIVE_LABEL, ' - ', $label);
         }
     }
     // combine the tables
     $dataTable = new Piwik_DataTable_Array();
     $dataTable->setKeyName($dataTable->getKeyName());
     $dataTable->metadata = $dataTableMetadata;
     foreach (array_keys(reset($dataTablesPerLabel)) as $dateLabel) {
         $newRow = new Piwik_DataTable_Row();
         foreach ($dataTablesPerLabel as $labelIndex => $tableArray) {
             $table = $tableArray[$dateLabel];
             if ($table->getRowsCount() == 0) {
                 $value = 0;
             } else {
                 $value = $table->getFirstRow()->getColumn($column);
                 $value = floatVal(str_replace(',', '.', $value));
                 if ($value == '') {
                     $value = 0;
                 }
             }
             // keep metric in the label so that unit (%, s, ...) can be guessed correctly
             $label = $column . '_' . $labelIndex;
             $newRow->addColumn($label, $value);
         }
         $newTable = new Piwik_DataTable();
         $newTable->addRow($newRow);
         $dataTable->addTable($newTable, $dateLabel);
     }
     // the available metrics for the report are returned as metadata / availableColumns
     $metadata['availableColumns'] = $metadata['metrics'];
     // metadata / metrics should document the rows that are compared
     // this way, UI code can be reused
     $metadata['metrics'] = array();
     foreach ($actualLabels as $labelIndex => $label) {
         $label .= ' (' . $metadata['availableColumns'][$column] . ')';
         $metadata['metrics'][$column . '_' . $labelIndex] = $label;
     }
     $this->enhanceRowEvolutionMetaData($metadata, $dataTable);
     return array('column' => $column, 'data' => $dataTable, 'metadata' => $metadata);
 }
Ejemplo n.º 21
0
 /**
  * @group Core
  * @group DataTable
  */
 public function testGetSerializedCallsCleanPostSerialize()
 {
     $mockedDataTableRow = $this->getMock('Piwik_DataTable_Row', array('cleanPostSerialize'));
     $mockedDataTableRow->expects($this->once())->method('cleanPostSerialize');
     $dataTableBeingSerialized = new Piwik_DataTable();
     $dataTableBeingSerialized->addRow($mockedDataTableRow);
     $dataTableBeingSerialized->getSerialized();
 }
Ejemplo n.º 22
0
 function test_generateDataTable_1row4level()
 {
     $table = new Piwik_DataTable();
     $rowpagecat3 = new Piwik_DataTable_Row(array(Piwik_DataTable_Row::COLUMNS => array('label' => '123123', 'visits' => 3, 'actions' => 5)));
     $rowcat3 = new Piwik_DataTable_Row(array(Piwik_DataTable_Row::COLUMNS => array('label' => '789.654', 'visits' => 3, 'actions' => 5)));
     $rowcat2 = new Piwik_DataTable_Row(array(Piwik_DataTable_Row::COLUMNS => array('label' => 'cat2', 'visits' => 3, 'actions' => 5)));
     $rowcat1 = new Piwik_DataTable_Row(array(Piwik_DataTable_Row::COLUMNS => array('label' => '&*()', 'visits' => 3, 'actions' => 5)));
     $subtablerowpagecat3 = new Piwik_DataTable();
     $subtablerowpagecat3->addRow($rowpagecat3);
     $rowcat3->addSubtable($subtablerowpagecat3);
     $subtablecat2 = new Piwik_DataTable();
     $subtablecat2->addRow($rowcat3);
     $rowcat2->addSubtable($subtablecat2);
     $subtablecat1 = new Piwik_DataTable();
     $subtablecat1->addRow($rowcat2);
     $rowcat1->addSubtable($subtablecat1);
     //-- add
     $table->addRow($rowcat1);
     // WHAT WE TEST
     $input = array('&*()' => array('cat2' => array('789.654' => array('123123' => $rowpagecat3))));
     $tableGenerated = Piwik_ArchiveProcessing_Day::generateDataTable($input);
     $r1 = new Piwik_DataTable_Renderer_Console();
     $r1->setTable($table);
     $r2 = new Piwik_DataTable_Renderer_Console();
     $r2->setTable($tableGenerated);
     $this->assertTrue(Piwik_DataTable::isEqual($table, $tableGenerated));
 }
Ejemplo n.º 23
0
 /**
  * Returns a custom data table.
  * This data table will be converted to all available formats 
  * when requested in the API request.
  * 
  * @return Piwik_DataTable
  */
 public function getCompetitionDatatable()
 {
     $dataTable = new Piwik_DataTable();
     $row1 = new Piwik_DataTable_Row();
     $row1->setColumns(array('name' => 'piwik', 'license' => 'GPL'));
     // Rows Metadata is useful to store non stats data for example (logos, urls, etc.)
     // When printed out, they are simply merged with columns
     $row1->setMetadata('logo', 'logo.png');
     $dataTable->addRow($row1);
     $dataTable->addRowFromSimpleArray(array('name' => 'google analytics', 'license' => 'commercial'));
     return $dataTable;
 }
Ejemplo n.º 24
0
 /**
  * General tests that tries to test the normal behaviour of DataTable
  * 
  * We create some tables, add rows, some of the rows link to sub tables
  * 
  * Then we serialize everything, and we check that the unserialize give the same object back
  */
 function test_general()
 {
     /*
      * create some fake tables to make sure that the serialized array of the first TABLE
      * does not take in consideration those tables
      */
     $useless1 = new Piwik_DataTable();
     $useless1->addRowFromArray(array(Piwik_DataTable_Row::COLUMNS => array(13)));
     /*
      * end fake tables
      */
     /*
      * MAIN TABLE
      */
     $table = new Piwik_DataTable();
     $subtable = new Piwik_DataTable();
     $idtable = $table->getId();
     $idsubtable = $subtable->getId();
     /*
      * create some fake tables to make sure that the serialized array of the first TABLE
      * does not take in consideration those tables
      * -> we check that the DataTable_Manager is not impacting DataTable 
      */
     $useless2 = new Piwik_DataTable();
     $useless1->addRowFromArray(array(Piwik_DataTable_Row::COLUMNS => array(8487)));
     $useless3 = new Piwik_DataTable();
     $useless3->addRowFromArray(array(Piwik_DataTable_Row::COLUMNS => array(8487)));
     /*
      * end fake tables
      */
     $row = array(Piwik_DataTable_Row::COLUMNS => array(0 => 1554, 1 => 42, 2 => 657, 3 => 155744), Piwik_DataTable_Row::METADATA => array('logo' => 'test.png'));
     $row = new Piwik_DataTable_Row($row);
     $table->addRow($row);
     $table->addRowFromArray(array(Piwik_DataTable_Row::COLUMNS => array(0 => 1554, 1 => 42), Piwik_DataTable_Row::METADATA => array('url' => 'piwik.org')));
     $table->addRowFromArray(array(Piwik_DataTable_Row::COLUMNS => array(0 => 787877888787.0), Piwik_DataTable_Row::METADATA => array('url' => 'OUPLA ADDED'), Piwik_DataTable_Row::DATATABLE_ASSOCIATED => $subtable));
     /*
      * SUB TABLE
      */
     $row = array(Piwik_DataTable_Row::COLUMNS => array(0 => 1554), Piwik_DataTable_Row::METADATA => array('searchengine' => 'google'));
     $subtable->addRowFromArray($row);
     $row = array(Piwik_DataTable_Row::COLUMNS => array(0 => 84894), Piwik_DataTable_Row::METADATA => array('searchengine' => 'yahoo'));
     $subtable->addRowFromArray($row);
     $row = array(Piwik_DataTable_Row::COLUMNS => array(0 => 4898978989.0), Piwik_DataTable_Row::METADATA => array('searchengine' => 'ask'));
     $subtable->addRowFromArray($row);
     /*
      * SUB SUB TABLE
      */
     $subsubtable = new Piwik_DataTable();
     $subsubtable->addRowFromArray(array(Piwik_DataTable_Row::COLUMNS => array(245), Piwik_DataTable_Row::METADATA => array('yes' => 'subsubmetadata1')));
     $subsubtable->addRowFromArray(array(Piwik_DataTable_Row::COLUMNS => array(13), Piwik_DataTable_Row::METADATA => array('yes' => 'subsubmetadata2')));
     $row = array(Piwik_DataTable_Row::COLUMNS => array(0 => 666666666666666.0), Piwik_DataTable_Row::METADATA => array('url' => 'NEW ROW ADDED'), Piwik_DataTable_Row::DATATABLE_ASSOCIATED => $subsubtable);
     $subtable->addRowFromArray($row);
     $idsubsubtable = $subsubtable->getId();
     $serialized = $table->getSerialized();
     $this->assertEqual(array_keys($serialized), array($idsubsubtable, $idsubtable, 0));
     // In the next test we compare an unserialized datatable with its original instance.
     // The unserialized datatable rows will have positive DATATABLE_ASSOCIATED ids.
     // Positive DATATABLE_ASSOCIATED ids mean that the associated sub-datatables are not loaded in memory.
     // In this case, this is NOT true: we know that the sub-datatable is loaded in memory.
     // HOWEVER, because of datatable id conflicts happening in the datatable manager, it is not yet
     // possible to know, after unserializing a datatable, if its sub-datatables are loaded in memory.
     $expectedTableRows = array();
     foreach ($table->getRows() as $currentRow) {
         $expectedTableRow = clone $currentRow;
         $currentRowAssociatedDatatableId = $currentRow->c[Piwik_DataTable_Row::DATATABLE_ASSOCIATED];
         if ($currentRowAssociatedDatatableId != null) {
             // making DATATABLE_ASSOCIATED ids positive
             $expectedTableRow->c[Piwik_DataTable_Row::DATATABLE_ASSOCIATED] = -1 * $currentRowAssociatedDatatableId;
         }
         $expectedTableRows[] = $expectedTableRow;
     }
     $tableAfter = new Piwik_DataTable();
     $tableAfter->addRowsFromSerializedArray($serialized[0]);
     $this->assertEqual($expectedTableRows, $tableAfter->getRows());
     $subsubtableAfter = new Piwik_DataTable();
     $subsubtableAfter->addRowsFromSerializedArray($serialized[$idsubsubtable]);
     $this->assertEqual($subsubtable->getRows(), $subsubtableAfter->getRows());
     $this->assertEqual($table, Piwik_DataTable_Manager::getInstance()->getTable($idtable));
     $this->assertEqual($subsubtable, Piwik_DataTable_Manager::getInstance()->getTable($idsubsubtable));
 }