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:
-rwxr-xr-xconfig/global.ini.php7
-rwxr-xr-xmodules/API/Proxy.php94
-rw-r--r--modules/API/Request.php103
-rw-r--r--modules/DataTable.php102
-rw-r--r--modules/DataTable/Renderer/Csv.php19
-rw-r--r--modules/DataTable/Renderer/Json.php3
-rw-r--r--modules/DataTable/Renderer/Php.php68
-rw-r--r--modules/DataTable/Renderer/Xml.php9
-rwxr-xr-xmodules/Piwik.php9
-rw-r--r--modules/ViewDataTable/Html.php4
-rw-r--r--plugins/API/Controller.php10
-rw-r--r--plugins/Home/templates/cloud.tpl3
-rw-r--r--plugins/Home/templates/index.tpl6
-rw-r--r--plugins/Home/templates/links_misc_modules.tpl8
-rw-r--r--plugins/Installation/Controller.php8
-rwxr-xr-xplugins/SitesManager/API.php35
-rw-r--r--plugins/SitesManager/Controller.php10
-rw-r--r--plugins/SitesManager/templates/DisplayJavascriptCode.tpl7
-rw-r--r--plugins/SitesManager/templates/SitesManager.js16
-rw-r--r--plugins/SitesManager/templates/SitesManager.tpl7
-rwxr-xr-xplugins/UsersManager/API.php7
-rw-r--r--plugins/UsersManager/templates/UsersManager.tpl6
-rw-r--r--tests/modules/PHP_Related.test.php24
-rw-r--r--themes/default/common-admin.css1
24 files changed, 471 insertions, 95 deletions
diff --git a/config/global.ini.php b/config/global.ini.php
index 9e7f5b01b0..7e4e842f52 100755
--- a/config/global.ini.php
+++ b/config/global.ini.php
@@ -26,9 +26,6 @@ current = en
default = en
[Plugins]
-enabled[] = Login
-enabled[] = UsersManager
-enabled[] = SitesManager
enabled[] = UserSettings
enabled[] = VisitsSummary
@@ -40,6 +37,10 @@ enabled[] = VisitFrequency
enabled[] = VisitTime
enabled[] = VisitorInterest
enabled[] = ExamplePlugin
+
+enabled[] = Login
+enabled[] = UsersManager
+enabled[] = SitesManager
;enabled[] = Openads
enabled[] = Installation
diff --git a/modules/API/Proxy.php b/modules/API/Proxy.php
index 3644404893..8d815ecefe 100755
--- a/modules/API/Proxy.php
+++ b/modules/API/Proxy.php
@@ -122,21 +122,97 @@ class Piwik_API_Proxy
}
$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@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 @@ class Piwik_API_Proxy
$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 @@ class Piwik_API_Proxy
assert(!is_null(self::$classCalled));
$this->registerClass(self::$classCalled);
-
+
$className = $this->getClassNameFromModule(self::$classCalled);
// instanciate the object
diff --git a/modules/API/Request.php b/modules/API/Request.php
index 6cea379ef4..05705ae0a5 100644
--- a/modules/API/Request.php
+++ b/modules/API/Request.php
@@ -79,10 +79,13 @@ class Piwik_API_Request
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 @@ class Piwik_API_Request
$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 @@ class Piwik_API_Request
}
- function getStandardSuccessOutput($format)
+ function getStandardSuccessOutput($format, $message = 'ok')
{
- $return = 'TO OVERWRITE! getStandardSuccessOutput()';
switch($format)
{
case 'xml':
@@ -171,22 +217,29 @@ class Piwik_API_Request
$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 @@ class Piwik_API_Request
}
function getExceptionOutput($message, $format)
{
- $return = 'TO OVERWRITE! getExceptionOutput()';
switch($format)
{
case 'xml':
@@ -232,6 +284,7 @@ class Piwik_API_Request
{
// 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 @@ class Piwik_API_Request
&& $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 @@ class Piwik_API_Request
}
- 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;
diff --git a/modules/DataTable.php b/modules/DataTable.php
index 75fd42ef78..173f19003c 100644
--- a/modules/DataTable.php
+++ b/modules/DataTable.php
@@ -479,11 +479,18 @@ class Piwik_DataTable
* 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 @@ class Piwik_DataTable
$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);
+ }
}
/**
diff --git a/modules/DataTable/Renderer/Csv.php b/modules/DataTable/Renderer/Csv.php
index b8bc98ac0b..4e7a7e4e9c 100644
--- a/modules/DataTable/Renderer/Csv.php
+++ b/modules/DataTable/Renderer/Csv.php
@@ -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 @@ class Piwik_DataTable_Renderer_Csv extends Piwik_DataTable_Renderer
}
}
// 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)
{
diff --git a/modules/DataTable/Renderer/Json.php b/modules/DataTable/Renderer/Json.php
index 33bba28eb7..d3a0d92ba9 100644
--- a/modules/DataTable/Renderer/Json.php
+++ b/modules/DataTable/Renderer/Json.php
@@ -22,7 +22,8 @@ class Piwik_DataTable_Renderer_Json extends Piwik_DataTable_Renderer
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;
}
diff --git a/modules/DataTable/Renderer/Php.php b/modules/DataTable/Renderer/Php.php
index c50dce64f1..90540b72b8 100644
--- a/modules/DataTable/Renderer/Php.php
+++ b/modules/DataTable/Renderer/Php.php
@@ -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 @@ class Piwik_DataTable_Renderer_Php extends Piwik_DataTable_Renderer
}
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 @@ class Piwik_DataTable_Renderer_Php extends Piwik_DataTable_Renderer
return $array;
}
+
+ protected $serialize;
+
protected function renderTable($table)
{
diff --git a/modules/DataTable/Renderer/Xml.php b/modules/DataTable/Renderer/Xml.php
index cb71476137..1c1e680a0f 100644
--- a/modules/DataTable/Renderer/Xml.php
+++ b/modules/DataTable/Renderer/Xml.php
@@ -21,10 +21,13 @@ class Piwik_DataTable_Renderer_Xml extends Piwik_DataTable_Renderer
}
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(
diff --git a/modules/Piwik.php b/modules/Piwik.php
index bdd2910539..42d1bf04c7 100755
--- a/modules/Piwik.php
+++ b/modules/Piwik.php
@@ -95,6 +95,15 @@ class Piwik
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()
{
diff --git a/modules/ViewDataTable/Html.php b/modules/ViewDataTable/Html.php
index 8fb6306b63..fbf821bfcc 100644
--- a/modules/ViewDataTable/Html.php
+++ b/modules/ViewDataTable/Html.php
@@ -69,7 +69,9 @@ class Piwik_ViewDataTable_Html extends Piwik_ViewDataTable
$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;
}
diff --git a/plugins/API/Controller.php b/plugins/API/Controller.php
index 43dee711b7..aa22304503 100644
--- a/plugins/API/Controller.php
+++ b/plugins/API/Controller.php
@@ -11,8 +11,14 @@ class Piwik_API_Controller extends Piwik_Controller
}
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();
diff --git a/plugins/Home/templates/cloud.tpl b/plugins/Home/templates/cloud.tpl
index 31e556bfde..744d558ebc 100644
--- a/plugins/Home/templates/cloud.tpl
+++ b/plugins/Home/templates/cloud.tpl
@@ -58,8 +58,7 @@ span.size6, span.size6 a {
{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"}
diff --git a/plugins/Home/templates/index.tpl b/plugins/Home/templates/index.tpl
index e94a25e843..a4302ad022 100644
--- a/plugins/Home/templates/index.tpl
+++ b/plugins/Home/templates/index.tpl
@@ -87,6 +87,11 @@ tr td.label img.plusMinus {
margin:10px;
}
+#miscLinks{
+ font-size:small;
+ padding-right:20px;
+}
+
#sitesSelection {
}
@@ -158,6 +163,7 @@ tr td.label img.plusMinus {
<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>
diff --git a/plugins/Home/templates/links_misc_modules.tpl b/plugins/Home/templates/links_misc_modules.tpl
new file mode 100644
index 0000000000..c21080836e
--- /dev/null
+++ b/plugins/Home/templates/links_misc_modules.tpl
@@ -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
diff --git a/plugins/Installation/Controller.php b/plugins/Installation/Controller.php
index b81ac78eb0..fe58e495dd 100644
--- a/plugins/Installation/Controller.php
+++ b/plugins/Installation/Controller.php
@@ -279,12 +279,8 @@ class Piwik_Installation_Controller extends Piwik_Controller
$view->websiteName = $_SESSION['site_name'];
-
- $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);
+
+ $jsTag = Piwik::getJavascriptCode($_SESSION['site_idSite'], Piwik_Url::getCurrentUrlWithoutFileName());
$view->javascriptTag = $jsTag;
$view->showNextStep = true;
diff --git a/plugins/SitesManager/API.php b/plugins/SitesManager/API.php
index c8f52cb7cd..5d0b68eef8 100755
--- a/plugins/SitesManager/API.php
+++ b/plugins/SitesManager/API.php
@@ -59,12 +59,12 @@ class Piwik_SitesManager_API extends Piwik_Apiable
* @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 @@ class Piwik_SitesManager_API extends Piwik_Apiable
*
* @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 @@ class Piwik_SitesManager_API extends Piwik_Apiable
$urls = array_slice($urls, 1);
$db->insert(Piwik::prefixTable("site"), array(
- 'name' => $name,
+ 'name' => $siteName,
'main_url' => $url,
)
);
@@ -270,16 +270,16 @@ class Piwik_SitesManager_API extends Piwik_Apiable
*
* @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 @@ class Piwik_SitesManager_API extends Piwik_Apiable
*
* @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 @@ class Piwik_SitesManager_API extends Piwik_Apiable
$bind['main_url'] = $url;
}
- $bind['name'] = $name;
+ $bind['name'] = $siteName;
$db = Zend_Registry::get('db');
@@ -366,7 +366,8 @@ class Piwik_SitesManager_API extends Piwik_Apiable
if(count($urls) > 1)
{
self::replaceSiteUrls($idSite, $urls);
- }
+ }
+
}
/**
@@ -430,9 +431,9 @@ class Piwik_SitesManager_API extends Piwik_Apiable
*
* @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.");
}
diff --git a/plugins/SitesManager/Controller.php b/plugins/SitesManager/Controller.php
index abd8455a34..239445d726 100644
--- a/plugins/SitesManager/Controller.php
+++ b/plugins/SitesManager/Controller.php
@@ -13,5 +13,15 @@ class Piwik_SitesManager_Controller extends Piwik_Controller
// 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
diff --git a/plugins/SitesManager/templates/DisplayJavascriptCode.tpl b/plugins/SitesManager/templates/DisplayJavascriptCode.tpl
new file mode 100644
index 0000000000..9151ba7103
--- /dev/null
+++ b/plugins/SitesManager/templates/DisplayJavascriptCode.tpl
@@ -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
diff --git a/plugins/SitesManager/templates/SitesManager.js b/plugins/SitesManager/templates/SitesManager.js
index 5363ba2fe2..8fdf9c74a4 100644
--- a/plugins/SitesManager/templates/SitesManager.js
+++ b/plugins/SitesManager/templates/SitesManager.js
@@ -1,5 +1,5 @@
-function getDeleteSiteAJAX( idsite )
+function getDeleteSiteAJAX( idSite )
{
var ajaxRequest = getStandardAjaxConf();
toggleAjaxLoading();
@@ -9,7 +9,7 @@ function getDeleteSiteAJAX( idsite )
parameters.module = 'API';
parameters.format = 'json';
parameters.method = 'SitesManager.deleteSite';
- parameters.idSite = idsite;
+ parameters.idSite = idSite;
ajaxRequest.data = parameters;
@@ -24,7 +24,7 @@ function getAddSiteAJAX( row )
// 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 @@ function getAddSiteAJAX( row )
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 @@ function getUpdateSiteAJAX( row )
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 @@ function getUpdateSiteAJAX( row )
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 @@ function getUpdateSiteAJAX( row )
$('.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 getUpdateSiteAJAX( row )
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)
diff --git a/plugins/SitesManager/templates/SitesManager.tpl b/plugins/SitesManager/templates/SitesManager.tpl
index 759025e5d0..f564f3be36 100644
--- a/plugins/SitesManager/templates/SitesManager.tpl
+++ b/plugins/SitesManager/templates/SitesManager.tpl
@@ -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>
diff --git a/plugins/UsersManager/API.php b/plugins/UsersManager/API.php
index 096bc34974..46b28b26ef 100755
--- a/plugins/UsersManager/API.php
+++ b/plugins/UsersManager/API.php
@@ -168,15 +168,16 @@ class Piwik_UsersManager_API extends Piwik_Apiable
*
* @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;
}
diff --git a/plugins/UsersManager/templates/UsersManager.tpl b/plugins/UsersManager/templates/UsersManager.tpl
index c3872eefa9..9bcd961349 100644
--- a/plugins/UsersManager/templates/UsersManager.tpl
+++ b/plugins/UsersManager/templates/UsersManager.tpl
@@ -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
diff --git a/tests/modules/PHP_Related.test.php b/tests/modules/PHP_Related.test.php
index 4a8b95f5bc..ff6f45eea1 100644
--- a/tests/modules/PHP_Related.test.php
+++ b/tests/modules/PHP_Related.test.php
@@ -253,8 +253,30 @@ class Test_PHP_Related extends UnitTestCase
$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);
}
-
}
diff --git a/themes/default/common-admin.css b/themes/default/common-admin.css
index dd34c2baf5..72800c6262 100644
--- a/themes/default/common-admin.css
+++ b/themes/default/common-admin.css
@@ -79,7 +79,6 @@ tbody td, tbody th{
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 {