[Piwik-svn] r147 - in trunk: config modules modules/API modules/DataTable/Renderer modules/ViewDataTable plugins/API plugins/Home/templates plugins/Installation plugins/SitesManager plugins/SitesManager/templates plugins/UsersManager plugins/UsersManager/templates tests/modules themes/default

svnmaster at piwik.org svnmaster at piwik.org
Sat Jan 12 02:10:44 CET 2008


Author: matt
Date: 2008-01-12 02:10:43 +0100 (Sat, 12 Jan 2008)
New Revision: 147

Added:
   trunk/plugins/Home/templates/links_misc_modules.tpl
   trunk/plugins/SitesManager/templates/DisplayJavascriptCode.tpl
Modified:
   trunk/config/global.ini.php
   trunk/modules/API/Proxy.php
   trunk/modules/API/Request.php
   trunk/modules/DataTable.php
   trunk/modules/DataTable/Renderer/Csv.php
   trunk/modules/DataTable/Renderer/Json.php
   trunk/modules/DataTable/Renderer/Php.php
   trunk/modules/DataTable/Renderer/Xml.php
   trunk/modules/Piwik.php
   trunk/modules/ViewDataTable/Html.php
   trunk/plugins/API/Controller.php
   trunk/plugins/Home/templates/cloud.tpl
   trunk/plugins/Home/templates/index.tpl
   trunk/plugins/Installation/Controller.php
   trunk/plugins/SitesManager/API.php
   trunk/plugins/SitesManager/Controller.php
   trunk/plugins/SitesManager/templates/SitesManager.js
   trunk/plugins/SitesManager/templates/SitesManager.tpl
   trunk/plugins/UsersManager/API.php
   trunk/plugins/UsersManager/templates/UsersManager.tpl
   trunk/tests/modules/PHP_Related.test.php
   trunk/themes/default/common-admin.css
Log:
- added links to admin modules in the UI
- added new module displayJavascriptCode
- php renderer now renders a flat version of the datatable for more convenience
- XML/JSON/CSV have a simple output now :-)
- added automatic conversion of know php data structures into DataTable so any API returning not-so-complex data structure can automatically benefit from DataTable power and get the output in XML/JSON/CSV/HTML/PHP etc.
- added a nice helper page that lists all API methods, + links to examples
- did test all API calls with all formats. seems to work good. had to fix a looooot of problems but im happy with the final result :-)

enjoy!!!

Modified: trunk/config/global.ini.php
===================================================================
--- trunk/config/global.ini.php	2008-01-11 15:21:35 UTC (rev 146)
+++ trunk/config/global.ini.php	2008-01-12 01:10:43 UTC (rev 147)
@@ -26,9 +26,6 @@
 default			= en
 
 [Plugins]
-enabled[] 		= Login
-enabled[] 		= UsersManager
-enabled[] 		= SitesManager
 
 enabled[] 		= UserSettings
 enabled[] 		= VisitsSummary
@@ -40,6 +37,10 @@
 enabled[] 		= VisitTime
 enabled[] 		= VisitorInterest
 enabled[] 		= ExamplePlugin
+
+enabled[] 		= Login
+enabled[] 		= UsersManager
+enabled[] 		= SitesManager
 
 ;enabled[] 		= Openads
 enabled[] 		= Installation

Modified: trunk/modules/API/Proxy.php
===================================================================
--- trunk/modules/API/Proxy.php	2008-01-11 15:21:35 UTC (rev 146)
+++ trunk/modules/API/Proxy.php	2008-01-12 01:10:43 UTC (rev 147)
@@ -122,21 +122,97 @@
 		}
 		
 		$this->alreadyRegistered[$fileName] = true;
+	}
+	
+	// Piwik_moduleName_API => moduleName
+	protected function getModuleNameFromClassName( $className )
+	{
+		$start = strpos($className, '_') + 1;
+		return substr($className, $start , strrpos($className, '_') - $start);
 	}
-	
+	// return false when not possible
+	public function getExampleUrl($class, $methodName)
+	{
+		$knowExampleDefaultParametersValues = array(
+			'access' => 'view',
+			'idSite' => '1',
+			'userLogin' => 'test',
+			'password' => 'passwordExample',
+			'email' => 'test at example.org',
+		
+			'siteName' => 'new example website',
+			'urls' => 'http://example.org', // used in addSite, updateSite
+
+			'period' => 'day',
+			'date' => 'today',
+		);
+		
+		$doNotPrintExampleForTheseMethods = array(
+			'deleteSite',
+			'deleteUser',
+		);
+		
+		if(in_array($methodName,$doNotPrintExampleForTheseMethods))
+		{
+			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($defaultValue === Piwik_API_Proxy::NO_DEFAULT_VALUE)
+			{
+				if(isset($knowExampleDefaultParametersValues[$nameVariable]))
+				{
+					$exampleValue = $knowExampleDefaultParametersValues[$nameVariable];
+					$urlExample .= $nameVariable . '=' . $exampleValue . '&';
+				}
+				else
+				{
+					return false;
+				}
+			}
+			
+		}
+		
+		return substr($urlExample,0,-1);
+	}
 	public function getAllInterfaceString()
 	{
 		$str = '';
 		foreach($this->api as $class => $info)
-		{
-			$str .= "\n<br>" . "List of the public methods for the class ".$class;
+		{
+			$moduleName = $this->getModuleNameFromClassName($class);
+			$str .= "\n<h2>Module ".$moduleName."</h2>";
 			
 			foreach($info as $methodName => $infoMethod)
-			{
+			{
+
+				$exampleUrl = $this->getExampleUrl($class, $methodName);
+				
 				$params = $this->getStrListParameters($class, $methodName);
-				$str .= "\n<br>" . "- $methodName : " . $params;
+				$str .= "\n" . "- <b>$methodName " . $params . "</b>";
+				
+				$str .= '<small>';
+				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>
+								]";
+				}
+				else
+				{
+					$str .= " [ No example available ]";
+				}
+				$str .= '</small>';
+				$str .= "\n<br>";
 			}
-			$str.="\n<br>";
 		}
 		return $str;
 	}
@@ -156,12 +232,12 @@
 			$str = $nameVariable;
 			if($defaultValue !== Piwik_API_Proxy::NO_DEFAULT_VALUE)
 			{
-				$str .= " = $defaultValue";
+				$str .= " = '$defaultValue'";
 			}
 			$asParameters[] = $str;
 		}
 		$sParameters = implode(", ", $asParameters);
-		return "[$sParameters]";
+		return "($sParameters)";
 	}
 	
 	/**
@@ -268,7 +344,7 @@
 			assert(!is_null(self::$classCalled));
 
 			$this->registerClass(self::$classCalled);
-			
+						
 			$className = $this->getClassNameFromModule(self::$classCalled);
 
 			// instanciate the object

Modified: trunk/modules/API/Request.php
===================================================================
--- trunk/modules/API/Request.php	2008-01-11 15:21:35 UTC (rev 146)
+++ trunk/modules/API/Request.php	2008-01-12 01:10:43 UTC (rev 147)
@@ -79,10 +79,13 @@
 	public function process()
 	{
 		try {
-			
+			// read the format requested for the output data
+			$outputFormatRequested = Piwik_Common::getRequestVar('format', 'xml', 'string', $this->requestToUse);
+			$outputFormatRequested = strtolower($outputFormatRequested);
+			
 			// read parameters
 			$moduleMethod = Piwik_Common::getRequestVar('method', null, null, $this->requestToUse);
-			
+			
 			list($module, $method) = $this->extractModuleAndMethod($moduleMethod); 
 			
 			if(!Piwik_PluginsManager::getInstance()->isPluginEnabled($module))
@@ -133,27 +136,71 @@
 				
 				$this->applyDataTableGenericFilters($dataTable);
 				
-				$dataTable->applyQueuedFilters();
+				$dataTable->applyQueuedFilters();
+				
 				$toReturn = $this->getRenderedDataTable($dataTable);
 				
-			}
-			elseif(!is_array($toReturn) // an empty array is not considered as "nothing has been returned"
-				&& empty($toReturn))
+			}
+			
+			// Case nothing returned (really nothing was 'return'ed), 
+			// => the operation was successful
+			elseif(!isset($toReturn))
 			{
-				$format = Piwik_Common::getRequestVar('format', 'xml', 'string', $this->requestToUse);
-				$toReturn = $this->getStandardSuccessOutput($format);
+				$toReturn = $this->getStandardSuccessOutput($outputFormatRequested);
+			}
+			
+			// Case an array is returned from the API call, we convert it to the requested format
+			// - if calling from inside the application (format = original)
+			//    => the data stays unchanged (ie. a standard php array or whatever data structure)
+			// - if any other format is requested, we have to convert this data structure (which we assume 
+			//   to be an array) to a DataTable in order to apply the requested DataTable_Renderer (for example XML)
+			elseif(is_array($toReturn))
+			{
+				if($outputFormatRequested == 'original')
+				{
+					// we handle the serialization. Because some php array have a very special structure that 
+					// couldn't be converted with the automatic DataTable->loadFromSimpleArray
+					// the user may want to request the original PHP data structure serialized by the API
+					// in case he has to setup serialize=1 in the URL
+					if($this->caseRendererPHPSerialize( $defaultSerialize = 0))
+					{
+						$toReturn = serialize($toReturn);
+					}
+				}
+				else
+				{
+//					var_dump($toReturn);exit;
+//					echo "$outputFormatRequested requested";
+					$dataTable = new Piwik_DataTable();
+					$dataTable->loadFromSimpleArray($toReturn);
+//					echo $dataTable;exit;
+					$toReturn = $this->getRenderedDataTable($dataTable);
+//					echo $toReturn;exit;
+				}
+			}
+			// bool // integer // float // anything else would'nt work and is not handled (objects!)
+			else
+			{
+				if( $toReturn === true )
+				{
+					$toReturn = 'true';
+				}
+				elseif( $toReturn === false )
+				{
+					$toReturn = 'false';
+				}
+				return $this->getStandardSuccessOutput($outputFormatRequested, $message = $toReturn);
 			}
 			
 		} catch(Exception $e ) {
-			$format = Piwik_Common::getRequestVar('format', 'xml', 'string', $this->requestToUse);
 			
 			// if it is not a direct API call, we are requesting the original data structure
 			// and we actually are handling this exception at the top level in the FrontController
-			if($format == 'original')
+			if($outputFormatRequested == 'original')
 			{
 				throw $e;
 			}
-			$toReturn =  $this->getExceptionOutput( $e->getMessage(), $format);
+			$toReturn =  $this->getExceptionOutput( $e->getMessage(), $outputFormatRequested);
 			
 		}
 		
@@ -161,9 +208,8 @@
 	}
 	
 	
-	function getStandardSuccessOutput($format)
+	function getStandardSuccessOutput($format, $message = 'ok')
 	{
-		$return = 'TO OVERWRITE! getStandardSuccessOutput()';
 		switch($format)
 		{
 			case 'xml':
@@ -171,22 +217,29 @@
 				$return = 
 					'<?xml version="1.0" encoding="utf-8" ?>'.
 					'<result>'.
-					'	<success message="ok" />'.
+					'	<success message="'.$message.'" />'.
 					'</result>';
 			break;
 			case 'json':
 				@header( "Content-type: application/json" );
-				$return = '{"result":"success", "message":"ok"}';
+				$return = '{"result":"success", "message":"'.$message.'"}';
 			break;
 			case 'php':
-				$return = array('result' => 'success', 'message' => 'ok');
+				$return = array('result' => 'success', 'message' => $message);
 				if($this->caseRendererPHPSerialize())
 				{
 					$return = serialize($return);
 				}
-			break;
+			break;
+			
+			case 'csv':
+				header("Content-type: application/vnd.ms-excel");
+				header("Content-Disposition: attachment; filename=piwik-report-export.csv");	
+				$return = "message\n".$message;
+			break;
+			
 			default:
-				$return = 'Success:ok';
+				$return = 'Success:'.$message;
 			break;
 		}
 		
@@ -194,7 +247,6 @@
 	}
 	function getExceptionOutput($message, $format)
 	{
-		$return = 'TO OVERWRITE! getExceptionOutput()';
 		switch($format)
 		{
 			case 'xml':
@@ -232,6 +284,7 @@
 	{
 		// Renderer
 		$format = Piwik_Common::getRequestVar('format', 'php', 'string', $this->requestToUse);
+		$format = strtolower($format);
 		
 		// if asked for original dataStructure
 		if($format == 'original')
@@ -241,6 +294,14 @@
 				&& $dataTable->getRowsCount() == 1)
 			{
 				return $dataTable->getRowFromId(0)->getColumn('value');
+			}
+			
+			// the original data structure can be asked as serialized. 
+			// but by default it's not serialized
+			if($this->caseRendererPHPSerialize( $defaultSerialize = 0))
+			{
+//				var_export($dataTable);exit;
+				$dataTable = serialize($dataTable);
 			}
 			return $dataTable;
 		}
@@ -258,9 +319,9 @@
 	}
 	
 	
-	function caseRendererPHPSerialize()
+	function caseRendererPHPSerialize($defaultSerializeValue = 1)
 	{
-		$serialize = Piwik_Common::getRequestVar('serialize', 1, 'int', $this->requestToUse);
+		$serialize = Piwik_Common::getRequestVar('serialize', $defaultSerializeValue, 'int', $this->requestToUse);
 		if($serialize)
 		{
 			return true;

Modified: trunk/modules/DataTable/Renderer/Csv.php
===================================================================
--- trunk/modules/DataTable/Renderer/Csv.php	2008-01-11 15:21:35 UTC (rev 146)
+++ trunk/modules/DataTable/Renderer/Csv.php	2008-01-12 01:10:43 UTC (rev 147)
@@ -17,7 +17,8 @@
   * If the text contains an embedded delimiter string or qualifier string, the text qualifier is placed around the text, and the embedded qualifier strings are doubled.
   * Formatting and layout are ignored.
   */
-require_once "DataTable/Renderer/Php.php";
+require_once "DataTable/Renderer/Php.php";
+
 class Piwik_DataTable_Renderer_Csv extends Piwik_DataTable_Renderer
 {
 	public $separator = ',';
@@ -95,8 +96,20 @@
 			}
 		}
 //		var_dump($csv);exit;
-		$str = '';
-		$str .= implode($this->separator, array_keys($allColumns));
+		$str = '';
+		
+		
+		// specific case, we have only one column and this column wasn't named properly (indexed by a number)
+		// we don't print anything in the CSV file => an empty line
+		if(sizeof($allColumns) == 1 && reset($allColumns) && !is_string(key($allColumns))  )
+		{
+			$str .= '';
+		}
+		else
+		{
+			$str .= implode($this->separator, array_keys($allColumns));
+		}
+		
 		// we render the CSV
 		foreach($csv as $theRow)
 		{

Modified: trunk/modules/DataTable/Renderer/Json.php
===================================================================
--- trunk/modules/DataTable/Renderer/Json.php	2008-01-11 15:21:35 UTC (rev 146)
+++ trunk/modules/DataTable/Renderer/Json.php	2008-01-12 01:10:43 UTC (rev 147)
@@ -22,7 +22,8 @@
 	protected function renderTable($table)
 	{
 		$renderer = new Piwik_DataTable_Renderer_Php($table, $serialize = false);
-		$array = $renderer->render();
+		$array = $renderer->flatRender();
+		
 		$str = json_encode($array);
 		return $str;
 	}

Modified: trunk/modules/DataTable/Renderer/Php.php
===================================================================
--- trunk/modules/DataTable/Renderer/Php.php	2008-01-11 15:21:35 UTC (rev 146)
+++ trunk/modules/DataTable/Renderer/Php.php	2008-01-12 01:10:43 UTC (rev 147)
@@ -2,26 +2,27 @@
 
 /**
  * Returns the equivalent PHP array of the DataTable.
- * You can specify in the constructor if you want the serialized version.
+ * You can specify in the constructor if you want the serialized version.
+ * Please note that by default it will produce a flat version of the array.
+ * See the method flatRender() for details.
  * 
  * @package Piwik_DataTable
  * @subpackage Piwik_DataTable_Renderer
  */
 class Piwik_DataTable_Renderer_Php extends Piwik_DataTable_Renderer
 {
-	protected $serialize;
-	function __construct($table = null, $serialize = true)
+	public function __construct($table = null, $serialize = true)
 	{
 		parent::__construct($table);
 		$this->setSerialize($serialize);
 	}
 	
-	function setSerialize( $bool )
+	public function setSerialize( $bool )
 	{
 		$this->serialize = $bool;
 	}
 	
-	function __toString()
+	public function __toString()
 	{
 		$data = $this->render();
 		if(!is_string($data))
@@ -30,8 +31,60 @@
 		}
 		return $data;
 	}
+	
+	/**
+	 * Produces a flat php array from the DataTable, putting "columns" and "details" on the same level.
+	 * 
+	 * For example, when  a originalRender() would be 
+	 * 	array( 'columns' => array( 'col1_name' => value1, 'col2_name' => value2 ),
+	 * 	       'details' => array( 'detail1_name' => value_detail) )
+	 * 
+	 * a flatRender() is
+	 * 	array( 'col1_name' => value1, 
+	 * 	       'col2_name' => value2,
+	 * 	       'detail1_name' => value_detail )
+	 *  
+	 * @return array Php array representing the 'flat' version of the datatable
+	 *
+	 */
+	public function flatRender()
+	{
+		// A DataTable_Simple is already flattened so no need to do some crazy stuff to convert it
+		if($this->table instanceof Piwik_DataTable_Simple)
+		{
+			$flatArray = $this->renderSimpleTable($this->table);
+		}
+		// A normal DataTable needs to be handled specifically
+		else
+		{
+			$array = $this->renderTable($this->table);
+			$flatArray = array();
+			foreach($array as $row)
+			{
+				$newRow = $row['columns'] + $row['details'];
+				if(isset($row['idsubdatatable']))
+				{
+					$newRow += array('idsubdatatable' => $row['idsubdatatable']);
+				}
+				$flatArray[] = $newRow;
+			}		
+		}
+		
+		if($this->serialize)
+		{
+			$flatArray = serialize($flatArray);
+		}
+		
+		return $flatArray;
+	}
+	
+	public function render()
+	{
+		$toReturn = $this->flatRender();
+		return $toReturn;
+	}
 	
-	function render()
+	public function originalRender()
 	{
 		if($this->table instanceof Piwik_DataTable_Simple)
 		{
@@ -49,6 +102,9 @@
 		
 		return $array;
 	}
+	
+	protected $serialize;
+	
 	
 	protected function renderTable($table)
 	{

Modified: trunk/modules/DataTable/Renderer/Xml.php
===================================================================
--- trunk/modules/DataTable/Renderer/Xml.php	2008-01-11 15:21:35 UTC (rev 146)
+++ trunk/modules/DataTable/Renderer/Xml.php	2008-01-12 01:10:43 UTC (rev 147)
@@ -21,10 +21,13 @@
 	}
 	
 	protected function renderTable($table)
-	{
+	{
+//		echo $table;exit;
 		$renderer = new Piwik_DataTable_Renderer_Php($table, $serialize = false);
-		$array = $renderer->render();
-		
+		$array = $renderer->flatRender();
+		
+//		var_dump($array); exit;
+
 		require_once 'XML/Serializer.php';
 		
 		$options = array(

Modified: trunk/modules/DataTable.php
===================================================================
--- trunk/modules/DataTable.php	2008-01-11 15:21:35 UTC (rev 146)
+++ trunk/modules/DataTable.php	2008-01-12 01:10:43 UTC (rev 147)
@@ -479,11 +479,18 @@
 	 * Load the data from a PHP array 
 	 * 
 	 * @param array Array with the following structure
-	 * 				array(
-	 * 					array(...), // row1
-	 * 					array(...), // row2
-	 * 						)
-	 * 				)
+	 * 			array(
+ 	 * 				// row1
+	 * 				array( 
+	 * 				Piwik_DataTable_Row::COLUMNS => array( col1_name => value1, col2_name => value2, ...),
+	 * 				Piwik_DataTable_Row::DETAILS => array( detail1_name => value1,  ...), // see Piwik_DataTable_Row
+	 * 
+	 * 				),
+	 * 					
+	 * 				// row2
+	 * 				array( ... ), 
+	 * 				
+	 * 			)
 	 * 
 	 * @see DataTable_Row::loadFromArray for the row structures
 	 */
@@ -498,6 +505,91 @@
 			
 			$this->addRow($row);
 		}
+	}
+	
+	/**
+	 * Load the data from a simple php array.
+	 * Basically maps a simple multidimensional php php array to a DataTable.
+	 * Not recursive (if a row contains a php array itself, it won't work well...)
+	 * 
+	 * @param array Array with the simple structure:
+	 * 		array(
+	 * 			array( col1_name => valueA, col2_name => valueC, ...),
+	 * 			array( col1_name => valueB, col2_name => valueD, ...), 
+	 *		)
+	 */
+	public function loadFromSimpleArray( $array )
+	{
+//		var_dump($array);exit;
+		
+		
+		// we define an exception we may throw if at one point we notice that we cannot handle the data structure
+		$e = new Exception(" Data structure returned is not convertible in the requested format.".
+						" Try to call this method with the parameters '&format=original&serialize=1'".
+						"; you will get the original php data structure serialized.".
+						" The data structure looks like this: \n \$data = " . var_export($array, true) . "; ");
+				
+		
+		// first pass to see if the array has the structure
+		// array(col1_name => val1, col2_name => val2, etc.)
+		// with val* that are never arrays (only strings/numbers/bool/etc.)
+		// if we detect such a "simple" data structure we convert it to a row with the correct columns' names
+		$rowBuilt = array(); $thisIsNotThatSimple = false;
+		foreach($array as $columnName => $columnValue )
+		{
+			if(is_array($columnValue) || is_object($columnValue)) 
+			{
+				$thisIsNotThatSimple = true;
+				break;
+			}
+			$rowBuilt += array($columnName => $columnValue );
+		}
+		if($thisIsNotThatSimple === false)
+		{
+			$this->addRow( new Piwik_DataTable_Row( array( Piwik_DataTable_Row::COLUMNS => $rowBuilt ) ) );
+			// we have converted our simple array to one single row
+			// => we exit the method as the job is now finished 
+			return;
+		}
+		
+		
+		foreach($array as $key => $row)
+		{
+			// stuff that looks like a line
+			if(is_array($row))
+			{
+				/**
+				 * We make sure we can convert this PHP array without losing information.
+				 * We are able to convert only simple php array (no strings keys, no sub arrays, etc.)
+				 * 
+				 */
+				
+				// if the key is a string it means that some information was contained in this key. 
+				// it cannot be lost during the conversion. Because we are not able to handle properly
+				// this key, we throw an explicit exception.
+				if(is_string($key))
+				{
+					throw $e;
+				}
+				// if any of the sub elements of row is an array we cannot handle this data structure...
+				foreach($row as $subRow)
+				{
+					if(is_array($subRow))
+					{
+						throw $e;						
+					}
+				}
+				
+				
+				$row = new Piwik_DataTable_Row( array( Piwik_DataTable_Row::COLUMNS => $row ) );		
+			}
+			// other (string, numbers...) => we build a line from this value
+			else
+			{
+				$row = new Piwik_DataTable_Row( array( Piwik_DataTable_Row::COLUMNS => array($key => $row)) );
+			}				
+			$this->addRow($row);
+		}
 	}
 	
 	/**

Modified: trunk/modules/Piwik.php
===================================================================
--- trunk/modules/Piwik.php	2008-01-11 15:21:35 UTC (rev 146)
+++ trunk/modules/Piwik.php	2008-01-12 01:10:43 UTC (rev 147)
@@ -95,6 +95,15 @@
 		return $resultCheck;
 	}
 	
+	static public function getJavascriptCode($idSite, $piwikUrl, $actionName = "''")
+	{	
+		$jsTag = file_get_contents( PIWIK_INCLUDE_PATH . "/modules/LogStats/javascriptTag.tpl");
+		$jsTag = nl2br(htmlentities($jsTag));
+		$jsTag = str_replace('{$actionName}', "''", $jsTag);
+		$jsTag = str_replace('{$idSite}', $idSite, $jsTag);
+		$jsTag = str_replace('{$piwikUrl}', $piwikUrl, $jsTag);
+		return $jsTag;
+	}
 	
 	static public function getMemoryLimitValue()
 	{

Modified: trunk/modules/ViewDataTable/Html.php
===================================================================
--- trunk/modules/ViewDataTable/Html.php	2008-01-11 15:21:35 UTC (rev 146)
+++ trunk/modules/ViewDataTable/Html.php	2008-01-12 01:10:43 UTC (rev 147)
@@ -69,7 +69,9 @@
 		$renderer = Piwik_DataTable_Renderer::factory('php');
 		$renderer->setTable($this->dataTable);
 		$renderer->setSerialize( false );
-		$phpArray = $renderer->render();
+		// we get the php array from the datatable
+		// but conserving the original datatable format, which means rows 'columns', 'details' and 'idsubdatatable'
+		$phpArray = $renderer->originalRender();
 		return $phpArray;
 	}
 

Modified: trunk/plugins/API/Controller.php
===================================================================
--- trunk/plugins/API/Controller.php	2008-01-11 15:21:35 UTC (rev 146)
+++ trunk/plugins/API/Controller.php	2008-01-12 01:10:43 UTC (rev 147)
@@ -11,8 +11,14 @@
 	}
 	
 	function listAllAPI()
-	{
-		echo "<h1>List of all modules API</h1>";
+	{
+//?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
+		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>";
 		$errors = '';
 		$plugins = Piwik_PluginsManager::getInstance()->getLoadedPluginsName();
 		

Modified: trunk/plugins/Home/templates/cloud.tpl
===================================================================
--- trunk/plugins/Home/templates/cloud.tpl	2008-01-11 15:21:35 UTC (rev 146)
+++ trunk/plugins/Home/templates/cloud.tpl	2008-01-12 01:10:43 UTC (rev 147)
@@ -58,8 +58,7 @@
 	{if false !== $labelDetails[$value.word].url}<a href="{$labelDetails[$value.word].url}" target="_blank">{/if}
 	{if false !== $labelDetails[$value.word].logo}<img src="{$labelDetails[$value.word].logo}" width="{$value.logoWidth}">{else}
 	
-	{$value.wordTruncated}{/if}{if false !== $labelDetails[$value.word].url}</a>{/if}
-	</span>
+	{$value.wordTruncated}{/if}{if false !== $labelDetails[$value.word].url}</a>{/if}</span>
 	{/foreach}
 {/if}
 {include file="Home/templates/datatable_footer.tpl"}

Modified: trunk/plugins/Home/templates/index.tpl
===================================================================
--- trunk/plugins/Home/templates/index.tpl	2008-01-11 15:21:35 UTC (rev 146)
+++ trunk/plugins/Home/templates/index.tpl	2008-01-12 01:10:43 UTC (rev 147)
@@ -87,6 +87,11 @@
 	margin:10px;
 }
 
+#miscLinks{
+	font-size:small;
+	padding-right:20px;
+}
+
 #sitesSelection {
 	 
 }
@@ -158,6 +163,7 @@
 		<p>User logged = {$userLogin}</p>
 		{include file="Home/templates/period_select.tpl"}<br><br>
 		{include file="Home/templates/sites_select.tpl"}<br>
+		{include file="Home/templates/links_misc_modules.tpl"}<br>
 	</div>
 </div>
 

Added: trunk/plugins/Home/templates/links_misc_modules.tpl
===================================================================
--- trunk/plugins/Home/templates/links_misc_modules.tpl	                        (rev 0)
+++ trunk/plugins/Home/templates/links_misc_modules.tpl	2008-01-12 01:10:43 UTC (rev 147)
@@ -0,0 +1,8 @@
+<span id="miscLinks">
+	<p>Links to other modules:</p>
+	<ul>
+		<li>Manage: <a href='?module=SitesManager'>Sites</a> - <a href='?module=UsersManager'>Users</a></li>
+		<li><a href='?module=Login'>Login</a> - <a href='?module=Logout'>Logout</a></a></li>
+		<li>Discover the power of the Piwik API!!! <br><a href='?module=API&action=listAllAPI'>API methods list</a></li>
+	</ul>
+</div>
\ No newline at end of file

Modified: trunk/plugins/Installation/Controller.php
===================================================================
--- trunk/plugins/Installation/Controller.php	2008-01-11 15:21:35 UTC (rev 146)
+++ trunk/plugins/Installation/Controller.php	2008-01-12 01:10:43 UTC (rev 147)
@@ -279,13 +279,9 @@
 		
 		
 		$view->websiteName = $_SESSION['site_name'];
+		
+		$jsTag = Piwik::getJavascriptCode($_SESSION['site_idSite'], Piwik_Url::getCurrentUrlWithoutFileName());
 		
-		$jsTag = file_get_contents( PIWIK_INCLUDE_PATH . "/modules/LogStats/javascriptTag.tpl");
-		$jsTag = nl2br(htmlentities($jsTag));
-		$jsTag = str_replace('{$actionName}', "''", $jsTag);
-		$jsTag = str_replace('{$idSite}', $_SESSION['site_idSite'], $jsTag);
-		$jsTag = str_replace('{$piwikUrl}', Piwik_Url::getCurrentUrlWithoutFileName(), $jsTag);
-		
 		$view->javascriptTag = $jsTag;
 		$view->showNextStep = true;
 		

Modified: trunk/plugins/SitesManager/API.php
===================================================================
--- trunk/plugins/SitesManager/API.php	2008-01-11 15:21:35 UTC (rev 146)
+++ trunk/plugins/SitesManager/API.php	2008-01-12 01:10:43 UTC (rev 147)
@@ -59,12 +59,12 @@
 	 * @exception if the website ID doesn't exist or the user doesn't have access to it
 	 * @return array list of URLs
 	 */
-	static public function getSiteUrlsFromId( $idsite )
+	static public function getSiteUrlsFromId( $idSite )
 	{
-		Piwik::checkUserHasViewAccess($idsite);
+		Piwik::checkUserHasViewAccess($idSite);
 		
-		$site = self::getSiteFromId($idsite);
-		$urls = self::getAliasSiteUrlsFromId($idsite);
+		$site = self::getSiteFromId($idSite);
+		$urls = self::getAliasSiteUrlsFromId($idSite);
 		
 		return array_merge(array($site['main_url']), $urls);
 	}
@@ -197,11 +197,11 @@
 	 * 
 	 * @return int the website ID created
 	 */
-	static public function addSite( $name, $urls )
+	static public function addSite( $siteName, $urls )
 	{
 		Piwik::checkUserIsSuperUser();
 		
-		self::checkName($name);
+		self::checkName($siteName);
 		$urls = self::cleanParameterUrls($urls);
 		self::checkUrls($urls);
 		self::checkAtLeastOneUrl($urls);
@@ -212,7 +212,7 @@
 		$urls = array_slice($urls, 1);
 		
 		$db->insert(Piwik::prefixTable("site"), array(
-									'name' => $name,
+									'name' => $siteName,
 									'main_url' => $url,
 									)
 								);
@@ -270,16 +270,16 @@
 	 * 
 	 * @return int the number of inserted URLs
 	 */
-	static public function addSiteAliasUrls( $idsite,  $urls)
+	static public function addSiteAliasUrls( $idSite,  $urls)
 	{
-		Piwik::checkUserHasAdminAccess( $idsite );
+		Piwik::checkUserHasAdminAccess( $idSite );
 		
 		$urls = self::cleanParameterUrls($urls);
 		self::checkUrls($urls);
 		
-		$urlsInit = self::getSiteUrlsFromId($idsite);
+		$urlsInit = self::getSiteUrlsFromId($idSite);
 		$toInsert = array_diff($urls, $urlsInit);
-		self::insertSiteUrls($idsite, $toInsert);
+		self::insertSiteUrls($idSite, $toInsert);
 		
 		return count($toInsert);
 	}
@@ -332,11 +332,11 @@
 	 * 
 	 * @return bool true on success
 	 */
-	static public function updateSite( $idSite, $name, $urls = null)
+	static public function updateSite( $idSite, $siteName, $urls = null)
 	{
 		Piwik::checkUserHasAdminAccess($idSite);
 
-		self::checkName($name);
+		self::checkName($siteName);
 		
 		// SQL fields to update
 		$bind = array();
@@ -351,7 +351,7 @@
 			$bind['main_url'] = $url;
 		}
 		
-		$bind['name'] = $name;
+		$bind['name'] = $siteName;
 		
 		$db = Zend_Registry::get('db');
 		
@@ -366,7 +366,8 @@
 		if(count($urls) > 1)
 		{
 			self::replaceSiteUrls($idSite, $urls);
-		}
+		}
+		
 	}
 	
 	/**
@@ -430,9 +431,9 @@
 	 * 
 	 * @exception if the website name is empty
 	 */
-	static private function checkName($name)
+	static private function checkName($siteName)
 	{
-		if(empty($name))
+		if(empty($siteName))
 		{
 			throw new Exception("The site name can't be empty.");
 		}

Modified: trunk/plugins/SitesManager/Controller.php
===================================================================
--- trunk/plugins/SitesManager/Controller.php	2008-01-11 15:21:35 UTC (rev 146)
+++ trunk/plugins/SitesManager/Controller.php	2008-01-12 01:10:43 UTC (rev 147)
@@ -13,5 +13,15 @@
 //		var_dump($sites);exit;
 		$view->sites = $sites;
 		echo $view->render();
+	}
+	
+	function displayJavascriptCode()
+	{
+		$jsTag = Piwik::getJavascriptCode(Piwik_Common::getRequestVar('idsite',1), Piwik_Url::getCurrentUrlWithoutFileName());
+
+		$view = new Piwik_View('SitesManager/templates/DisplayJavascriptCode.tpl');
+		$view->jsTag = $jsTag;
+		
+		echo $view->render();
 	}
 }
\ No newline at end of file

Added: trunk/plugins/SitesManager/templates/DisplayJavascriptCode.tpl
===================================================================
--- trunk/plugins/SitesManager/templates/DisplayJavascriptCode.tpl	                        (rev 0)
+++ trunk/plugins/SitesManager/templates/DisplayJavascriptCode.tpl	2008-01-12 01:10:43 UTC (rev 147)
@@ -0,0 +1,7 @@
+<p>Here is the javascript code to include on all your pages:</p>
+
+<code>
+{$jsTag}
+</code>
+
+<p><a href='index.php'>Back to Piwik homepage</a></p>
\ No newline at end of file

Modified: trunk/plugins/SitesManager/templates/SitesManager.js
===================================================================
--- trunk/plugins/SitesManager/templates/SitesManager.js	2008-01-11 15:21:35 UTC (rev 146)
+++ trunk/plugins/SitesManager/templates/SitesManager.js	2008-01-12 01:10:43 UTC (rev 147)
@@ -1,5 +1,5 @@
 
-function getDeleteSiteAJAX( idsite )
+function getDeleteSiteAJAX( idSite )
 {
 	var ajaxRequest = getStandardAjaxConf();
 	toggleAjaxLoading();
@@ -9,7 +9,7 @@
 	parameters.module = 'API';
 	parameters.format = 'json';
  	parameters.method =  'SitesManager.deleteSite';
- 	parameters.idSite = idsite;
+ 	parameters.idSite = idSite;
 	
 	ajaxRequest.data = parameters;
 	
@@ -24,7 +24,7 @@
 	// prepare the API parameters to add the user
 	var parameters = new Object;
 	
- 	var name = $(row).find('input[@id=siteadd_name]').val();
+ 	var siteName = $(row).find('input[@id=siteadd_name]').val();
  	var urls =  $(row).find('textarea[@id=siteadd_urls]').val();
 	var urls = urls.trim().split("\n");
  	
@@ -32,7 +32,7 @@
 	request += '&module=API';
 	request += '&format=json';
 	request += '&method=SitesManager.addSite';
-	request += '&name='+escape(name);
+	request += '&siteName='+escape(siteName);
 	
 	$.each(urls, function (key,value){ request+= '&urls[]='+escape(value);} );
 
@@ -46,7 +46,7 @@
 	var ajaxRequest = getStandardAjaxConf();
 	toggleAjaxLoading();
 	
-	var name = $(row).find('input[@id=name]').val();
+	var siteName = $(row).find('input[@id=siteName]').val();
 	var idSite = $(row).children('#idSite').html();
 	var urls = $(row).find('textarea[@id=urls]').val().trim().split("\n");
 	
@@ -54,7 +54,7 @@
 	request += '&module=API';
 	request += '&format=json';
 	request += '&method=SitesManager.updateSite';
-	request += '&name='+escape(name);
+	request += '&siteName='+escape(siteName);
 	request += '&idSite='+idSite;
 	$.each(urls, function (key,value){ if(value.length>1) request+= '&urls[]='+value;} );
 
@@ -93,7 +93,7 @@
 	$('.deleteSite').click( function() {
 			ajaxHideError();
 			var idRow = $(this).attr('id');
-			var nameToDelete = $(this).parent().parent().find('#name').html();
+			var nameToDelete = $(this).parent().parent().find('#siteName').html();
 			var idsiteToDelete = $(this).parent().parent().find('#idSite').html();
 			if(confirm('Are you sure you want to delete the website "'+nameToDelete+'" (idSite = '+idsiteToDelete+')?'))
 			{
@@ -116,7 +116,7 @@
 							function (i,n) {
 								var contentBefore = $(n).html();
 								var idName = $(n).attr('id');
-								if(idName == 'name')
+								if(idName == 'siteName')
 								{
 									var contentAfter = '<input id="'+idName+'" value="'+contentBefore+'" size="10">';
 									$(n)

Modified: trunk/plugins/SitesManager/templates/SitesManager.tpl
===================================================================
--- trunk/plugins/SitesManager/templates/SitesManager.tpl	2008-01-11 15:21:35 UTC (rev 146)
+++ trunk/plugins/SitesManager/templates/SitesManager.tpl	2008-01-12 01:10:43 UTC (rev 147)
@@ -19,16 +19,18 @@
 		<th>URLs</th>
 		<th> </th>
 		<th> </th>
+		<th> Javascript code </th>
 		</tr>
 	</thead>
 	<tbody>
 		{foreach from=$sites key=i item=site}
 		<tr id="row{$i}">
 			<td id="idSite">{$site.idsite}</td>
-			<td id="name" class="editableSite">{$site.name}</td>
+			<td id="siteName" class="editableSite">{$site.name}</td>
 			<td id="urls" class="editableSite">{foreach from=$site.alias_urls item=url}{$url}<br>{/foreach}</td>       
 			<td><img src='plugins/UsersManager/images/edit.png' class="editSite" id="row{$i}" href='#'></td>
 		    <td><img src='plugins/UsersManager/images/remove.png' class="deleteSite" id="row{$i}" value="Delete"></td>
+	        <td><a href='{url action=displayJavascriptCode idsite=$site.idsite}'>Show Code</a></td>
 		</tr>
 		{/foreach}
 		
@@ -37,3 +39,6 @@
 
 <div id="addRowSite"><img src='plugins/UsersManager/images/add.png'> <a href="#">Add a new Site</a></div>
 
+
+
+<p><a href='index.php'>Back to Piwik homepage</a></p>

Modified: trunk/plugins/UsersManager/API.php
===================================================================
--- trunk/plugins/UsersManager/API.php	2008-01-11 15:21:35 UTC (rev 146)
+++ trunk/plugins/UsersManager/API.php	2008-01-12 01:10:43 UTC (rev 147)
@@ -168,15 +168,16 @@
 	 * 
 	 * @return array the user information
 	 */
-	static public function getUser( $login )
+	static public function getUser( $userLogin )
 	{
 		Piwik::checkUserIsSuperUser();
-		self::checkUserExists($login);
+		self::checkUserExists($userLogin);
 		
 		$db = Zend_Registry::get('db');
 		$user = $db->fetchRow("SELECT * 
 								FROM ".Piwik::prefixTable("user")
-								." WHERE login = ?", $login);
+								." WHERE login = ?", $userLogin);
+//		var_dump($user); exit;
 		return $user;
 	}
 	

Modified: trunk/plugins/UsersManager/templates/UsersManager.tpl
===================================================================
--- trunk/plugins/UsersManager/templates/UsersManager.tpl	2008-01-11 15:21:35 UTC (rev 146)
+++ trunk/plugins/UsersManager/templates/UsersManager.tpl	2008-01-12 01:10:43 UTC (rev 147)
@@ -2,7 +2,7 @@
 <script type="text/javascript" src="themes/default/common.js"></script>
 <link rel="stylesheet" href="themes/default/common-admin.css">
 
-<h2>Access</h2>
+<h2>Manage access</h2>
 
 <div id="sites">
 <form method="get" action="{$formUrl}" id="accessSites">
@@ -49,7 +49,7 @@
 <div id="accessUpdated">Done!</div>
 
 
-<h2>Users</h2>
+<h2>Manage users</h2>
 
 <div id="ajaxError" style="display:none"></div>
 <div id="ajaxLoading" style="display:none">Loading... <img src="themes/default/loading.gif"></div>
@@ -81,3 +81,5 @@
 </table>
 <div id="addrow"><img src='plugins/UsersManager/images/add.png'> <a href="#">Add a new user</a></div>
 <script type="text/javascript" src="plugins/UsersManager/templates/UsersManager.js"></script>
+
+<p><a href='index.php'>Back to Piwik homepage</a></p>
\ No newline at end of file

Modified: trunk/tests/modules/PHP_Related.test.php
===================================================================
--- trunk/tests/modules/PHP_Related.test.php	2008-01-11 15:21:35 UTC (rev 146)
+++ trunk/tests/modules/PHP_Related.test.php	2008-01-12 01:10:43 UTC (rev 147)
@@ -253,8 +253,30 @@
 		$size = round($size/1024/1024,3);
 		//echo "<br>size compressed string = ". $size."mb";
 		//echo "<br>after compression all sub arrays = ". $timer;
+	}
+	
+	function test_functionReturnNothing()
+	{
+		function givemenothing()
+		{
+			$a = 4;
+		}
+		
+		$return = givemenothing();
+		
+		$this->assertFalse(isset($return));
+		$this->assertTrue(empty($return));
+		$this->assertTrue(!is_int($return));
+		$this->assertTrue(!is_string($return));
+		$this->assertTrue(!is_bool($return));
 	}
-	
+	
+	function test_unserializeObject()
+	{
+//		$o = new Piwik_DataTable;
+//		$o = 'O:15:"Piwik_DataTable":6:{s:7:"�*�rows";a:10:{i:0;O:19:"Piwik_DataTable_Row":1:{s:1:"c";a:3:{i:0;a:12:{s:5:"label";s:6:"/index";s:9:"nb_visits";s:2:"17";s:7:"nb_hits";s:2:"17";s:23:"entry_nb_unique_visitor";s:2:"12";s:15:"entry_nb_visits";s:2:"16";s:16:"entry_nb_actions";s:2:"19";s:22:"entry_sum_visit_length";s:4:"8102";s:18:"entry_bounce_count";s:2:"15";s:22:"exit_nb_unique_visitor";s:2:"12";s:14:"exit_nb_visits";s:2:"16";s:17:"exit_bounce_count";s:2:"15";s:14:"sum_time_spent";s:4:"3292";}i:1;a:0:{}i:3;N;}}i:1;O:36:"Piwik_DataTable_Row_DataTableSummary":1:{s:1:"c";a:3:{i:0;a:12:{s:5:"label";i:1;s:9:"nb_visits";i:7;s:7:"nb_hits";i:7;s:23:"entry_nb_unique_visitor";i:6;s:15:"entry_nb_visits";i:6;s:16:"entry_nb_actions";i:6;s:22:"entry_sum_visit_length";i:60;s:18:"entry_bounce_count";i:6;s:22:"exit_nb_unique_visitor";i:6;s:14:"exit_nb_visits";i:6;s:17:"exit_bounce_count";i:6;s:14:"sum_time_spent";i:2284;}i:1;a:1:{s:18:"databaseSubtableId";i:38;}i:3;i:193;}}i:2;O:36:"Piwik_DataTable_Row_DataTableSummary":1:{s:1:"c";a:3:{i:0;a:11:{s:5:"label";i:9;s:9:"nb_visits";i:6;s:7:"nb_hits";i:6;s:23:"entry_nb_unique_visitor";i:6;s:15:"entry_nb_visits";i:6;s:16:"entry_nb_actions";i:6;s:22:"entry_sum_visit_length";i:60;s:18:"entry_bounce_count";i:6;s:22:"exit_nb_unique_visitor";i:6;s:14:"exit_nb_visits";i:6;s:17:"exit_bounce_count";i:6;}i:1;a:1:{s:18:"databaseSubtableId";i:18;}i:3;i:173;}}i:3;O:36:"Piwik_DataTable_Row_DataTableSummary":1:{s:1:"c";a:3:{i:0;a:11:{s:5:"label";i:3;s:9:"nb_visits";i:6;s:7:"nb_hits";i:6;s:23:"entry_nb_unique_visitor";i:6;s:15:"entry_nb_visits";i:6;s:16:"entry_nb_actions";i:6;s:22:"entry_sum_visit_length";i:60;s:18:"entry_bounce_count";i:6;s:22:"exit_nb_unique_visitor";i:6;s:14:"exit_nb_visits";i:6;s:17:"exit_bounce_count";i:6;}i:1;a:1:{s:18:"databaseSubtableId";i:9;}i:3;i:164;}}i:4;O:36:"Piwik_DataTable_Row_DataTableSummary":1:{s:1:"c";a:3:{i:0;a:12:{s:5:"label";s:1:"f";s:9:"nb_visits";i:6;s:7:"nb_hits";i:6;s:23:"entry_nb_unique_visitor";i:4;s:15:"entry_nb_visits";i:4;s:16:"entry_nb_actions";i:4;s:22:"entry_sum_visit_length";i:40;s:18:"entry_bounce_count";i:4;s:22:"exit_nb_unique_visitor";i:5;s:14:"exit_nb_visits";i:5;s:17:"exit_bounce_count";i:4;s:14:"sum_time_spent";i:2623;}i:1;a:1:{s:18:"databaseSubtableId";i:31;}i:3;i:186;}}i:5;O:19:"Piwik_DataTable_Row":1:{s:1:"c";a:3:{i:0;a:11:{s:5:"label";s:2:"/9";s:9:"nb_visits";s:1:"5";s:7:"nb_hits";s:1:"5";s:23:"entry_nb_unique_visitor";s:1:"5";s:15:"entry_nb_visits";s:1:"5";s:16:"entry_nb_actions";s:1:"5";s:22:"entry_sum_visit_length";s:2:"50";s:18:"entry_bounce_count";s:1:"5";s:22:"exit_nb_unique_visitor";s:1:"5";s:14:"exit_nb_visits";s:1:"5";s:17:"exit_bounce_count";s:1:"5";}i:1;a:0:{}i:3;N;}}i:6;O:36:"Piwik_DataTable_Row_DataTableSummary":1:{s:1:"c";a:3:{i:0;a:12:{s:5:"label";s:1:"e";s:9:"nb_visits";i:5;s:7:"nb_hits";i:5;s:23:"entry_nb_unique_visitor";i:5;s:15:"entry_nb_visits";i:5;s:16:"entry_nb_actions";i:11;s:22:"entry_sum_visit_length";i:15972;s:18:"entry_bounce_count";i:3;s:22:"exit_nb_unique_visitor";i:3;s:14:"exit_nb_visits";i:3;s:17:"exit_bounce_count";i:3;s:14:"sum_time_spent";i:4711;}i:1;a:1:{s:18:"databaseSubtableId";i:22;}i:3;i:177;}}i:7;O:36:"Piwik_DataTable_Row_DataTableSummary":1:{s:1:"c";a:3:{i:0;a:12:{s:5:"label";s:1:"g";s:9:"nb_visits";i:4;s:7:"nb_hits";i:4;s:23:"entry_nb_unique_visitor";i:4;s:15:"entry_nb_visits";i:4;s:16:"entry_nb_actions";i:5;s:22:"entry_sum_visit_length";i:2267;s:18:"entry_bounce_count";i:3;s:22:"exit_nb_unique_visitor";i:3;s:14:"exit_nb_visits";i:3;s:17:"exit_bounce_count";i:3;s:14:"sum_time_spent";i:2237;}i:1;a:1:{s:18:"databaseSubtableId";i:28;}i:3;i:183;}}i:8;O:19:"Piwik_DataTable_Row":1:{s:1:"c";a:3:{i:0;a:11:{s:5:"label";s:2:"/e";s:9:"nb_visits";s:1:"4";s:7:"nb_hits";s:1:"4";s:23:"entry_nb_unique_visitor";s:1:"3";s:15:"entry_nb_visits";s:1:"3";s:16:"entry_nb_actions";s:1:"3";s:22:"entry_sum_visit_length";s:2:"30";s:18:"entry_bounce_count";s:1:"3";s:22:"exit_nb_unique_visitor";s:1:"4";s:14:"exit_nb_visits";s:1:"4";s:17:"exit_bounce_count";s:1:"3";}i:1;a:0:{}i:3;N;}}i:9;O:19:"Piwik_DataTable_Row":1:{s:1:"c";a:3:{i:0;a:11:{s:5:"label";s:2:"/f";s:9:"nb_visits";s:1:"4";s:7:"nb_hits";s:1:"4";s:23:"entry_nb_unique_visitor";s:1:"4";s:15:"entry_nb_visits";s:1:"4";s:16:"entry_nb_actions";s:1:"4";s:22:"entry_sum_visit_length";s:2:"40";s:18:"entry_bounce_count";s:1:"4";s:22:"exit_nb_unique_visitor";s:1:"4";s:14:"exit_nb_visits";s:1:"4";s:17:"exit_bounce_count";s:1:"4";}i:1;a:0:{}i:3;N;}}}s:12:"�*�currentId";i:163;s:13:"�*�depthLevel";i:0;s:19:"�*�indexNotUpToDate";b:1;s:16:"�*�queuedFilters";a:0:{}s:29:"�*�rowsCountBeforeLimitFilter";i:34;}';
+//		$o = unserialize($o);
+	}
 }
 
 

Modified: trunk/themes/default/common-admin.css
===================================================================
--- trunk/themes/default/common-admin.css	2008-01-11 15:21:35 UTC (rev 146)
+++ trunk/themes/default/common-admin.css	2008-01-12 01:10:43 UTC (rev 147)
@@ -79,7 +79,6 @@
  color:#6C8C37;
  text-decoration:none;
  font-weight:normal;
- background: transparent url(links_yellow.gif) no-repeat 0% 50%;
  padding-left:15px;
 }
 tbody td:hover, tbody th:hover {



More information about the Piwik-svn mailing list