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:
authormatt <matt@59fd770c-687e-43c8-a1e3-f5a4ff64c105>2009-05-05 02:55:35 +0400
committermatt <matt@59fd770c-687e-43c8-a1e3-f5a4ff64c105>2009-05-05 02:55:35 +0400
commitcb346a4546a53bdc5054129d3331470cb3a447fc (patch)
tree155a924d3e86b7869c89022e3fbf19ca7be2ce2f
parent92da6b8181282800f4f28cae77d776b67540b477 (diff)
- ADDED search field below data tables is now using the regular expression syntax. For example, a search for "google|yahoo" would match all rows containing "google" or "yahoo". All search strings containing any of the special characters from this list: . \ + * ? [ ^ ] $ ( ) { } = ! < > | must be escaped with a back slash, eg. if you want to search for keywords containing "piwik!" you would search for "piwik\!".
- ADDED new configuration option: default number of rows returned in API responses "API_datatable_default_limit = 50" - REMOVED the automatic generic filters. The limit and sort and safe decode are applied by each module when necessary. - removed exact match filter. Now all searches are using regular expressions syntax. Exact match can be done using ^exact search here$ - fixed notice when natural sort on a non existing column - fixed CSV export for datatable_array - clarified code for plotting multiple lines in an evolution chart - FIXED #624 Added icon "save as image" below all graphs (next to the Export icon) - moved all JS functions into the piwikHelper static class - added example in ExampleUI plugin to plot only visits from google and yahoo! in 4 lines of code - added message when flash is disabled and graph not showing, linking to piwik faq. - added expressInstall.swf feature
-rwxr-xr-xconfig/global.ini.php8
-rw-r--r--core/API/DataTableGenericFilter.php9
-rw-r--r--core/API/Request.php1
-rw-r--r--core/API/ResponseBuilder.php3
-rw-r--r--core/Archive/Array/IndexedByDate.php2
-rw-r--r--core/ArchiveProcessing.php3
-rw-r--r--core/Common.php26
-rw-r--r--core/Controller.php7
-rw-r--r--core/DataTable/Filter.php1
-rw-r--r--core/DataTable/Filter/ExactMatch.php52
-rw-r--r--core/DataTable/Filter/Pattern.php5
-rw-r--r--core/DataTable/Filter/Sort.php18
-rw-r--r--core/DataTable/Renderer/Csv.php5
-rw-r--r--core/Date.php17
-rw-r--r--core/FrontController.php7
-rw-r--r--core/Piwik.php24
-rw-r--r--core/Url.php30
-rw-r--r--core/ViewDataTable.php26
-rw-r--r--core/ViewDataTable/Cloud.php5
-rw-r--r--core/ViewDataTable/GenerateGraphData.php33
-rw-r--r--core/ViewDataTable/GenerateGraphData/ChartEvolution.php119
-rw-r--r--core/ViewDataTable/GenerateGraphHTML.php94
-rw-r--r--core/ViewDataTable/GenerateGraphHTML/ChartEvolution.php7
-rw-r--r--core/ViewDataTable/HtmlTable.php3
-rw-r--r--core/ViewDataTable/Sparkline.php1
-rw-r--r--core/Visualization/Chart.php38
-rw-r--r--core/Visualization/Chart/Evolution.php18
-rw-r--r--core/Visualization/Chart/Pie.php8
-rw-r--r--core/Visualization/Chart/VerticalBar.php18
-rw-r--r--core/Visualization/Cloud.php3
-rw-r--r--core/Visualization/Sparkline.php6
-rw-r--r--core/iView.php7
-rw-r--r--lang/en.php3
-rw-r--r--libs/swfobject/expressInstall.swfbin0 -> 773 bytes
-rw-r--r--plugins/API/Controller.php5
-rw-r--r--plugins/Actions/Controller.php3
-rw-r--r--plugins/CoreHome/templates/datatable.js10
-rw-r--r--plugins/CoreHome/templates/datatable_footer.tpl23
-rw-r--r--plugins/CoreHome/templates/graph.tpl1
-rw-r--r--plugins/CoreHome/templates/menu.js2
-rw-r--r--plugins/CoreHome/templates/sparkline.js4
-rw-r--r--plugins/CoreUpdater/Controller.php40
-rw-r--r--plugins/Dashboard/Controller.php3
-rw-r--r--plugins/Dashboard/templates/Dashboard.js2
-rw-r--r--plugins/Dashboard/templates/index.tpl1
-rw-r--r--plugins/Dashboard/templates/widgetMenu.js2
-rw-r--r--plugins/ExampleUI/API.php4
-rw-r--r--plugins/ExampleUI/Controller.php16
-rw-r--r--plugins/ExampleUI/ExampleUI.php2
-rw-r--r--plugins/Goals/templates/GoalForm.js8
-rw-r--r--plugins/Referers/Controller.php14
-rw-r--r--plugins/Referers/Referers.php1
-rw-r--r--plugins/SitesManager/templates/SitesManager.js20
-rw-r--r--plugins/UserCountry/Controller.php1
-rw-r--r--plugins/UserCountry/templates/index.tpl6
-rw-r--r--plugins/UserSettings/Controller.php4
-rw-r--r--plugins/UsersManager/templates/UsersManager.js26
-rw-r--r--plugins/VisitsSummary/Controller.php4
-rw-r--r--tests/core/DataTable/Filter/Pattern.test.php65
-rw-r--r--themes/default/common.js44
-rw-r--r--themes/default/images/image.pngbin0 -> 1205 bytes
61 files changed, 458 insertions, 460 deletions
diff --git a/config/global.ini.php b/config/global.ini.php
index 8afdc24ef7..b2a985d4b2 100755
--- a/config/global.ini.php
+++ b/config/global.ini.php
@@ -73,11 +73,11 @@ default_currency = "$"
; plugin, and set this default_language (users won't see the language drop down)
default_language = en
-; default sorting order used by all datatables (desc or asc)
-dataTable_default_sort_order = desc
-
; default number of elements in the datatable
-dataTable_default_limit = 10
+datatable_default_limit = 10
+
+; default number of rows returned in API responses
+API_datatable_default_limit = 50
; if set to 1, the website selector will be displayed in the Piwik UI
; if your Piwik installation has thousands of websites, you may disable the website selector
diff --git a/core/API/DataTableGenericFilter.php b/core/API/DataTableGenericFilter.php
index 0143397d40..59e616e1ee 100644
--- a/core/API/DataTableGenericFilter.php
+++ b/core/API/DataTableGenericFilter.php
@@ -36,10 +36,6 @@ class Piwik_API_DataTableGenericFilter
'filter_column_recursive' => array('string'),
'filter_pattern_recursive' => array('string'),
),
- 'ExactMatch' => array(
- 'filter_exact_column' => array('string'),
- 'filter_exact_pattern' => array('array'),
- ),
'ExcludeLowPopulation' => array(
'filter_excludelowpop' => array('string'),
'filter_excludelowpop_value'=> array('float', '0'),
@@ -52,13 +48,12 @@ class Piwik_API_DataTableGenericFilter
),
'Sort' => array(
'filter_sort_column' => array('string'),
- 'filter_sort_order' => array('string', Zend_Registry::get('config')->General->dataTable_default_sort_order),
+ 'filter_sort_order' => array('string'),
),
'Limit' => array(
'filter_offset' => array('integer', '0'),
- 'filter_limit' => array('integer', Zend_Registry::get('config')->General->dataTable_default_limit),
+ 'filter_limit' => array('integer'),
),
- 'SafeDecodeLabel' => array(),
);
return $genericFilters;
diff --git a/core/API/Request.php b/core/API/Request.php
index 60bef14822..c9d9d3202f 100644
--- a/core/API/Request.php
+++ b/core/API/Request.php
@@ -67,7 +67,6 @@ class Piwik_API_Request
Piwik_PostEvent('API.Request.authenticate', $requestArray['token_auth']);
Zend_Registry::get('access')->reloadAccess();
}
-
$requestArray = $requestArray + $defaultRequest;
}
diff --git a/core/API/ResponseBuilder.php b/core/API/ResponseBuilder.php
index 1f6f04c8fb..87c279fabe 100644
--- a/core/API/ResponseBuilder.php
+++ b/core/API/ResponseBuilder.php
@@ -249,6 +249,9 @@ class Piwik_API_ResponseBuilder
$genericFilter->filter();
}
+ // we automatically safe decode all datatable labels (against xss)
+ $datatable->queueFilter('SafeDecodeLabel');
+
// if the flag disable_queued_filters is defined we skip the filters that were queued
if(Piwik_Common::getRequestVar('disable_queued_filters', 'false', 'string', $this->request) == 'false')
{
diff --git a/core/Archive/Array/IndexedByDate.php b/core/Archive/Array/IndexedByDate.php
index f9fe5eb3a1..3a84e30089 100644
--- a/core/Archive/Array/IndexedByDate.php
+++ b/core/Archive/Array/IndexedByDate.php
@@ -83,9 +83,7 @@ class Piwik_Archive_Array_IndexedByDate extends Piwik_Archive_Array
FROM $table
WHERE idarchive IN ( $inIds )
AND name IN ( $inNames )";
-
$values = $db->fetchAll($sql);
-
foreach($values as $value)
{
$arrayValues[$value['timestamp']][$value['name']] = (float)$value['value'];
diff --git a/core/ArchiveProcessing.php b/core/ArchiveProcessing.php
index d2b5c6f72f..66d0a33a9b 100644
--- a/core/ArchiveProcessing.php
+++ b/core/ArchiveProcessing.php
@@ -592,11 +592,9 @@ abstract class Piwik_ArchiveProcessing
protected function isArchivingDisabled()
{
static $archivingIsDisabled = null;
-
if(is_null($archivingIsDisabled))
{
$archivingIsDisabled = false;
-
$enableBrowserArchivingTriggering = (bool)Zend_Registry::get('config')->General->enable_browser_archiving_triggering;
if($enableBrowserArchivingTriggering == false)
{
@@ -606,7 +604,6 @@ abstract class Piwik_ArchiveProcessing
}
}
}
-
return $archivingIsDisabled;
}
}
diff --git a/core/Common.php b/core/Common.php
index 8c3b79c25b..9c53ef72ce 100644
--- a/core/Common.php
+++ b/core/Common.php
@@ -46,17 +46,20 @@ class Piwik_Common
*/
static public function prefixTable($table)
{
- $prefixTable = false;
- if(defined('PIWIK_TRACKER_MODE') && PIWIK_TRACKER_MODE)
+ static $prefixTable = null;
+ if(is_null($prefixTable))
{
- $prefixTable = Piwik_Tracker_Config::getInstance()->database['tables_prefix'];
- }
- else
- {
- $config = Zend_Registry::get('config');
- if($config !== false)
+ if(defined('PIWIK_TRACKER_MODE') && PIWIK_TRACKER_MODE)
{
- $prefixTable = $config->database->tables_prefix;
+ $prefixTable = Piwik_Tracker_Config::getInstance()->database['tables_prefix'];
+ }
+ else
+ {
+ $config = Zend_Registry::get('config');
+ if($config !== false)
+ {
+ $prefixTable = $config->database->tables_prefix;
+ }
}
}
return $prefixTable . $table;
@@ -402,9 +405,7 @@ class Piwik_Common
{
$requestArrayToUse = $_GET + $_POST;
}
-
$varDefault = self::sanitizeInputValues( $varDefault );
-
if($varType == 'int')
{
// settype accepts only integer
@@ -435,7 +436,7 @@ class Piwik_Common
return $varDefault;
}
}
-
+
// Normal case, there is a value available in REQUEST for the requested varName
$value = self::sanitizeInputValues( $requestArrayToUse[$varName] );
@@ -483,7 +484,6 @@ class Piwik_Common
}
}
}
-
return $value;
}
diff --git a/core/Controller.php b/core/Controller.php
index 36c56852a0..9d99b2f8ae 100644
--- a/core/Controller.php
+++ b/core/Controller.php
@@ -67,7 +67,7 @@ abstract class Piwik_Controller
{
return 'index';
}
-
+
protected $standardColumnNameToTranslation = array(
'label' => 'General_ColumnLabel',
'nb_visits' => 'General_ColumnNbVisits',
@@ -82,7 +82,7 @@ abstract class Piwik_Controller
'revenue_per_visit' => 'General_ColumnValuePerVisit',
'goals_conversion_rate' => 'General_ColumnVisitsWithConversions',
);
-
+
/**
* Given an Object implementing Piwik_iView interface, we either:
* - echo the output of the rendering if fetch = false
@@ -129,6 +129,9 @@ abstract class Piwik_Controller
require_once "ViewDataTable/GenerateGraphHTML.php";
$view = Piwik_ViewDataTable::factory('graphEvolution');
$view->init( $currentModuleName, $currentControllerAction, $apiMethod );
+ $view->disableExcludeLowPopulation();
+ $view->disableShowAllViewsIcons();
+ $view->disableShowTable();
// if the date is not yet a nicely formatted date range ie. YYYY-MM-DD,YYYY-MM-DD we build it
// otherwise the current controller action is being called with the good date format already so it's fine
diff --git a/core/DataTable/Filter.php b/core/DataTable/Filter.php
index 46984d5426..64654905ce 100644
--- a/core/DataTable/Filter.php
+++ b/core/DataTable/Filter.php
@@ -57,7 +57,6 @@ require_once "DataTable/Filter/ReplaceColumnNames.php";
require_once "DataTable/Filter/Sort.php";
require_once "DataTable/Filter/AddSummaryRow.php";
require_once "DataTable/Filter/ReplaceSummaryRowLabel.php";
-require_once "DataTable/Filter/ExactMatch.php";
require_once "DataTable/Filter/SafeDecodeLabel.php";
require_once "DataTable/Filter/AddColumnsWhenShowAllColumns.php";
require_once "DataTable/Filter/UpdateColumnsWhenShowAllGoals.php";
diff --git a/core/DataTable/Filter/ExactMatch.php b/core/DataTable/Filter/ExactMatch.php
deleted file mode 100644
index 3f68658d61..0000000000
--- a/core/DataTable/Filter/ExactMatch.php
+++ /dev/null
@@ -1,52 +0,0 @@
-<?php
-/**
- * Piwik - Open source web analytics
- *
- * @link http://piwik.org
- * @license http://www.gnu.org/licenses/gpl-3.0.html Gpl v3 or later
- * @version $Id$
- *
- * @package Piwik_DataTable
- */
-
-/**
- * Delete all rows for which the given $columnToFilter do not equal $patternToSearch
- * This filter can be used on both integer and string columns.
- * You can pass an array of integers in $patternToSearch parameter.
- *
- * @package Piwik_DataTable
- * @subpackage Piwik_DataTable_Filter
- */
-class Piwik_DataTable_Filter_ExactMatch extends Piwik_DataTable_Filter
-{
- private $columnToFilter;
- private $patternToSearch;
-
- public function __construct( $table, $columnToFilter, $patternToSearch )
- {
- parent::__construct($table);
- $this->patternToSearch = $patternToSearch;
- $this->columnToFilter = $columnToFilter;
- $this->filter();
- }
-
- protected function filter()
- {
- foreach($this->table->getRows() as $key => $row)
- {
- if( is_array($this->patternToSearch) )
- {
- if( in_array($row->getColumn($this->columnToFilter), $this->patternToSearch) == false )
- {
- $this->table->deleteRow($key);
- }
- }
- else if( $row->getColumn($this->columnToFilter) != $this->patternToSearch )
- {
- $k = $row->getColumn($this->columnToFilter);
- $this->table->deleteRow($key);
- }
- }
- }
-}
-
diff --git a/core/DataTable/Filter/Pattern.php b/core/DataTable/Filter/Pattern.php
index d12e4920ec..8a3c1eb7fe 100644
--- a/core/DataTable/Filter/Pattern.php
+++ b/core/DataTable/Filter/Pattern.php
@@ -34,7 +34,7 @@ class Piwik_DataTable_Filter_Pattern extends Piwik_DataTable_Filter
static public function getPatternQuoted( $pattern )
{
- return "/". preg_quote($pattern, '/') ."/";
+ return "/". str_replace('/','\/', $pattern) ."/";
}
/*
@@ -42,8 +42,7 @@ class Piwik_DataTable_Filter_Pattern extends Piwik_DataTable_Filter
*/
static public function match($pattern, $patternQuoted, $string)
{
- return preg_match($patternQuoted . "i", $string) == 1
- && stripos($string, $pattern) !== false;
+ return @preg_match($patternQuoted . "i", $string) == 1;
}
protected function filter()
diff --git a/core/DataTable/Filter/Sort.php b/core/DataTable/Filter/Sort.php
index 0b80a322d8..5c066cbe54 100644
--- a/core/DataTable/Filter/Sort.php
+++ b/core/DataTable/Filter/Sort.php
@@ -76,10 +76,20 @@ class Piwik_DataTable_Filter_Sort extends Piwik_DataTable_Filter
function naturalSort($a, $b)
{
- return $this->sign * strnatcasecmp(
- $a->c[Piwik_DataTable_Row::COLUMNS][$this->columnToSort],
- $b->c[Piwik_DataTable_Row::COLUMNS][$this->columnToSort]
- );
+ return !isset($a->c[Piwik_DataTable_Row::COLUMNS][$this->columnToSort])
+ && !isset($b->c[Piwik_DataTable_Row::COLUMNS][$this->columnToSort] )
+ ? 0
+ : (!isset($a->c[Piwik_DataTable_Row::COLUMNS][$this->columnToSort])
+ ? 1
+ : (!isset($b->c[Piwik_DataTable_Row::COLUMNS][$this->columnToSort] )
+ ? -1
+ : $this->sign * strnatcasecmp(
+ $a->c[Piwik_DataTable_Row::COLUMNS][$this->columnToSort],
+ $b->c[Piwik_DataTable_Row::COLUMNS][$this->columnToSort]
+ )
+ )
+ )
+ ;
}
function sortString($a, $b)
diff --git a/core/DataTable/Renderer/Csv.php b/core/DataTable/Renderer/Csv.php
index 53dbc25a8d..567ece1b6f 100644
--- a/core/DataTable/Renderer/Csv.php
+++ b/core/DataTable/Renderer/Csv.php
@@ -65,7 +65,7 @@ class Piwik_DataTable_Renderer_Csv extends Piwik_DataTable_Renderer
function render()
{
- return $this->renderTable($this->table);
+ return $this->output($this->renderTable($this->table));
}
protected function renderTable($table)
@@ -104,8 +104,7 @@ class Piwik_DataTable_Renderer_Csv extends Piwik_DataTable_Renderer
{
$str = $this->renderDataTable($table);
}
-
- return $this->output($str);
+ return $str;
}
protected function renderDataTable( $table )
diff --git a/core/Date.php b/core/Date.php
index 394adab8d4..001af599fa 100644
--- a/core/Date.php
+++ b/core/Date.php
@@ -67,16 +67,6 @@ class Piwik_Date
$this->timestamp = $date ;
}
- /*
- * @param int Timestamp
- * @return string Pretty date in the current locale
- */
- static public function getPrettyDateFromTimestamp($timestamp)
- {
- $date = Piwik_Date::factory($timestamp);
- return $date->getLocalized(Piwik_Translate('CoreHome_LocalizedDateFormat'));
- }
-
/**
* Sets the time part of the date
* Doesn't modify $this
@@ -237,7 +227,12 @@ class Piwik_Date
return date($part, $this->getTimestamp());
}
- //TODO to test
+ /**
+ * Returns a localized date string, given a template.
+ * Allowed tags are: %day%, %shortDay%, %longDay%, etc.
+ * @param $template string eg. %shortMonth% %longYear%
+ * @return string eg. "Aug 2009"
+ */
public function getLocalized($template)
{
$day = $this->toString('j');
diff --git a/core/FrontController.php b/core/FrontController.php
index 8270f53212..0eb1112c10 100644
--- a/core/FrontController.php
+++ b/core/FrontController.php
@@ -230,14 +230,9 @@ class Piwik_FrontController
Piwik::createDatabaseObject();
Piwik::createLogObject();
-
// creating the access object, so that core/Updates/* can enforce Super User and use some APIs
Piwik::createAccessObject();
-
- require_once "CoreUpdater/Controller.php";
- //TODO should not be a controller!
- $updaterController = new Piwik_CoreUpdater_Controller();
- $updaterController->checkForCoreAndPluginsUpdates();
+ Piwik::displayScreenForCoreAndPluginsUpdatesIfNecessary();
Piwik_PluginsManager::getInstance()->installLoadedPlugins();
Piwik::install();
diff --git a/core/Piwik.php b/core/Piwik.php
index 8f928ccf3f..428b17ead6 100644
--- a/core/Piwik.php
+++ b/core/Piwik.php
@@ -904,6 +904,30 @@ class Piwik
return false;
}
+ static public function displayScreenForCoreAndPluginsUpdatesIfNecessary()
+ {
+ require_once "Updater.php";
+ require_once "Version.php";
+ $updater = new Piwik_Updater();
+ $updater->addComponentToCheck('core', Piwik_Version::VERSION);
+
+ $plugins = Piwik_PluginsManager::getInstance()->getInstalledPlugins();
+ foreach($plugins as $pluginName => $plugin)
+ {
+ $updater->addComponentToCheck($pluginName, $plugin->getVersion());
+ }
+
+ $componentsWithUpdateFile = $updater->getComponentsWithUpdateFile();
+ if(count($componentsWithUpdateFile) == 0)
+ {
+ return;
+ }
+
+ require_once "CoreUpdater/Controller.php";
+ $updaterController = new Piwik_CoreUpdater_Controller();
+ $updaterController->runUpdaterAndExit($componentsWithUpdateFile);
+ }
+
/**
* Sends http request ensuring the request will fail before $timeout seconds
* Returns the response content (no header, trimmed)
diff --git a/core/Url.php b/core/Url.php
index 27b57310ec..c1fca7f647 100644
--- a/core/Url.php
+++ b/core/Url.php
@@ -165,14 +165,28 @@ class Piwik_Url
static function getCurrentQueryStringWithParametersModified( $params )
{
$urlValues = self::getArrayFromCurrentQueryString();
-
foreach($params as $key => $value)
{
$urlValues[$key] = $value;
}
-
+ $query = self::getQueryStringFromParameters($urlValues);
+ if(strlen($query) > 0)
+ {
+ return '?'.$query;
+ }
+ return '';
+ }
+
+ /**
+ * Given an array of parameters name->value, returns the query string.
+ * Also works with array values using the php array syntax for GET parameters.
+ * @param $parameters eg. array( 'param1' => 10, 'param2' => array(1,2))
+ * @return string eg. "param1=10&param2[]=1&param2[]=2"
+ */
+ static public function getQueryStringFromParameters($parameters)
+ {
$query = '';
- foreach($urlValues as $name => $value)
+ foreach($parameters as $name => $value)
{
if(empty($value))
{
@@ -191,15 +205,7 @@ class Piwik_Url
}
}
$query = substr($query, 0, -1);
-
- if(strlen($query) > 0)
- {
- return '?'.$query;
- }
- else
- {
- return '';
- }
+ return $query;
}
/**
diff --git a/core/ViewDataTable.php b/core/ViewDataTable.php
index 0321171ba9..df329b585f 100644
--- a/core/ViewDataTable.php
+++ b/core/ViewDataTable.php
@@ -251,8 +251,10 @@ abstract class Piwik_ViewDataTable
$this->viewProperties['show_goals'] = false;
$this->viewProperties['show_search'] = Piwik_Common::getRequestVar('show_search', true);
+ $this->viewProperties['show_table'] = Piwik_Common::getRequestVar('show_table', true);
$this->viewProperties['show_table_all_columns'] = Piwik_Common::getRequestVar('show_table_all_columns', true);
$this->viewProperties['show_all_views_icons'] = Piwik_Common::getRequestVar('show_all_views_icons', true);
+ $this->viewProperties['show_export_as_image_icon'] = Piwik_Common::getRequestVar('show_export_as_image_icon', false);
$this->viewProperties['show_exclude_low_population'] = Piwik_Common::getRequestVar('show_exclude_low_population', true);
$this->viewProperties['show_offset_information'] = Piwik_Common::getRequestVar('show_offset_information', true);;
$this->viewProperties['show_footer'] = Piwik_Common::getRequestVar('show_footer', true);
@@ -368,8 +370,6 @@ abstract class Piwik_ViewDataTable
'filter_excludelowpop_value',
'filter_column',
'filter_pattern',
- 'filter_exact_pattern',
- 'filter_exact_column',
'disable_generic_filters',
'disable_queued_filters'
);
@@ -666,6 +666,15 @@ abstract class Piwik_ViewDataTable
}
/**
+ * Whether or not to show the "View table" icon
+ * @return void
+ */
+ public function disableShowTable()
+ {
+ $this->viewProperties['show_table'] = false;
+ }
+
+ /**
* Whether or not to show the "View more data" icon
* @return void
*/
@@ -696,19 +705,6 @@ abstract class Piwik_ViewDataTable
}
/**
- * Sets the pattern to look for in the table (only rows with column equal to the pattern will be kept)
- *
- * @param array $pattern arrays of patterns to look for
- * @param string $column to compare the pattern to
- * @return void
- */
- public function setExactPattern($pattern, $column)
- {
- $this->variablesDefault['filter_exact_pattern'] = $pattern;
- $this->variablesDefault['filter_exact_column'] = $column;
- }
-
- /**
* Sets the value to use for the Exclude low population filter.
*
* @param int|float If a row value is less than this value, it will be removed from the dataTable
diff --git a/core/ViewDataTable/Cloud.php b/core/ViewDataTable/Cloud.php
index c5fc45a67e..8c3d93a5f0 100644
--- a/core/ViewDataTable/Cloud.php
+++ b/core/ViewDataTable/Cloud.php
@@ -22,9 +22,9 @@ class Piwik_ViewDataTable_Cloud extends Piwik_ViewDataTable
{
protected $displayLogoInsteadOfLabel = false;
- public function displayLogoInTagCloud()
+ public function setDisplayLogoInTagCloud($bool)
{
- $this->displayLogoInsteadOfLabel = true;
+ $this->displayLogoInsteadOfLabel = $bool;
}
protected function getViewDataTableId()
@@ -79,6 +79,7 @@ class Piwik_ViewDataTable_Cloud extends Piwik_ViewDataTable
$columnTranslation = $this->getColumnTranslation($columnToDisplay);
$values = $this->dataTable->getColumn($columnToDisplay);
$labels = $this->dataTable->getColumn('label');
+ $labelMetadata = array();
foreach($this->dataTable->getRows() as $row)
{
$logo = false;
diff --git a/core/ViewDataTable/GenerateGraphData.php b/core/ViewDataTable/GenerateGraphData.php
index af61510bac..a197a88bf8 100644
--- a/core/ViewDataTable/GenerateGraphData.php
+++ b/core/ViewDataTable/GenerateGraphData.php
@@ -59,11 +59,27 @@ abstract class Piwik_ViewDataTable_GenerateGraphData extends Piwik_ViewDataTable
*
* @return int
*/
- function getGraphLimit()
+ public function getGraphLimit()
{
return $this->graphLimit;
}
+ protected $displayPercentageInTooltip = true;
+
+ /**
+ * The percentage in tooltips is computed based on the sum of all values for the plotted column.
+ * If the sum of the column in the data set is not the number of elements in the data set,
+ * for example when plotting visits that have a given plugin enabled:
+ * one visit can have several plugins, hence the sum is much greater than the number of visits.
+ * In this case displaying the percentage doesn't make sense.
+ *
+ * @return void
+ */
+ public function disallowPercentageInGraphTooltip()
+ {
+ $this->displayPercentageInTooltip = false;
+ }
+
public function main()
{
if($this->mainAlreadyExecuted)
@@ -74,7 +90,6 @@ abstract class Piwik_ViewDataTable_GenerateGraphData extends Piwik_ViewDataTable
// the queued filters will be manually applied later. This is to ensure that filtering using search
// will be done on the table before the labels are enhanced (see ReplaceColumnNames)
- $this->disableGenericFilters();
$this->disableQueuedFilters();
$this->loadDataTableFromAPI();
@@ -97,14 +112,12 @@ abstract class Piwik_ViewDataTable_GenerateGraphData extends Piwik_ViewDataTable
}
else
{
- $this->generateDataFromDataTable();
+ $this->initChartObjectData();
}
- //TODO rename
- $this->view->customizeGraph();
+ $this->view->customizeChartProperties();
}
- //TODO rename
- protected function generateDataFromDataTable()
+ protected function initChartObjectData()
{
$this->dataTable->applyQueuedFilters();
@@ -118,16 +131,16 @@ abstract class Piwik_ViewDataTable_GenerateGraphData extends Piwik_ViewDataTable
unset($columnNames[$labelColumnFound]);
}
- $columnNameToTranslation = $columnNameToValue = $columnNameToUnit = array();
+ $columnNameToTranslation = $columnNameToValue = array();
foreach($columnNames as $columnName)
{
$columnNameToTranslation[$columnName] = $this->getColumnTranslation($columnName);
$columnNameToValue[$columnName] = $this->dataTable->getColumn($columnName);
- $columnNameToUnit[$columnName] = $this->yAxisUnit;
}
$this->view->setAxisXLabels($xLabels);
$this->view->setAxisYValues($columnNameToValue);
$this->view->setAxisYLabels($columnNameToTranslation);
- $this->view->setAxisYUnits($columnNameToUnit);
+ $this->view->setAxisYUnit($this->yAxisUnit);
+ $this->view->setDisplayPercentageInTooltip($this->displayPercentageInTooltip);
}
}
diff --git a/core/ViewDataTable/GenerateGraphData/ChartEvolution.php b/core/ViewDataTable/GenerateGraphData/ChartEvolution.php
index dc4eab30c0..6e950a1ada 100644
--- a/core/ViewDataTable/GenerateGraphData/ChartEvolution.php
+++ b/core/ViewDataTable/GenerateGraphData/ChartEvolution.php
@@ -19,13 +19,32 @@ class Piwik_ViewDataTable_GenerateGraphData_ChartEvolution extends Piwik_ViewDat
$this->view = new Piwik_Visualization_Chart_Evolution;
}
- protected function generateDataFromDataTable()
+ protected function guessUnitFromRequestedColumnNames($requestedColumnNames)
+ {
+ $nameToUnit = array(
+ '_rate' => '%',
+ '_revenue' => Piwik::getCurrency(),
+ );
+ foreach($requestedColumnNames as $columnName)
+ {
+ foreach($nameToUnit as $pattern => $type)
+ {
+ if(strpos($columnName, $pattern) !== false)
+ {
+ return $type;
+ }
+ }
+ }
+ return false;
+ }
+
+ protected function initChartObjectData()
{
// if the loaded datatable is a simple DataTable, it is most likely a plugin plotting some custom data
// we don't expect plugin developers to return a well defined Piwik_DataTable_Array
if($this->dataTable instanceof Piwik_DataTable)
{
- return parent::generateDataFromDataTable();
+ return parent::initChartObjectData();
}
$this->dataTable->applyQueuedFilters();
@@ -33,42 +52,53 @@ class Piwik_ViewDataTable_GenerateGraphData_ChartEvolution extends Piwik_ViewDat
{
throw new Exception("Expecting a DataTable_Array with custom format to draw an evolution chart");
}
+
+ // the X label is extracted from the 'period' object in the table's metadata
$xLabels = $uniqueIdsDataTable = array();
foreach($this->dataTable->metadata as $idDataTable => $metadataDataTable)
{
+ //eg. "Aug 2009"
$xLabels[] = $metadataDataTable['period']->getLocalizedShortString();
+ // we keep track of all unique data table that we need to set a Y value for
$uniqueIdsDataTable[] = $idDataTable;
}
- // list of column names requested to be plotted, we only need to forward these to the Graph object
- $columnNameRequested = $this->getColumnsToDisplay();
-
- $columnNameToValue = array();
+ $requestedColumnNames = $this->getColumnsToDisplay();
+ $yAxisLabelToValue = array();
foreach($this->dataTable->getArray() as $idDataTable => $dataTable)
{
- if($dataTable->getRowsCount() > 1)
+ foreach($dataTable->getRows() as $row)
{
- throw new Exception("Expecting only one row per DataTable");
- }
- $row = $dataTable->getFirstRow();
- if($row !== false)
- {
- foreach($row->getColumns() as $columnName => $columnValue)
+ $rowLabel = $row->getColumn('label');
+ foreach($requestedColumnNames as $requestedColumnName)
{
- if(array_search($columnName, $columnNameRequested) !== false)
+ $metricLabel = $this->getColumnTranslation($requestedColumnName);
+ if($rowLabel !== false)
+ {
+ // eg. "Yahoo! (Visits)"
+ $yAxisLabel = "$rowLabel ($metricLabel)";
+ }
+ else
{
- $columnNameToValue[$columnName][$idDataTable] = $columnValue;
+ // eg. "Visits"
+ $yAxisLabel = $metricLabel;
+ }
+ if(($columnValue = $row->getColumn($requestedColumnName)) !== false)
+ {
+ $yAxisLabelToValue[$yAxisLabel][$idDataTable] = $columnValue;
}
}
}
}
- // make sure all column values are set (at least zero) in order for all unique idDataTable
- $columnNameToValueCleaned = array();
+ // make sure all column values are set to at least zero (no gap in the graph)
+ $yAxisLabelToValueCleaned = array();
+ $yAxisLabels = array();
foreach($uniqueIdsDataTable as $uniqueIdDataTable)
{
- foreach($columnNameToValue as $columnName => $idDataTableToColumnValue)
+ foreach($yAxisLabelToValue as $yAxisLabel => $idDataTableToColumnValue)
{
+ $yAxisLabels[$yAxisLabel] = $yAxisLabel;
if(isset($idDataTableToColumnValue[$uniqueIdDataTable]))
{
$columnValue = $idDataTableToColumnValue[$uniqueIdDataTable];
@@ -77,43 +107,20 @@ class Piwik_ViewDataTable_GenerateGraphData_ChartEvolution extends Piwik_ViewDat
{
$columnValue = 0;
}
- $columnNameToValueCleaned[$columnName][] = $columnValue;
+ $yAxisLabelToValueCleaned[$yAxisLabel][] = $columnValue;
}
}
- $columnNames = array_keys($columnNameToValueCleaned);
- $columnNameToTranslation = array();
- $columnNameToUnit = array();
- $nameToUnit = array(
- '_rate' => '%',
- '_revenue' => Piwik::getCurrency(),
- );
- foreach($columnNames as $columnName)
+
+ $unit = $this->yAxisUnit;
+ if(empty($unit))
{
- $columnNameToTranslation[$columnName] = $this->getColumnTranslation($columnName);
-
- $columnNameToUnit[$columnName] = false;
- // if the unit was specified, we use it
- if(!empty($this->yAxisUnit))
- {
- $columnNameToUnit[$columnName] = $this->yAxisUnit;
- }
- // otherwise we guess the unit from the column name
- else
- {
- foreach($nameToUnit as $pattern => $type)
- {
- if(strpos($columnName, $pattern) !== false)
- {
- $columnNameToUnit[$columnName] = $type;
- break;
- }
- }
- }
+ $unit = $this->guessUnitFromRequestedColumnNames($requestedColumnNames);
}
+
$this->view->setAxisXLabels($xLabels);
- $this->view->setAxisYValues($columnNameToValueCleaned);
- $this->view->setAxisYLabels($columnNameToTranslation);
- $this->view->setAxisYUnits($columnNameToUnit);
+ $this->view->setAxisYValues($yAxisLabelToValueCleaned);
+ $this->view->setAxisYLabels($yAxisLabels);
+ $this->view->setAxisYUnit($unit);
$firstDatatable = reset($this->dataTable->metadata);
$period = $firstDatatable['period'];
@@ -134,14 +141,14 @@ class Piwik_ViewDataTable_GenerateGraphData_ChartEvolution extends Piwik_ViewDat
$period = $metadataDataTable['period'];
$dateInUrl = $period->getDateStart();
$link = Piwik_Url::getCurrentUrlWithoutQueryString() .
- Piwik_Url::getCurrentQueryStringWithParametersModified( array(
- 'date' => $dateInUrl,
+ '?' .
+ Piwik_Url::getQueryStringFromParameters( array(
'module' => 'CoreHome',
'action' => 'index',
- 'viewDataTable' => null, // we reset the viewDataTable parameter (useless in the link)
- 'idGoal' => null, // we reset idGoal
- 'columns' => null,
- ));
+ 'idSite' => Piwik_Common::getRequestVar('idSite'),
+ 'period' => $period->getLabel(),
+ 'date' => $dateInUrl,
+ ));
$axisXOnClick[] = $link;
}
$this->view->setAxisXOnClick($axisXOnClick);
diff --git a/core/ViewDataTable/GenerateGraphHTML.php b/core/ViewDataTable/GenerateGraphHTML.php
index 0523531a82..445824f98e 100644
--- a/core/ViewDataTable/GenerateGraphHTML.php
+++ b/core/ViewDataTable/GenerateGraphHTML.php
@@ -38,6 +38,8 @@ abstract class Piwik_ViewDataTable_GenerateGraphHTML extends Piwik_ViewDataTable
$this->disableOffsetInformation();
$this->disableExcludeLowPopulation();
$this->disableSearchBox();
+ $this->enableShowExportAsImageIcon();
+
$this->parametersToModify = array(
'viewDataTable' => $this->getViewDataTableIdToLoad(),
// in the case this controller is being executed by another controller
@@ -48,6 +50,11 @@ abstract class Piwik_ViewDataTable_GenerateGraphHTML extends Piwik_ViewDataTable
);
}
+ public function enableShowExportAsImageIcon()
+ {
+ $this->viewProperties['show_export_as_image_icon'] = true;
+ }
+
/**
* Sets parameters to modify in the future generated URL
* @param array $array array('nameParameter' => $newValue, ...)
@@ -58,6 +65,15 @@ abstract class Piwik_ViewDataTable_GenerateGraphHTML extends Piwik_ViewDataTable
}
/**
+ * We persist the parametersToModify values in the javascript footer.
+ * This is used by the "export links" that use the "date" attribute from the json properties array in the datatable footer.
+ */
+ protected function getJavascriptVariablesToSet()
+ {
+ return $this->parametersToModify + parent::getJavascriptVariablesToSet();
+ }
+
+ /**
* @see Piwik_ViewDataTable::main()
*/
public function main()
@@ -76,61 +92,73 @@ abstract class Piwik_ViewDataTable_GenerateGraphHTML extends Piwik_ViewDataTable
$view = new Piwik_View($this->dataTableTemplate);
$this->uniqueIdViewDataTable = $this->getUniqueIdViewDataTable();
$view->graphType = $this->graphType;
+ $this->chartDivId = $this->uniqueIdViewDataTable . "Chart_swf";
$this->parametersToModify['action'] = $this->currentControllerAction;
+ $this->parametersToModify = array_merge($this->variablesDefault, $this->parametersToModify);
+
$url = Piwik_Url::getCurrentQueryStringWithParametersModified($this->parametersToModify);
$view->jsInvocationTag = $this->getFlashInvocationCode($url);
$view->urlGraphData = $url;
-
+ $view->chartDivId = $this->chartDivId;
$view->formEmbedId = "formEmbed".$this->uniqueIdViewDataTable;
- $view->graphCodeEmbed = $this->graphCodeEmbed;
-
$view->javascriptVariablesToSet = $this->getJavascriptVariablesToSet();
$view->properties = $this->getViewProperties();
return $view;
}
- protected function getFlashInvocationCode( $url = 'libs/open-flash-chart/data-files/nodata.txt', $use_swfobject = true )
+ protected function getFlashInvocationCode( $url = 'libs/open-flash-chart/data-files/nodata.txt' )
{
$width = $this->width;
$height = $this->height;
- $libPathInPiwik = 'libs/open-flash-chart/';
$currentPath = Piwik_Url::getCurrentUrlWithoutFileName();
- $pathToLibraryOpenChart = $currentPath . $libPathInPiwik;
+ $pathToLibraryOpenChart = $currentPath . 'libs/open-flash-chart/';
+ $pathToLibrarySwfObject = $currentPath . 'libs/swfobject/';
$url = Piwik_Url::getCurrentUrlWithoutQueryString() . $url;
// escape the & and stuff:
$url = urlencode($url);
- $obj_id = $this->uniqueIdViewDataTable . "Chart";
- $div_name = $this->uniqueIdViewDataTable . "FlashContent";
- $return = '';
- if( $use_swfobject )
- {
- // Using library for auto-enabling Flash object on IE, disabled-Javascript proof
- $return .= '
-<div id="'. $div_name .'"><div id="'. $obj_id .'_swf"><noscript>';
- }
- $urlGraph = $pathToLibraryOpenChart."open-flash-chart.swf?data=" . $url;
-
- // when the object/embed is changed, see also widgetize.js; it may require a logic update
- $this->graphCodeEmbed .= '<div><object classid="clsid:d27cdb6e-ae6d-11cf-96b8-444553540000" codebase="http://fpdownload.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=9,0,0,0" width="' . $width . '" height="' . $height . '" id="'. $obj_id .'" >
-<param name="movie" value="'.$urlGraph.'" />
-<param name="wmode" value="opaque" />
-<param name="allowScriptAccess" value="sameDomain" />
-<embed src="'.$urlGraph.'" wmode="opaque" allowScriptAccess="sameDomain" quality="high" bgcolor="#FFFFFF" width="'. $width .'" height="'. $height .'" name="open-flash-chart" type="application/x-shockwave-flash" id="'. $obj_id .'" />
-</object></div>';
- $return .= $this->graphCodeEmbed;
- if( $use_swfobject )
- {
- $return .= '
-</noscript></div></div>
-<script type="text/javascript">
-swfobject.embedSWF("'.$pathToLibraryOpenChart.'open-flash-chart.swf", "'. $obj_id .'_swf", "'. $width . '", "' . $height . '", "9.0.0", false, {"data-file":"'.$url.'"}, {"allowScriptAccess":"sameDomain","wmode":"opaque"}, {"bgcolor":"#FFFFFF"});
-</script>';
- }
+ $requiredFlashVersion = "9.0.0";
+ // - Export as Image feature from Open Flash Chart
+ // - Using library for auto-enabling Flash object on IE, disabled-Javascript proof
+ $return = '
+ <div id="'. $this->chartDivId .'">Displaying Graphs in Piwik requires Flash >= '.$requiredFlashVersion.'. <a target="_blank" href="misc/redirectToUrl.php?url=http://piwik.org/faq/troubleshooting/#faq_53">More information about displaying graphs in Piwik.</a></div>
+ <script type="text/javascript">
+ OFC = {};
+ OFC.jquery = {
+ name: "jQuery",
+ rasterize: function (src, dst) { $("#"+ dst).replaceWith(Control.OFC.image(src)) },
+ image: function(src) { return "<img title=\'Piwik Graph\' src=\'data:image/png;base64," + $("#"+src)[0].get_img_binary() + "\' />"},
+ popup: function(src) {
+ var img_win = window.open("", "Charts: Export as Image")
+ with(img_win.document) {
+ write("<html><head><title>'.Piwik_Translate('General_ExportAsImage').'<\/title><\/head><body>" + Control.OFC.image(src) + "<br><br><p>'.htmlentities(Piwik_Translate('General_SaveImageOnYourComputer')).'</p><\/body><\/html>") }
+ }
+ }
+ if (typeof(Control == "undefined")) {var Control = {OFC: OFC.jquery}}
+ // By default, right-clicking on OFC and choosing "save image locally" calls this function.
+ function save_image() { OFC.jquery.popup("'.$this->chartDivId.'") }
+
+ swfobject.embedSWF(
+ "'.$pathToLibraryOpenChart.'open-flash-chart.swf",
+ "'. $this->chartDivId .'",
+ "'. $width . '", "' . $height . '",
+ "'.$requiredFlashVersion.'",
+ "'.$pathToLibrarySwfObject.'expressInstall.swf",
+ {
+ "data-file":"'.$url.'",
+ "loading":"'.htmlspecialchars(Piwik_Translate('General_Loading')).'"
+ },
+ {
+ "allowScriptAccess":"sameDomain",
+ "wmode":"opaque"
+ },
+ {"bgcolor":"#FFFFFF"}
+ );
+ </script>';
return $return;
}
}
diff --git a/core/ViewDataTable/GenerateGraphHTML/ChartEvolution.php b/core/ViewDataTable/GenerateGraphHTML/ChartEvolution.php
index 77082e99f9..8729a452f4 100644
--- a/core/ViewDataTable/GenerateGraphHTML/ChartEvolution.php
+++ b/core/ViewDataTable/GenerateGraphHTML/ChartEvolution.php
@@ -35,7 +35,8 @@ class Piwik_ViewDataTable_GenerateGraphHTML_ChartEvolution extends Piwik_ViewDat
$apiMethodToRequestDataTable );
$this->setParametersToModify(array('date' => Piwik_Common::getRequestVar('date', 'last30', 'string')));
- $this->disableFooter();
+ $this->disableShowAllViewsIcons();
+ $this->disableShowTable();
}
/**
@@ -46,6 +47,10 @@ class Piwik_ViewDataTable_GenerateGraphHTML_ChartEvolution extends Piwik_ViewDat
*/
public function setColumnsToDisplay( $columnsNames)
{
+ if(!is_array($columnsNames))
+ {
+ $columnsNames = array($columnsNames);
+ }
$this->setParametersToModify( array('columns' => $columnsNames) );
}
}
diff --git a/core/ViewDataTable/HtmlTable.php b/core/ViewDataTable/HtmlTable.php
index cfd079da48..f3dab41d5f 100644
--- a/core/ViewDataTable/HtmlTable.php
+++ b/core/ViewDataTable/HtmlTable.php
@@ -48,7 +48,8 @@ class Piwik_ViewDataTable_HtmlTable extends Piwik_ViewDataTable
$controllerActionCalledWhenRequestSubTable);
$this->dataTableTemplate = 'CoreHome/templates/datatable.tpl';
$this->variablesDefault['enable_sort'] = '1';
-
+ $this->setSortedColumn('nb_visits', 'desc');
+ $this->setLimit(Zend_Registry::get('config')->General->datatable_default_limit);
$this->handleLowPopulation();
}
diff --git a/core/ViewDataTable/Sparkline.php b/core/ViewDataTable/Sparkline.php
index 4a2d0c1514..3ada3c5fbe 100644
--- a/core/ViewDataTable/Sparkline.php
+++ b/core/ViewDataTable/Sparkline.php
@@ -34,7 +34,6 @@ class Piwik_ViewDataTable_Sparkline extends Piwik_ViewDataTable
}
$this->mainAlreadyExecuted = true;
- $this->disableGenericFilters();
$this->loadDataTableFromAPI();
$this->isDataAvailable = $this->dataTable->getRowsCount() != 0;
diff --git a/core/Visualization/Chart.php b/core/Visualization/Chart.php
index 9a1ca5ebc2..f51e308519 100644
--- a/core/Visualization/Chart.php
+++ b/core/Visualization/Chart.php
@@ -29,7 +29,11 @@ abstract class Piwik_Visualization_Chart implements Piwik_iView
protected $yLabels = array();
protected $yValues = array();
- protected $yUnits = array();
+ protected $yUnit = '';
+
+ protected $maxValue;
+ protected $minValue;
+ protected $displayPercentageInTooltip = true;
function __construct()
{
@@ -51,9 +55,12 @@ abstract class Piwik_Visualization_Chart implements Piwik_iView
$this->yValues = $values;
}
- function setAxisYUnits($yUnits)
+ function setAxisYUnit($yUnit)
{
- $this->yUnits = $yUnits;
+ if(!empty($yUnit))
+ {
+ $this->yUnit = $yUnit;
+ }
}
public function setAxisYLabels($labels)
@@ -61,6 +68,11 @@ abstract class Piwik_Visualization_Chart implements Piwik_iView
$this->yLabels = $labels;
}
+ public function setDisplayPercentageInTooltip($bool)
+ {
+ $this->displayPercentageInTooltip = $bool;
+ }
+
//TODO call + make sure matches beginning of period? (hard..)
// day -> every 7 days
@@ -115,7 +127,7 @@ abstract class Piwik_Visualization_Chart implements Piwik_iView
return $this->chart->toPrettyString();
}
- function customizeGraph()
+ function customizeChartProperties()
{
$this->chart->set_number_format($num_decimals = 0,
$is_fixed_num_decimals_forced = true,
@@ -124,8 +136,8 @@ abstract class Piwik_Visualization_Chart implements Piwik_iView
$gridColour = '#E0E1E4';
$countValues = count($this->xLabels);
- $maxValue = $this->getMaxValue();
- $minValue = 0;
+ $this->maxValue = $this->getMaxValue();
+ $this->minValue = 0;
// X Axis
$this->x = new x_axis();
@@ -154,21 +166,17 @@ abstract class Piwik_Visualization_Chart implements Piwik_iView
$this->y->set_colour('#ffffff');
$this->y->set_grid_colour($gridColour);
$stepsCount = 2;
- $stepsEveryNLabel = ceil(($maxValue - $minValue) / $stepsCount);
- if($maxValue == 0)
+ $stepsEveryNLabel = ceil(($this->maxValue - $this->minValue) / $stepsCount);
+ if($this->maxValue == 0)
{
- $maxValue = 1;
+ $this->maxValue = 1;
}
- $this->y->set_range( $minValue, $maxValue, $stepsEveryNLabel);
+ $this->y->set_range( $this->minValue, $this->maxValue, $stepsEveryNLabel);
$dataSetsToDisplay = $this->getDataSetsToDisplay();
if($dataSetsToDisplay != false)
{
$dataSetToDisplay = current($dataSetsToDisplay);
- if(isset($this->yUnits[$dataSetToDisplay]))
- {
- $unit = $this->yUnits[$dataSetToDisplay];
- $this->y->set_label_text("#val#$unit");
- }
+ $this->y->set_label_text("#val#".$this->yUnit);
}
// Tooltip
diff --git a/core/Visualization/Chart/Evolution.php b/core/Visualization/Chart/Evolution.php
index 314acbffd9..3b28fa3d4c 100644
--- a/core/Visualization/Chart/Evolution.php
+++ b/core/Visualization/Chart/Evolution.php
@@ -18,9 +18,9 @@ require_once "Visualization/Chart.php";
*/
class Piwik_Visualization_Chart_Evolution extends Piwik_Visualization_Chart
{
- function customizeGraph()
+ function customizeChartProperties()
{
- parent::customizeGraph();
+ parent::customizeChartProperties();
$dataSetsToDisplay = $this->getDataSetsToDisplay();
if($dataSetsToDisplay === false)
{
@@ -61,18 +61,14 @@ class Piwik_Visualization_Chart_Evolution extends Piwik_Visualization_Chart
$lineValues = array();
$j = 0;
foreach($this->xLabels as $label) {
- $value = $yValues[$j];
+ $value = (float)$yValues[$j];
$lineValue = new hollow_dot($value);
- $unit = '';
- if(!empty($this->yUnits[$dataSetToDisplay]))
- {
- $unit = $this->yUnits[$dataSetToDisplay];
- }
+ $unit = $this->yUnit;
$lineValue->tooltip("$label<br>$value$unit $labelName");
if(!empty($this->xOnClick))
{
- $lineValue->on_click('redirectToUrl("'.$this->xOnClick[$j].'")');
+ $lineValue->on_click('piwikHelper.redirectToUrl("'.$this->xOnClick[$j].'")');
}
$lineValues[] = $lineValue;
$j++;
@@ -87,8 +83,8 @@ class Piwik_Visualization_Chart_Evolution extends Piwik_Visualization_Chart
}
// if one column is a percentage we set the grid accordingly
// note: it is invalid to plot a percentage dataset along with a numeric dataset
- //TODO only if the max was 100!!
- if(array_search('%', $this->yUnits) !== false)
+ if($this->yUnit == '%'
+ && $this->maxValue > 90)
{
$this->y->set_range( 0, 100, 50);
}
diff --git a/core/Visualization/Chart/Pie.php b/core/Visualization/Chart/Pie.php
index 12effb7f6c..542770e6f4 100644
--- a/core/Visualization/Chart/Pie.php
+++ b/core/Visualization/Chart/Pie.php
@@ -28,9 +28,9 @@ class Piwik_Visualization_Chart_Pie extends Piwik_Visualization_Chart
return array_slice($dataSetsToDisplay, 0, 1);
}
- function customizeGraph()
+ function customizeChartProperties()
{
- parent::customizeGraph();
+ parent::customizeChartProperties();
$dataSetsToDisplay = $this->getDataSetsToDisplay();
if($dataSetsToDisplay === false)
{
@@ -49,12 +49,12 @@ class Piwik_Visualization_Chart_Pie extends Piwik_Visualization_Chart
// create the Pie values
$yValues = $this->yValues[$dataSetToDisplay];
$labelName = $this->yLabels[$dataSetToDisplay];
- $unit = @$this->yUnits[$dataSetToDisplay];
+ $unit = $this->yUnit;
$sum = array_sum($yValues);
$pieValues = array();
$i = 0;
foreach($this->xLabels as $label) {
- $value = $yValues[$i];
+ $value = (float)$yValues[$i];
$i++;
// we never plot empty pie slices (eg. visits by server time pie chart)
if($value <= 0) {
diff --git a/core/Visualization/Chart/VerticalBar.php b/core/Visualization/Chart/VerticalBar.php
index c9794f4f00..5dbd954bac 100644
--- a/core/Visualization/Chart/VerticalBar.php
+++ b/core/Visualization/Chart/VerticalBar.php
@@ -29,9 +29,9 @@ class Piwik_Visualization_Chart_VerticalBar extends Piwik_Visualization_Chart
return array_slice($dataSetsToDisplay, 0, 1);
}
- function customizeGraph()
+ function customizeChartProperties()
{
- parent::customizeGraph();
+ parent::customizeChartProperties();
$dataSetsToDisplay = $this->getDataSetsToDisplay();
if($dataSetsToDisplay === false)
{
@@ -52,13 +52,21 @@ class Piwik_Visualization_Chart_VerticalBar extends Piwik_Visualization_Chart
// create the bar values
$yValues = $this->yValues[$dataSetToDisplay];
$labelName = $this->yLabels[$dataSetToDisplay];
- $unit = @$this->yUnits[$dataSetToDisplay];
+ $unit = $this->yUnit;
$barValues = array();
$i = 0;
+ $sum = array_sum($yValues);
foreach($this->xLabels as $label) {
- $value = $yValues[$i];
+ $value = (float)$yValues[$i];
+
+ $displayPercentage = '';
+ if($this->displayPercentageInTooltip)
+ {
+ $percentage = round(100 * $value / $sum);
+ $displayPercentage = "($percentage%)";
+ }
$barValue = new bar_value($value);
- $barValue->set_tooltip("$label<br>$value$unit $labelName");
+ $barValue->set_tooltip("$label<br>$value$unit $labelName $displayPercentage");
$barValues[] = $barValue;
$i++;
}
diff --git a/core/Visualization/Cloud.php b/core/Visualization/Cloud.php
index 287c57d86c..b3d6d26719 100644
--- a/core/Visualization/Cloud.php
+++ b/core/Visualization/Cloud.php
@@ -44,6 +44,9 @@ class Piwik_Visualization_Cloud
{
$this->shuffleCloud();
$return = array();
+ if(empty($this->wordsArray)) {
+ return array();
+ }
$maxValue = max($this->wordsArray);
foreach ($this->wordsArray as $word => $popularity)
{
diff --git a/core/Visualization/Sparkline.php b/core/Visualization/Sparkline.php
index 5dba26696a..369f0b3e6c 100644
--- a/core/Visualization/Sparkline.php
+++ b/core/Visualization/Sparkline.php
@@ -69,7 +69,7 @@ class Piwik_Visualization_Sparkline implements Piwik_iView
$i++;
}
$sparkline->SetYMin(0);
- $sparkline->setYMax($max[1] + 1); // the +1 seems to be mandatory to not lose some pixels when value = max
+ $sparkline->setYMax($max[1] + 0.5); // the +0.5 seems to be mandatory to not lose some pixels when value = max
$sparkline->SetPadding( 3, 0, 2, 0);
$font = FONT_2;
// the -0.5 is a hack as the sparkline samping rendering is obviously slightly bugged
@@ -78,7 +78,9 @@ class Piwik_Visualization_Sparkline implements Piwik_iView
$sparkline->SetFeaturePoint($max[0] -0.5, $max[1], 'green', 5);
$sparkline->SetFeaturePoint($last[0] -0.5, $last[1], 'blue', 5);
$sparkline->SetLineSize(3); // for renderresampled, linesize is on virtual image
- $sparkline->RenderResampled($width, $height);
+ $ratio = 1;
+// var_dump($min);var_dump($max);var_dump($lasts);exit;
+ $sparkline->RenderResampled($width*$ratio, $height*$ratio);
$this->sparkline = $sparkline;
}
diff --git a/core/iView.php b/core/iView.php
index 04c93c6600..6c21b1e94f 100644
--- a/core/iView.php
+++ b/core/iView.php
@@ -10,18 +10,13 @@
*/
/**
- * Piwik_ViewDataTable must create a $view attribute which implements this interface.
- *
* @package Piwik_Visualization
*/
interface Piwik_iView
{
/**
* Outputs the data.
- * Either outputs html, xml, an image, nothing, etc.
- *
- * @return mixed
- *
+ * @return mixed (image, array, html...)
*/
function render();
}
diff --git a/lang/en.php b/lang/en.php
index 26e63e35ad..1f89a01aa2 100644
--- a/lang/en.php
+++ b/lang/en.php
@@ -26,6 +26,7 @@ $translations = array(
'General_Logout' => 'Sign out',
'General_Done' => 'Done',
'General_LoadingData' => 'Loading data...',
+ 'General_Loading' => 'Loading...',
'General_ErrorRequest' => 'Oops&hellip; problem during the request, please try again.',
'General_Next' => 'Next',
'General_Previous' => 'Previous',
@@ -36,6 +37,8 @@ $translations = array(
'General_TagCloud' => 'Tag Cloud',
'General_VBarGraph' => 'Vertical bar graph',
'General_Export' => 'Export',
+ 'General_ExportAsImage' => 'Export as Image',
+ 'General_SaveImageOnYourComputer' => 'To save the image on your computer, right click on the image and select "Save Image As..."',
'General_Refresh' => 'Refresh the page',
'General_Visitors' => 'Visitors',
'General_ColumnNbUniqVisitors' => 'Unique visitors',
diff --git a/libs/swfobject/expressInstall.swf b/libs/swfobject/expressInstall.swf
new file mode 100644
index 0000000000..86958bf3a7
--- /dev/null
+++ b/libs/swfobject/expressInstall.swf
Binary files differ
diff --git a/plugins/API/Controller.php b/plugins/API/Controller.php
index 8eb442cca1..29c1d64cd1 100644
--- a/plugins/API/Controller.php
+++ b/plugins/API/Controller.php
@@ -20,6 +20,11 @@ class Piwik_API_Controller extends Piwik_Controller
{
function index()
{
+ // when calling the API through http, we limit the number of returned results
+ if(!isset($_GET['filter_limit']))
+ {
+ $_GET['filter_limit'] = Zend_Registry::get('config')->General->API_datatable_default_limit;
+ }
$request = new Piwik_API_Request('token_auth='.Piwik_Common::getRequestVar('token_auth', 'anonymous', 'string'));
echo $request->process();
}
diff --git a/plugins/Actions/Controller.php b/plugins/Actions/Controller.php
index b3b7e13d42..9240161877 100644
--- a/plugins/Actions/Controller.php
+++ b/plugins/Actions/Controller.php
@@ -108,7 +108,6 @@ class Piwik_Actions_Controller extends Piwik_Controller
$view->setLimit( 100 );
$view->setColumnsToDisplay( array('label','nb_hits','nb_visits') );
- $view->setSortedColumn( 'nb_visits', 'desc' );
$view->setColumnTranslation('nb_hits', Piwik_Translate('General_ColumnPageviews'));
$view->setColumnTranslation('nb_visits', Piwik_Translate('General_ColumnUniquePageviews'));
@@ -143,7 +142,6 @@ class Piwik_Actions_Controller extends Piwik_Controller
$view->setColumnsToDisplay( array('label','nb_visits','nb_hits') );
$view->setColumnTranslation('nb_hits', Piwik_Translate('Actions_ColumnDownloads'));
$view->setColumnTranslation('nb_visits', Piwik_Translate('Actions_ColumnUniqueDownloads'));
- $view->setSortedColumn( 'nb_visits','desc' );
$view->disableExcludeLowPopulation();
$view->setLimit( 15 );
}
@@ -153,7 +151,6 @@ class Piwik_Actions_Controller extends Piwik_Controller
$view->setColumnsToDisplay( array('label','nb_visits','nb_hits') );
$view->setColumnTranslation('nb_hits', Piwik_Translate('Actions_ColumnClicks'));
$view->setColumnTranslation('nb_visits', Piwik_Translate('Actions_ColumnUniqueClicks'));
- $view->setSortedColumn( 'nb_visits','desc' );
$view->disableExcludeLowPopulation();
$view->setLimit( 15 );
}
diff --git a/plugins/CoreHome/templates/datatable.js b/plugins/CoreHome/templates/datatable.js
index 9dae015f58..a19e99424c 100644
--- a/plugins/CoreHome/templates/datatable.js
+++ b/plugins/CoreHome/templates/datatable.js
@@ -114,7 +114,7 @@ dataTable.prototype =
url: piwik.piwik_url + 'index.php',
dataType: 'html',
async: true,
- error: ajaxHandleError, // Callback when the request fails
+ error: piwikHelper.ajaxHandleError, // Callback when the request fails
success: callbackSuccess, // Callback when the request succeeds
data: new Object
};
@@ -178,7 +178,7 @@ dataTable.prototype =
else
{
dataTableSel.html( $(content).html() );
- lazyScrollTo(dataTableSel[0], 400);
+ piwikHelper.lazyScrollTo(dataTableSel[0], 400);
}
},
@@ -486,7 +486,7 @@ dataTable.prototype =
.click(
function(){
// we only reset the limit filter, in case switch to table view from cloud view where limit is custom set to 30
- // this value is stored in config file General->dataTable_default_limit but this is more an edge case so ok to set it to 10
+ // this value is stored in config file General->datatable_default_limit but this is more an edge case so ok to set it to 10
delete self.param.filter_limit;
delete self.param.enable_filter_excludelowpop;
self.param.viewDataTable = 'tableGoals';
@@ -499,7 +499,7 @@ dataTable.prototype =
.click(
function(){
// we only reset the limit filter, in case switch to table view from cloud view where limit is custom set to 30
- // this value is stored in config file General->dataTable_default_limit but this is more an edge case so ok to set it to 10
+ // this value is stored in config file General->datatable_default_limit but this is more an edge case so ok to set it to 10
delete self.param.filter_limit;
self.param.viewDataTable = self.param.viewDataTable == 'table' ? 'tableAllColumns' : 'table';
// when switching to display simple table, do not exclude low pop by default
@@ -953,7 +953,7 @@ actionDataTable.prototype =
var dataTableSel = $('#'+idToReplace);
dataTableSel.html($(content).html());
- lazyScrollTo(dataTableSel[0], 400);
+ piwikHelper.lazyScrollTo(dataTableSel[0], 400);
},
// Called when a set of rows for a category of actions is loaded
diff --git a/plugins/CoreHome/templates/datatable_footer.tpl b/plugins/CoreHome/templates/datatable_footer.tpl
index 6c3f3a0d06..0921b01523 100644
--- a/plugins/CoreHome/templates/datatable_footer.tpl
+++ b/plugins/CoreHome/templates/datatable_footer.tpl
@@ -20,32 +20,39 @@
<div>
<span id="dataTableFooterIcons">
<span id="exportToFormat" style="display:none;padding-left:4px;">
+ {if $properties.show_export_as_image_icon}
+ <span id="dataTableFooterExportAsImageIcon">
+ <a href="javascript:OFC.jquery.popup('{$chartDivId}');"><img title="{'General_ExportAsImage'|translate}" src="{$piwikUrl}themes/default/images/image.png" /></a>
+ </span>
+ {/if}
<img width="16" height="16" src="{$piwikUrl}themes/default/images/export.png" title="{'General_Export'|translate}" />
- <span id="linksExportToFormat" style="display:none;">
+ <span id="linksExportToFormat" style="display:none">
<a target="_blank" class="exportToFormat" methodToCall="{$properties.apiMethodToRequestDataTable}" format="CSV" filter_limit="100">CSV</a> |
<a target="_blank" class="exportToFormat" methodToCall="{$properties.apiMethodToRequestDataTable}" format="XML" filter_limit="100">XML</a> |
<a target="_blank" class="exportToFormat" methodToCall="{$properties.apiMethodToRequestDataTable}" format="JSON" filter_limit="100">Json</a> |
<a target="_blank" class="exportToFormat" methodToCall="{$properties.apiMethodToRequestDataTable}" format="PHP" filter_limit="100">Php</a> |
<a target="_blank" class="exportToFormat" methodToCall="{$properties.apiMethodToRequestDataTable}" format="RSS" filter_limit="100" date="last10"><img border="0" src="{$piwikUrl}themes/default/images/feed.png"></a>
</span>
- {if $properties.show_all_views_icons}
- <a class="viewDataTable" format="cloud"><img width="16" height="16" src="{$piwikUrl}themes/default/images/tagcloud.png" title="{'General_TagCloud'|translate}" /></a>
- <a class="viewDataTable" format="graphVerticalBar"><img width="16" height="16" src="{$piwikUrl}themes/default/images/chart_bar.png" title="{'General_VBarGraph'|translate}" /></a>
- <a class="viewDataTable" format="graphPie"><img width="16" height="16" src="{$piwikUrl}themes/default/images/chart_pie.png" title="{'General_Piechart'|translate}" /></a>
- {/if}
+ {if $properties.show_all_views_icons}
+ <a class="viewDataTable" format="cloud"><img width="16" height="16" src="{$piwikUrl}themes/default/images/tagcloud.png" title="{'General_TagCloud'|translate}" /></a>
+ <a class="viewDataTable" format="graphVerticalBar"><img width="16" height="16" src="{$piwikUrl}themes/default/images/chart_bar.png" title="{'General_VBarGraph'|translate}" /></a>
+ <a class="viewDataTable" format="graphPie"><img width="16" height="16" src="{$piwikUrl}themes/default/images/chart_pie.png" title="{'General_Piechart'|translate}" /></a>
+ {/if}
</span>
<span id="dataTableFooterIconsShow" style="display:none;padding-left:4px;">
<img src="{$piwikUrl}plugins/CoreHome/templates/images/more.png" />
</span>
- {if $properties.show_table_all_columns}
+
+ {if $properties.show_table}
<span id="tableAllColumnsSwitch" style="display:none;float:right;padding-right:4px;border-right:1px solid #82A1D2;">
{if $javascriptVariablesToSet.viewDataTable != 'table'}
<img title="{'General_DisplayNormalTable'|translate}" src="{$piwikUrl}themes/default/images/table.png" />
- {else}
+ {elseif $properties.show_table_all_columns}
<img title="{'General_DisplayMoreData'|translate}" src="{$piwikUrl}themes/default/images/table_more.png" />
{/if}
</span>
{/if}
+
{if $properties.show_goals}
<span id="tableGoals" style="display:none;float:right;padding-right:4px;">
{if $javascriptVariablesToSet.viewDataTable != 'tableGoals'}
diff --git a/plugins/CoreHome/templates/graph.tpl b/plugins/CoreHome/templates/graph.tpl
index 097090bc78..b0f827dcaf 100644
--- a/plugins/CoreHome/templates/graph.tpl
+++ b/plugins/CoreHome/templates/graph.tpl
@@ -1,7 +1,6 @@
<div id="{$properties.uniqueId}">
<div class="{if $graphType=='evolution'}dataTableGraphEvolutionWrapper{else}dataTableGraphWrapper{/if}">
{$jsInvocationTag}
-
{if $properties.show_footer}
{include file="CoreHome/templates/datatable_footer.tpl"}
{include file="CoreHome/templates/datatable_js.tpl"}
diff --git a/plugins/CoreHome/templates/menu.js b/plugins/CoreHome/templates/menu.js
index 5f0603c55f..9c4e00800d 100644
--- a/plugins/CoreHome/templates/menu.js
+++ b/plugins/CoreHome/templates/menu.js
@@ -18,7 +18,7 @@ menu.prototype =
customAjaxHandleError: function ()
{
menu.prototype.lastUrlRequested = null;
- ajaxHandleError();
+ piwikHelper.ajaxHandleError();
},
overMainLI: function ()
diff --git a/plugins/CoreHome/templates/sparkline.js b/plugins/CoreHome/templates/sparkline.js
index 5753235977..1d7712516e 100644
--- a/plugins/CoreHome/templates/sparkline.js
+++ b/plugins/CoreHome/templates/sparkline.js
@@ -15,8 +15,8 @@ $(document).ready( function(){
//on click, reload the graph with the new url
$(this).click( function() {
//get the main page graph and reload with new data
- findSWFGraph(graph.attr('graphId')+"Chart_swf").reload(url);
- lazyScrollTo(graph[0], 400);
+ piwikHelper.findSWFGraph(graph.attr('graphId')+"Chart_swf").reload(url);
+ piwikHelper.lazyScrollTo(graph[0], 400);
});
$(this).hover(
function() {
diff --git a/plugins/CoreUpdater/Controller.php b/plugins/CoreUpdater/Controller.php
index 613028b2a3..4d08d03bb4 100644
--- a/plugins/CoreUpdater/Controller.php
+++ b/plugins/CoreUpdater/Controller.php
@@ -1,14 +1,10 @@
<?php
-require_once "Updater.php";
-require_once "Version.php";
-
class Piwik_CoreUpdater_Controller extends Piwik_Controller
{
const CONFIG_FILE_BACKUP = '/config/global.ini.auto-backup-before-update.php';
const PATH_TO_EXTRACT_LATEST_VERSION = '/tmp/latest';
const LATEST_PIWIK_URL = 'http://piwik.org/latest.zip';
- private $componentsWithUpdateFile = array();
private $coreError = false;
private $warningMessages = array();
private $errorMessages = array();
@@ -59,26 +55,6 @@ class Piwik_CoreUpdater_Controller extends Piwik_Controller
$view->feedbackMessages = $messages;
echo $view->render();
}
-
- public function checkForCoreAndPluginsUpdates()
- {
- $this->updater = new Piwik_Updater();
- $this->updater->addComponentToCheck('core', Piwik_Version::VERSION);
-
- $plugins = Piwik_PluginsManager::getInstance()->getInstalledPlugins();
- foreach($plugins as $pluginName => $plugin)
- {
- $this->updater->addComponentToCheck($pluginName, $plugin->getVersion());
- }
-
- $this->componentsWithUpdateFile = $this->updater->getComponentsWithUpdateFile();
- if(count($this->componentsWithUpdateFile) == 0)
- {
- return;
- }
-
- $this->runUpdaterAndExit();
- }
private function checkNewVersionIsAvailableOrDie()
{
@@ -152,20 +128,20 @@ class Piwik_CoreUpdater_Controller extends Piwik_Controller
{
}
- private function runUpdaterAndExit()
+ private function runUpdaterAndExit($componentsWithUpdateFile)
{
if(Piwik_Common::getRequestVar('updateCorePlugins', 0, 'integer') == 1)
{
- $this->doExecuteUpdates();
+ $this->doExecuteUpdates($componentsWithUpdateFile);
}
else
{
- $this->doWelcomeUpdates();
+ $this->doWelcomeUpdates($componentsWithUpdateFile);
}
exit;
}
- private function doWelcomeUpdates()
+ private function doWelcomeUpdates($componentsWithUpdateFile)
{
$view = new Piwik_View('CoreUpdater/templates/update_welcome.tpl');
$view->new_piwik_version = Piwik_Version::VERSION;
@@ -178,7 +154,7 @@ class Piwik_CoreUpdater_Controller extends Piwik_Controller
$pluginNamesToUpdate = array();
$coreToUpdate = false;
- foreach($this->componentsWithUpdateFile as $name => $filenames)
+ foreach($componentsWithUpdateFile as $name => $filenames)
{
if($name == 'core')
{
@@ -195,9 +171,9 @@ class Piwik_CoreUpdater_Controller extends Piwik_Controller
echo $view->render();
}
- private function doExecuteUpdates()
+ private function doExecuteUpdates($componentsWithUpdateFile)
{
- $this->loadAndExecuteUpdateFiles();
+ $this->loadAndExecuteUpdateFiles($componentsWithUpdateFile);
$view = new Piwik_View('CoreUpdater/templates/update_database_done.tpl');
$view->coreError = $this->coreError;
@@ -213,7 +189,7 @@ class Piwik_CoreUpdater_Controller extends Piwik_Controller
// if errors in any plugins updates, show them on screen, disable plugins that errored + CONTINUE
// if warning in any core update or in any plugins update, show message + CONTINUE
// if no error or warning, success message + CONTINUE
- foreach($this->componentsWithUpdateFile as $name => $filenames)
+ foreach($componentsWithUpdateFile as $name => $filenames)
{
try {
$this->warningMessages = array_merge($this->warningMessages, $this->updater->update($name));
diff --git a/plugins/Dashboard/Controller.php b/plugins/Dashboard/Controller.php
index f270efaf0d..0ee2d6f8c0 100644
--- a/plugins/Dashboard/Controller.php
+++ b/plugins/Dashboard/Controller.php
@@ -24,7 +24,8 @@ class Piwik_Dashboard_Controller extends Piwik_Controller
$layout = html_entity_decode($this->getLayout());
if(strstr($layout, '[[') == false) {
$layout = "'$layout'";
- }
+ }
+ $view->layout = $layout;
$view->availableWidgets = json_encode(Piwik_GetWidgetsList());
return $view;
}
diff --git a/plugins/Dashboard/templates/Dashboard.js b/plugins/Dashboard/templates/Dashboard.js
index de12a8fcc6..c8c1aded31 100644
--- a/plugins/Dashboard/templates/Dashboard.js
+++ b/plugins/Dashboard/templates/Dashboard.js
@@ -221,7 +221,7 @@ dashboard.prototype =
url: 'index.php',
dataType: 'html',
async: true,
- error: ajaxHandleError,
+ error: piwikHelper.ajaxHandleError,
data: { "module": "Dashboard",
"action": "saveLayout",
"layout": layoutString
diff --git a/plugins/Dashboard/templates/index.tpl b/plugins/Dashboard/templates/index.tpl
index 0b2f8d044a..faf0a11323 100644
--- a/plugins/Dashboard/templates/index.tpl
+++ b/plugins/Dashboard/templates/index.tpl
@@ -25,7 +25,6 @@
]
];
{/literal}
-
{*
the old dashboard layout style is:
piwik.dashboardLayout = 'VisitsSummary.getEvolutionGraph~VisitorInterest.getNumberOfVisitsPerVisitDuration~UserSettings.getBrowser~ExampleFeedburner.feedburner|Referers.getKeywords~Referers.getWebsites|Referers.getSearchEngines~VisitTime.getVisitInformationPerServerTime~ExampleRssWidget.rssPiwik|';
diff --git a/plugins/Dashboard/templates/widgetMenu.js b/plugins/Dashboard/templates/widgetMenu.js
index 701056be78..d6e4a8e4aa 100644
--- a/plugins/Dashboard/templates/widgetMenu.js
+++ b/plugins/Dashboard/templates/widgetMenu.js
@@ -48,7 +48,7 @@ widgetsHelper.getLoadWidgetAjaxRequest = function (widgetUniqueId, widgetParamet
url: 'index.php',
dataType: 'html',
async: true,
- error: ajaxHandleError,
+ error: piwikHelper.ajaxHandleError,
success: onWidgetLoadedCallback,
data: piwikHelper.getQueryStringFromParameters(widgetParameters) + "&idSite="+piwik.idSite+"&period="+piwik.period+"&date="+piwik.currentDateString
};
diff --git a/plugins/ExampleUI/API.php b/plugins/ExampleUI/API.php
index 97f0ad8100..688fe6a00f 100644
--- a/plugins/ExampleUI/API.php
+++ b/plugins/ExampleUI/API.php
@@ -54,8 +54,8 @@ class Piwik_ExampleUI_API
function getTemperatures()
{
$xAxis = array(
- '12AM', '1AM', '2AM', '3AM', '4AM', '5AM', '6AM', '7AM', '8AM', '9AM', '10AM', '11AM',
- '12PM', '1PM', '2PM', '3PM', '4PM', '5PM', '6PM', '7PM', '8PM', '9PM', '10PM', '11PM',
+ '0h', '1h', '2h', '3h', '4h', '5h', '6h', '7h', '8h', '9h', '10h', '11h',
+ '12h', '13h', '14h', '15h', '16h', '17h', '18h', '19h', '20h', '21h', '22h', '23h',
);
$temperatureValues = array_slice(range(50,90), 0, count($xAxis));
shuffle($temperatureValues);
diff --git a/plugins/ExampleUI/Controller.php b/plugins/ExampleUI/Controller.php
index 92041a3fd5..ccf88bdaec 100644
--- a/plugins/ExampleUI/Controller.php
+++ b/plugins/ExampleUI/Controller.php
@@ -19,6 +19,7 @@ class Piwik_ExampleUI_Controller extends Piwik_Controller
$view = Piwik_ViewDataTable::factory('table');
$view->init( $this->pluginName, __FUNCTION__, 'ExampleUI.getTemperatures' );
$view->setColumnTranslation('value', "Temperature in °C");
+ $view->setSortedColumn('label', 'asc');
$view->setGraphLimit( 24 );
$view->setLimit( 24 );
$view->disableExcludeLowPopulation();
@@ -90,7 +91,7 @@ class Piwik_ExampleUI_Controller extends Piwik_Controller
{
$view = Piwik_ViewDataTable::factory('cloud');
$view->init( $this->pluginName, __FUNCTION__, 'ExampleUI.getPlanetRatiosWithLogos' );
- $view->displayLogoInTagCloud();
+ $view->setDisplayLogoInTagCloud(true);
$view->disableFooterExceptExportIcons();
$view->setColumnsToDisplay( array('label','value') );
$view->setColumnTranslation('value', "times the diameter of Earth");
@@ -118,8 +119,17 @@ class Piwik_ExampleUI_Controller extends Piwik_Controller
$this->renderView($view);
}
- function sparklinesWithEvolutionGraph()
+ function misc()
{
-
+ echo "<h2>Evolution graph filtered to Google and Yahoo!</h2>";
+ $this->echoDataTableSearchEnginesFiltered();
}
+
+ function echoDataTableSearchEnginesFiltered()
+ {
+ $view = $this->getLastUnitGraph($this->pluginName, __FUNCTION__, 'Referers.getSearchEngines');
+ $view->setColumnsToDisplay( 'nb_visits' );
+ $view->setSearchPattern('^(Google|Yahoo!)$', 'label');
+ return $this->renderView($view);
+ }
} \ No newline at end of file
diff --git a/plugins/ExampleUI/ExampleUI.php b/plugins/ExampleUI/ExampleUI.php
index 8ef1e8e15f..4f36f55782 100644
--- a/plugins/ExampleUI/ExampleUI.php
+++ b/plugins/ExampleUI/ExampleUI.php
@@ -50,7 +50,7 @@ class Piwik_ExampleUI extends Piwik_Plugin
'Pie graph' => 'pieGraph',
'Tag clouds' => 'tagClouds',
'Sparklines' => 'sparklines',
- 'Sparklines with evolution graph' => 'sparklinesWithEvolutionGraph',
+ 'Misc' => 'misc',
);
foreach($menus as $subMenu => $action)
{
diff --git a/plugins/Goals/templates/GoalForm.js b/plugins/Goals/templates/GoalForm.js
index a3f82154c5..48240a561f 100644
--- a/plugins/Goals/templates/GoalForm.js
+++ b/plugins/Goals/templates/GoalForm.js
@@ -84,8 +84,8 @@ function bindListGoalEdit()
}
function getAjaxDeleteGoal(idGoal)
{
- var ajaxRequest = getStandardAjaxConf();
- toggleAjaxLoading();
+ var ajaxRequest = piwikHelper.getStandardAjaxConf();
+ piwikHelper.toggleAjaxLoading();
var parameters = new Object;
parameters.idSite = piwik.idSite;
@@ -100,8 +100,8 @@ function getAjaxDeleteGoal(idGoal)
function getAjaxAddGoal()
{
- var ajaxRequest = getStandardAjaxConf();
- toggleAjaxLoading();
+ var ajaxRequest = piwikHelper.getStandardAjaxConf();
+ piwikHelper.toggleAjaxLoading();
var parameters = new Object;
diff --git a/plugins/Referers/Controller.php b/plugins/Referers/Controller.php
index ed120e09e4..6690f6ca36 100644
--- a/plugins/Referers/Controller.php
+++ b/plugins/Referers/Controller.php
@@ -178,20 +178,6 @@ class Piwik_Referers_Controller extends Piwik_Controller
return $this->renderView($view, $fetch);
}
-
- // TODO FIXME WITH NEW API
- // example of how to show evolution of a given column over multiple days
- public function getSearchEnginesEvolution($fetch = false)
- {
- $view = Piwik_ViewDataTable::factory('graphEvolution');
- $view->init( $this->pluginName, __FUNCTION__, 'Referers.getSearchEngines' );
-
- $view->setColumnsToDisplay( 'nb_visits' );
- $view->setExactPattern( array('Google','Yahoo!'), 'label');
-
- return $this->renderView($view, $fetch);
- }
-
protected function getReferersVisitorsByType()
{
// we disable the queued filters because here we want to get the visits coming from search engines
diff --git a/plugins/Referers/Referers.php b/plugins/Referers/Referers.php
index 8bf6446d0f..4c16fe7bf0 100644
--- a/plugins/Referers/Referers.php
+++ b/plugins/Referers/Referers.php
@@ -64,7 +64,6 @@ class Piwik_Referers extends Piwik_Plugin
Piwik_AddMenu('Referers_Referers', 'Referers_SubmenuSearchEngines', array('module' => 'Referers', 'action' => 'getSearchEnginesAndKeywords'));
Piwik_AddMenu('Referers_Referers', 'Referers_SubmenuWebsites', array('module' => 'Referers', 'action' => 'getWebsites'));
Piwik_AddMenu('Referers_Referers', 'Referers_SubmenuCampaigns', array('module' => 'Referers', 'action' => 'getCampaigns'));
- //Piwik_AddMenu('Referers_Referers', 'Referers_SubmenuEvolution', array('module' => 'Referers', 'action' => 'getSearchEnginesEvolution'));
}
function archivePeriod( $notification )
diff --git a/plugins/SitesManager/templates/SitesManager.js b/plugins/SitesManager/templates/SitesManager.js
index e21e7a2e2d..172340b9b3 100644
--- a/plugins/SitesManager/templates/SitesManager.js
+++ b/plugins/SitesManager/templates/SitesManager.js
@@ -1,7 +1,7 @@
function getDeleteSiteAJAX( idSite )
{
- var ajaxRequest = getStandardAjaxConf();
- toggleAjaxLoading();
+ var ajaxRequest = piwikHelper.getStandardAjaxConf();
+ piwikHelper.toggleAjaxLoading();
var parameters = new Object;
parameters.module = 'API';
@@ -17,8 +17,8 @@ function getDeleteSiteAJAX( idSite )
function getAddSiteAJAX( row )
{
- var ajaxRequest = getStandardAjaxConf();
- toggleAjaxLoading();
+ var ajaxRequest = piwikHelper.getStandardAjaxConf();
+ piwikHelper.toggleAjaxLoading();
var parameters = new Object;
var siteName = $(row).find('input[@id=siteadd_name]').val();
@@ -41,8 +41,8 @@ function getAddSiteAJAX( row )
function getUpdateSiteAJAX( row )
{
- var ajaxRequest = getStandardAjaxConf();
- toggleAjaxLoading();
+ var ajaxRequest = piwikHelper.getStandardAjaxConf();
+ piwikHelper.toggleAjaxLoading();
var siteName = $(row).find('input[@id=siteName]').val();
var idSite = $(row).children('#idSite').html();
@@ -65,7 +65,7 @@ function getUpdateSiteAJAX( row )
$(document).ready( function() {
$('.addRowSite').click( function() {
- ajaxHideError();
+ piwikHelper.ajaxHideError();
$(this).toggle();
var numberOfRows = $('table#editSites')[0].rows.length;
@@ -82,13 +82,13 @@ $(document).ready( function() {
;
$('#'+newRowId).keypress( submitSiteOnEnter );
$('.addsite').click( function(){ $.ajax( getAddSiteAJAX($('tr#'+newRowId)) ); } );
- $('.cancel').click(function() { ajaxHideError(); $(this).parents('tr').remove(); $('.addRowSite').toggle(); });
+ $('.cancel').click(function() { piwikHelper.ajaxHideError(); $(this).parents('tr').remove(); $('.addRowSite').toggle(); });
} );
// when click on deleteuser, the we ask for confirmation and then delete the user
$('.deleteSite').click( function() {
- ajaxHideError();
+ piwikHelper.ajaxHideError();
var idRow = $(this).attr('id');
var nameToDelete = $(this).parent().parent().find('#siteName').html();
var idsiteToDelete = $(this).parent().parent().find('#idSite').html();
@@ -101,7 +101,7 @@ $(document).ready( function() {
var alreadyEdited = new Array;
$('.editSite')
.click( function() {
- ajaxHideError();
+ piwikHelper.ajaxHideError();
var idRow = $(this).attr('id');
if(alreadyEdited[idRow]==1) return;
alreadyEdited[idRow] = 1;
diff --git a/plugins/UserCountry/Controller.php b/plugins/UserCountry/Controller.php
index a7fadc8b17..ad6b406323 100644
--- a/plugins/UserCountry/Controller.php
+++ b/plugins/UserCountry/Controller.php
@@ -59,6 +59,7 @@ class Piwik_UserCountry_Controller extends Piwik_Controller
function getLastDistinctCountriesGraph( $fetch = false )
{
$view = $this->getLastUnitGraph('UserCountry',__FUNCTION__, "UserCountry.getNumberOfDistinctCountries");
+ $view->setColumnsToDisplay('UserCountry_distinctCountries');
return $this->renderView($view, $fetch);
}
}
diff --git a/plugins/UserCountry/templates/index.tpl b/plugins/UserCountry/templates/index.tpl
index efea18c986..da9b84f503 100644
--- a/plugins/UserCountry/templates/index.tpl
+++ b/plugins/UserCountry/templates/index.tpl
@@ -8,7 +8,9 @@
<h2>{'UserCountry_Continent'|translate}</h2>
{$dataTableContinent}
-<p>{sparkline src=$urlSparklineCountries}<span>
-{'UserCountry_DistinctCountries'|translate:"<strong>$numberDistinctCountries</strong>"} </span></p>
+<div class="sparkline">
+ {sparkline src=$urlSparklineCountries}
+ {'UserCountry_DistinctCountries'|translate:"<strong>$numberDistinctCountries</strong>"}
+</div>
{postEvent name="template_footerUserCountry"}
diff --git a/plugins/UserSettings/Controller.php b/plugins/UserSettings/Controller.php
index f8306b39d0..eda8b076ba 100644
--- a/plugins/UserSettings/Controller.php
+++ b/plugins/UserSettings/Controller.php
@@ -85,12 +85,10 @@ class Piwik_UserSettings_Controller extends Piwik_Controller
$view->disableSort();
$view->disableOffsetInformation();
$view->disableShowAllColumns();
-
+ $view->disallowPercentageInGraphTooltip();
$view->setColumnsToDisplay( array('label','nb_visits') );
- $view->setSortedColumn( 'nb_visits' );
$view->setGraphLimit( 10 );
$view->setLimit( 10 );
-
return $this->renderView($view, $fetch);
}
diff --git a/plugins/UsersManager/templates/UsersManager.js b/plugins/UsersManager/templates/UsersManager.js
index 5dc9fa9ca2..62cb090baa 100644
--- a/plugins/UsersManager/templates/UsersManager.js
+++ b/plugins/UsersManager/templates/UsersManager.js
@@ -1,7 +1,7 @@
function getUpdateUserAJAX( row )
{
- var ajaxRequest = getStandardAjaxConf();
- toggleAjaxLoading();
+ var ajaxRequest = piwikHelper.getStandardAjaxConf();
+ piwikHelper.toggleAjaxLoading();
var parameters = new Object;
parameters.module = 'API';
@@ -21,8 +21,8 @@ function getUpdateUserAJAX( row )
function getDeleteUserAJAX( login )
{
- var ajaxRequest = getStandardAjaxConf();
- toggleAjaxLoading();
+ var ajaxRequest = piwikHelper.getStandardAjaxConf();
+ piwikHelper.toggleAjaxLoading();
var parameters = new Object;
parameters.module = 'API';
@@ -38,8 +38,8 @@ function getDeleteUserAJAX( login )
function getAddUserAJAX( row )
{
- var ajaxRequest = getStandardAjaxConf();
- toggleAjaxLoading();
+ var ajaxRequest = piwikHelper.getStandardAjaxConf();
+ piwikHelper.toggleAjaxLoading();
var parameters = new Object;
parameters.module = 'API';
@@ -63,7 +63,7 @@ function getIdSites()
function getUpdateUserAccess(login, access, successCallback)
{
- var ajaxRequest = getStandardAjaxConf();
+ var ajaxRequest = piwikHelper.getStandardAjaxConf();
ajaxRequest.success = successCallback;
ajaxRequest.async = false;
@@ -113,12 +113,12 @@ function bindUpdateAccess()
// if the permission couldn't be granted
if(response.result == "error")
{
- ajaxShowError(response.message);
+ piwikHelper.ajaxShowError(response.message);
}
// if the permission change was successful
else
{
- ajaxHideError();
+ piwikHelper.ajaxHideError();
$(self).parent().parent().find('.accessGranted')
.attr("src","plugins/UsersManager/images/no-access.png" )
@@ -163,7 +163,7 @@ $(document).ready( function() {
// when click on edituser, the cells become editable
$('.edituser')
.click( function() {
- ajaxHideError();
+ piwikHelper.ajaxHideError();
var idRow = $(this).attr('id');
if(alreadyEdited[idRow]==1) return;
alreadyEdited[idRow] = 1;
@@ -197,7 +197,7 @@ $(document).ready( function() {
// when click on deleteuser, the we ask for confirmation and then delete the user
$('.deleteuser')
.click( function() {
- ajaxHideError();
+ piwikHelper.ajaxHideError();
var idRow = $(this).attr('id');
var loginToDelete = $(this).parent().parent().find('#userLogin').html();
if( confirm(sprintf(_pk_translate('UsersManager_DeleteConfirm_js'),'"'+loginToDelete+'"')) )
@@ -208,7 +208,7 @@ $(document).ready( function() {
);
$('.addrow').click( function() {
- ajaxHideError();
+ piwikHelper.ajaxHideError();
$(this).toggle();
var numberOfRows = $('table#users')[0].rows.length;
@@ -228,7 +228,7 @@ $(document).ready( function() {
;
$('#'+newRowId).keypress( submitOnEnter );
$('.adduser').click( function(){ $.ajax( getAddUserAJAX($('tr#'+newRowId)) ); } );
- $('.cancel').click(function() { ajaxHideError(); $(this).parents('tr').remove(); $('.addrow').toggle(); });
+ $('.cancel').click(function() { piwikHelper.ajaxHideError(); $(this).parents('tr').remove(); $('.addrow').toggle(); });
});
$('.updateAccess')
diff --git a/plugins/VisitsSummary/Controller.php b/plugins/VisitsSummary/Controller.php
index 48d43d97aa..ab648ada62 100644
--- a/plugins/VisitsSummary/Controller.php
+++ b/plugins/VisitsSummary/Controller.php
@@ -36,7 +36,7 @@ class Piwik_VisitsSummary_Controller extends Piwik_Controller
"&format=original".
// we disable filters for example "search for pattern", in the case this method is called
// by a method that already calls the API with some generic filters applied
- "&disable_generic_filters=true";
+ "&disable_generic_filters=1";
$request = new Piwik_API_Request($requestString);
return $request->process();
}
@@ -45,7 +45,7 @@ class Piwik_VisitsSummary_Controller extends Piwik_Controller
{
$requestString = "method=VisitsSummary.getVisits".
"&format=original".
- "&disable_generic_filters=true";
+ "&disable_generic_filters=1";
$request = new Piwik_API_Request($requestString);
return $request->process();
}
diff --git a/tests/core/DataTable/Filter/Pattern.test.php b/tests/core/DataTable/Filter/Pattern.test.php
index 0bcf3db83b..71c902a754 100644
--- a/tests/core/DataTable/Filter/Pattern.test.php
+++ b/tests/core/DataTable/Filter/Pattern.test.php
@@ -25,45 +25,30 @@ class Test_Piwik_DataTable_Filter_Pattern extends UnitTestCase
array( $idcol => array('label'=>'piwik')),
array( $idcol => array('label'=>'yahoo')),
array( $idcol => array('label'=>'amazon')),
- array( $idcol => array('label'=>'238975247578949')),
- array( $idcol => array('label'=>'Q*(%&*("$&%*(&"$*")"))')));
-
+ array( $idcol => array('label'=>'2389752/47578949')),
+ array( $idcol => array('label'=>'Q*(%&*("$&%*(&"$*")"))'))
+ );
$table->addRowsFromArray( $rows );
-
-
- $expectedtable = clone $table;
- $expectedtable->deleteRows(array(1,2,4,5,6));
-
- $filter = new Piwik_DataTable_Filter_Pattern($table, 'label', 'oo');
-
- $this->assertEqual($table->getRows(), $expectedtable->getRows());
+ $rowIds = array_keys($rows);
+
+ $tests = array(
+ array('ask', array(1)),
+ array('oo', array(0,3)),
+ array('^yah', array(3)),
+ array('\*', array(6)),
+ array('2/4', array(5)),
+ array('amazon|yahoo', array(3,4)),
+ );
+
+ foreach($tests as $test) {
+ $pattern = $test[0];
+ $expectedRows = $test[1];
+ $rowToDelete = array_diff($rowIds, $expectedRows);
+ $expectedtable = clone $table;
+ $expectedtable->deleteRows($rowToDelete);
+ $filteredTable = clone $table;
+ $filteredTable->filter('Pattern', array('label', $pattern));
+ $this->assertEqual($filteredTable->getRows(), $expectedtable->getRows(), "pattern search failed for pattern $pattern");
+ }
}
- /**
- * Test to filter a column with a pattern
- */
- function test_filter_Pattern2()
- {
- $table = new Piwik_DataTable;
-
- $idcol = Piwik_DataTable_Row::COLUMNS;
-
- $rows = array(
- array( $idcol => array('label'=>'google')),
- array( $idcol => array('label'=>'ask')),
- array( $idcol => array('label'=>'piwik')),
- array( $idcol => array('label'=>'yahoo')),
- array( $idcol => array('label'=>'amazon')),
- array( $idcol => array('label'=>'238975247578949')),
- array( $idcol => array('label'=>'Q*(%&*("$&%*(&"$*")"))')));
-
- $table->addRowsFromArray( $rows );
-
-
- $expectedtable = clone $table;
- $expectedtable->deleteRows(array(0,1,2,3,4,5));
-
- $filter = new Piwik_DataTable_Filter_Pattern($table, 'label', '*');
-
- $this->assertEqual($table->getRows(), $expectedtable->getRows());
- }
-}
+} \ No newline at end of file
diff --git a/themes/default/common.js b/themes/default/common.js
index 29a16923dd..7135e3df3c 100644
--- a/themes/default/common.js
+++ b/themes/default/common.js
@@ -28,8 +28,7 @@ piwikHelper.getQueryStringFromParameters = function(parameters)
return queryString.substring(0, queryString.length-1);
}
-//TODO all piwik global functions should be static of piwikHelper
-function findSWFGraph(name) {
+piwikHelper.findSWFGraph = function(name) {
if (navigator.appName.indexOf("Microsoft")!= -1) {
return window[name];
} else {
@@ -37,10 +36,12 @@ function findSWFGraph(name) {
}
}
-function redirectToUrl(url) {
+piwikHelper.redirectToUrl = function(url) {
+ alert(url);
window.location = url;
}
-function ajaxHandleError()
+
+piwikHelper.ajaxHandleError = function()
{
$('#loadingError').show();
setTimeout( function(){
@@ -48,55 +49,48 @@ function ajaxHandleError()
}, 2000);
}
-function ajaxShowError( string )
+piwikHelper.ajaxShowError = function( string )
{
$('#ajaxError').html(string).show();
}
-function ajaxHideError()
+piwikHelper.ajaxHideError = function()
{
$('#ajaxError').hide();
}
-function ajaxHandleResponse(response)
+piwikHelper.ajaxHandleResponse = function(response)
{
if(response.result == "error")
{
- ajaxShowError(response.message);
+ piwikHelper.ajaxShowError(response.message);
}
else
{
window.location.reload();
}
- toggleAjaxLoading();
+ piwikHelper.toggleAjaxLoading();
}
-function toggleAjaxLoading()
+piwikHelper.toggleAjaxLoading = function()
{
$('#ajaxLoading').toggle();
}
-String.prototype.trim = function() {
- return this.replace(/^\s+|\s+$/g,"");
-}
-
-function getStandardAjaxConf()
+piwikHelper.getStandardAjaxConf = function()
{
var ajaxRequest = new Object;
-
- //prepare the ajax request
ajaxRequest.type = 'GET';
ajaxRequest.url = 'index.php';
ajaxRequest.dataType = 'json';
- ajaxRequest.error = ajaxHandleError;
- ajaxRequest.success = ajaxHandleResponse;
-
+ ajaxRequest.error = piwikHelper.ajaxHandleError;
+ ajaxRequest.success = piwikHelper.ajaxHandleResponse;
return ajaxRequest;
}
-//scroll the window to the jquery element 'elem' if necessary
-//time specify the duration of the animation in ms
-function lazyScrollTo(elem, time)
+// Scrolls the window to the jquery element 'elem' if necessary.
+// "time" specifies the duration of the animation in ms
+piwikHelper.lazyScrollTo = function(elem, time)
{
var elemTop = $(elem).offset().top;
//only scroll the page if the graph is not visible
@@ -107,3 +101,7 @@ function lazyScrollTo(elem, time)
$.scrollTo(elem, time);
}
}
+
+String.prototype.trim = function() {
+ return this.replace(/^\s+|\s+$/g,"");
+}
diff --git a/themes/default/images/image.png b/themes/default/images/image.png
new file mode 100644
index 0000000000..fbcdb8ea71
--- /dev/null
+++ b/themes/default/images/image.png
Binary files differ