public function testForInfiniteRecursion() { $dataTableBeingFiltered = new 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 Row and its // enclosing DataTable. // This can happen because identifiers are not thoroughly synchronized when the expanded parameter // is false. $rowBeingFiltered->subtableId = $dataTableBeingFiltered->getId(); $filter = new Truncate($dataTableBeingFiltered, 1); $filter->filter($dataTableBeingFiltered); }
/** * @param DataTable $table */ public function filter($table) { $idSubtable = $this->idSubtable ?: $table->getId(); $subTableRow = $this->firstLevelSearchEnginesTable->getRowFromIdSubDataTable($idSubtable); if (!empty($subTableRow)) { $searchEngineUrl = $subTableRow->getMetadata('url'); $table->queueFilter('ColumnCallbackAddMetadata', array('label', 'url', 'Piwik\\Plugins\\Referrers\\getSearchEngineUrlFromKeywordAndUrl', array($searchEngineUrl))); $table->queueFilter(function (DataTable $table) { $row = $table->getRowFromId(DataTable::ID_SUMMARY_ROW); if ($row) { $row->deleteMetadata('url'); } }); } $table->queueFilter('Piwik\\Plugins\\Referrers\\DataTable\\Filter\\KeywordNotDefined'); }
/** * @param DataTable $table */ public function filter($table) { $idSubtable = $this->idSubtable ?: $table->getId(); $table->queueFilter('ColumnCallbackAddMetadata', array('label', 'url', 'Piwik\\Plugins\\Referrers\\getSearchEngineUrlFromName')); $table->queueFilter('MetadataCallbackAddMetadata', array('url', 'logo', 'Piwik\\Plugins\\Referrers\\getSearchEngineLogoFromUrl')); // get the keyword and create the URL to the search result page $rootRow = $this->firstLevelKeywordTable->getRowFromIdSubDataTable($idSubtable); if ($rootRow) { $keyword = $rootRow->getColumn('label'); $table->queueFilter('MetadataCallbackReplace', array('url', 'Piwik\\Plugins\\Referrers\\getSearchEngineUrlFromUrlAndKeyword', array($keyword))); $table->queueFilter(function (DataTable $table) { $row = $table->getRowFromId(DataTable::ID_SUMMARY_ROW); if ($row) { $row->deleteMetadata('url'); } }); } }
/** * test with a row without child * a row with a child that has a child * a row with w child * * @group Core */ public function testConsole2SubLevelAnd2Different() { $table = new DataTable(); $table->addRowFromArray(array(Row::COLUMNS => array('visits' => 245, 'visitors' => 245), Row::METADATA => array('logo' => 'test.png'))); $subsubtable = new DataTable(); $idsubsubtable = $subsubtable->getId(); $subsubtable->addRowFromArray(array(Row::COLUMNS => array('visits' => 2))); $subtable = new DataTable(); $idsubtable1 = $subtable->getId(); $subtable->addRowFromArray(array(Row::COLUMNS => array('visits' => 1), Row::DATATABLE_ASSOCIATED => $subsubtable)); $table->addRowFromArray(array(Row::COLUMNS => array('visits' => 3), Row::DATATABLE_ASSOCIATED => $subtable)); $subtable2 = new DataTable(); $idsubtable2 = $subtable2->getId(); $subtable2->addRowFromArray(array(Row::COLUMNS => array('visits' => 5))); $table->addRowFromArray(array(Row::COLUMNS => array('visits' => 9), 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 Console(); $render->setTable($table); $render->setPrefixRow('*'); $rendered = $render->render(); $this->assertEquals($expected, $rendered); }
/** * @param DataTable $table */ public function filter($table) { $idSubtable = $this->idSubtable ?: $table->getId(); $table->queueFilter('ColumnCallbackAddMetadata', array('label', 'url', function ($url) { return SearchEngine::getInstance()->getUrlFromName($url); })); $table->queueFilter('MetadataCallbackAddMetadata', array('url', 'logo', function ($url) { return SearchEngine::getInstance()->getLogoFromUrl($url); })); // get the keyword and create the URL to the search result page $rootRow = $this->firstLevelKeywordTable->getRowFromIdSubDataTable($idSubtable); if ($rootRow) { $keyword = $rootRow->getColumn('label'); $table->queueFilter('MetadataCallbackReplace', array('url', function ($url, $keyword) { return SearchEngine::getInstance()->getBackLinkFromUrlAndKeyword($url, $keyword); }, array($keyword))); $table->queueFilter(function (DataTable $table) { $row = $table->getRowFromId(DataTable::ID_SUMMARY_ROW); if ($row) { $row->deleteMetadata('url'); } }); } }
/** * 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 */ 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 = $this->createDataTable(array(array(13))); /* * end fake tables */ /* * MAIN TABLE */ $table = new DataTable(); $subtable = new DataTable(); $idtable = $table->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 */ $useless1->addRowFromArray(array(Row::COLUMNS => array(8487))); $useless3 = $this->createDataTable(array(array(8487))); /* * end fake tables */ $row = array(Row::COLUMNS => array(0 => 1554, 1 => 42, 2 => 657, 3 => 155744), Row::METADATA => array('logo' => 'test.png')); $row = new Row($row); $table->addRow($row); $table->addRowFromArray(array(Row::COLUMNS => array(0 => 1554, 1 => 42), Row::METADATA => array('url' => 'piwik.org'))); $table->addRowFromArray(array(Row::COLUMNS => array(0 => 787877888787), Row::METADATA => array('url' => 'OUPLA ADDED'), Row::DATATABLE_ASSOCIATED => $subtable)); /* * SUB TABLE */ $row = array(Row::COLUMNS => array(0 => 1554), Row::METADATA => array('searchengine' => 'google')); $subtable->addRowFromArray($row); $row = array(Row::COLUMNS => array(0 => 84894), Row::METADATA => array('searchengine' => 'yahoo')); $subtable->addRowFromArray($row); $row = array(Row::COLUMNS => array(0 => 4898978989), Row::METADATA => array('searchengine' => 'ask')); $subtable->addRowFromArray($row); /* * SUB SUB TABLE */ $subsubtable = new DataTable(); $subsubtable->addRowFromArray(array(Row::COLUMNS => array(245), Row::METADATA => array('yes' => 'subsubmetadata1'))); $subsubtable->addRowFromArray(array(Row::COLUMNS => array(13), Row::METADATA => array('yes' => 'subsubmetadata2'))); $row = array(Row::COLUMNS => array(0 => 666666666666666), Row::METADATA => array('url' => 'NEW ROW ADDED'), Row::DATATABLE_ASSOCIATED => $subsubtable); $subtable->addRowFromArray($row); $idsubsubtable = $subsubtable->getId(); $serialized = $table->getSerialized(); $this->assertEquals(array_keys($serialized), array(2, 1, 0)); // subtableIds are now consecutive // 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(); $i = 0; foreach ($table->getRows() as $currentRow) { $expectedTableRow = clone $currentRow; $currentRowAssociatedDatatableId = $currentRow->subtableId; if ($currentRowAssociatedDatatableId != null) { $expectedTableRow->setNonLoadedSubtableId(++$i); // subtableIds are consecutive } $expectedTableRows[] = $expectedTableRow; } $tableAfter = new DataTable(); $tableAfter->addRowsFromSerializedArray($serialized[0]); $this->assertEquals($expectedTableRows, $tableAfter->getRows()); $subsubtableAfter = new DataTable(); $subsubtableAfter->addRowsFromSerializedArray($serialized[$consecutiveSubtableId = 2]); $this->assertEquals($subsubtable->getRows(), $subsubtableAfter->getRows()); $this->assertEquals($subsubtable->getRows(), DataTable::fromSerializedArray($serialized[$consecutiveSubtableId = 2])->getRows()); $this->assertTrue($subsubtable->getRowsCount() > 0); $this->assertEquals($table, Manager::getInstance()->getTable($idtable)); $this->assertEquals($subsubtable, Manager::getInstance()->getTable($idsubsubtable)); }
/** * Attaches a subtable to this row, overwriting the existing subtable, * if any. * * @param DataTable $subTable DataTable to associate to this row. * @return DataTable Returns `$subTable`. */ public function setSubtable(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; }
/** * Attaches a subtable to this row, overwriting the existing subtable, * if any. * * @param DataTable $subTable DataTable to associate to this row. * @return DataTable Returns `$subTable`. */ public function setSubtable(DataTable $subTable) { $this->subtableId = $subTable->getId(); $this->isSubtableLoaded = true; return $subTable; }