[Piwik-svn] r156 - in trunk: . modules modules/API modules/SmartyPlugins plugins/API

svnmaster at piwik.org svnmaster at piwik.org
Mon Jan 14 02:12:26 CET 2008


Author: matt
Date: 2008-01-14 02:12:26 +0100 (Mon, 14 Jan 2008)
New Revision: 156

Modified:
   trunk/index.php
   trunk/modules/API/APIable.php
   trunk/modules/API/Proxy.php
   trunk/modules/API/Request.php
   trunk/modules/FrontController.php
   trunk/modules/SmartyPlugins/function.url.php
   trunk/modules/View.php
   trunk/plugins/API/Controller.php
Log:
working on http://dev.piwik.org/trac/wiki/API

Modified: trunk/index.php
===================================================================
--- trunk/index.php	2008-01-14 00:55:04 UTC (rev 155)
+++ trunk/index.php	2008-01-14 01:12:26 UTC (rev 156)
@@ -5,8 +5,17 @@
 error_reporting(E_ALL|E_NOTICE);
 @ini_set('display_errors', 1);
 @ini_set('magic_quotes_runtime', 0);
-date_default_timezone_set('Europe/London');
-define('PIWIK_INCLUDE_PATH', '.');
+date_default_timezone_set('Europe/London');
+if(!defined('PIWIK_INCLUDE_PATH'))
+{
+	define('PIWIK_INCLUDE_PATH', '.');
+}
+
+if(!defined('ENABLE_DISPATCH'))
+{
+	define('ENABLE_DISPATCH', true);	
+}
+
 define('PIWIK_PLUGINS_PATH', PIWIK_INCLUDE_PATH . '/plugins');
 define('PIWIK_DATAFILES_INCLUDE_PATH', PIWIK_INCLUDE_PATH . "/modules/DataFiles");
 
@@ -36,6 +45,9 @@
 
 
 $controller = new Piwik_FrontController;
-$controller->init();
-$controller->dispatch();
+$controller->init();
+if(ENABLE_DISPATCH)
+{
+	$controller->dispatch();
+}
 $controller->end();

Modified: trunk/modules/API/APIable.php
===================================================================
--- trunk/modules/API/APIable.php	2008-01-14 00:55:04 UTC (rev 155)
+++ trunk/modules/API/APIable.php	2008-01-14 01:12:26 UTC (rev 156)
@@ -1,13 +1,17 @@
 <?php
 /**
- * This class is the parent class of all the modules that can be called using the 
- * API Proxy.
+ * This class is the parent class of all the modules that can be called using the API Proxy. 
+ * For example a plugin "Provider" can publish its API by creating a file plugins/Provider/API.php
+ * that is extending this Piwik_Apiable class.
+ * 
+ * All the Piwik_Apiable classes are read and loaded by the Piwik_API_Proxy class. 
  * 
- * @package Piwik_API
+ * @package Piwik_API
+ * @see Piwik_API_Proxy
  */
 require_once "Archive.php";
 
-class Piwik_Apiable 
+abstract class Piwik_Apiable 
 {
 	static public $methodsNotToPublish = array();
 	
@@ -18,7 +22,7 @@
 	/**
 	 * Register a public method as "not to be published in the API".
 	 * Sometimes methods have to be marked as public to be used by other classes but
-	 * we don't want these methods to be called from outside the application.
+	 * we don't want these methods to be called from outside the application using the API.
 	 * 
 	 * @param string Method name not to be published
 	 */

Modified: trunk/modules/API/Proxy.php
===================================================================
--- trunk/modules/API/Proxy.php	2008-01-14 00:55:04 UTC (rev 155)
+++ trunk/modules/API/Proxy.php	2008-01-14 01:12:26 UTC (rev 156)
@@ -1,13 +1,13 @@
 <?php
 /**
- * 
  * The API Proxy receives all the API calls requests and forwards them to the given module.
  *  
  * It registers all the APIable modules (@see Piwik_Apiable)
- * The class checks that a call to the API has to correct number of parameters.
- * The proxy has the knowledge of every method available, and their parameters and default value.
- * It also logs the calls performances (time spent, parameter values, etc.)
+ * The class checks that a call to the API has the correct number of parameters.
+ * The proxy is a singleton that has the knowledge of every method available, their parameters and default values.
  * 
+ * It can also log the performances of the API calls (time spent, parameter values, etc.)
+ * 
  * @package Piwik_API
  */
 class Piwik_API_Proxy
@@ -15,13 +15,19 @@
 	static $classCalled = null;
 	protected $alreadyRegistered = array();
 	private $api = array();
-	
+	
+	// when a parameter doesn't have a default value we use this constant
 	const NO_DEFAULT_VALUE = null;
-		
+
 	static private $instance = null;
 	protected function __construct()
 	{}
-	
+	
+	/**
+	 * Singleton, returns instance
+	 *
+	 * @return Piwik_API_Proxy
+	 */
 	static public function getInstance()
 	{
 		if (self::$instance == null)
@@ -35,13 +41,15 @@
 	/**
 	 * Registers the API information of a given module.
 	 * 
-	 * The module to register must be
+	 * The module to be registered must be
 	 * - extending the Piwik_Apiable class
 	 * - a singleton (providing a getInstance() method)
-	 * - the API file must be located in plugins/MODULE/API.php
+	 * - the API file must be located in plugins/ModuleName/API.php
 	 *   for example plugins/Referers/API.php
 	 * 
-	 * The method will introspect the methods, their parameters, etc. 
+	 * The method will introspect the methods, their parameters, etc. 
+	 * 
+	 * @param string ModuleName
 	 */
 	public function registerClass( $fileName )
 	{
@@ -52,7 +60,6 @@
 		
 		$potentialPaths = array(
 			 PIWIK_INCLUDE_PATH . "/plugins/". $fileName ."/API.php",
-			 PIWIK_INCLUDE_PATH . "/modules/". $fileName .".php",
 	  	);
 		
 		$found = false;
@@ -84,8 +91,6 @@
 		// check that is is singleton
 		$this->checkClassIsSingleton($class);
 		
-
-		
 		$rMethods = $rClass->getMethods();
 		foreach($rMethods as $method)
 		{
@@ -124,13 +129,27 @@
 		$this->alreadyRegistered[$fileName] = true;
 	}
 	
-	// Piwik_moduleName_API => moduleName
+	/**
+	 * Returns the  'moduleName' part of 'Piwik_moduleName_API' classname 
+	 * 
+	 * @param string moduleName
+	 * @return string className 
+	 */ 
 	protected function getModuleNameFromClassName( $className )
 	{
 		$start = strpos($className, '_') + 1;
 		return substr($className, $start , strrpos($className, '_') - $start);
-	}
-	// return false when not possible
+	}
+	
+	/**
+	 * Returns a string containing links to examples on how to call a given method on a given API
+	 * It will export links to XML, CSV, HTML, JSON, PHP, etc.
+	 * It will not export links for method such as deleteSite or deleteUser
+	 *
+	 * @param string the class 
+	 * @param methodName the method
+	 * @return string|false when not possible
+	 */
 	public function getExampleUrl($class, $methodName)
 	{
 		$knowExampleDefaultParametersValues = array(
@@ -147,6 +166,7 @@
 			'date' => 'today',
 		);
 		
+		// no links for these method names
 		$doNotPrintExampleForTheseMethods = array(
 			'deleteSite',
 			'deleteUser',
@@ -156,13 +176,16 @@
 		{
 			return false;
 		}
+		
+		
 		// we try to give an URL example to call the API
 		$aParameters = $this->getParametersList($class, $methodName);
 		$moduleName = $this->getModuleNameFromClassName($class);
 		$urlExample = '?module=API&method='.$moduleName.'.'.$methodName.'&';
 		foreach($aParameters as $nameVariable=> $defaultValue)
 		{
-			// there is NO default value we need an example value or we can't generate the example
+			// if there isn't a default value for a given parameter, 
+			// we need a 'know default value' or we can't generate the link
 			if($defaultValue === Piwik_API_Proxy::NO_DEFAULT_VALUE)
 			{
 				if(isset($knowExampleDefaultParametersValues[$nameVariable]))
@@ -179,8 +202,17 @@
 		}
 		
 		return substr($urlExample,0,-1);
-	}
-	public function getAllInterfaceString()
+	}
+	
+	/**
+	 * Returns a HTML page containing help for all the successfully loaded APIs.
+	 * 
+	 * For each module it will return a mini help with the method names, parameters to give, 
+	 * links to get the result in Xml/Csv/etc
+	 *
+	 * @return string
+	 */
+	public function getAllInterfaceString( $outputExampleUrls = true )
 	{
 		$str = '';
 		foreach($this->api as $class => $info)
@@ -191,26 +223,30 @@
 			foreach($info as $methodName => $infoMethod)
 			{
 
-				$exampleUrl = $this->getExampleUrl($class, $methodName);
 				
 				$params = $this->getStrListParameters($class, $methodName);
 				$str .= "\n" . "- <b>$methodName " . $params . "</b>";
 				
 				$str .= '<small>';
-				if($exampleUrl !== false)
+				
+				if($outputExampleUrls)
 				{
-					$str .= " [ Example in  
-								<a target=_blank href='$exampleUrl&format=xml'>XML</a>, 
-								<a target=_blank href='$exampleUrl&format=PHP'>PHP</a>, 
-								<a target=_blank href='$exampleUrl&format=JSON'>Json</a>, 
-								<a target=_blank href='$exampleUrl&format=Csv'>Csv</a>, 
-								<a target=_blank href='$exampleUrl&format=Html'>Basic html</a>
-								]";
+					$exampleUrl = $this->getExampleUrl($class, $methodName);
+					if($exampleUrl !== false)
+					{
+						$str .= " [ Example in  
+									<a target=_blank href='$exampleUrl&format=xml'>XML</a>, 
+									<a target=_blank href='$exampleUrl&format=PHP'>PHP</a>, 
+									<a target=_blank href='$exampleUrl&format=JSON'>Json</a>, 
+									<a target=_blank href='$exampleUrl&format=Csv'>Csv</a>, 
+									<a target=_blank href='$exampleUrl&format=Html'>Basic html</a>
+									]";
+					}
+					else
+					{
+						$str .= " [ No example available ]";
+					}
 				}
-				else
-				{
-					$str .= " [ No example available ]";
-				}
 				$str .= '</small>';
 				$str .= "\n<br>";
 			}
@@ -222,7 +258,9 @@
 	 * Returns the methods $class.$name parameters (and default value if provided)
 	 * as a string.
 	 * 
-	 * Example: [ idSite, period, date = today ]
+	 * @param string The class name
+	 * @param string The method name
+	 * @return string For example "(idSite, period, date = 'today')"
 	 */
 	private function getStrListParameters($class, $name)
 	{
@@ -244,9 +282,11 @@
 	/**
 	 * Returns the parameters names and default values for the method $name 
 	 * of the class $class
-	 * 
+	 * 
+	 * @param string The class name
+	 * @param string The method name
 	 * @return array Format array(
-	 * 					'parameter1Name'	=> '',
+	 * 					'testParameter'		=> null, // no default value
 	 * 					'life'				=> 42, // default value = 42
 	 * 					'date'				=> 'yesterday',
 	 * 				);
@@ -257,7 +297,11 @@
 	}
 	
 	/**
-	 * Returns the number of required parameters (parameters without default values).
+	 * Returns the number of required parameters (parameters without default values).
+	 * 
+	 * @param string The class name
+	 * @param string The method name
+	 * @return int The number of required parameters
 	 */
 	private function getNumberOfRequiredParameters($class, $name)
 	{
@@ -265,21 +309,26 @@
 	}
 	
 	/**
-	 * Returns true if the method is found in the API
+	 * Returns true if the method is found in the API
+	 * 
+	 * 
+	 * @param string The class name
+	 * @param string The method name
+	 * @return bool 
 	 */
 	private function isMethodAvailable( $className, $methodName)
 	{
 		return isset($this->api[$className][$methodName]);
 	}
 	
-	public function __get($name)
-	{
-		self::$classCalled = $name;
-		return $this;
-	}	
 	
 	/**
-	 * 
+	 * Checks that the count of the given parameters do match with the count of the required ones
+	 * 
+	 * @param string The class name
+	 * @param string The method name
+	 * @param array
+	 * @throws exception If less parameters than required were given
 	 */
 	private function checkNumberOfParametersMatch($className, $methodName, $parameters)
 	{
@@ -295,7 +344,8 @@
 	
 	/**
 	 * Checks that the class is a Singleton (presence of the getInstance() method)
-	 * 
+	 * 
+	 * @param string The class name
 	 * @throws exception If the class is not a Singleton
 	 */
 	private function checkClassIsSingleton($className)
@@ -308,7 +358,9 @@
 	
 	/**
 	 * Checks that the method exists in the class 
-	 * 
+	 * 
+	 * @param string The class name
+	 * @param string The method name
 	 * @throws exception If the method is not found
 	 */	
 	public function checkMethodExists($className, $methodName)
@@ -324,18 +376,38 @@
 	 * 
 	 * For exemple for $module = 'Referers' it returns 'Piwik_Referers_API' 
 	 * Piwik_Referers_API is the class that extends Piwik_Apiable 
-	 * and that contains the methods to be published in the API.
+	 * and that contains the methods to be published in the API.
+	 * 
+	 * @param string module name
+	 * @return string class name
 	 */
 	protected  function getClassNameFromModule($module)
 	{
 		$class = Piwik::prefixClass($module ."_API");
 		return $class;
 	}
-	
+	
+	/**
+	 * Magic method used to set a flag telling the module named currently being called
+	 *
+	 */
+	public function __get($name)
+	{
+		self::$classCalled = $name;
+		return $this;
+	}	
+
 	/**
 	 * Method always called when making an API request.
 	 * It checks several things before actually calling the real method on the given module.
-	 * It also logs the API calls, with the parameters values, the returned value, the performance, etc.
+	 * 
+	 * It also logs the API calls, with the parameters values, the returned value, the performance, etc.
+	 * You can enable logging in config/global.ini.php (log_api_call)
+	 * 
+	 * @param string The method name
+	 * @param array The parameters
+	 * 
+	 * @throw Piwik_Access_NoAccessException 
 	 */
 	public function __call($methodName, $parameterValues )
 	{

Modified: trunk/modules/API/Request.php
===================================================================
--- trunk/modules/API/Request.php	2008-01-14 00:55:04 UTC (rev 155)
+++ trunk/modules/API/Request.php	2008-01-14 01:12:26 UTC (rev 156)
@@ -1,8 +1,10 @@
 <?php
 /**
  * An API request is the object used to make a call to the API and get the result.
- * The request has the form of a normal GET request, ie. parameter_1=X&parameter_2=Y
- * 
+ * The request has the format of a normal GET request, ie. parameter_1=X&parameter_2=Y
+ * 
+ * You can use this object from anywhere in piwik (inside plugins for example).
+ * You can even call it outside of piwik (see 
  * Example: 
  * $request = new Piwik_API_Request('
  * 				method=UserSettings.getWideScreen
@@ -40,7 +42,10 @@
 			// but we handle the case when an array is specified but we also want
 			// to look for the value in the _REQUEST
 			$requestArray = array_merge( $_REQUEST, $requestArray);
-		}
+		}
+		
+		// remove all spaces from parameters values (when calling internally the API for example)
+		$requestArray = array_map('trim',$requestArray);
 		
 		$this->requestToUse = $requestArray;
 	}

Modified: trunk/modules/FrontController.php
===================================================================
--- trunk/modules/FrontController.php	2008-01-14 00:55:04 UTC (rev 155)
+++ trunk/modules/FrontController.php	2008-01-14 01:12:26 UTC (rev 156)
@@ -26,9 +26,15 @@
 require_once "Controller.php";
 
 class Piwik_FrontController
-{
+{
+	static public $enableDispatch = true;
+	
 	function dispatch()
-	{
+	{
+		if( self::$enableDispatch === false)
+		{
+			return;
+		}
 		$defaultModule = 'Home';
 		
 		// load the module requested

Modified: trunk/modules/SmartyPlugins/function.url.php
===================================================================
--- trunk/modules/SmartyPlugins/function.url.php	2008-01-14 00:55:04 UTC (rev 155)
+++ trunk/modules/SmartyPlugins/function.url.php	2008-01-14 01:12:26 UTC (rev 156)
@@ -2,35 +2,24 @@
 /**
  * Smarty plugin
  * @package Smarty
- * @subpackage plugins
  */
 require_once "Url.php";
 
 /**
- * Smarty {mailto} function plugin
+ * Smarty {url} function plugin
  *
  * Examples:
  * <pre>
- * {mailto address="me at domain.com"}
- * {mailto address="me at domain.com" encode="javascript"}
- * {mailto address="me at domain.com" encode="hex"}
- * {mailto address="me at domain.com" subject="Hello to you!"}
- * {mailto address="me at domain.com" cc="you at domain.com,they at domain.com"}
- * {mailto address="me at domain.com" extra='class="mailto"'}
- * </pre>
- * @link http://smarty.php.net/manual/en/language.function.mailto.php {mailto}
- *          (Smarty online manual)
- * @version  1.2
- * @author   Monte Ohrt <monte at ohrt dot com>
- * @author   credits to Jason Sweat (added cc, bcc and subject functionality)
- * @param    array
- * @param    Smarty
- * @return   string
+ * {url module="API"} will rewrite the URL modifying the module GET parameter
+ * {url module="API" method="getKeywords"} will rewrite the URL modifying the parameters module=API method=getKeywords
+ * </pre>
+ * 
+ * @see Piwik_Url::getCurrentQueryStringWithParametersModified()
+ * @param	array
+ * @param	Smarty
+ * @return	string
  */
 function smarty_function_url($params, &$smarty)
 {
 	return Piwik_Url::getCurrentQueryStringWithParametersModified( $params );
 }
-
-/* vim: set expandtab: */
-

Modified: trunk/modules/View.php
===================================================================
--- trunk/modules/View.php	2008-01-14 00:55:04 UTC (rev 155)
+++ trunk/modules/View.php	2008-01-14 01:12:26 UTC (rev 156)
@@ -20,12 +20,31 @@
 		foreach($smConf as $key => $value)
 		{
 			$this->smarty->$key = $value;
-		}
-		$this->smarty->template_dir = $smConf->template_dir->toArray();
-		$this->smarty->plugins_dir = $smConf->plugins_dir->toArray();
+		}
 		
+		$this->smarty->template_dir = $this->getCorrectPath( $smConf->template_dir->toArray() );
+		$this->smarty->plugins_dir = $this->getCorrectPath( $smConf->plugins_dir->toArray() );
+		$this->smarty->compile_dir = $this->getCorrectPath( $smConf->compile_dir );
+		$this->smarty->cache_dir = $this->getCorrectPath( $smConf->cache_dir );
+		
 		$this->smarty->load_filter('output','trimwhitespace');
 		
+	}
+	
+	protected function getCorrectPath( $path )
+	{
+		if(is_array($path))
+		{
+			foreach($path as &$dir)
+			{
+				$dir = PIWIK_INCLUDE_PATH . '/' . $dir ;
+			}
+			return $path;
+		}
+		else
+		{
+			return PIWIK_INCLUDE_PATH . '/' . $path;
+		}
 	}
 
 	/**

Modified: trunk/plugins/API/Controller.php
===================================================================
--- trunk/plugins/API/Controller.php	2008-01-14 00:55:04 UTC (rev 155)
+++ trunk/plugins/API/Controller.php	2008-01-14 01:12:26 UTC (rev 156)
@@ -9,39 +9,47 @@
 		$request = new Piwik_API_Request();
 		echo $request->process();
 	}
+	
+	function init()
+	{
+		$plugins = Piwik_PluginsManager::getInstance()->getLoadedPluginsName();
+		
+		$loaded = 0;
+		foreach( $plugins as $plugin )
+		{		
+			$plugin = Piwik::unprefixClass($plugin);
+				
+			try {
+				Piwik_API_Proxy::getInstance()->registerClass($plugin);
+				$loaded++;
+			}
+			catch(Exception $e){
+//				$errors .= "<br>\n" . $e->getMessage();
+			}
+		}
+		return $loaded;
+	}
+	
+	function listAllMethods()
+	{
+		$this->init();
+		echo Piwik_API_Proxy::getInstance()->getAllInterfaceString( $outputExampleUrls = false );
+	}
+	
 	
 	function listAllAPI()
 	{
-//?module=API&method=Referers.getKeywords&idSite=1&period=month&date=today&format=xml
-//
-//or yesterday visits information in JSON
-//?module=API&method=VisitsSummary.get&idSite=1&period=month&date=yesterday&format=json
-
-//		http://127.0.0.1/svn-dev/trunk/?module=API&method=UserSettings.getResolution&idSite=1&period=day&date=today&format=xml&token_auth=0b809661490d605bfd77f57ed11f0b14
-
 		$token_auth = Zend_Registry::get('auth')->getTokenAuth();
 		echo "<style>body{ font-family:georgia,arial; font-size:0.95em;} </style>";
 		echo "<h1>API quick documentation</h1>";
-		echo "<p>If you don't have data for today you can first <a href='misc/generateVisits.php' target=_blank>generate some data</a> using the Visits Generator script.</p>";
+		echo "<p>If you don't have data for today you can first <a href='misc/generateVisits.php' target=_blank>generate some data</a> using the Visits Generator script.</p>";
 		echo "<p>You can try the different formats available for every method. It is very easy to extract any data you want from piwik!</p>";
 		echo "<p>If you want to <b>request the data without being logged in to Piwik</b> you need to add the parameter <code><u>&token_auth=$token_auth</u></code> to the API calls URLs that require authentication.</p>";
-		$errors = '';
-		$plugins = Piwik_PluginsManager::getInstance()->getLoadedPluginsName();
+		$errors = '';
+		
+		$loaded = $this->init();
+		echo "<p><i> Loaded successfully $loaded APIs</i></p>\n";
 		
-		$loaded = 0;
-		foreach( $plugins as $plugin )
-		{		
-			$plugin = Piwik::unprefixClass($plugin);
-				
-			try {
-				Piwik_API_Proxy::getInstance()->registerClass($plugin);
-				$loaded++;
-			}
-			catch(Exception $e){
-				$errors .= "<br>\n" . $e->getMessage();
-			}
-		}
-		echo "<p><i> Loaded successfully $loaded APIs</i></p>\n";
 		echo Piwik_API_Proxy::getInstance()->getAllInterfaceString();
 		
 		echo "<p>Notice = " . $errors . "</p>\n";



More information about the Piwik-svn mailing list