Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/matomo-org/matomo.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authormatthieu_ <matthieu_@59fd770c-687e-43c8-a1e3-f5a4ff64c105>2007-08-17 22:08:14 +0400
committermatthieu_ <matthieu_@59fd770c-687e-43c8-a1e3-f5a4ff64c105>2007-08-17 22:08:14 +0400
commit00f5a744883fc3a5ce0706714d98fd9b86a7f51e (patch)
tree82fb3dc171acb7093e8b9eadab6e1d9cb013d66c
parent49c593b1cc964373c1a2567a7e03154c166639fc (diff)
Implemented half of the PERIOD archiving
still have to implement the DataTable::addDataTable( ) for recursive table
-rwxr-xr-xindex.php35
-rw-r--r--misc/generateVisits.php10
-rw-r--r--modules/Archive.php91
-rw-r--r--modules/ArchiveProcessing.php48
-rw-r--r--modules/ArchiveProcessing/Day.php4
-rw-r--r--modules/ArchiveProcessing/Month.php71
-rw-r--r--modules/DataTable.php492
-rw-r--r--modules/DataTable/Manager.php43
-rw-r--r--modules/DataTable/Row.php196
-rw-r--r--modules/DataTable/Row/DataTableSummary.php15
-rw-r--r--modules/ExceptionHandler.php1
-rw-r--r--modules/LogStats/Generator.php18
-rw-r--r--modules/LogStats/Visit.php5
-rwxr-xr-xmodules/Piwik.php29
-rw-r--r--plugins/Actions.php36
-rw-r--r--plugins/Referers.php20
-rwxr-xr-xtests/all_tests.php3
-rwxr-xr-xtests/config_test.php10
-rw-r--r--tests/modules/ArchiveProcessing/Day.test.php21
-rw-r--r--tests/modules/DataTable.test.php222
-rw-r--r--tests/modules/Piwik.test.php53
-rwxr-xr-xtests/simpletest/errors.php3
22 files changed, 999 insertions, 427 deletions
diff --git a/index.php b/index.php
index 377fbf14b8..290d7761d0 100755
--- a/index.php
+++ b/index.php
@@ -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