/** * * @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); }
/** * test with a row without child * a row with a child that has a child * a row with w child * * @group Core * @group DataTable * @group DataTable_Renderer * @group DataTable_Renderer_Console */ public function testConsole2SubLevelAnd2Different() { $table = new Piwik_DataTable(); $table->addRowFromArray(array(Piwik_DataTable_Row::COLUMNS => array('visits' => 245, 'visitors' => 245), Piwik_DataTable_Row::METADATA => array('logo' => 'test.png'))); $subsubtable = new Piwik_DataTable(); $idsubsubtable = $subsubtable->getId(); $subsubtable->addRowFromArray(array(Piwik_DataTable_Row::COLUMNS => array('visits' => 2))); $subtable = new Piwik_DataTable(); $idsubtable1 = $subtable->getId(); $subtable->addRowFromArray(array(Piwik_DataTable_Row::COLUMNS => array('visits' => 1), Piwik_DataTable_Row::DATATABLE_ASSOCIATED => $subsubtable)); $table->addRowFromArray(array(Piwik_DataTable_Row::COLUMNS => array('visits' => 3), Piwik_DataTable_Row::DATATABLE_ASSOCIATED => $subtable)); $subtable2 = new Piwik_DataTable(); $idsubtable2 = $subtable2->getId(); $subtable2->addRowFromArray(array(Piwik_DataTable_Row::COLUMNS => array('visits' => 5))); $table->addRowFromArray(array(Piwik_DataTable_Row::COLUMNS => array('visits' => 9), Piwik_DataTable_Row::DATATABLE_ASSOCIATED => $subtable2)); $expected = "- 1 ['visits' => 245, 'visitors' => 245] ['logo' => 'test.png'] [idsubtable = ]<br />\n- 2 ['visits' => 3] [] [idsubtable = {$idsubtable1}]<br />\n*- 1 ['visits' => 1] [] [idsubtable = {$idsubsubtable}]<br />\n**- 1 ['visits' => 2] [] [idsubtable = ]<br />\n- 3 ['visits' => 9] [] [idsubtable = {$idsubtable2}]<br />\n*- 1 ['visits' => 5] [] [idsubtable = ]<br />\n"; $render = new Piwik_DataTable_Renderer_Console(); $render->setTable($table); $render->setPrefixRow('*'); $rendered = $render->render(); $this->assertEquals($expected, $rendered); }
/** * 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 * * @group Core * @group DataTable */ public function testGeneral() { /* * 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->assertEquals(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->assertEquals($expectedTableRows, $tableAfter->getRows()); $subsubtableAfter = new Piwik_DataTable(); $subsubtableAfter->addRowsFromSerializedArray($serialized[$idsubsubtable]); $this->assertEquals($subsubtable->getRows(), $subsubtableAfter->getRows()); $this->assertEquals($table, Piwik_DataTable_Manager::getInstance()->getTable($idtable)); $this->assertEquals($subsubtable, Piwik_DataTable_Manager::getInstance()->getTable($idsubsubtable)); }
/** * 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)); }
/** * Set a DataTable to this row. If there is already * a DataTable associated, it is simply overwritten. * * @param Piwik_DataTable DataTable to associate to this row */ public function setSubtable(Piwik_DataTable $subTable) { $this->c[self::DATATABLE_ASSOCIATED] = $subTable->getId(); }
/** * 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; }
/** * 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; }
/** * Set a DataTable to this row. If there is already * a DataTable associated, it is simply overwritten. * * @param Piwik_DataTable $subTable DataTable to associate to this row * @return Piwik_DataTable Returns $subTable. */ public function setSubtable(Piwik_DataTable $subTable) { // Hacking -1 to ensure value is negative, so we know the table was loaded // @see isSubtableLoaded() $this->c[self::DATATABLE_ASSOCIATED] = -1 * $subTable->getId(); return $subTable; }