diff options
author | matthieu_ <matthieu_@59fd770c-687e-43c8-a1e3-f5a4ff64c105> | 2007-08-17 22:08:14 +0400 |
---|---|---|
committer | matthieu_ <matthieu_@59fd770c-687e-43c8-a1e3-f5a4ff64c105> | 2007-08-17 22:08:14 +0400 |
commit | 00f5a744883fc3a5ce0706714d98fd9b86a7f51e (patch) | |
tree | 82fb3dc171acb7093e8b9eadab6e1d9cb013d66c | |
parent | 49c593b1cc964373c1a2567a7e03154c166639fc (diff) |
Implemented half of the PERIOD archiving
still have to implement the DataTable::addDataTable( ) for recursive table
-rwxr-xr-x | index.php | 35 | ||||
-rw-r--r-- | misc/generateVisits.php | 10 | ||||
-rw-r--r-- | modules/Archive.php | 91 | ||||
-rw-r--r-- | modules/ArchiveProcessing.php | 48 | ||||
-rw-r--r-- | modules/ArchiveProcessing/Day.php | 4 | ||||
-rw-r--r-- | modules/ArchiveProcessing/Month.php | 71 | ||||
-rw-r--r-- | modules/DataTable.php | 492 | ||||
-rw-r--r-- | modules/DataTable/Manager.php | 43 | ||||
-rw-r--r-- | modules/DataTable/Row.php | 196 | ||||
-rw-r--r-- | modules/DataTable/Row/DataTableSummary.php | 15 | ||||
-rw-r--r-- | modules/ExceptionHandler.php | 1 | ||||
-rw-r--r-- | modules/LogStats/Generator.php | 18 | ||||
-rw-r--r-- | modules/LogStats/Visit.php | 5 | ||||
-rwxr-xr-x | modules/Piwik.php | 29 | ||||
-rw-r--r-- | plugins/Actions.php | 36 | ||||
-rw-r--r-- | plugins/Referers.php | 20 | ||||
-rwxr-xr-x | tests/all_tests.php | 3 | ||||
-rwxr-xr-x | tests/config_test.php | 10 | ||||
-rw-r--r-- | tests/modules/ArchiveProcessing/Day.test.php | 21 | ||||
-rw-r--r-- | tests/modules/DataTable.test.php | 222 | ||||
-rw-r--r-- | tests/modules/Piwik.test.php | 53 | ||||
-rwxr-xr-x | tests/simpletest/errors.php | 3 |
22 files changed, 999 insertions, 427 deletions
@@ -16,6 +16,12 @@ assert_options(ASSERT_ACTIVE, 1); assert_options(ASSERT_WARNING, 1); assert_options(ASSERT_BAIL, 1); +//ini_set('xdebug.collect_vars', 'on'); +//ini_set('xdebug.collect_params', '4'); +//ini_set('xdebug.dump_globals', 'on'); +//ini_set('xdebug.dump.SERVER', 'REQUEST_URI'); +//ini_set('xdebug.show_local_vars', 'on'); + /** * Error / exception handling functions */ @@ -54,10 +60,11 @@ Piwik::createDatabaseObject(); // Create the log objects Piwik::createLogObject(); +Piwik::printMemoryUsage('Start program'); //TODO move all DB related methods in a DB static class Piwik::createDatabase(); Piwik::createDatabaseObject(); -Piwik::dropTables(array(Piwik::prefixTable('log_visit'),Piwik::prefixTable('log_link_visit_action'),Piwik::prefixTable('log_action'))); +Piwik::dropTables(array(Piwik::prefixTable('log_visit'),Piwik::prefixTable('log_link_visit_action'),Piwik::prefixTable('log_action'),Piwik::prefixTable('log_profiling'))); Piwik::createTables(); // load plugins @@ -85,29 +92,39 @@ Zend_Registry::get('access')->loadAccess(); Zend_Loader::loadClass('Piwik_Archive'); Zend_Loader::loadClass('Piwik_Date'); +Piwik::printMemoryUsage('Before archiving'); $test = new Piwik_Archive; $period = new Piwik_Period_Day( Piwik_Date::today() ); $site = new Piwik_Site(1); $test->setPeriod($period); $test->setSite($site); -$test->get('toto0'); -$test->get('toto1'); +Piwik::log($test->get('toto0')); +Piwik::log($test->get('toto1')); + $test = new Piwik_Archive; -$period = new Piwik_Period_Day(Piwik_Date::today()); -$site = new Piwik_Site(12); +$period = new Piwik_Period_Month(Piwik_Date::today()); +$site = new Piwik_Site(1); $test->setPeriod($period); $test->setSite($site); -$test->get('nb_visits'); -$test->get('toto12'); +Piwik::log($test->get('nb_visits')); +Piwik::log($test->get('toto12')); +// +//$test = new Piwik_Archive; +//$period = new Piwik_Period_Day(Piwik_Date::today()); +//$site = new Piwik_Site(12); +//$test->setPeriod($period); +//$test->setSite($site); +//$test->get('nb_visits'); +//$test->get('toto12'); //main(); //displayProfiler(); Piwik::printMemoryUsage(); - +Piwik::printQueryCount(); echo $timer; -//Piwik::uninstall(); +//Piwik::uninstall(); //Piwik_Log::dump( Zend_Registry::get('db')->getProfiler()->getQueryProfiles() ); function displayProfiler() diff --git a/misc/generateVisits.php b/misc/generateVisits.php index 72414eaed6..9aca0cdeef 100644 --- a/misc/generateVisits.php +++ b/misc/generateVisits.php @@ -32,7 +32,7 @@ require_once "LogStats/Generator.php"; ob_start(); Piwik_PluginsManager::getInstance()->doNotLoadPlugins(); $generator = new Piwik_LogStats_Generator; -//$generator->disableProfiler(); +$generator->disableProfiler(); $generator->emptyAllLogTables(); $generator->init(); @@ -41,17 +41,17 @@ $t = new Piwik_Timer; /* * Generate visits / actions for the last 31 days */ -$daysToCompute = 1; +$daysToCompute = 4; $startTime = time() - ($daysToCompute-1)*86400; $nbActionsTotal = 0; while($startTime <= time()) { $visits = rand(1,2); $actions = 10; - $visits = rand(100,1000); - $actions = 10; + $visits = rand(10,30); + $actions = 5; - Piwik_LogStats_Generator_Visit::setTimestampToUse($startTime); + $generator->setTimestampToUse($startTime); $nbActionsTotalThisDay = $generator->generate($visits,$actions); $actionsPerVisit = round($nbActionsTotalThisDay / $visits); diff --git a/modules/Archive.php b/modules/Archive.php index 5b6f5693ec..7d007c9428 100644 --- a/modules/Archive.php +++ b/modules/Archive.php @@ -37,6 +37,7 @@ * - The *ArchiveProcessing* saves in the DB *numbers* or *Table* objects * */ + require_once 'Period.php'; require_once 'ArchiveProcessing.php'; @@ -53,9 +54,14 @@ class Piwik_Archive protected $id = null; protected $isThereSomeVisits = false; protected $alreadyChecked = false; + protected $archiveProcessing = null; + + public function __construct() + { + } // to be used only once - public function setPeriod( Piwik_Period $period ) + public function setPeriod( Piwik_Period $period ) { $this->period = $period; } @@ -63,10 +69,9 @@ class Piwik_Archive function setSite( Piwik_Site $site ) { $this->site = $site; - } - + } - function prepareArchive() + public function prepareArchive() { if(!$this->alreadyChecked) { @@ -77,6 +82,7 @@ class Piwik_Archive $archiveProcessing->setPeriod($this->period); $IdArchive = $archiveProcessing->loadArchive(); + $this->archiveProcessing = $archiveProcessing; $isThereSomeVisits = Zend_Registry::get('db')->fetchOne( 'SELECT value FROM '.$archiveProcessing->getTableArchiveNumericName(). @@ -86,30 +92,93 @@ class Piwik_Archive { $this->isThereSomeVisits = true; } + $this->idArchive = $IdArchive; $this->alreadyChecked = true; } } - - // returns a field of the archive - function get( $name ) + + //TODO implement cache + public function get( $name, $typeValue = 'numeric' ) { $this->prepareArchive(); + + if($name == 'idarchive') + { + return $this->idArchive; + } + Piwik::log("-- get '$name'"); if(!$this->isThereSomeVisits) { return false; } - return 1; - // select the data requested + + // select the table to use depending on the type of the data requested + $tableBlob = $this->archiveProcessing->getTableArchiveBlobName(); + $tableNumeric = $this->archiveProcessing->getTableArchiveNumericName(); + switch($typeValue) + { + case 'blob': + // select data from the blob table + $table = $tableBlob; + break; + + case 'numeric': + default: + // select data from the numeric table (by default) + $table = $tableNumeric; + break; + } + + // we select the requested value + $db = Zend_Registry::get('db'); + $value = $db->fetchOne("SELECT value + FROM $table + WHERE idarchive = ? + AND name = ?", + array( $this->idArchive , $name) + ); + + // uncompresss when selecting from the BLOB table + if($typeValue == 'blob') + { + $value = gzuncompress($value); + } + + return $value; + } + + public function getDataTable( $name ) + { + $data = $this->get($name, 'blob'); + + $table = new Piwik_DataTable; + if($data !== false) + { + $table->loadFromSerialized($data); + } + + return $table; + } + + + public function getNumeric( $name ) + { + return $this->get($name, 'numeric'); + } + + public function getBlob( $name ) + { + return $this->get($name, 'blob'); } // fetches many fields at once for performance function preFetch( $aName ) { - - } + // TODO implement prefetch + } } diff --git a/modules/ArchiveProcessing.php b/modules/ArchiveProcessing.php index 95977cd364..6fd8b80600 100644 --- a/modules/ArchiveProcessing.php +++ b/modules/ArchiveProcessing.php @@ -24,7 +24,7 @@ abstract class Piwik_ArchiveProcessing const DONE_ERROR = 2; - protected $idArchives; + protected $idArchive; protected $periodId; protected $dateStart; protected $dateEnd; @@ -43,7 +43,8 @@ abstract class Piwik_ArchiveProcessing public $logTable; public $logVisitActionTable; public $logActionTable; - + + protected function loadArchiveProperties() { $this->idsite = $this->site->getId(); @@ -70,16 +71,24 @@ abstract class Piwik_ArchiveProcessing } } + public function getTableArchiveNumericName() { return $this->tableArchiveNumeric; } + public function getTableArchiveBlobName() + { + return $this->tableArchiveBlob; + } + + // to be used only once public function setPeriod( Piwik_Period $period ) { $this->period = $period; } + public function setSite( Piwik_Site $site ) { $this->site = $site; @@ -88,23 +97,23 @@ abstract class Piwik_ArchiveProcessing public function loadArchive() { $this->loadArchiveProperties(); - $idArchive = $this->isArchived(); - if(!$idArchive) + $this->idArchive = $this->isArchived(); + if(!$this->idArchive) { - $this->idArchivesSubperiods = $this->loadSubperiodsArchive(); + $this->archivesSubperiods = $this->loadSubperiodsArchive(); $this->initCompute(); $this->compute(); $this->postCompute(); - Piwik::log("New archive computed, id = {$this->idArchives}"); + Piwik::log("New archive computed, id = {$this->idArchive}"); } else { - Piwik::log("Archive already available, id = $idArchive"); + Piwik::log("Archive already available, id = {$this->idArchive}"); } - return $idArchive; + return $this->idArchive; } /** @@ -115,7 +124,7 @@ abstract class Piwik_ArchiveProcessing protected function initCompute() { - $this->loadNextIdarchives(); + $this->loadNextIdarchive(); $record = new Piwik_Archive_Processing_Record_Numeric('done', Piwik_ArchiveProcessing::DONE_ERROR); $this->insertRecord( $record); @@ -135,7 +144,7 @@ abstract class Piwik_ArchiveProcessing Zend_Registry::get('db')->query(" DELETE FROM ".$this->tableArchiveNumeric." WHERE idarchive = ? AND name = 'done'", - array($this->idArchives) + array($this->idArchive) ); $finalRecord = new Piwik_Archive_Processing_Record_Numeric('done', Piwik_ArchiveProcessing::DONE_OK); @@ -157,7 +166,7 @@ abstract class Piwik_ArchiveProcessing } - protected function loadNextIdarchives() + protected function loadNextIdarchive() { $db = Zend_Registry::get('db'); $id = $db->fetchOne("SELECT max(idarchive) FROM ".$this->tableArchiveNumeric); @@ -165,7 +174,7 @@ abstract class Piwik_ArchiveProcessing { $id = 0; } - $this->idArchives = $id + 1; + $this->idArchive = $id + 1; } protected function insertRecord($record) @@ -182,7 +191,8 @@ abstract class Piwik_ArchiveProcessing $query = "INSERT INTO ".$table." (idarchive, idsite, date1, date2, period, ts_archived, name, value) VALUES (?,?,?,?,?,?,?,?)"; - Zend_Registry::get('db')->query($query, array( $this->idArchives, + Zend_Registry::get('db')->query($query, + array( $this->idArchive, $this->idsite, $this->strDateStart, $this->strDateEnd, @@ -191,7 +201,7 @@ abstract class Piwik_ArchiveProcessing $record->name, $record->value, ) - ); + ); } /** @@ -199,20 +209,20 @@ abstract class Piwik_ArchiveProcessing */ protected function loadSubperiodsArchive() { - $periodsId = array(); + $periods = array(); // we first compute every subperiod of the archive foreach($this->period->getSubperiods() as $period) { - $archivePeriod = Piwik_ArchiveProcessing::factory($period->getLabel()); - + $archivePeriod = new Piwik_Archive; $archivePeriod->setSite( $this->site ); $archivePeriod->setPeriod( $period ); + $archivePeriod->prepareArchive(); - $periodsId[] = $archivePeriod->loadArchive(); + $periods[] = $archivePeriod; } - return $periodsId; + return $periods; } protected function isArchived() diff --git a/modules/ArchiveProcessing/Day.php b/modules/ArchiveProcessing/Day.php index f67619e1bb..d34110dee1 100644 --- a/modules/ArchiveProcessing/Day.php +++ b/modules/ArchiveProcessing/Day.php @@ -116,8 +116,8 @@ class Piwik_ArchiveProcessing_Day extends Piwik_ArchiveProcessing if( !($maybeDatatableRow instanceof Piwik_DataTable_Row) ) { $subTable = self::generateDataTable($maybeDatatableRow); - $row = new Piwik_DataTable_Row_ActionTableSummary( $subTable ); - $row->addColumn('label', $label); + $row = new Piwik_DataTable_Row_DataTableSummary( $subTable ); + $row->setColumn('label', $label); } // if aInfo is a simple Row we build it else diff --git a/modules/ArchiveProcessing/Month.php b/modules/ArchiveProcessing/Month.php index 94b87c2be7..fd7e5b9114 100644 --- a/modules/ArchiveProcessing/Month.php +++ b/modules/ArchiveProcessing/Month.php @@ -7,9 +7,78 @@ class Piwik_ArchiveProcessing_Month extends Piwik_ArchiveProcessing { } + protected function getRecordNumericSum( $aNames ) + { + if(!is_array($aNames)) + { + $aNames = array($aNames); + } + + // fetch the numeric values and sum them + $results = array(); + foreach($this->archives as $archive) + { + $archive->preFetch($aNames); + + foreach($aNames as $name) + { + if(!isset($results[$name])) + { + $results[$name] = 0; + } + $valueToSum = $archive->getNumeric($name); + + if($valueToSum !== false) + { + $results[$name] += $valueToSum; + } + } + } + + // build the Record Numeric objects + $records = array(); + foreach($results as $name => $value) + { + $records[$name] = new Piwik_Archive_Processing_Record_Numeric( + $name, + $value + ); + } + + // if asked for only one field to sum + if(count($records) == 1) + { + return $records[$name]; + } + + // returns the array of records once summed + return $records; + } + + protected function getRecordDataTableSum( $name ) + { + $table = new Piwik_DataTable; + foreach($this->archives as $archive) + { + $datatableToSum = $archive->getDataTable($name); + $table->addDataTable($datatableToSum); + } + return $table; + } + protected function compute() { - $idArchives = $this->idArchivesSubperiods; + $this->archives = $this->archivesSubperiods; + + echo $this->getRecordNumericSum('nb_visits'); + $records = $this->getRecordNumericSum(array('nb_uniq_visitors', 'nb_actions')); + foreach($records as $rec) echo $rec."<br>"; + + echo $this->getRecordDataTableSum('UserSettings_browserType'); +// Piwik_PostEvent('ArchiveProcessing_Month.compute', $this); + +// $nbVisits = new Piwik_ArchiveProcessing_Record('nb_visits', +// new Piwik_ArchiveProcessing_Record_NumericSum) } } diff --git a/modules/DataTable.php b/modules/DataTable.php index e2c1032ea1..5ffabe3efe 100644 --- a/modules/DataTable.php +++ b/modules/DataTable.php @@ -1,5 +1,11 @@ <?php /** + * + * Initial Specification + * --------------------------------------------------------- + * CAREFUL: It may be outdated as I have not reviewed it yet + * --------------------------------------------------------- + * * ---- DataTable * A DataTable is a data structure used to store complex tables of data. * @@ -104,76 +110,171 @@ */ require_once "DataTable/Renderer.php"; require_once "DataTable/Filter.php"; +require_once "DataTable/Row.php"; +require_once "DataTable/Manager.php"; -class Piwik_DataTable_Manager -{ - static private $instance = null; - protected function __construct() - {} +class Piwik_DataTable +{ + protected $rows = array(); + protected $currentId; + protected $depthLevel = 0; + + const MAXIMUM_DEPTH_LEVEL_ALLOWED = 20; - static public function getInstance() + public function __construct() { - if (self::$instance == null) - { - $c = __CLASS__; - self::$instance = new $c(); - } - return self::$instance; + $this->currentId = Piwik_DataTable_Manager::getInstance()->addTable($this); } - protected $tables = array(); - protected $count = 0; - - function addTable( $table ) + /** + * Add a new DataTable to this DataTable + * Go through all the rows of the new DataTable and applies the algorithm: + * - if a row in $table doesnt exist in $this we add the row to $this + * - if a row exists in both $table and $this we add the columns values into $this + * + * A common row to 2 DataTable is defined by + * - the same label + * - the same idSubtable (or the absence of a subTable associated with the row) + * + * Details: + * - if a row in $this doesnt exist in $table we do nothing + * + * @example @see tests/modules/DataTable.test.php + */ + public function addDataTable( Piwik_DataTable $tableToSum ) { - $this->tables[] = $table; - $this->count++; - return $this->count; + foreach($tableToSum->getRows() as $row) + { + $labelToLookFor = $row->getColumn('label'); + $rowFound = $this->getRowFromLabel( $labelToLookFor ); + + // the row with this label already exists + if($rowFound === false) + { + $this->addRow( $row ); + } + else + { + $rowFound->sumRow( $row ); + // if the row to add has a subtable whereas the current row doesn't + // we simply add it (cloning the subtable) + +// $rowFound->addSubtable( $row->) + + // if the row has the subtable already + // then we have to recursively sum the subtables + } + + } } - function getTable( $idTable ) + public function getRowFromLabel( $label ) { - // the array tables is indexed at 0 - // but the index is computed as the count() of the array after inserting the table - $idTable -= 1; - - if(isset($this->tables[$idTable])) + $label = (string)$label; + if(!isset($this->rowsIndexByLabel[$label])) { - return $this->tables[$idTable]; + return false; } - - return null; - } -} + return $this->rows[$this->rowsIndexByLabel[$label]]; + } -function Piwik_DataTable_orderRowByLabel($o1,$o2) -{ - return ($o1->getColumn('label') < $o2->getColumn('label')) ? -1 : 1; -} -class Piwik_DataTable -{ - protected $rows = array(); - protected $currentId; - protected $depthLevel = 0; + /** + * Shortcut function used for performance reasons + */ + public function addRow( $row ) + { + $this->rows[] = $row; + + $label = $row->getColumn('label'); + + if($label !== false) + { + if(isset($this->rowsIndexByLabel[$label])) + { + throw new Exception("The row with the label $label already exist in this DataTable"); + } + $this->rowsIndexByLabel[$label] = count($this->rows) - 1; + } + } - const MAXIMUM_DEPTH_LEVEL_ALLOWED = 20; + public function getId() + { + return $this->currentId; + } - public function __construct() + + /** + * You should use loadFromArray for performance! + */ + public function addRowFromArray( $row ) { - $this->currentId = Piwik_DataTable_Manager::getInstance()->addTable($this); - -// self::$idSubtableAssociated[$this->currentId] = true; + $this->loadFromArray(array($row)); } + /** + * Returns the array of Piwik_DataTable_Row + */ + public function getRows() + { + return $this->rows; + } + /** + * Returns the number of rows + */ + public function getRowsCount() + { + return count($this->rows); + } + + public function deleteRow( $key ) + { + if(!isset($this->rows[$key])) + { + throw new Exception("Trying to delete unknown row with idkey = $key"); + } + unset($this->rows[$key]); + } + + public function deleteRowsOffset( $offset, $limit = null ) + { + if(is_null($limit)) + { + $limit = count($this->rows); + } + array_splice($this->rows, $offset, $limit); + } + + public function deleteRows( array $aKeys ) + { + foreach($aKeys as $key) + { + $this->deleteRow($key); + } + } + + public function __toString() + { + $renderer = new Piwik_DataTable_Renderer_Console($this); + return (string)$renderer; + } + + static public function isEqual($table1, $table2) { - $rows1 = $table1->getRows(); - $rows2 = $table2->getRows(); + $rows1before = $table1->getRows(); + $rows2before = $table2->getRows(); - usort($rows1, 'Piwik_DataTable_orderRowByLabel'); - usort($rows2, 'Piwik_DataTable_orderRowByLabel'); +// usort($rows1, 'Piwik_DataTable_orderRowByLabel'); +// usort($rows2, 'Piwik_DataTable_orderRowByLabel'); + $rows1 = $rows2 = array(); + foreach($rows1before as $row){ + $rows1[$row->getColumn('label')] = $row; + } + foreach($rows2before as $row){ + $rows2[$row->getColumn('label')] = $row; + } $countrows1 = count($rows1); $countrows2 = count($rows2); @@ -182,23 +283,17 @@ class Piwik_DataTable return false; } - $i = 0; - while($i < $countrows1) - { - if( !Piwik_DataTable_Row::isEqual($rows1[$i],$rows2[$i]) ) + foreach($rows1 as $label => $row1) + { + if( !isset($rows2[$label]) + || !Piwik_DataTable_Row::isEqual($row1,$rows2[$label]) ) { return false; } - $i++; } return true; } - - public function getId() - { - return $this->currentId; - } /** * The serialization returns a one dimension array containing all the @@ -304,7 +399,7 @@ class Piwik_DataTable $row = new Piwik_DataTable_Row($row); } - $this->rows[] = $row; + $this->addRow($row); } } @@ -355,290 +450,17 @@ class Piwik_DataTable $cleanRow[Piwik_DataTable_Row::DATATABLE_ASSOCIATED] = $subtablePerLabel[$label]; } - $this->rows[] = new Piwik_DataTable_Row($cleanRow); - } - } - /* - public function loadFromRowLabelIsKey( $arrayOfRows ) - { - foreach($arrayOfRows as $label => $row) - { - $row->addColumn('label', $label); - $this->rows[] = $row; - } - }*/ - - /** - * Shortcut function used for performance reasons - */ - public function addRow( $row ) - { - $this->rows[] = $row; - } - - /** - * You should use loadFromArray for performance! - */ - public function addRowFromArray( $row ) - { - $this->loadFromArray(array($row)); - } - - /** - * Returns the array of Piwik_DataTable_Row - */ - public function getRows() - { - return $this->rows; - } - /** - * Returns the number of rows - */ - public function getRowsCount() - { - return count($this->rows); - } - - public function deleteRow( $key ) - { - if(!isset($this->rows[$key])) - { - throw new Exception("Trying to delete unknown row with idkey = $key"); - } - unset($this->rows[$key]); - } - - public function deleteRowsOffset( $offset, $limit = null ) - { - if(is_null($limit)) - { - $limit = count($this->rows); - } - array_splice($this->rows, $offset, $limit); - } - - public function deleteRows( array $aKeys ) - { - foreach($aKeys as $key) - { - $this->deleteRow($key); + $this->addRow( new Piwik_DataTable_Row($cleanRow) ); } } - - public function __toString() - { - $renderer = new Piwik_DataTable_Renderer_Console($this); - return (string)$renderer; - } } -class Piwik_DataTable_Row_ActionTableSummary extends Piwik_DataTable_Row +function Piwik_DataTable_orderRowByLabel($o1,$o2) { - function __construct($subTable) - { - $currentColumns = array(); - - // go through the subTable and compute the summary - foreach($subTable->getRows() as $row) - { - $columns = $row->getColumns(); - foreach($columns as $name => $value) - { - if($name != 'label' - && ( Piwik::isNumeric($value) ) - ) - { - if(!isset($currentColumns[$name])) - { - $currentColumns[$name] = $value; - } - else - { - $currentColumns[$name] += $value; - } - } - } - } - $newRow = array(); - $newRow[Piwik_DataTable_Row::COLUMNS] = $currentColumns; - $newRow[Piwik_DataTable_Row::DATATABLE_ASSOCIATED] = $subTable; - - parent::__construct($newRow); - } + return strcmp($o1->getColumn('label'), $o2->getColumn('label')); } -class Piwik_DataTable_Row -{ - // Row content - public $c = array(); - const COLUMNS = 0; - const DETAILS = 1; - const DATATABLE_ASSOCIATED = 2; - - public function __construct( $row = array() ) - { - $this->c[self::COLUMNS] = array(); - $this->c[self::DETAILS] = array(); - $this->c[self::DATATABLE_ASSOCIATED] = null; - - if(isset($row[self::COLUMNS])) - { - $this->c[self::COLUMNS] = $row[self::COLUMNS]; - } - if(isset($row[self::DETAILS])) - { - $this->c[self::DETAILS] = $row[self::DETAILS]; - } - if(isset($row[self::DATATABLE_ASSOCIATED]) - && $row[self::DATATABLE_ASSOCIATED] instanceof Piwik_DataTable) - { - $this->c[self::DATATABLE_ASSOCIATED] = $row[self::DATATABLE_ASSOCIATED]->getId(); - } - } - // 2rows are equal is exact same columns / details - // and if subtable is there then subtable has to be the same! - static public function isEqual( $row1, $row2 ) - { - //same columns - $cols1 = $row1->getColumns(); - $cols2 = $row2->getColumns(); - - uksort($cols1, 'strnatcasecmp'); - uksort($cols2, 'strnatcasecmp'); - - if($cols1 != $cols2) - { - return false; - } - - $dets1 = $row1->getDetails(); - $dets2 = $row2->getDetails(); - - ksort($dets1); - ksort($dets2); - - // same details - if($dets1 != $dets2) - { - return false; - } - - // either both are null - // or both have a value - if( !(is_null($row1->getIdSubDataTable()) - && is_null($row2->getIdSubDataTable()) - ) - ) - { - $subtable1 = Piwik_DataTable_Manager::getInstance()->getTable($row1->getIdSubDataTable()); - $subtable2 = Piwik_DataTable_Manager::getInstance()->getTable($row2->getIdSubDataTable()); - if(!is_null($subtable1) && !is_null($subtable2)) - { - if(!Piwik_DataTable::isEqual($subtable1, $subtable2)) - { - return false; - } - } - else - { - return false; - } - - } - return true; - } - - public function getColumn( $name ) - { - if(!isset($this->c[self::COLUMNS][$name])) - { - return false; - } - return $this->c[self::COLUMNS][$name]; - } - public function getColumns() - { - return $this->c[self::COLUMNS]; - } - - public function getDetails() - { - return $this->c[self::DETAILS]; - } - - public function getIdSubDataTable() - { - return $this->c[self::DATATABLE_ASSOCIATED]; - } - public function addSubtable(Piwik_DataTable $subTable) - { - if(!is_null($this->c[self::DATATABLE_ASSOCIATED])) - { - throw new Exception("Adding a subtable to the row, but it already has a subtable associated."); - } - $this->c[self::DATATABLE_ASSOCIATED] = $subTable->getId(); - } - - public function setColumn($name, $value) - { - $this->c[self::COLUMNS][$name] = $value; - } - - public function addColumn($name, $value) - { - if(isset($this->c[self::COLUMNS][$name])) - { - throw new Exception("Column $name already in the array!"); - } - $this->c[self::COLUMNS][$name] = $value; - } - - /** - * Add the given $row columns values to the existing row' columns values. - * It will take in consideration only the int or float values of $row. - * - * If a given column doesn't exist in $this then it is added with the value of $row. - * If the column already exists in $this then we have - * this.columns[idThisCol] += $row.column[idThisCol] - */ - public function sumRow( $rowToSum ) - { - foreach($rowToSum->getColumns() as $name => $value) - { - if(Piwik::isNumeric($value)) - { - $current = $this->getColumn($name); - if($current==false) - { - $current = 0; - } - $this->setColumn( $name, $current + $value); - } - } - } - - /** - * Very efficient load of the Row structure from a well structured php array - * - * @param array The row array has the structure - * array( - * DataTable_Row::COLUMNS => array( - * 0 => 1554, - * 1 => 42, - * 2 => 657, - * 3 => 155744, - * ), - * DataTable_Row::DETAILS => array( - * 'logo' => 'test.png' - * ), - * DataTable_Row::DATATABLE_ASSOCIATED => #DataTable object // numeric idDataTable - * ) - */ - -} - - /** * ---- Other * We can also imagine building a DataTable_Compare which would take 2 DataTable that have the same diff --git a/modules/DataTable/Manager.php b/modules/DataTable/Manager.php new file mode 100644 index 0000000000..cef45a2466 --- /dev/null +++ b/modules/DataTable/Manager.php @@ -0,0 +1,43 @@ +<?php + +class Piwik_DataTable_Manager +{ + static private $instance = null; + protected function __construct() + {} + + static public function getInstance() + { + if (self::$instance == null) + { + $c = __CLASS__; + self::$instance = new $c(); + } + return self::$instance; + } + + protected $tables = array(); + protected $count = 0; + + function addTable( $table ) + { + $this->tables[] = $table; + $this->count++; + return $this->count; + } + + function getTable( $idTable ) + { + // the array tables is indexed at 0 + // but the index is computed as the count() of the array after inserting the table + $idTable -= 1; + + if(isset($this->tables[$idTable])) + { + return $this->tables[$idTable]; + } + + return null; + } +} +?> diff --git a/modules/DataTable/Row.php b/modules/DataTable/Row.php new file mode 100644 index 0000000000..9d8b21617b --- /dev/null +++ b/modules/DataTable/Row.php @@ -0,0 +1,196 @@ +<?php +/** + * IMPORTANT: A column named 'label' must not be composed only of the characters [0-9.] + * Otherwise the methods to addDataTable, sumRow, etc. would fail because they would consider + * the label as being a column to sum + */ +class Piwik_DataTable_Row +{ + // Row content + public $c = array(); + + const COLUMNS = 0; + const DETAILS = 1; + const DATATABLE_ASSOCIATED = 3; + + + /** + * Very efficient load of the Row structure from a well structured php array + * + * @param array The row array has the structure + * array( + * DataTable_Row::COLUMNS => array( + * 0 => 1554, + * 1 => 42, + * 2 => 657, + * 3 => 155744, + * ), + * DataTable_Row::DETAILS => array( + * 'logo' => 'test.png' + * ), + * DataTable_Row::DATATABLE_ASSOCIATED => #DataTable object // numeric idDataTable + * ) + */ + public function __construct( $row = array() ) + { + $this->c[self::COLUMNS] = array(); + $this->c[self::DETAILS] = array(); + $this->c[self::DATATABLE_ASSOCIATED] = null; + + if(isset($row[self::COLUMNS])) + { + $this->c[self::COLUMNS] = $row[self::COLUMNS]; + } + if(isset($row[self::DETAILS])) + { + $this->c[self::DETAILS] = $row[self::DETAILS]; + } + if(isset($row[self::DATATABLE_ASSOCIATED]) + && $row[self::DATATABLE_ASSOCIATED] instanceof Piwik_DataTable) + { + $this->c[self::DATATABLE_ASSOCIATED] = $row[self::DATATABLE_ASSOCIATED]->getId(); + } + } + + public function getColumn( $name ) + { + if(!isset($this->c[self::COLUMNS][$name])) + { + return false; + } + return $this->c[self::COLUMNS][$name]; + } + + public function getColumns() + { + return $this->c[self::COLUMNS]; + } + + public function getDetails() + { + return $this->c[self::DETAILS]; + } + + public function getIdSubDataTable() + { + return $this->c[self::DATATABLE_ASSOCIATED]; + } + + public function addSubtable(Piwik_DataTable $subTable) + { + $this->checkNoSubTable(); + $this->c[self::DATATABLE_ASSOCIATED] = $subTable->getId(); + } + + protected function checkNoSubTable() + { + if(!is_null($this->c[self::DATATABLE_ASSOCIATED])) + { + throw new Exception("Adding a subtable to the row, but it already has a subtable associated."); + } + } + + public function setColumn($name, $value) + { + $this->c[self::COLUMNS][$name] = $value; + } + + public function addColumn($name, $value) + { + if(isset($this->c[self::COLUMNS][$name])) + { + throw new Exception("Column $name already in the array!"); + } + $this->c[self::COLUMNS][$name] = $value; + } + + /** + * Add the given $row columns values to the existing row' columns values. + * It will take in consideration only the int or float values of $row. + * + * If a given column doesn't exist in $this then it is added with the value of $row. + * If the column already exists in $this then we have + * this.columns[idThisCol] += $row.columns[idThisCol] + */ + public function sumRow( $rowToSum ) + { +// if( $rowToSum->getIdSubDataTable() != null xor $this->getIdSubDataTable() != null ) +// { +// throw new Exception("Only one of either \$this or \$rowToSum +// has a subTable associated. Not expected."); +// } +// + foreach($rowToSum->getColumns() as $name => $value) + { + if($name != 'label' + && Piwik::isNumeric($value)) + { + $current = $this->getColumn($name); + if($current==false) + { + $current = 0; + } + $this->setColumn( $name, $current + $value); + } + } + } + + + /** + * 2rows are equal is exact same columns / details + * and if subtable is there then subtable has to be the same! + */ + static public function isEqual( $row1, $row2 ) + { + //same columns + $cols1 = $row1->getColumns(); + $cols2 = $row2->getColumns(); + + uksort($cols1, 'strnatcasecmp'); + uksort($cols2, 'strnatcasecmp'); + + if($cols1 != $cols2) + { + return false; + } + + $dets1 = $row1->getDetails(); + $dets2 = $row2->getDetails(); + + ksort($dets1); + ksort($dets2); + + // same details + if($dets1 != $dets2) + { + return false; + } + + // either both are null + // or both have a value + if( !(is_null($row1->getIdSubDataTable()) + && is_null($row2->getIdSubDataTable()) + ) + ) + { + $subtable1 = Piwik_DataTable_Manager::getInstance()->getTable($row1->getIdSubDataTable()); + $subtable2 = Piwik_DataTable_Manager::getInstance()->getTable($row2->getIdSubDataTable()); + if(!is_null($subtable1) && !is_null($subtable2)) + { + if(!Piwik_DataTable::isEqual($subtable1, $subtable2)) + { + return false; + } + } + else + { + return false; + } + + } + return true; + } +} + +require_once "Row/DataTableSummary.php"; +?> diff --git a/modules/DataTable/Row/DataTableSummary.php b/modules/DataTable/Row/DataTableSummary.php new file mode 100644 index 0000000000..6881c6b8d6 --- /dev/null +++ b/modules/DataTable/Row/DataTableSummary.php @@ -0,0 +1,15 @@ +<?php + +class Piwik_DataTable_Row_DataTableSummary extends Piwik_DataTable_Row +{ + function __construct($subTable) + { + parent::__construct(); + $this->addSubtable($subTable); + foreach($subTable->getRows() as $row) + { + $this->sumRow($row); + } + } +} +?> diff --git a/modules/ExceptionHandler.php b/modules/ExceptionHandler.php index b26570f6d2..62c2441534 100644 --- a/modules/ExceptionHandler.php +++ b/modules/ExceptionHandler.php @@ -13,7 +13,6 @@ function Piwik_ExceptionHandler(Exception $exception) print("<br> -------------------------- <br> This exception occured and also raised this exception: "); print("'" . $e->getMessage()."'"); - } } ?> diff --git a/modules/LogStats/Generator.php b/modules/LogStats/Generator.php index c540ac530a..e2ffb7e175 100644 --- a/modules/LogStats/Generator.php +++ b/modules/LogStats/Generator.php @@ -32,6 +32,7 @@ class Piwik_LogStats_Generator public $reinitProfilingAtEveryRequest = true; public $host = 'http://localhost'; + protected $timestampToUse; public function __construct() { @@ -48,6 +49,16 @@ class Piwik_LogStats_Generator $this->profiling = true; Piwik_LogStats_Db::enableProfiling(); + $this->timestampToUse = time(); + } + + public function setTimestampToUse($timestamp) + { + $this->timestampToUse = $timestamp; + } + public function getTimestampToUse() + { + return $this->timestampToUse; } public function addParam( $name, $aValue) { @@ -182,6 +193,8 @@ class Piwik_LogStats_Generator // print("$i "); $nbActions = mt_rand(1, $nbActionsMaxPerVisit); + Piwik_LogStats_Generator_Visit::setTimestampToUse($this->getTimestampToUse()); + $this->generateNewVisit(); for($j = 1; $j <= $nbActions; $j++) { @@ -308,7 +321,7 @@ class Piwik_LogStats_Generator $len = mt_rand($minLength, $maxLength); // Register the lower case alphabet array - $alpha = array('a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm'); + $alpha = array('a', 'b', 'c', 'd', 'e', 'f', 'g'); // Register the upper case alphabet array $ALPHA = array('A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', @@ -427,8 +440,7 @@ class Piwik_LogStats_Generator_Visit extends Piwik_LogStats_Visit } protected function getCurrentDate( $format = "Y-m-d") { - if($format == "Y-m-d") return date($format); - else return date($format, $this->getCurrentTimestamp() ); + return date($format, $this->getCurrentTimestamp() ); } protected function getCurrentTimestamp() diff --git a/modules/LogStats/Visit.php b/modules/LogStats/Visit.php index 2b801ebb82..d42faee6d4 100644 --- a/modules/LogStats/Visit.php +++ b/modules/LogStats/Visit.php @@ -398,8 +398,9 @@ class Piwik_LogStats_Visit $localTime = Piwik_Common::getRequestVar( 'h', $this->getCurrentDate("H"), 'numeric') .':'. Piwik_Common::getRequestVar( 'm', $this->getCurrentDate("i"), 'numeric') .':'. Piwik_Common::getRequestVar( 's', $this->getCurrentDate("s"), 'numeric'); - $serverDate = $this->getCurrentDate(); - $serverTime = $this->getCurrentTimestamp(); + + $serverTime = $this->getCurrentTimestamp(); + $serverDate = $this->getCurrentDate(); if($this->isVisitorKnown()) { diff --git a/modules/Piwik.php b/modules/Piwik.php index 831b280a45..172146c7bb 100755 --- a/modules/Piwik.php +++ b/modules/Piwik.php @@ -11,10 +11,10 @@ class Piwik const CLASSES_PREFIX = "Piwik_"; static $idPeriods = array( - 'day' =>1, - 'week' =>2, - 'month' =>3, - 'year' =>4, + 'day' =>1, + 'week' =>2, + 'month' =>3, + 'year' =>4, ); static public function log($message, $priority = Zend_Log::NOTICE) @@ -22,6 +22,7 @@ class Piwik Zend_Registry::get('logger_message')->log($message); Zend_Registry::get('logger_message')->log( "<br>" . PHP_EOL); } + //TODO TEST secureDiv static public function secureDiv( $i1, $i2 ) { @@ -31,15 +32,30 @@ class Piwik } return 0; } - static public function printMemoryUsage() + + static public function printQueryCount() + { + $profiler = Zend_Registry::get('db')->getProfiler(); + $totalTime = $profiler->getTotalElapsedSecs(); + $queryCount = $profiler->getTotalNumQueries(); + Piwik::log("Total queries = $queryCount (total sql time = ".round($totalTime,2)."s)"); + } + + static public function printMemoryUsage( $prefixString = null ) { $usage = round(memory_get_usage() / 1024 / 1024, 2); + if(!is_null($prefixString)) + { + Piwik::log($prefixString); + } Piwik::log("Memory usage = $usage Mb"); } + static public function isNumeric($value) { - return !is_array($value) && ereg('^([0-9.]*)$', $value); + return !is_array($value) && ereg('^([-]{0,1}[0-9]{1,}[.]{0,1}[0-9]*)$', $value); } + static public function loadPlugins() { Piwik_PluginsManager::getInstance()->setPluginsToLoad( Zend_Registry::get('config')->Plugins->enabled ); @@ -453,6 +469,7 @@ class Piwik unset($tablesToCreate['archive_blob']); unset($tablesToCreate['archive_numeric']); + $tablesAlreadyInstalled = self::getTablesInstalled(); foreach($tablesToCreate as $tableName => $tableSql) diff --git a/plugins/Actions.php b/plugins/Actions.php index 32067689c7..50760e699a 100644 --- a/plugins/Actions.php +++ b/plugins/Actions.php @@ -56,8 +56,14 @@ class Piwik_Plugin_Actions extends Piwik_Plugin { $archiveProcessing = $notification->getNotificationObject(); + require_once "LogStats/Action.php"; + + $this->actionsTablesByType = array( + Piwik_LogStats_Action::TYPE_ACTION => array(), + Piwik_LogStats_Action::TYPE_DOWNLOAD => array(), + Piwik_LogStats_Action::TYPE_OUTLINK => array(), + ); - $this->actionsTablesByType = array(); $timer = new Piwik_Timer; Piwik::printMemoryUsage(); @@ -96,7 +102,7 @@ class Piwik_Plugin_Actions extends Piwik_Plugin sum(case visit_total_actions when 1 then 1 else 0 end) as entry_bounce_count FROM ".$archiveProcessing->logTable." - LEFT JOIN ".$archiveProcessing->logActionTable." ON (visit_entry_idaction = idaction) + JOIN ".$archiveProcessing->logActionTable." ON (visit_entry_idaction = idaction) WHERE visit_server_date = ? AND idsite = ? GROUP BY visit_entry_idaction @@ -107,7 +113,7 @@ class Piwik_Plugin_Actions extends Piwik_Plugin Piwik::log("$modified rows for entry actions"); - Piwik::printMemoryUsage(); +// Piwik::printMemoryUsage(); /* * Exit actions @@ -119,7 +125,7 @@ class Piwik_Plugin_Actions extends Piwik_Plugin sum(case visit_total_actions when 1 then 1 else 0 end) as exit_bounce_count FROM ".$archiveProcessing->logTable." - LEFT JOIN ".$archiveProcessing->logActionTable." ON (visit_exit_idaction = idaction) + JOIN ".$archiveProcessing->logActionTable." ON (visit_exit_idaction = idaction) WHERE visit_server_date = ? AND idsite = ? GROUP BY visit_exit_idaction @@ -130,7 +136,7 @@ class Piwik_Plugin_Actions extends Piwik_Plugin Piwik::log("$modified rows for exit actions"); - Piwik::printMemoryUsage(); +// Piwik::printMemoryUsage(); /* * Time per action */ @@ -138,8 +144,8 @@ class Piwik_Plugin_Actions extends Piwik_Plugin type, sum(time_spent_ref_action) as sum_time_spent FROM (".$archiveProcessing->logTable." log_visit - LEFT JOIN ".$archiveProcessing->logVisitActionTable." log_link_visit_action USING (idvisit)) - LEFT JOIN ".$archiveProcessing->logActionTable." log_action ON (log_action.idaction = log_link_visit_action.idaction_ref) + JOIN ".$archiveProcessing->logVisitActionTable." log_link_visit_action USING (idvisit)) + JOIN ".$archiveProcessing->logActionTable." log_action ON (log_action.idaction = log_link_visit_action.idaction_ref) WHERE visit_server_date = ? AND idsite = ? GROUP BY idaction_ref @@ -148,30 +154,28 @@ class Piwik_Plugin_Actions extends Piwik_Plugin $modified = $this->updateActionsTableWithRowQuery($query); - require_once "LogStats/Action.php"; Piwik::log("$modified rows for sum time per action"); - Piwik::printMemoryUsage(); +// Piwik::printMemoryUsage(); $data = Piwik_ArchiveProcessing_Day::generateDataTable($this->actionsTablesByType[Piwik_LogStats_Action::TYPE_ACTION]); -// echo $data; $s = $data->getSerialized(); $record = new Piwik_Archive_Processing_Record_Blob_Array('Actions_actions', $s); - print(" serialized has ".count($s)." elements"); - Piwik::printMemoryUsage(); + Piwik::log(" Action serialized has ".count($s)." elements"); +// Piwik::printMemoryUsage(); $data = Piwik_ArchiveProcessing_Day::generateDataTable($this->actionsTablesByType[Piwik_LogStats_Action::TYPE_DOWNLOAD]); $s = $data->getSerialized(); $record = new Piwik_Archive_Processing_Record_Blob_Array('Actions_downloads', $s); - print(" serialized has ".count($s)." elements"); - Piwik::printMemoryUsage(); + Piwik::log(" Download serialized has ".count($s)." elements"); +// Piwik::printMemoryUsage(); $data = Piwik_ArchiveProcessing_Day::generateDataTable($this->actionsTablesByType[Piwik_LogStats_Action::TYPE_OUTLINK]); $s = $data->getSerialized(); $record = new Piwik_Archive_Processing_Record_Blob_Array('Actions_outlink', $s); - print(" serialized has ".count($s)." elements"); - Piwik::printMemoryUsage(); + Piwik::log(" Outlink serialized has ".count($s)." elements"); +// Piwik::printMemoryUsage(); } /* $query = "SELECT count(distinct l.idaction) as nb_uniq_actions diff --git a/plugins/Referers.php b/plugins/Referers.php index 2b85bfe6c2..b884d1c385 100644 --- a/plugins/Referers.php +++ b/plugins/Referers.php @@ -62,8 +62,22 @@ class Piwik_Plugin_Referers extends Piwik_Plugin AND idsite = ? GROUP BY referer_type, referer_name, referer_keyword"; $query = $archiveProcessing->db->query($query, array( $archiveProcessing->strDateStart, $archiveProcessing->idsite )); - + $timer = new Piwik_Timer; + + $interestBySearchEngine = + $interestByKeyword = + $keywordBySearchEngine = + $searchEngineByKeyword = + $interestByWebsite[Piwik_Common::REFERER_TYPE_WEBSITE] = + $interestByWebsite[Piwik_Common::REFERER_TYPE_PARTNER] = + $urlByWebsite[Piwik_Common::REFERER_TYPE_WEBSITE] = + $urlByWebsite[Piwik_Common::REFERER_TYPE_PARTNER] = + $interestByNewsletter = + $keywordByCampaign = + $interestByCampaign = + $interestByType = array(); + while($rowBefore = $query->fetch() ) { $row = array( @@ -134,7 +148,7 @@ class Piwik_Plugin_Referers extends Piwik_Plugin if(!isset($interestByType[$row['referer_type']] )) $interestByType[$row['referer_type']] = $archiveProcessing->getNewInterestRow(); $archiveProcessing->updateInterestStats($row, $interestByType[$row['referer_type']]); } - echo "after loop = ". $timer; +// echo "after loop = ". $timer; // Piwik::log("By search engine:"); // Piwik::log($interestBySearchEngine); @@ -185,6 +199,6 @@ class Piwik_Plugin_Referers extends Piwik_Plugin $data = $archiveProcessing->getDataTablesSerialized($urlByWebsite[Piwik_Common::REFERER_TYPE_PARTNER], $interestByWebsite[Piwik_Common::REFERER_TYPE_PARTNER]); $record = new Piwik_Archive_Processing_Record_Blob_Array('referer_url_by_partner', $data); - echo "after serialization = ". $timer; +// echo "after serialization = ". $timer; } }
\ No newline at end of file diff --git a/tests/all_tests.php b/tests/all_tests.php index 03809bacfc..a8a7c64e15 100755 --- a/tests/all_tests.php +++ b/tests/all_tests.php @@ -75,6 +75,7 @@ foreach($toInclude as $file) } $timer = new Piwik_Timer; $test->run(new HtmlReporter()); -echo $timer; +echo $timer."<br>"; +Piwik::printMemoryUsage(); ?> diff --git a/tests/config_test.php b/tests/config_test.php index 28cb30eb40..afb60c06e1 100755 --- a/tests/config_test.php +++ b/tests/config_test.php @@ -14,6 +14,8 @@ if(!defined('PIWIK_INCLUDE_PATH')) } set_include_path(PATH_TEST_TO_ROOT .'/' + . PATH_SEPARATOR . getcwd() + . PATH_SEPARATOR . getcwd() . '/../' . PATH_SEPARATOR . PATH_TEST_TO_ROOT . '/libs/' . PATH_SEPARATOR . getcwd() . '/../../libs/' . PATH_SEPARATOR . getcwd() . '/../libs/' @@ -73,4 +75,10 @@ assert_options(ASSERT_WARNING, 1); assert_options(ASSERT_BAIL, 0); define('CONFIG_TEST_INCLUDED', true); -?> + + + + + + + diff --git a/tests/modules/ArchiveProcessing/Day.test.php b/tests/modules/ArchiveProcessing/Day.test.php index 41895a8780..aac006869f 100644 --- a/tests/modules/ArchiveProcessing/Day.test.php +++ b/tests/modules/ArchiveProcessing/Day.test.php @@ -25,16 +25,14 @@ class Test_Piwik_ArchiveProcessing_Day extends UnitTestCase { } - + //TODO test with a label in the column list that is composed of numbers only function test_generateDataTable_simple() { - - $row1 = new Piwik_DataTable_Row( array( Piwik_DataTable_Row::COLUMNS => array( 'label' => 'page1', 'visits' => 1, 'actions' => 2))); $input = array( - 'page1' => $row1, + 'page1' => $row1, ); $table = new Piwik_DataTable; @@ -160,7 +158,7 @@ class Test_Piwik_ArchiveProcessing_Day extends UnitTestCase //FIRST ROW + SUBTABLE $rowcat2 = new Piwik_DataTable_Row( array( Piwik_DataTable_Row::COLUMNS => - array( 'label' => 'pagecat2', 'visits' => 3, 'actions' => 5 ))); + array( 'label' => '456', 'visits' => 3, 'actions' => 5 ))); $cat2 = new Piwik_DataTable_Row( array( Piwik_DataTable_Row::COLUMNS => array( 'label' => 'cat2', 'visits' => 3, 'actions' => 5 ))); @@ -209,14 +207,14 @@ class Test_Piwik_ArchiveProcessing_Day extends UnitTestCase $table = new Piwik_DataTable; $rowpagecat3 = new Piwik_DataTable_Row( array( Piwik_DataTable_Row::COLUMNS => - array( 'label' => 'pagecat3', 'visits' => 3, 'actions' => 5 ))); + array( 'label' => '123123', 'visits' => 3, 'actions' => 5 ))); $rowcat3 = new Piwik_DataTable_Row( array( Piwik_DataTable_Row::COLUMNS => - array( 'label' => 'cat3', 'visits' => 3, 'actions' => 5 ))); + 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' => 'cat1', 'visits' => 3, 'actions' => 5 ))); + array( 'label' => '&*()', 'visits' => 3, 'actions' => 5 ))); $subtablerowpagecat3 = new Piwik_DataTable; $subtablerowpagecat3->addRow($rowpagecat3); @@ -236,14 +234,15 @@ class Test_Piwik_ArchiveProcessing_Day extends UnitTestCase // WHAT WE TEST $input = array( - 'cat1' => array( + '&*()' => array( 'cat2' => array( - 'cat3' => array( - 'pagecat3' => $rowpagecat3, + '789.654' => array( + '123123' => $rowpagecat3, ), ), ), ); + $tableGenerated = Piwik_ArchiveProcessing_Day::generateDataTable($input); $r1 = new Piwik_DataTable_Renderer_Console($table); diff --git a/tests/modules/DataTable.test.php b/tests/modules/DataTable.test.php index b81d31c499..ed01b88be4 100644 --- a/tests/modules/DataTable.test.php +++ b/tests/modules/DataTable.test.php @@ -52,8 +52,11 @@ class Test_Piwik_DataTable extends UnitTestCase $idsubtable = $subtable->getId(); /* - * create some fake tables to make sure that the serialized array of the first TABLE + * create some fake tables to make sure + * that the serialized array of the first TABLE * does not take in consideration those tables + * (yes theres a story of an ID given by some DataTable_Manager + * we check this module is not messing around) */ $useless2 = new Piwik_DataTable; $useless1->addRowFromArray(array(Piwik_DataTable_Row::COLUMNS => array( 8487,),)); @@ -465,4 +468,221 @@ class Test_Piwik_DataTable extends UnitTestCase $this->assertEqual(array_values($table->getRows()), array_values($expectedtable->getRows())); } + + /** + * for all datatable->addDatatable tests we check that + * - row uniqueness is based on the label + presence of the SUBTABLE id + * => the label is the criteria used to match 2 rows in 2 datatable + * - no details are lost in the first datatable rows that have been changed + * - when a subtable + */ + + + /** + * add an empty datatable to a normal datatable + */ + public function test_addSimpleNoRowTable2() + { + $idcol = Piwik_DataTable_Row::COLUMNS; + + $rows = array( + array( $idcol => array('label'=>'google', 'visits' => 1)), + array( $idcol => array('label'=>'ask', 'visits' => 2)), + array( $idcol => array('label'=>'123', 'visits' => 2)), + ); + $table = new Piwik_DataTable; + $table->loadFromArray( $rows ); + + $tableEmpty = new Piwik_DataTable; + + $tableAfter = clone $table; + $tableAfter->addDataTable($tableEmpty); + $this->assertTrue( Piwik_DataTable::isEqual($table, $tableAfter) ); + } + + /** + * add a normal datatable to an empty datatable + */ + public function test_addSimpleNoRowTable1() + { + $idcol = Piwik_DataTable_Row::COLUMNS; + + $rows = array( + array( $idcol => array('label'=>'google', 'visits' => 1)), + array( $idcol => array('label'=>'ask', 'visits' => 2)), + array( $idcol => array('label'=>'123', 'visits' => 2)), + ); + $table = new Piwik_DataTable; + $table->loadFromArray( $rows ); + + $tableEmpty = new Piwik_DataTable; + + $tableAfter = clone $tableEmpty; + $tableEmpty->addDataTable($table); + $this->assertTrue( Piwik_DataTable::isEqual($tableEmpty, $table) ); + } + + /** + * add to the datatable another datatable// they don't have any row in common + */ + public function test_addSimpleNoCommonRow() + { + $idcol = Piwik_DataTable_Row::COLUMNS; + + $rows = array( + array( $idcol => array('label'=>'google', 'visits' => 1)), + array( $idcol => array('label'=>'ask', 'visits' => 2)), + array( $idcol => array('label'=>'123', 'visits' => 2)), + ); + $table = new Piwik_DataTable; + $table->loadFromArray( $rows ); + + + $rows2 = array( + array( $idcol => array('label'=>'test', 'visits' => 1)), + array( $idcol => array('label'=>' google ', 'visits' => 3)), + array( $idcol => array('label'=>'123a', 'visits' => 2)), + ); + $table2 = new Piwik_DataTable; + $table2->loadFromArray( $rows2 ); + + $table->addDataTable($table2); + + $rowsExpected = array_merge($rows,$rows2); + $tableExpected = new Piwik_DataTable; + $tableExpected->loadFromArray( $rowsExpected ); + + $this->assertTrue( Piwik_DataTable::isEqual($table, $tableExpected) ); + } + + /** + * add 2 datatable with some common rows + */ + public function test_addSimpleSomeCommonRow() + { + + $idcol = Piwik_DataTable_Row::COLUMNS; + + $rows = array( + array( $idcol => array('label'=>'google', 'visits' => 1)), + array( $idcol => array('label'=>'ask', 'visits' => 2)), + array( $idcol => array('label'=>'123', 'visits' => 2)), + ); + $table = new Piwik_DataTable; + $table->loadFromArray( $rows ); + + + $rows2 = array( + array( $idcol => array('label'=>'test', 'visits' => 1)), + array( $idcol => array('label'=>'ask', 'visits' => 111)), + array( $idcol => array('label'=>' google ', 'visits' => 5)), + array( $idcol => array('label'=>'123', 'visits' => 2)), + ); + $table2 = new Piwik_DataTable; + $table2->loadFromArray( $rows2 ); + + $table->addDataTable($table2); + + $rowsExpected = array( + array( $idcol => array('label'=>'google', 'visits' => 1)), + array( $idcol => array('label'=>'ask', 'visits' => 113)), + array( $idcol => array('label'=>'test', 'visits' => 1)), + array( $idcol => array('label'=>' google ', 'visits' => 5)), + array( $idcol => array('label'=>'123', 'visits' => 4)), + ); + $tableExpected = new Piwik_DataTable; + $tableExpected->loadFromArray( $rowsExpected ); + + $this->assertTrue( Piwik_DataTable::isEqual($table, $tableExpected) ); + } + + /** + * add 2 datatable with only common rows + */ + public function test_addSimpleAllCommonRow() + { + $idcol = Piwik_DataTable_Row::COLUMNS; + + $rows = array( + array( $idcol => array('label'=>'google', 'visits' => 1)), + array( $idcol => array('label'=>'ask', 'visits' => 2)), + array( $idcol => array('label'=>'123', 'visits' => 2)), + ); + $table = new Piwik_DataTable; + $table->loadFromArray( $rows ); + + + $rows2 = array( + array( $idcol => array('label'=>'google', 'visits' => -1)), + array( $idcol => array('label'=>'ask', 'visits' => 0)), + array( $idcol => array('label'=>'123', 'visits' => 1.5)), + ); + $table2 = new Piwik_DataTable; + $table2->loadFromArray( $rows2 ); + + $table->addDataTable($table2); + + $rowsExpected = array( + array( $idcol => array('label'=>'google', 'visits' => 0)), + array( $idcol => array('label'=>'ask', 'visits' => 2)), + array( $idcol => array('label'=>'123', 'visits' => 3.5)), + ); + $tableExpected = new Piwik_DataTable; + $tableExpected->loadFromArray( $rowsExpected ); + + $this->assertTrue( Piwik_DataTable::isEqual($table, $tableExpected) ); + } + + /** + * test add 2 different tables to the same table + */ + + public function test_addDataTable2times() + { + + $idcol = Piwik_DataTable_Row::COLUMNS; + + $rows = array( + array( $idcol => array('label'=>'google', 'visits' => 1)), + array( $idcol => array('label'=>'ask', 'visits' => 0)), + array( $idcol => array('label'=>'123', 'visits' => 2)), + ); + $table = new Piwik_DataTable; + $table->loadFromArray( $rows ); + + + $rows2 = array( + array( $idcol => array('label'=>'google2', 'visits' => -1)), + array( $idcol => array('label'=>'ask', 'visits' => 100)), + array( $idcol => array('label'=>'123456', 'visits' => 1.5)), + ); + $table2 = new Piwik_DataTable; + $table2->loadFromArray( $rows2 ); + + + $rows3 = array( + array( $idcol => array('label'=>'google2', 'visits' => -1)), + array( $idcol => array('label'=>'ask', 'visits' => -10)), + array( $idcol => array('label'=>'123ab', 'visits' => 1.5)), + ); + $table3 = new Piwik_DataTable; + $table3->loadFromArray( $rows3 ); + + // add the 2 tables + $table->addDataTable($table2); + $table->addDataTable($table3); + + $rowsExpected = array( + array( $idcol => array('label'=>'google', 'visits' => 1)), + array( $idcol => array('label'=>'123', 'visits' => 2)), + array( $idcol => array('label'=>'google2', 'visits' => -2)), + array( $idcol => array('label'=>'ask', 'visits' => 90)), + array( $idcol => array('label'=>'123456', 'visits' => 1.5)), + array( $idcol => array('label'=>'123ab', 'visits' => 1.5)), + ); + $tableExpected = new Piwik_DataTable; + $tableExpected->loadFromArray( $rowsExpected ); + + $this->assertTrue( Piwik_DataTable::isEqual($table, $tableExpected) ); + } }
\ No newline at end of file diff --git a/tests/modules/Piwik.test.php b/tests/modules/Piwik.test.php new file mode 100644 index 0000000000..a33e4f9eaa --- /dev/null +++ b/tests/modules/Piwik.test.php @@ -0,0 +1,53 @@ +<?php +if(!defined("PATH_TEST_TO_ROOT")) { + define('PATH_TEST_TO_ROOT', '..'); +} +if(!defined('CONFIG_TEST_INCLUDED')) +{ + require_once PATH_TEST_TO_ROOT ."/../tests/config_test.php"; +} + +//Zend_Loader::loadClass('Piwik_'); + +class Test_Piwik extends UnitTestCase +{ + function __construct( $title = '') + { + parent::__construct( $title ); + } + + public function setUp() + { + } + + public function tearDown() + { + } + + + public function test_isNumericValid() + { + $valid = array( + -1, 0 , 1, 1.5, -1.5, 21111, 89898, 99999999999, -4565656, + (float)-1, (float)0 , (float)1, (float)1.5, (float)-1.5, (float)21111, (float)89898, (float)99999999999, (float)-4565656, + (int)-1, (int)0 , (int)1, (int)1.5, (int)-1.5, (int)21111, (int)89898, (int)99999999999, (int)-4565656, + '-1', '0' , '1', '1.5', '-1.5', '21111', '89898', '99999999999', '-4565656', + ); + foreach($valid as $toTest) + { + $this->assertTrue(Piwik::isNumeric($toTest), $toTest." not valid!"); + } + } + + public function test_isNumericNotValid() + { + $notvalid = array( + '-1.0.0', '1e3','1,2', '0x123', '--1', '-.', "-1e-2", '- 1', '1-', + ); + foreach($notvalid as $toTest) + { + $this->assertFalse(Piwik::isNumeric($toTest), $toTest." valid but shouldn't!"); + } + } +} +?> diff --git a/tests/simpletest/errors.php b/tests/simpletest/errors.php index f38dc6354e..94a7fb4a4b 100755 --- a/tests/simpletest/errors.php +++ b/tests/simpletest/errors.php @@ -269,8 +269,10 @@ class SimpleErrorQueue { */ function SimpleTestErrorHandler($severity, $message, $filename = null, $line = null, $super_globals = null, $mask = null) { $severity = $severity & error_reporting(); + if ($severity) { restore_error_handler(); + if (ini_get('log_errors')) { $label = SimpleErrorQueue::getSeverityAsString($severity); error_log("$label: $message in $filename on line $line"); @@ -280,6 +282,7 @@ function SimpleTestErrorHandler($severity, $message, $filename = null, $line = n $queue->add($severity, $message, $filename, $line); set_error_handler('SimpleTestErrorHandler'); } + return true; } ?>
\ No newline at end of file |