diff options
author | mattpiwik <matthieu.aubry@gmail.com> | 2007-08-22 22:14:37 +0400 |
---|---|---|
committer | mattpiwik <matthieu.aubry@gmail.com> | 2007-08-22 22:14:37 +0400 |
commit | f11210f7a74569bc25b4f89c4ff7ae5afebfca86 (patch) | |
tree | 558c23cf9b11172643773ddbe51cc7a32af5a315 /modules | |
parent | 6307df6d62c3507e7f9779ea441b0f8bc9f35dc9 (diff) |
-wrote some renderers: php, xml
-wrote the API request class to handle the GET request to get data from the API provided by the plugins
-organized the files into new directories
git-svn-id: http://dev.piwik.org/svn/trunk@47 59fd770c-687e-43c8-a1e3-f5a4ff64c105
Diffstat (limited to 'modules')
-rwxr-xr-x | modules/API/APIable.php (renamed from modules/APIable.php) | 0 | ||||
-rwxr-xr-x | modules/API/Proxy.php (renamed from modules/PublicAPI.php) | 68 | ||||
-rw-r--r-- | modules/API/Request.php | 133 | ||||
-rwxr-xr-x | modules/Access.php | 4 | ||||
-rw-r--r-- | modules/Archive.php | 45 | ||||
-rw-r--r-- | modules/ArchiveProcessing/Period.php | 22 | ||||
-rw-r--r-- | modules/DataTable.php | 1 | ||||
-rw-r--r-- | modules/DataTable/Filter/ColumnCallback.php | 2 | ||||
-rw-r--r-- | modules/DataTable/Renderer.php | 89 | ||||
-rw-r--r-- | modules/DataTable/Renderer/Console.php | 67 | ||||
-rw-r--r-- | modules/DataTable/Renderer/PHP.php | 41 | ||||
-rw-r--r-- | modules/DataTable/Renderer/XML.php | 48 | ||||
-rw-r--r-- | modules/Date.php | 10 | ||||
-rwxr-xr-x | modules/ErrorHandler.php | 8 | ||||
-rw-r--r-- | modules/Period.php | 25 | ||||
-rw-r--r-- | modules/PluginsManager.php | 2 | ||||
-rwxr-xr-x | modules/SitesManager.php | 4 | ||||
-rwxr-xr-x | modules/UsersManager.php | 2 |
18 files changed, 472 insertions, 99 deletions
diff --git a/modules/APIable.php b/modules/API/APIable.php index f3ce32a1fe..f3ce32a1fe 100755 --- a/modules/APIable.php +++ b/modules/API/APIable.php diff --git a/modules/PublicAPI.php b/modules/API/Proxy.php index d281eb0100..009cfc5fe7 100755 --- a/modules/PublicAPI.php +++ b/modules/API/Proxy.php @@ -1,5 +1,5 @@ <?php -class Piwik_PublicAPI +class Piwik_API_Proxy { static $classCalled = null; private $api = null; @@ -18,13 +18,31 @@ class Piwik_PublicAPI return self::$instance; } - public function registerClass( $class ) - { - Zend_Loader::loadClass($class); - - // check that is is singleton - $this->checkClassIsSingleton($class); + public function registerClass( $fileName ) + { + $potentialPaths = array( + PIWIK_INCLUDE_PATH . "/plugins/". $fileName ."/API.php", + PIWIK_INCLUDE_PATH . "/modules/". $fileName .".php", + ); + $found = false; + foreach($potentialPaths as $path) + { + if(is_file($path)) + { + require_once $path; + $found = true; + break; + } + } + + if(!$found) + { + throw new Exception("API module $fileName not found."); + } + + $class= $this->getClassNameFromModule($fileName); + $rClass = new ReflectionClass($class); // check that it is a subclass of Piwik_APIable @@ -32,6 +50,10 @@ class Piwik_PublicAPI { throw new Exception("To publish its public methods in the API, the class '$class' must be a subclass of 'Piwik_Apiable'."); } + + // check that is is singleton + $this->checkClassIsSingleton($class); + Piwik::log("List of the public methods for the class $class"); @@ -41,7 +63,8 @@ class Piwik_PublicAPI // use this trick to read the static attribute of the class // $class::$methodsNotToPublish doesn't work $variablesClass = get_class_vars($class); - + $variablesClass['methodsNotToPublish'][] = 'getInstance'; + if($method->isPublic() && !$method->isConstructor() && !in_array($method->getName(), $variablesClass['methodsNotToPublish'] ) @@ -88,16 +111,18 @@ class Piwik_PublicAPI $sParameters = implode(", ", $asParameters); return "[$sParameters]"; } + /** * Returns the parameters names and default values for the method $name * of the class $class * * @return array Format array( - * 'parameter1Name' => 42 // default value = 42, + * 'parameter1Name' => '', + * 'life' => 42, // default value = 42 * 'date' => 'yesterday', * ); */ - private function getParametersList($class, $name) + public function getParametersList($class, $name) { return $this->api[$class][$name]['parameters']; } @@ -143,27 +168,34 @@ class Piwik_PublicAPI } } - private function checkMethodExists($className, $methodName) + public function checkMethodExists($className, $methodName) { if(!$this->isMethodAvailable($className, $methodName)) { - throw new Exception("The method '$methodName' does not exist or is not available in the module '".self::$classCalled."'."); + throw new Exception("The method '$methodName' does not exist or is not available in the module '".$className."'."); } } + public function getClassNameFromModule($module) + { + $class = Piwik::prefixClass($module ."_API"); + return $class; + } public function __call($methodName, $parameterValues ) { + $returnedValue = null; + try { assert(!is_null(self::$classCalled)); - - $className = Piwik::prefixClass(self::$classCalled); - + + $className = $this->getClassNameFromModule(self::$classCalled); + // instanciate the object $object = call_user_func(array($className, "getInstance")); - + // check method exists $this->checkMethodExists($className, $methodName); - + // first check number of parameters do match $this->checkNumberOfParametersMatch($className, $methodName, $parameterValues); @@ -192,6 +224,8 @@ class Piwik_PublicAPI } self::$classCalled = null; + + return $returnedValue; } } ?>
\ No newline at end of file diff --git a/modules/API/Request.php b/modules/API/Request.php new file mode 100644 index 0000000000..09049c9267 --- /dev/null +++ b/modules/API/Request.php @@ -0,0 +1,133 @@ +<?php + +class Piwik_API_Request +{ + private function extractModuleAndMethod($parameter) + { + $a = explode('.',$parameter); + if(count($a) != 2) + { + throw new Exception("The method name is invalid. Must be on the form 'module.methodName'"); + } + return $a; + } + + public function process() + { + // read parameters + $moduleMethod = Piwik_Common::getRequestVar('method'); + + list($module, $method) = $this->extractModuleAndMethod($moduleMethod); + + + // call the method via the PublicAPI class + $api = Piwik_Api_Proxy::getInstance(); + $api->registerClass($module); + + // read method to call meta information + $className = "Piwik_" . $module . "_API"; + + // check method exists + $api->checkMethodExists($className, $method); + + $parameters = $api->getParametersList($className, $method); + + $finalParameters = array(); + foreach($parameters as $name => $defaultValue) + { + if(!empty($defaultValue)) + { + $requestValue = Piwik_Common::getRequestVar($name, $defaultValue); + } + else + { + $requestValue = Piwik_Common::getRequestVar($name); + } + $finalParameters[] = $requestValue; + } + + $returnedValue = call_user_func_array( array( $api->$module, $method), $finalParameters ); + + $toReturn = $returnedValue; + + // If the returned value is an object DataTable we + // apply the set of generic filters if asked in the URL + // and we render the DataTable according to the format specified in the URL + if($returnedValue instanceof Piwik_DataTable) + { + $dataTable = $returnedValue; + + $this->applyDataTableGenericFilters($dataTable); + $toReturn = $this->getRenderedDataTable($dataTable); + + } + + return $toReturn; + } + + protected function getRenderedDataTable($dataTable) + { + // Renderer + $format = Piwik_Common::getRequestVar('format', 'php', 'string'); + $renderer = Piwik_DataTable_Renderer::factory($format); + $renderer->setTable($dataTable); + + $toReturn = (string)$renderer; + return $toReturn; + } + + protected function applyDataTableGenericFilters($dataTable) + { + + // Generic filters + // PatternFileName => Parameter names to match to constructor parameters + $genericFilters = array( + 'Limit' => array( + 'filter_offset' => 'integer', + 'filter_limit' => 'integer', + ), + 'Pattern' => array( + 'filter_column' => 'string', + 'filter_pattern' => 'string', + ), + ); + + foreach($genericFilters as $filterName => $parameters) + { + $filterParameters = array(); + $exceptionRaised = false; + + foreach($parameters as $name => $type) + { + try { + $value = Piwik_Common::getRequestVar($name); + settype($value, $type); + $filterParameters[] = $value; + } + catch(Exception $e) + { + $exceptionRaised = true; + break; + } + } + + if(!$exceptionRaised) + { + assert(count($filterParameters)==count($parameters)); + + // a generic filter class name must follow this pattern + $class = "Piwik_DataTable_Filter_".$filterName; + + // build the set of parameters for the filter + $filterParameters = array_merge(array($dataTable), $filterParameters); + + // make a reflection object + $reflectionObj = new ReflectionClass($class); + + // use Reflection to create a new instance, using the $args + $filter = $reflectionObj->newInstanceArgs($filterParameters); + } + } + } + +}
\ No newline at end of file diff --git a/modules/Access.php b/modules/Access.php index 830877f454..6de0673257 100755 --- a/modules/Access.php +++ b/modules/Access.php @@ -1,5 +1,5 @@ <?php -Zend_Loader::loadClass('Piwik_SitesManager'); +require_once 'SitesManager.php'; class Piwik_Access { private $acl = null; @@ -37,7 +37,7 @@ class Piwik_Access if($result->getCode() == Piwik_Auth::SUCCESS_SUPERUSER_AUTH_CODE) { $this->isSuperUser = true; - $sitesId = Piwik_SitesManager::getAllSitesId(); + $sitesId = Piwik_SitesManager_API::getAllSitesId(); foreach($sitesId as $idSite) { $accessByIdsite[$idSite] = 'superuser'; diff --git a/modules/Archive.php b/modules/Archive.php index d1a52fb558..0d39db9c10 100644 --- a/modules/Archive.php +++ b/modules/Archive.php @@ -62,6 +62,18 @@ class Piwik_Archive { } + static public function build($idSite, $date, $period ) + { + $oDate = Piwik_Date::factory($date); + $oPeriod = Piwik_Period::factory($period, $oDate); + $oSite = new Piwik_Site($idSite); + + $archive = new Piwik_Archive; + $archive->setPeriod($oPeriod); + $archive->setSite($oSite); + return $archive; + } + // to be used only once public function setPeriod( Piwik_Period $period ) { @@ -71,7 +83,11 @@ class Piwik_Archive function setSite( Piwik_Site $site ) { $this->site = $site; - } + } + function getIdSite() + { + return $this->site->getId(); + } public function prepareArchive() { @@ -180,6 +196,33 @@ class Piwik_Archive return $value; } + + public function loadSubDataTables($name, Piwik_DataTable $dataTableToLoad) + { + // we have to recursively load all the subtables associated to this table's rows + // and update the subtableID so that it matches the newly instanciated table + foreach($dataTableToLoad->getRows() as $row) + { + $subTableID = $row->getIdSubDataTable(); + + if($subTableID !== null) + { + $subDataTableLoaded = $this->getDataTable($name, $subTableID); + + $this->loadSubDataTables($name, $subDataTableLoaded); + + $row->setSubtable( $subDataTableLoaded ); + } + } + } + + public function getDataTableExpanded($name) + { + $dataTableToLoad = $this->getDataTable($name); + $this->loadSubDataTables($name, $dataTableToLoad); + return $dataTableToLoad; + } + public function getDataTable( $name, $idSubTable = null ) { if(!is_null($idSubTable)) diff --git a/modules/ArchiveProcessing/Period.php b/modules/ArchiveProcessing/Period.php index f29beb0eb6..7a7a6e6519 100644 --- a/modules/ArchiveProcessing/Period.php +++ b/modules/ArchiveProcessing/Period.php @@ -92,24 +92,6 @@ class Piwik_ArchiveProcessing_Period extends Piwik_ArchiveProcessing return $records; } - private function reloadSubtables($name, $dataTableToLoad, $archive) - { - // we have to recursively load all the subtables associated to this table's rows - // and update the subtableID so that it matches the newly instanciated table - foreach($dataTableToLoad->getRows() as $row) - { - $subTableID = $row->getIdSubDataTable(); - - if($subTableID !== null) - { - $subDataTableLoaded = $archive->getDataTable($name, $subTableID); - - $this->reloadSubtables($name, $subDataTableLoaded, $archive); - - $row->setSubtable( $subDataTableLoaded ); - } - } - } protected function getRecordDataTableSum( $name ) { @@ -120,7 +102,7 @@ class Piwik_ArchiveProcessing_Period extends Piwik_ArchiveProcessing $datatableToSum = $archive->getDataTable($name); - $this->reloadSubtables($name, $datatableToSum, $archive); + $archive->loadSubDataTables($name, $datatableToSum); // echo $datatableToSum; $table->addDataTable($datatableToSum); @@ -148,7 +130,7 @@ class Piwik_ArchiveProcessing_Period extends Piwik_ArchiveProcessing Piwik_PostEvent('ArchiveProcessing_Period.compute', $this); //delete all DataTable instanciated - Piwik_DataTable_Manager::getInstance()->deleteAll(); +// Piwik_DataTable_Manager::getInstance()->deleteAll(); } } diff --git a/modules/DataTable.php b/modules/DataTable.php index c0311c3d3f..0d4fb6dc47 100644 --- a/modules/DataTable.php +++ b/modules/DataTable.php @@ -109,6 +109,7 @@ * */ require_once "DataTable/Renderer.php"; +require_once "DataTable/Renderer/Console.php"; require_once "DataTable/Filter.php"; require_once "DataTable/Row.php"; require_once "DataTable/Manager.php"; diff --git a/modules/DataTable/Filter/ColumnCallback.php b/modules/DataTable/Filter/ColumnCallback.php index d9455df8ce..78ac773979 100644 --- a/modules/DataTable/Filter/ColumnCallback.php +++ b/modules/DataTable/Filter/ColumnCallback.php @@ -27,4 +27,4 @@ class Piwik_DataTable_Filter_ColumnCallback extends Piwik_DataTable_Filter } } } -?> + diff --git a/modules/DataTable/Renderer.php b/modules/DataTable/Renderer.php index 06aca5d62f..dbc5dc198e 100644 --- a/modules/DataTable/Renderer.php +++ b/modules/DataTable/Renderer.php @@ -3,7 +3,16 @@ class Piwik_DataTable_Renderer { protected $table; - function __construct($table) + + function __construct($table = null) + { + if(!is_null($table)) + { + $this->setTable($table); + } + } + + public function setTable($table) { if(!($table instanceof Piwik_DataTable)) { @@ -16,60 +25,40 @@ class Piwik_DataTable_Renderer { return $this->render(); } -} - -class Piwik_DataTable_Renderer_Console extends Piwik_DataTable_Renderer -{ - protected $prefixRows; - function __construct($table) - { - parent::__construct($table); - $this->setPrefixRow('#'); - } - - function render() - { - return $this->renderTable($this->table); - } - - function setPrefixRow($str) - { - $this->prefixRows = $str; - } - function renderTable($table) + static public function factory( $name ) { - static $depth=0; - $output = ''; - $i = 1; - foreach($table->getRows() as $row) + $name = strtolower($name); + switch ($name) { - $columns=array(); - foreach($row->getColumns() as $column => $value) - { - if(is_string($value)) $value = "'$value'"; - $columns[] = "'$column' => $value"; - } - $columns = implode(", ", $columns); - $details=array(); - foreach($row->getDetails() as $detail => $value) - { - $details[] = "'$detail' => $value"; - } - $details = implode(", ", $details); - $output.= str_repeat($this->prefixRows, $depth) . "- $i [".$columns."] [".$details."] [idsubtable = ".$row->getIdSubDataTable()."]<br>\n"; + case 'console': + require_once "DataTable/Renderer/Console.php"; + $class = 'Piwik_DataTable_Renderer_Console'; + break; - if($row->getIdSubDataTable() !== null) - { - $depth++; - $output.= $this->renderTable( Piwik_DataTable_Manager::getInstance()->getTable($row->getIdSubDataTable())); - $depth--; - } - $i++; - } + case 'xml': + require_once "DataTable/Renderer/XML.php"; + $class = 'Piwik_DataTable_Renderer_XML'; + break; + + case 'rss': + require_once "DataTable/Renderer/RSS.php"; + $class = 'Piwik_DataTable_Renderer_RSS'; + break; + + case 'php': + require_once "DataTable/Renderer/PHP.php"; + $class = 'Piwik_DataTable_Renderer_PHP'; + break; - return $output; + default: + throw new Exception("Renderer format $name unknown!"); + break; + } - } + return new $class; + } + + } ?> diff --git a/modules/DataTable/Renderer/Console.php b/modules/DataTable/Renderer/Console.php new file mode 100644 index 0000000000..dc3fdc6bfc --- /dev/null +++ b/modules/DataTable/Renderer/Console.php @@ -0,0 +1,67 @@ +<?php + +class Piwik_DataTable_Renderer_Console extends Piwik_DataTable_Renderer +{ + protected $prefixRows; + function __construct($table = null) + { + parent::__construct($table); + $this->setPrefixRow('#'); + } + + function render() + { + return $this->renderTable($this->table); + } + + function setPrefixRow($str) + { + $this->prefixRows = $str; + } + function renderTable($table) + { + if($table->getRowsCount() == 0) + { + return "Empty table <br>\n"; + } + + static $depth=0; + $output = ''; + $i = 1; + foreach($table->getRows() as $row) + { + $columns=array(); + foreach($row->getColumns() as $column => $value) + { + if(is_string($value)) $value = "'$value'"; + $columns[] = "'$column' => $value"; + } + $columns = implode(", ", $columns); + $details=array(); + foreach($row->getDetails() as $detail => $value) + { + $details[] = "'$detail' => $value"; + } + $details = implode(", ", $details); + $output.= str_repeat($this->prefixRows, $depth) . "- $i [".$columns."] [".$details."] [idsubtable = ".$row->getIdSubDataTable()."]<br>\n"; + + if($row->getIdSubDataTable() !== null) + { + $depth++; + try{ + $output.= $this->renderTable( Piwik_DataTable_Manager::getInstance()->getTable($row->getIdSubDataTable())); + } catch(Exception $e) + { + $output.= "-- Sub DataTable not loaded<br>\n"; + } + $depth--; + } + $i++; + } + + return $output; + + } +} + +?> diff --git a/modules/DataTable/Renderer/PHP.php b/modules/DataTable/Renderer/PHP.php new file mode 100644 index 0000000000..b4f7c1437d --- /dev/null +++ b/modules/DataTable/Renderer/PHP.php @@ -0,0 +1,41 @@ +<?php + + +class Piwik_DataTable_Renderer_PHP extends Piwik_DataTable_Renderer +{ + protected $serialize; + function __construct($table = null, $serialize = true) + { + parent::__construct($table); + $this->serialize = $serialize; + } + + function render() + { + return $this->renderTable($this->table); + } + + function renderTable($table) + { + $array = array(); + + foreach($table->getRows() as $row) + { + $newRow = array( + 'columns' => $row->getColumns(), + 'details' => $row->getDetails(), + 'idsubdatatable' => $row->getIdSubDataTable() + ); + $array[] = $newRow; + } + + if($this->serialize) + { + serialize($array); + } + else + { + return $array; + } + } +}
\ No newline at end of file diff --git a/modules/DataTable/Renderer/XML.php b/modules/DataTable/Renderer/XML.php new file mode 100644 index 0000000000..51ea618536 --- /dev/null +++ b/modules/DataTable/Renderer/XML.php @@ -0,0 +1,48 @@ +<?php + +require_once "DataTable/Renderer/PHP.php"; +class Piwik_DataTable_Renderer_XML extends Piwik_DataTable_Renderer +{ + function __construct($table = null) + { + parent::__construct($table); + } + + function render() + { + return $this->renderTable($this->table); + } + + function renderTable($table) + { + $renderer = new Piwik_DataTable_Renderer_PHP($table, $serialize = false); + $array = $renderer->render(); + $xmlStr = $this->array_to_simplexml($array)->asXML(); + $xmlStr = str_replace("<","\n<",$xmlStr); + + return $xmlStr; + } + + // from http://uk3.php.net/simplexml + function array_to_simplexml($array, $name="result" ,&$xml=null ) + { + if(is_null($xml)) + { + $xml = new SimpleXMLElement("<{$name}/>"); + } + + foreach($array as $key => $value) + { + if(is_array($value)) + { + $xml->addChild($key); + $this->array_to_simplexml($value, $name, $xml->$key); + } + else + { + $xml->addChild($key, $value); + } + } + return $xml; + } +}
\ No newline at end of file diff --git a/modules/Date.php b/modules/Date.php index 27f3b43c60..507af231b3 100644 --- a/modules/Date.php +++ b/modules/Date.php @@ -31,5 +31,15 @@ class Piwik_Date extends Zend_Date $date = new Piwik_Date(date("Y-m-d", strtotime("yesterday"))); return $date; } + + static public function factory($strDate) + { + switch($strDate) + { + case 'today': return self::today(); break; + case 'yesterday': return self::yesterday(); break; + default: return new Piwik_Date($strDate); break; + } + } } ?> diff --git a/modules/ErrorHandler.php b/modules/ErrorHandler.php index 79b6acd578..cb746380e6 100755 --- a/modules/ErrorHandler.php +++ b/modules/ErrorHandler.php @@ -1,10 +1,10 @@ <?php function Piwik_ErrorHandler($errno, $errstr, $errfile, $errline) { -// ob_start(); -// debug_print_backtrace(); -// $backtrace = ob_get_contents(); -// ob_end_clean(); + ob_start(); + debug_print_backtrace(); + $backtrace = ob_get_contents(); + ob_end_clean(); Zend_Registry::get('logger_error')->log($errno, $errstr, $errfile, $errline, $backtrace); } ?> diff --git a/modules/Period.php b/modules/Period.php index 99724b32f2..b2d0d899fd 100644 --- a/modules/Period.php +++ b/modules/Period.php @@ -24,6 +24,31 @@ abstract class Piwik_Period $this->date = clone $date; } + static public function factory($strPeriod, $date) + { + switch ($strPeriod) { + case 'day': + return new Piwik_Period_Day($date); + break; + + case 'week': + return new Piwik_Period_Week($date); + break; + + case 'month': + return new Piwik_Period_Month($date); + break; + + case 'year': + return new Piwik_Period_Year($date); + break; + + default: + throw new Exception("Unknown period!"); + break; + } + } + //TODO test getDate public function getDate() { diff --git a/modules/PluginsManager.php b/modules/PluginsManager.php index f678b4f985..295597e1cc 100644 --- a/modules/PluginsManager.php +++ b/modules/PluginsManager.php @@ -89,7 +89,7 @@ class Piwik_PluginsManager foreach($this->pluginsToLoad as $pluginName) { $pluginFileName = $pluginName . ".php"; - $pluginClassName = "Piwik_Plugin_".$pluginName; + $pluginClassName = "Piwik_".$pluginName; // TODO make sure the plugin name is secure // make sure thepluigin is a child of Piwik_Plugin diff --git a/modules/SitesManager.php b/modules/SitesManager.php index 86e8f7d810..6064e04009 100755 --- a/modules/SitesManager.php +++ b/modules/SitesManager.php @@ -1,8 +1,8 @@ <?php -Zend_Loader::loadClass('Piwik_APIable'); +require_once "API/APIable.php"; -class Piwik_SitesManager extends Piwik_APIable +class Piwik_SitesManager_API extends Piwik_APIable { static private $instance = null; protected function __construct() diff --git a/modules/UsersManager.php b/modules/UsersManager.php index 2d45f57b30..14f021d42b 100755 --- a/modules/UsersManager.php +++ b/modules/UsersManager.php @@ -1,7 +1,7 @@ <?php Zend_Loader::loadClass("Piwik_Access"); -class Piwik_UsersManager extends Piwik_APIable +class Piwik_UsersManager_API extends Piwik_APIable { static private $instance = null; protected function __construct() |