diff options
Diffstat (limited to 'core/DataTable.php')
-rw-r--r-- | core/DataTable.php | 174 |
1 files changed, 92 insertions, 82 deletions
diff --git a/core/DataTable.php b/core/DataTable.php index c92935868c..a1dd872ec5 100644 --- a/core/DataTable.php +++ b/core/DataTable.php @@ -9,7 +9,17 @@ * @package Piwik */ +namespace Piwik; + +use Closure; +use Exception; use Piwik\Common; +use Piwik\DataTable\Manager; +use Piwik\DataTable\Renderer\Html; +use Piwik\DataTable\Row; +use Piwik\DataTable\Filter; +use Piwik\DataTable\Row\DataTableSummaryRow; +use ReflectionClass; /** * @see Common::destroy() @@ -21,7 +31,7 @@ require_once PIWIK_INCLUDE_PATH . '/core/Common.php'; * ---- DataTable * A DataTable is a data structure used to store complex tables of data. * - * A DataTable is composed of multiple DataTable_Row. + * A DataTable is composed of multiple DataTable\Row. * A DataTable can be applied one or several DataTable_Filter. * A DataTable can be given to a DataTable_Renderer that would export the data under a given format (XML, HTML, etc.). * @@ -31,7 +41,7 @@ require_once PIWIK_INCLUDE_PATH . '/core/Common.php'; * - efficient way of loading data from an external source (from a PHP array structure) * - very simple interface to get data from the table * - * ---- DataTable_Row + * ---- DataTable\Row * A DataTableRow in the table is defined by * - multiple columns (a label, multiple values, ...) * - optional metadata @@ -45,7 +55,7 @@ require_once PIWIK_INCLUDE_PATH . '/core/Common.php'; * - metadata = array('logo' => '/plugins/UserSettings/images/browsers/FF.gif') * - no sub DataTable * - * A more complex example would be a DataTable_Row that is associated to a sub DataTable. + * A more complex example would be a DataTable\Row that is associated to a sub DataTable. * For example, for the row of the search engine Google, * we want to get the list of keywords associated, with their statistics. * - columns = array( 'label' => 'Google', @@ -54,8 +64,8 @@ require_once PIWIK_INCLUDE_PATH . '/core/Common.php'; * 'returning_visits' => 77) * - metadata = array( 'logo' => '/plugins/Referers/images/searchEngines/google.com.png', * 'url' => 'http://google.com') - * - DataTable = DataTable containing several DataTable_Row containing the keywords information for this search engine - * Example of one DataTable_Row + * - DataTable = DataTable containing several DataTable\Row containing the keywords information for this search engine + * Example of one DataTable\Row * - the keyword columns specific to this search engine = * array( 'label' => 'Piwik', // the keyword * 'visitors' => 155, // Piwik has been searched on Google by 155 visitors @@ -67,7 +77,7 @@ require_once PIWIK_INCLUDE_PATH . '/core/Common.php'; * * ---- DataTable_Filter * A DataTable_Filter is a applied to a DataTable and so - * can filter information in the multiple DataTable_Row. + * can filter information in the multiple DataTable\Row. * * For example a DataTable_Filter can: * - remove rows from the table, @@ -132,12 +142,12 @@ require_once PIWIK_INCLUDE_PATH . '/core/Common.php'; * [ keyword2, +1000% ] * [ keyword3, -430% ] * - * @see Piwik_DataTable_Row A Piwik_DataTable is composed of Piwik_DataTable_Row + * @see Piwik_DataTable\Row A DataTable is composed of Piwik_DataTable\Row * * @package Piwik - * @subpackage Piwik_DataTable + * @subpackage DataTable */ -class Piwik_DataTable +class DataTable { /** Name for metadata that describes when a report was archived. */ const ARCHIVED_DATE_METADATA_NAME = 'archived_date'; @@ -151,9 +161,9 @@ class Piwik_DataTable private static $maximumDepthLevelAllowed = self::MAX_DEPTH_DEFAULT; /** - * Array of Piwik_DataTable_Row + * Array of Row * - * @var Piwik_DataTable_Row[] + * @var Row[] */ protected $rows = array(); @@ -197,7 +207,7 @@ class Piwik_DataTable protected $tableSortedBy = false; /** - * List of Piwik_DataTable_Filter queued to this table + * List of Filter queued to this table * * @var array */ @@ -230,7 +240,7 @@ class Piwik_DataTable protected $rowsIndexByLabel = array(); /** - * @var Piwik_DataTable_Row + * @var \Piwik\DataTable\Row */ protected $summaryRow = null; @@ -251,7 +261,7 @@ class Piwik_DataTable /** * The operations that should be used when aggregating columns from multiple rows. - * @see self::addDataTable() and Piwik_DataTable_Row::sumRow() + * @see self::addDataTable() and Piwik_DataTable\Row::sumRow() */ protected $columnAggregationOperations = array(); @@ -264,7 +274,7 @@ class Piwik_DataTable */ public function __construct() { - $this->currentId = Piwik_DataTable_Manager::getInstance()->addTable($this); + $this->currentId = Manager::getInstance()->addTable($this); } /** @@ -282,7 +292,7 @@ class Piwik_DataTable Common::destroy($row); } unset($this->rows); - Piwik_DataTable_Manager::getInstance()->setTableDeleted($this->getId()); + Manager::getInstance()->setTableDeleted($this->getId()); $depth--; } } @@ -302,7 +312,7 @@ class Piwik_DataTable if ($this->enableRecursiveSort === true) { foreach ($this->getRows() as $row) { if (($idSubtable = $row->getIdSubDataTable()) !== null) { - $table = Piwik_DataTable_Manager::getInstance()->getTable($idSubtable); + $table = Manager::getInstance()->getTable($idSubtable); $table->enableRecursiveSort(); $table->sort($functionCallback, $columnSortedBy); } @@ -363,7 +373,7 @@ class Piwik_DataTable /** * Apply a filter to this datatable * - * @param string|Closure $className Class name, eg. "Sort" or "Piwik_DataTable_Filter_Sort". + * @param string|Closure $className Class name, eg. "Sort" or "Sort". * If this variable is a closure, it will get executed immediately. * @param array $parameters Array of parameters to the filter, eg. array('nb_visits', 'asc') */ @@ -374,8 +384,8 @@ class Piwik_DataTable return; } - if (!class_exists($className, false)) { - $className = "Piwik_DataTable_Filter_" . $className; + if (!class_exists($className, true)) { + $className = 'Piwik\DataTable\Filter\\' . $className; } $reflectionObj = new ReflectionClass($className); @@ -394,8 +404,8 @@ class Piwik_DataTable * Queue a DataTable_Filter that will be applied when applyQueuedFilters() is called. * (just before sending the datatable back to the browser (or API, etc.) * - * @param string $className The class name of the filter, eg. Piwik_DataTable_Filter_Limit - * @param array $parameters The parameters to give to the filter, eg. array( $offset, $limit) for the filter Piwik_DataTable_Filter_Limit + * @param string $className The class name of the filter, eg. Limit + * @param array $parameters The parameters to give to the filter, eg. array( $offset, $limit) for the filter Limit */ public function queueFilter($className, $parameters = array()) { @@ -428,9 +438,9 @@ class Piwik_DataTable * * @example tests/core/DataTable.test.php * - * @param Piwik_DataTable $tableToSum + * @param \Piwik\DataTable $tableToSum */ - public function addDataTable(Piwik_DataTable $tableToSum) + public function addDataTable(DataTable $tableToSum) { foreach ($tableToSum->getRows() as $row) { $labelToLookFor = $row->getColumn('label'); @@ -449,7 +459,7 @@ class Piwik_DataTable // if the row has the subtable already // then we have to recursively sum the subtables if (($idSubTable = $row->getIdSubDataTable()) !== null) { - $subTable = Piwik_DataTable_Manager::getInstance()->getTable($idSubTable); + $subTable = Manager::getInstance()->getTable($idSubTable); $subTable->setColumnAggregationOperations($this->columnAggregationOperations); $rowFound->sumSubtable($subTable); } @@ -458,15 +468,15 @@ class Piwik_DataTable } /** - * Returns the Piwik_DataTable_Row that has a column 'label' with the value $label + * Returns the Row that has a column 'label' with the value $label * * @param string $label Value of the column 'label' of the row to return - * @return Piwik_DataTable_Row|false The row if found, false otherwise + * @return \Piwik\DataTable\Row|false The row if found, false otherwise */ public function getRowFromLabel($label) { $rowId = $this->getRowIdFromLabel($label); - if ($rowId instanceof Piwik_DataTable_Row) { + if ($rowId instanceof Row) { return $rowId; } if (is_int($rowId) && isset($this->rows[$rowId])) { @@ -506,11 +516,11 @@ class Piwik_DataTable * * @param bool $keepFilters * - * @return Piwik_DataTable + * @return \Piwik\DataTable */ public function getEmptyClone($keepFilters = true) { - $clone = new Piwik_DataTable; + $clone = new DataTable; if ($keepFilters) { $clone->queuedFilters = $this->queuedFilters; } @@ -536,7 +546,7 @@ class Piwik_DataTable * Returns the ith row in the array * * @param int $id - * @return Piwik_DataTable_Row or false if not found + * @return \Piwik\DataTable\Row or false if not found */ public function getRowFromId($id) { @@ -555,7 +565,7 @@ class Piwik_DataTable * Returns a row that has the subtable ID matching the parameter * * @param int $idSubTable - * @return Piwik_DataTable_Row|false if not found + * @return \Piwik\DataTable\Row|false if not found */ public function getRowFromIdSubDataTable($idSubTable) { @@ -571,10 +581,10 @@ class Piwik_DataTable /** * 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 - * @return Piwik_DataTable_Row + * @param \Piwik\DataTable\Row $row to add at the end of the array + * @return \Piwik\DataTable\Row */ - public function addRow(Piwik_DataTable_Row $row) + public function addRow(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 @@ -583,8 +593,8 @@ class Piwik_DataTable ) { if ($this->summaryRow === null) // create the summary row if necessary { - $this->addSummaryRow(new Piwik_DataTable_Row(array( - Piwik_DataTable_Row::COLUMNS => $row->getColumns() + $this->addSummaryRow(new Row(array( + Row::COLUMNS => $row->getColumns() ))); $this->summaryRow->setColumn('label', self::LABEL_SUMMARY_ROW); } else { @@ -609,10 +619,10 @@ class Piwik_DataTable /** * Sets the summary row (a dataTable can have only one summary row) * - * @param Piwik_DataTable_Row $row - * @return Piwik_DataTable_Row Returns $row. + * @param Row $row + * @return Row Returns $row. */ - public function addSummaryRow(Piwik_DataTable_Row $row) + public function addSummaryRow(Row $row) { $this->summaryRow = $row; return $row; @@ -631,7 +641,7 @@ class Piwik_DataTable /** * Adds a new row from a PHP array data structure * - * @param array $row eg. array(Piwik_DataTable_Row::COLUMNS => array( 'visits' => 13, 'test' => 'toto'),) + * @param array $row eg. array(Row::COLUMNS => array( 'visits' => 13, 'test' => 'toto'),) */ public function addRowFromArray($row) { @@ -649,9 +659,9 @@ class Piwik_DataTable } /** - * Returns the array of Piwik_DataTable_Row + * Returns the array of Row * - * @return Piwik_DataTable_Row[] + * @return Row[] */ public function getRows() { @@ -746,7 +756,7 @@ class Piwik_DataTable /** * Returns the first row of the DataTable * - * @return Piwik_DataTable_Row + * @return \Piwik\DataTable\Row */ public function getFirstRow() { @@ -763,7 +773,7 @@ class Piwik_DataTable /** * Returns the last row of the DataTable * - * @return Piwik_DataTable_Row + * @return Row */ public function getLastRow() { @@ -789,7 +799,7 @@ class Piwik_DataTable $totalCount = 0; foreach ($this->rows as $row) { if (($idSubTable = $row->getIdSubDataTable()) !== null) { - $subTable = Piwik_DataTable_Manager::getInstance()->getTable($idSubTable); + $subTable = Manager::getInstance()->getTable($idSubTable); $count = $subTable->getRowsCountRecursive(); $totalCount += $count; } @@ -825,7 +835,7 @@ class Piwik_DataTable foreach ($this->getRows() as $row) { $row->renameColumn($oldName, $newName); if (($idSubDataTable = $row->getIdSubDataTable()) !== null) { - Piwik_DataTable_Manager::getInstance()->getTable($idSubDataTable)->renameColumn($oldName, $newName); + Manager::getInstance()->getTable($idSubDataTable)->renameColumn($oldName, $newName); } } if (!is_null($this->summaryRow)) { @@ -846,7 +856,7 @@ class Piwik_DataTable $row->deleteColumn($name); } if (($idSubDataTable = $row->getIdSubDataTable()) !== null) { - Piwik_DataTable_Manager::getInstance()->getTable($idSubDataTable)->deleteColumns($names, $deleteRecursiveInSubtables); + Manager::getInstance()->getTable($idSubDataTable)->deleteColumns($names, $deleteRecursiveInSubtables); } } if (!is_null($this->summaryRow)) { @@ -932,7 +942,7 @@ class Piwik_DataTable */ public function __toString() { - $renderer = new Piwik_DataTable_Renderer_Html(); + $renderer = new Html(); $renderer->setTable($this); return (string)$renderer; } @@ -941,11 +951,11 @@ class Piwik_DataTable * Returns true if both DataTable are exactly the same. * Used in unit tests. * - * @param Piwik_DataTable $table1 - * @param Piwik_DataTable $table2 + * @param \Piwik\DataTable $table1 + * @param \Piwik\DataTable $table2 * @return bool */ - public static function isEqual(Piwik_DataTable $table1, Piwik_DataTable $table2) + public static function isEqual(DataTable $table1, DataTable $table2) { $rows1 = $table1->getRows(); $rows2 = $table2->getRows(); @@ -960,7 +970,7 @@ class Piwik_DataTable foreach ($rows1 as $row1) { $row2 = $table2->getRowFromLabel($row1->getColumn('label')); if ($row2 === false - || !Piwik_DataTable_Row::isEqual($row1, $row2) + || !Row::isEqual($row1, $row2) ) { return false; } @@ -1010,12 +1020,12 @@ class Piwik_DataTable if ($depth > self::$maximumDepthLevelAllowed) { $depth = 0; - throw new Exception("Maximum recursion level of " . self::$maximumDepthLevelAllowed . " reached. Maybe you have set a DataTable_Row with an associated DataTable belonging already to one of its parent tables?"); + throw new Exception("Maximum recursion level of " . self::$maximumDepthLevelAllowed . " reached. Maybe you have set a DataTable\Row with an associated DataTable belonging already to one of its parent tables?"); } if (!is_null($maximumRowsInDataTable)) { $this->filter('AddSummaryRow', array($maximumRowsInDataTable - 1, - Piwik_DataTable::LABEL_SUMMARY_ROW, + DataTable::LABEL_SUMMARY_ROW, $columnToSortByBeforeTruncation) ); } @@ -1026,7 +1036,7 @@ class Piwik_DataTable $aSerializedDataTable = array(); foreach ($this->rows as $row) { if (($idSubTable = $row->getIdSubDataTable()) !== null) { - $subTable = Piwik_DataTable_Manager::getInstance()->getTable($idSubTable); + $subTable = Manager::getInstance()->getTable($idSubTable); $depth++; $aSerializedDataTable = $aSerializedDataTable + $subTable->getSerialized($maximumRowsInSubDataTable, $maximumRowsInSubDataTable, $columnToSortByBeforeTruncation); $depth--; @@ -1057,7 +1067,7 @@ class Piwik_DataTable * Does not load recursively all the sub DataTable. * They will be loaded only when requesting them specifically. * - * The function creates all the necessary DataTable_Row + * The function creates all the necessary DataTable\Row * * @param string $stringSerialized string of serialized datatable * @throws Exception @@ -1078,8 +1088,8 @@ class Piwik_DataTable * array( * // row1 * array( - * Piwik_DataTable_Row::COLUMNS => array( col1_name => value1, col2_name => value2, ...), - * Piwik_DataTable_Row::METADATA => array( metadata1_name => value1, ...), // see Piwik_DataTable_Row + * Row::COLUMNS => array( col1_name => value1, col2_name => value2, ...), + * Row::METADATA => array( metadata1_name => value1, ...), // see Row * ), * // row2 * array( ... ), @@ -1089,7 +1099,7 @@ class Piwik_DataTable { foreach ($array as $id => $row) { if (is_array($row)) { - $row = new Piwik_DataTable_Row($row); + $row = new Row($row); } if ($id == self::ID_SUMMARY_ROW) { $this->summaryRow = $row; @@ -1140,10 +1150,10 @@ class Piwik_DataTable // case when the array is indexed by the default numeric index if (array_keys($array) == array_keys(array_fill(0, count($array), true))) { foreach ($array as $row) { - $this->addRow(new Piwik_DataTable_Row(array(Piwik_DataTable_Row::COLUMNS => array($row)))); + $this->addRow(new Row(array(Row::COLUMNS => array($row)))); } } else { - $this->addRow(new Piwik_DataTable_Row(array(Piwik_DataTable_Row::COLUMNS => $array))); + $this->addRow(new Row(array(Row::COLUMNS => $array))); } // we have converted our simple array to one single row // => we exit the method as the job is now finished @@ -1171,10 +1181,10 @@ class Piwik_DataTable throw $e; } } - $row = new Piwik_DataTable_Row(array(Piwik_DataTable_Row::COLUMNS => $row)); + $row = new Row(array(Row::COLUMNS => $row)); } // other (string, numbers...) => we build a line from this value else { - $row = new Piwik_DataTable_Row(array(Piwik_DataTable_Row::COLUMNS => array($key => $row))); + $row = new Row(array(Row::COLUMNS => array($key => $row))); } $this->addRow($row); } @@ -1188,8 +1198,8 @@ class Piwik_DataTable * ) * to a DataTable, ie. with the internal structure * array ( - * array( Piwik_DataTable_Row::COLUMNS => array('label' => LABEL, col1 => X, col2 => Y)), - * array( Piwik_DataTable_Row::COLUMNS => array('label' => LABEL2, col1 => X, col2 => Y)), + * array( Row::COLUMNS => array('label' => LABEL, col1 => X, col2 => Y)), + * array( Row::COLUMNS => array('label' => LABEL2, col1 => X, col2 => Y)), * ) * * It also works with array having only one value per row, eg. @@ -1199,18 +1209,18 @@ class Piwik_DataTable * ) * would be converted to: * array ( - * array( Piwik_DataTable_Row::COLUMNS => array('label' => LABEL, 'value' => X)), - * array( Piwik_DataTable_Row::COLUMNS => array('label' => LABEL2, 'value' => Y)), + * array( Row::COLUMNS => array('label' => LABEL, 'value' => X)), + * array( Row::COLUMNS => array('label' => LABEL2, 'value' => Y)), * ) * * * @param array $array Indexed array, two formats are supported * @param array|null $subtablePerLabel An indexed array of up to one DataTable to associate as a sub table - * @return Piwik_DataTable + * @return \Piwik\DataTable */ public static function makeFromIndexedArray($array, $subtablePerLabel = null) { - $table = new Piwik_DataTable(); + $table = new DataTable(); $cleanRow = array(); foreach ($array as $label => $row) { // Support the case of an $array of single values @@ -1218,12 +1228,12 @@ class Piwik_DataTable $row = array('value' => $row); } // Put the 'label' column first - $cleanRow[Piwik_DataTable_Row::COLUMNS] = array('label' => $label) + $row; + $cleanRow[Row::COLUMNS] = array('label' => $label) + $row; // Assign subtable if specified if (isset($subtablePerLabel[$label])) { - $cleanRow[Piwik_DataTable_Row::DATATABLE_ASSOCIATED] = $subtablePerLabel[$label]; + $cleanRow[Row::DATATABLE_ASSOCIATED] = $subtablePerLabel[$label]; } - $table->addRow(new Piwik_DataTable_Row($cleanRow)); + $table->addRow(new Row($cleanRow)); } return $table; } @@ -1326,7 +1336,7 @@ class Piwik_DataTable return array(false, $i); } else // if we're adding missing rows, add a new row { - $row = new Piwik_DataTable_Row_DataTableSummary(); + $row = new DataTableSummaryRow(); $row->setColumns(array('label' => $segment) + $missingRowColumns); $next = $table->addRow($row); @@ -1348,7 +1358,7 @@ class Piwik_DataTable return array(false, $i); } else if ($i != $pathLength - 1) // create subtable if missing, but only if not on the last segment { - $table = new Piwik_DataTable(); + $table = new DataTable(); $table->setMaximumAllowedRows($maxSubtableRows); $table->setColumnAggregationOperations($this->columnAggregationOperations); $next->setSubtable($table); @@ -1371,11 +1381,11 @@ class Piwik_DataTable * @param bool $useMetadataColumn If true and if $labelColumn is supplied, the parent row's * label will be added as metadata. * - * @return Piwik_DataTable + * @return \Piwik\DataTable */ public function mergeSubtables($labelColumn = false, $useMetadataColumn = false) { - $result = new Piwik_DataTable(); + $result = new DataTable(); foreach ($this->getRows() as $row) { $subtable = $row->getSubtable(); if ($subtable !== false) { @@ -1423,18 +1433,18 @@ class Piwik_DataTable * Returns a new DataTable created with data from a 'simple' array. * * @param array $array - * @return Piwik_DataTable + * @return \Piwik\DataTable */ public static function makeFromSimpleArray($array) { - $dataTable = new Piwik_DataTable(); + $dataTable = new DataTable(); $dataTable->addRowsFromSimpleArray($array); return $dataTable; } /** * Set the aggregation operation for a column, e.g. "min". - * @see self::addDataTable() and Piwik_DataTable_Row::sumRow() + * @see self::addDataTable() and Piwik_DataTable\Row::sumRow() * * @param string $columnName * @param string $operation @@ -1467,11 +1477,11 @@ class Piwik_DataTable * Creates a new DataTable instance from a serialize()'d array of rows. * * @param string $data - * @return Piwik_DataTable + * @return \Piwik\DataTable */ public static function fromSerializedArray($data) { - $result = new Piwik_DataTable(); + $result = new DataTable(); $result->addRowsFromSerializedArray($data); return $result; } |