See {@link getSerialized()} and {@link addRowsFromSerializedArray()}
for more information on DataTable serialization.
public static fromSerializedArray ( string $data ) : |
||
$data | string | |
Résultat |
/** * Utility function. Gets row count of a set of tables grouped by the 'name' column. * This is the implementation of the getRowCountsAndSizeBy... functions. */ private function getRowCountsByArchiveName($statuses, $getRowSizeMethod, $forceCache = false, $otherSelects = array(), $otherDataTableColumns = array()) { $extraCols = ''; if (!empty($otherSelects)) { $extraCols = ', ' . implode(', ', $otherSelects); } $cols = array_merge(array('row_count'), $otherDataTableColumns); $dataTable = new DataTable(); foreach ($statuses as $status) { $dataTableOptionName = $this->getCachedOptionName($status['Name'], 'byArchiveName'); // if option exists && !$forceCache, use the cached data, otherwise create the $cachedData = Option::get($dataTableOptionName); if ($cachedData !== false && !$forceCache) { $table = DataTable::fromSerializedArray($cachedData); } else { $table = new DataTable(); $table->addRowsFromSimpleArray($this->dataAccess->getRowCountsByArchiveName($status['Name'], $extraCols)); $reduceArchiveRowName = array($this, 'reduceArchiveRowName'); $table->filter('GroupBy', array('label', $reduceArchiveRowName)); $serializedTables = $table->getSerialized(); $serializedTable = reset($serializedTables); Option::set($dataTableOptionName, $serializedTable); } // add estimated_size column $getEstimatedSize = array($this, $getRowSizeMethod); $table->filter('ColumnCallbackAddColumn', array($cols, 'estimated_size', $getEstimatedSize, array($status))); $dataTable->addDataTable($table); } return $dataTable; }
/** * 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)); }
/** * Creates DataTables from $dataTable's subtable blobs (stored in $blobRow) and sets * the subtable IDs of each DataTable row. * * @param DataTable $dataTable * @param array $blobRow An array associating record names (w/ subtable if applicable) * with blob values. This should hold every subtable blob for * the loaded DataTable. * @param int $treeLevel */ private function setSubtables($dataTable, $blobRow, $treeLevel = 0) { if ($this->maxSubtableDepth && $treeLevel >= $this->maxSubtableDepth) { // unset the subtables so DataTableManager doesn't throw foreach ($dataTable->getRows() as $row) { $row->removeSubtable(); } return; } $dataName = reset($this->dataNames); foreach ($dataTable->getRows() as $row) { $sid = $row->getIdSubDataTable(); if ($sid === null) { continue; } $blobName = $dataName . "_" . $sid; if (isset($blobRow[$blobName])) { $subtable = DataTable::fromSerializedArray($blobRow[$blobName]); $this->setSubtables($subtable, $blobRow, $treeLevel + 1); // we edit the subtable ID so that it matches the newly table created in memory // NB: we dont overwrite the datatableid in the case we are displaying the table expanded. if ($this->addMetadataSubtableId) { // this will be written back to the column 'idsubdatatable' just before rendering, // see Renderer/Php.php $row->addMetadata('idsubdatatable_in_db', $row->getIdSubDataTable()); } $row->setSubtable($subtable); } } }