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:
-rw-r--r--config/global.ini.php1
-rw-r--r--core/Archive.php13
-rw-r--r--core/Archive/DataCollection.php4
-rw-r--r--core/Archive/DataTableFactory.php41
-rw-r--r--core/ArchiveProcessor/Period.php2
-rw-r--r--core/AssetManager.php1
-rw-r--r--core/Controller.php9
-rw-r--r--core/DataTableVisualization.php202
-rw-r--r--core/FrontController.php2
-rw-r--r--core/PluginsManager.php1
-rw-r--r--core/Tracker/Request.php14
-rw-r--r--core/Twig.php9
-rw-r--r--core/ViewDataTable.php447
-rw-r--r--core/ViewDataTable/Cloud.php81
-rw-r--r--core/ViewDataTable/Properties.php310
-rw-r--r--core/ViewDataTable/Sparkline.php9
-rw-r--r--core/ViewDataTable/VisualizationPropertiesProxy.php30
-rw-r--r--core/Visualization/JqplotGraph.php132
-rw-r--r--core/Visualization/JqplotGraph/Bar.php35
-rw-r--r--core/Visualization/JqplotGraph/Pie.php36
-rw-r--r--plugins/Actions/API.php6
-rw-r--r--plugins/Actions/Actions.php38
-rw-r--r--plugins/Actions/stylesheets/dataTableActions.less4
-rwxr-xr-xplugins/Annotations/API.php4
-rw-r--r--plugins/CoreHome/CoreHome.php6
-rw-r--r--plugins/CoreHome/DataTableRowAction/RowEvolution.php18
-rw-r--r--plugins/CoreHome/javascripts/dataTable.js4
-rw-r--r--plugins/CoreHome/javascripts/dataTable_manager.js12
-rw-r--r--plugins/CoreHome/stylesheets/dataTable/_dataTable.less27
-rw-r--r--plugins/CoreHome/templates/_dataTable.twig3
-rw-r--r--plugins/CoreHome/templates/_dataTableActions_subDataTable.twig8
-rw-r--r--plugins/CoreHome/templates/_dataTableFooter.twig29
-rw-r--r--plugins/CoreHome/templates/_dataTableViz_jqplotGraph.twig10
-rw-r--r--plugins/CoreHome/templates/getMultiRowEvolutionPopover.twig2
-rw-r--r--plugins/CoreHome/templates/getRowEvolutionPopover.twig2
-rw-r--r--plugins/CoreVisualizations/CoreVisualizations.php58
-rw-r--r--plugins/CoreVisualizations/JqplotDataGenerator.php (renamed from core/JqplotDataGenerator.php)24
-rw-r--r--plugins/CoreVisualizations/JqplotDataGenerator/Evolution.php (renamed from core/JqplotDataGenerator/Evolution.php)10
-rw-r--r--plugins/CoreVisualizations/Visualizations/Cloud.php (renamed from core/Visualization/Cloud.php)15
-rw-r--r--plugins/CoreVisualizations/Visualizations/HtmlTable.php (renamed from core/Visualization/HtmlTable.php)110
-rw-r--r--plugins/CoreVisualizations/Visualizations/HtmlTable/AllColumns.php34
-rw-r--r--plugins/CoreVisualizations/Visualizations/HtmlTable/Goals.php34
-rw-r--r--plugins/CoreVisualizations/Visualizations/JqplotGraph.php206
-rw-r--r--plugins/CoreVisualizations/Visualizations/JqplotGraph/Bar.php35
-rw-r--r--plugins/CoreVisualizations/Visualizations/JqplotGraph/Evolution.php (renamed from core/Visualization/JqplotGraph/Evolution.php)21
-rw-r--r--plugins/CoreVisualizations/Visualizations/JqplotGraph/Pie.php36
-rw-r--r--plugins/CoreVisualizations/javascripts/jqplot.js (renamed from plugins/CoreHome/javascripts/jqplot.js)25
-rw-r--r--plugins/CoreVisualizations/stylesheets/dataTableVisualizations.less18
-rw-r--r--plugins/CoreVisualizations/stylesheets/jqplot.css (renamed from plugins/CoreHome/stylesheets/jqplot.css)0
-rw-r--r--plugins/CoreVisualizations/templates/_dataTableViz_htmlTable.twig (renamed from plugins/CoreHome/templates/_dataTableViz_htmlTable.twig)6
-rw-r--r--plugins/CoreVisualizations/templates/_dataTableViz_jqplotGraph.twig10
-rw-r--r--plugins/CoreVisualizations/templates/_dataTableViz_tagCloud.twig (renamed from plugins/CoreHome/templates/_dataTableViz_tagCloud.twig)0
-rw-r--r--plugins/DBStats/DBStats.php12
-rw-r--r--plugins/Dashboard/stylesheets/dashboard.less5
-rw-r--r--plugins/DevicesDetection/DevicesDetection.php10
-rw-r--r--plugins/ExampleUI/Controller.php8
-rw-r--r--plugins/ExtraVisualizations/ExtraVisualizations.php47
-rw-r--r--plugins/ExtraVisualizations/Visualizations/Treemap.php31
-rw-r--r--plugins/ExtraVisualizations/stylesheets/dataTableVisualizations.less0
-rw-r--r--plugins/Goals/Controller.php2
-rw-r--r--plugins/Goals/Goals.php2
-rw-r--r--plugins/Live/Live.php6
-rw-r--r--plugins/PleineLune/stylesheets/_menuDashboard.less1
-rw-r--r--plugins/Referers/Controller.php6
-rw-r--r--plugins/Referers/Referers.php44
-rw-r--r--plugins/UserSettings/UserSettings.php166
-rw-r--r--plugins/VisitTime/VisitTime.php26
-rw-r--r--plugins/VisitorInterest/VisitorInterest.php12
-rw-r--r--tests/PHPUnit/Integration/FlattenReportsTest.php8
-rw-r--r--tests/PHPUnit/Integration/expected/test_FlattenReports_expandedWithDepth__Actions.getPageUrls_week.xml155
-rwxr-xr-xtests/PHPUnit/IntegrationTestCase.php3
-rw-r--r--tests/PHPUnit/TestingEnvironment.php3
-rw-r--r--tests/PHPUnit/UI/UIIntegrationTest.php13
-rw-r--r--tests/PHPUnit/proxy/index.php3
74 files changed, 1727 insertions, 1030 deletions
diff --git a/config/global.ini.php b/config/global.ini.php
index 10d71efd31..1114efc681 100644
--- a/config/global.ini.php
+++ b/config/global.ini.php
@@ -494,6 +494,7 @@ logger_file_path = tmp/logs
Plugins[] = CorePluginsAdmin
Plugins[] = CoreAdminHome
Plugins[] = CoreHome
+Plugins[] = CoreVisualizations
Plugins[] = Proxy
Plugins[] = API
Plugins[] = Widgetize
diff --git a/core/Archive.php b/core/Archive.php
index 6e060cc2da..2c53a8e665 100644
--- a/core/Archive.php
+++ b/core/Archive.php
@@ -251,15 +251,17 @@ class Archive
* Manager::getTable() function.
*
* @param string $name The name of the record to get.
- * @param int|string|null $idSubtable The subtable ID (if any) or self::ID_SUBTABLE_LOAD_ALL_SUBTABLES if requesting every datatable.
+ * @param int|string|null $idSubtable The subtable ID (if any) or self::ID_SUBTABLE_LOAD_ALL_SUBTABLES
+ * if requesting every datatable.
+ * @param int|null $depth The maximum number of subtable levels to load. If null, all levels are loaded.
* @param bool $addMetadataSubtableId Whether to add the DB subtable ID as metadata to each datatable,
* or not.
* @return DataTable
*/
- public function getDataTableExpanded($name, $idSubtable = null, $addMetadataSubtableId = true)
+ public function getDataTableExpanded($name, $idSubtable = null, $depth = null, $addMetadataSubtableId = true)
{
$data = $this->get($name, 'blob', self::ID_SUBTABLE_LOAD_ALL_SUBTABLES);
- return $data->getExpandedDataTable($this->getResultIndices(), $idSubtable, $addMetadataSubtableId);
+ return $data->getExpandedDataTable($this->getResultIndices(), $idSubtable, $depth, $addMetadataSubtableId);
}
/**
@@ -291,7 +293,8 @@ class Archive
* @param int|null $idSubtable
* @return DataTable|DataTable\Map
*/
- public static function getDataTableFromArchive($name, $idSite, $period, $date, $segment, $expanded, $idSubtable = null)
+ public static function getDataTableFromArchive($name, $idSite, $period, $date, $segment, $expanded,
+ $idSubtable = null, $depth = null)
{
Piwik::checkUserHasViewAccess($idSite);
$archive = Archive::build($idSite, $period, $date, $segment);
@@ -300,7 +303,7 @@ class Archive
}
if ($expanded) {
- $dataTable = $archive->getDataTableExpanded($name, $idSubtable);
+ $dataTable = $archive->getDataTableExpanded($name, $idSubtable, $depth);
} else {
$dataTable = $archive->getDataTable($name, $idSubtable);
}
diff --git a/core/Archive/DataCollection.php b/core/Archive/DataCollection.php
index 61499219d4..9cd96f3540 100644
--- a/core/Archive/DataCollection.php
+++ b/core/Archive/DataCollection.php
@@ -234,7 +234,7 @@ class DataCollection
* @throws Exception
* @return DataTable|DataTable\Map
*/
- public function getExpandedDataTable($resultIndices, $idSubTable = null, $addMetadataSubTableId = false)
+ public function getExpandedDataTable($resultIndices, $idSubTable = null, $depth = null, $addMetadataSubTableId = false)
{
if ($this->dataType != 'blob') {
throw new Exception("DataCollection: cannot call getExpandedDataTable with "
@@ -248,7 +248,7 @@ class DataCollection
$dataTableFactory = new DataTableFactory(
$this->dataNames, 'blob', $this->sitesId, $this->periods, $this->defaultRow);
- $dataTableFactory->expandDataTable($addMetadataSubTableId);
+ $dataTableFactory->expandDataTable($depth, $addMetadataSubTableId);
$dataTableFactory->useSubtable($idSubTable);
$index = $this->getArray($resultIndices);
diff --git a/core/Archive/DataTableFactory.php b/core/Archive/DataTableFactory.php
index 4fc42d662c..f45e1a3d58 100644
--- a/core/Archive/DataTableFactory.php
+++ b/core/Archive/DataTableFactory.php
@@ -15,8 +15,6 @@ use Piwik\Site;
use Piwik\DataTable;
use Piwik\DataTable\Row;
-const FIX_ME_OMG = 'this is a warning and reminder to fix this code ';
-
/**
* Creates a DataTable or Set instance based on an array
* index created by DataCollection.
@@ -53,6 +51,14 @@ class DataTableFactory
private $addMetadataSubtableId = false;
/**
+ * The maximum number of subtable levels to create when creating an expanded
+ * DataTable.
+ *
+ * @var int
+ */
+ private $maxSubtableDepth = null;
+
+ /**
* @see DataCollection::$sitesId.
*/
private $sitesId;
@@ -96,9 +102,10 @@ class DataTableFactory
* database to the in-memory DataTables as
* metadata or not.
*/
- public function expandDataTable($addMetadataSubtableId = false)
+ public function expandDataTable($maxSubtableDepth = null, $addMetadataSubtableId = false)
{
$this->expandDataTable = true;
+ $this->maxSubtableDepth = $maxSubtableDepth;
$this->addMetadataSubtableId = $addMetadataSubtableId;
}
@@ -292,9 +299,7 @@ class DataTableFactory
// would break.
if (count($this->dataNames) == 1) {
$name = reset($this->dataNames);
- $table->addRow(new Row(array(
- Row::COLUMNS => array($name => 0)
- )));
+ $table->addRow(new Row(array(Row::COLUMNS => array($name => 0))));
}
}
@@ -329,8 +334,19 @@ class DataTableFactory
* with blob values. This should hold every subtable blob for
* the loaded DataTable.
*/
- private function setSubtables($dataTable, $blobRow)
+ private function setSubtables($dataTable, $blobRow, $treeLevel = 0)
{
+ if ($this->maxSubtableDepth
+ && $treeLevel >= $this->maxSubtableDepth
+ ) {
+ // unset the subtables so DataTableManager doesn't throw
+ foreach ($dataTable->getRows() as $row) {
+ $row->removeSubtable();
+ }
+
+ return;
+ }
+
$dataName = reset($this->dataNames);
foreach ($dataTable->getRows() as $row) {
@@ -342,7 +358,7 @@ class DataTableFactory
$blobName = $dataName . "_" . $sid;
if (isset($blobRow[$blobName])) {
$subtable = DataTable::fromSerializedArray($blobRow[$blobName]);
- $this->setSubtables($subtable, $blobRow);
+ $this->setSubtables($subtable, $blobRow, $treeLevel + 1);
// we edit the subtable ID so that it matches the newly table created in memory
// NB: we dont overwrite the datatableid in the case we are displaying the table expanded.
@@ -366,9 +382,7 @@ class DataTableFactory
$periods = $this->periods;
$table->filter(function ($table) use ($periods) {
$table->metadata['site'] = new Site($table->metadata['site']);
- $table->metadata['period'] = empty($periods[$table->metadata['period']])
- ? FIX_ME_OMG
- : $periods[$table->metadata['period']];
+ $table->metadata['period'] = $periods[$table->metadata['period']];
});
}
@@ -381,12 +395,9 @@ class DataTableFactory
*/
private function prettifyIndexLabel($labelType, $label)
{
- if (empty($this->periods[$label])) {
- return $label; // BAD BUG FIXME
- }
if ($labelType == 'period') { // prettify period labels
return $this->periods[$label]->getPrettyString();
}
return $label;
}
-}
+} \ No newline at end of file
diff --git a/core/ArchiveProcessor/Period.php b/core/ArchiveProcessor/Period.php
index 6f7085c1a9..778b41f075 100644
--- a/core/ArchiveProcessor/Period.php
+++ b/core/ArchiveProcessor/Period.php
@@ -165,7 +165,7 @@ class Period extends ArchiveProcessor
$table->setColumnAggregationOperations($columnAggregationOperations);
}
- $data = $this->archiver->getDataTableExpanded($name, $idSubTable = null, $addMetadataSubtableId = false);
+ $data = $this->archiver->getDataTableExpanded($name, $idSubTable = null, $depth = null, $addMetadataSubtableId = false);
if ($data instanceof DataTable\Map) {
foreach ($data->getArray() as $date => $tableToSum) {
$table->addDataTable($tableToSum);
diff --git a/core/AssetManager.php b/core/AssetManager.php
index bdc311a720..2823373090 100644
--- a/core/AssetManager.php
+++ b/core/AssetManager.php
@@ -266,6 +266,7 @@ class AssetManager
'plugins/Zeitgeist/stylesheets/base.less',
'plugins/Zeitgeist/stylesheets/',
'plugins/',
+ 'plugins/Dashboard/stylesheets/dashboard.less',
);
return self::prioritySort($priorityCssOrdered, $cssFiles);
diff --git a/core/Controller.php b/core/Controller.php
index 5aac70c2e2..9b02395d81 100644
--- a/core/Controller.php
+++ b/core/Controller.php
@@ -176,8 +176,9 @@ abstract class Controller
*/
protected function getLastUnitGraph($currentModuleName, $currentControllerAction, $apiMethod)
{
- $view = ViewDataTable::factory('graphEvolution');
- $view->init($currentModuleName, $currentControllerAction, $apiMethod);
+ $view = ViewDataTable::factory(
+ 'graphEvolution', $apiMethod, $currentModuleName . '.' . $currentControllerAction, $forceDefault = true);
+ $view->show_goals = false;
return $view;
}
@@ -219,14 +220,14 @@ abstract class Controller
// initialize the graph and load the data
$view = $this->getLastUnitGraph($currentModuleName, $currentControllerAction, $apiMethod);
$view->columns_to_display = $columnsToDisplay;
- $view->selectable_columns = array_merge($view->selectable_columns, $selectableColumns);
+ $view->visualization_properties->selectable_columns =
+ array_merge($view->visualization_properties->selectable_columns ?: array(), $selectableColumns);
$view->translations += $translations;
if ($reportDocumentation) {
$view->documentation = $reportDocumentation;
}
- $view->main();
return $view;
}
diff --git a/core/DataTableVisualization.php b/core/DataTableVisualization.php
index ca41f65377..e70099ff03 100644
--- a/core/DataTableVisualization.php
+++ b/core/DataTableVisualization.php
@@ -14,43 +14,94 @@ namespace Piwik;
use Piwik\DataTable;
/**
- * TODO
+ * Base class for all DataTable visualizations. Different visualizations are used to
+ * handle different values of the viewDataTable query parameter. Each one will display
+ * DataTable data in a different way.
+ *
+ * TODO: must be more in depth
*/
abstract class DataTableVisualization
{
/**
- * TODO
+ * This event is used to gather all available DataTable visualizations. Callbacks
+ * should add visualization class names to the incoming array.
+ *
+ * Callback Signature: function (&$visualizations) {}
+ */
+ const GET_AVAILABLE_EVENT = 'DataTableVisualization.getAvailable';
+
+ /**
+ * Rendering function. Must return the view HTML.
+ *
+ * @param Piwik_DataTable|Piwik_DataTable_Map $dataTable The data.
+ * @param array $properties The view properties.
+ * @return string The visualization HTML.
*/
public abstract function render($dataTable, $properties);
/**
- * TODO
+ * Returns the array of view properties that a DataTable visualization will require
+ * to be both visible to client side JavaScript, and passed along as query parameters
+ * in every AJAX request.
+ *
+ * Derived DataTableVisualizations can specify client side parameters by declaring
+ * a static $clientSideParameters field.
+ *
+ * @return array
*/
- public static function getJavaScriptProperties()
+ public static function getClientSideParameters()
{
- if (isset(static::$javaScriptProperties)) {
- return static::$javaScriptProperties;
+ if (isset(static::$clientSideParameters)) {
+ $result = array();
+
+ $lineage = static::getThisVisualizationClassLineage();
+ foreach ($lineage as $klass) {
+ if (isset($klass::$clientSideParameters)) {
+ $result = array_merge($result, $clientSideParameters);
+ }
+ }
+
+ return $result;
} else {
return array();
}
}
/**
- * TODO
+ * Returns an array of view property names that a DataTable visualization will
+ * require to be visible to client side JavaScript. Unlike 'client side parameters',
+ * these will not be passed with AJAX requests as query parameters.
+ *
+ * Derived DataTableVisualizations can specify client side properties by declaring
+ * a static $clientSideProperties field.
+ *
+ * @return array
*/
- public static function getOverridableProperties()
+ public static function getClientSideProperties()
{
- if (isset(static::$overridableProperties)) {
- return static::$overridableProperties;
+ if (isset(static::$clientSideProperties)) {
+ $result = array();
+
+ $lineage = static::getThisVisualizationClassLineage();
+ foreach ($lineage as $klass) {
+ if (isset($klass::$clientSideProperties)) {
+ $result = array_merge($result, $clientSideProperties);
+ }
+ }
+
+ return $result;
} else {
return array();
}
}
/**
- * TODO
+ * Returns the viewDataTable ID for this DataTable visualization. Derived classes
+ * should declare a const ID field with the viewDataTable ID.
+ *
+ * @return string
*/
- public static function getViewDataTableId($view)
+ public static function getViewDataTableId()
{
if (defined('static::ID')) {
return static::ID;
@@ -58,4 +109,129 @@ abstract class DataTableVisualization
return Piwik::getUnnamespacedClassName($this);
}
}
-}
+
+ /**
+ * Returns the list of parents for a DataTableVisualization class excluding the
+ * DataTableVisualization class and above.
+ *
+ * @param string $klass The class name of the DataTableVisualization.
+ * @return array The list of parent classes in order from highest ancestor to
+ * the descended class.
+ */
+ public static function getVisualizationClassLineage($klass)
+ {
+ $klasses = array_merge(array($klass), class_parents($klass, $autoload = false));
+
+ $idx = array_search('Piwik\\DataTableVisualization', $klasses);
+ if ($idx !== false) {
+ unset($klasses[$idx]);
+ }
+
+ return array_reverse($klasses);
+ }
+
+ /**
+ * Returns the class lineage for this class. For use with late static bindings.
+ *
+ * @see self::getVisualizationClassLineage
+ *
+ * @return array
+ */
+ protected static function getThisVisualizationClassLineage()
+ {
+ return self::getVisualizationClassLineage(__CLASS__);
+ }
+
+ /**
+ * Returns the viewDataTable IDs of a visualization's class lineage.
+ *
+ * @see self::getVisualizationClassLineage
+ *
+ * @param string $klass The visualization class.
+ */
+ public static function getVisualizationIdsWithInheritance($klass)
+ {
+ $klasses = self::getVisualizationClassLineage($klass);
+ return array_map(array('Piwik\\Piwik', 'getUnnamespacedClassName'), $klasses);
+ }
+
+ /**
+ * Returns all registered visualization classes. Uses the 'DataTableVisualization.getAvailable'
+ * event to retrieve visualizations.
+ *
+ * @return array Array mapping visualization IDs with their associated visualization classes.
+ * @throws Exception If a visualization class does not exist or if a duplicate visualization ID
+ * is found.
+ */
+ public static function getAvailableVisualizations()
+ {
+ $visualizations = array();
+ Piwik_PostEvent(self::GET_AVAILABLE_EVENT, array(&$visualizations));
+
+ $result = array();
+ foreach ($visualizations as $viz) {
+ if (!class_exists($viz)) {
+ throw new \Exception(
+ "Invalid visualization class '$viz' found in DataTableVisualization.getAvailableVisualizations.");
+ }
+
+ if (is_subclass_of($viz, __CLASS__)) {
+ $vizId = $viz::getViewDataTableId();
+ if (isset($result[$vizId])) {
+ throw new Exception("Visualization ID '$vizId' is already in use!");
+ }
+
+ $result[$vizId] = $viz;
+ }
+ }
+ return $result;
+ }
+
+ /**
+ * Returns all available visualizations that are not part of the CoreVisualizations plugin.
+ *
+ * @return array Array mapping visualization IDs with their associated visualization classes.
+ */
+ public static function getNonCoreVisualizations()
+ {
+ $result = array();
+ foreach (self::getAvailableVisualizations() as $vizId => $vizClass) {
+ if (strpos($vizClass, 'Piwik\\Plugins\\CoreVisualizations') === false) {
+ $result[$vizId] = $vizClass;
+ }
+ }
+ return $result;
+ }
+
+ /**
+ * Returns an array mapping visualization IDs with information necessary for adding the
+ * visualizations to the footer of DataTable views.
+ *
+ * @param array $visualizations An array mapping visualization IDs w/ their associated classes.
+ * @return array
+ */
+ public static function getVisualizationInfoFor($visualizations)
+ {
+ $result = array();
+ foreach ($visualizations as $vizId => $vizClass) {
+ $result[$vizId] = array('table_icon' => $vizClass::FOOTER_ICON, 'title' => $vizClass::FOOTER_ICON_TITLE);
+ }
+ return $result;
+ }
+
+ /**
+ * Returns the visualization class by it's viewDataTable ID.
+ *
+ * @param string $id The visualization ID.
+ * @return string The visualization class name.
+ * @throws Exception if $id is not a valid visualization ID.
+ */
+ public static function getClassFromId($id)
+ {
+ $visualizationClasses = self::getAvailableVisualizations();
+ if (!isset($visualizationClasses[$id])) {
+ throw new \Exception("Invalid DataTable visualization ID: '$id'.");
+ }
+ return $visualizationClasses[$id];
+ }
+} \ No newline at end of file
diff --git a/core/FrontController.php b/core/FrontController.php
index 4d4e814ebf..e0bb8258e2 100644
--- a/core/FrontController.php
+++ b/core/FrontController.php
@@ -131,7 +131,7 @@ class FrontController
} catch (Exception $e) {
$debugTrace = $e->getTraceAsString();
$message = Common::sanitizeInputValue($e->getMessage());
- Piwik_ExitWithMessage($message, '' /* $debugTrace */, true);
+ Piwik_ExitWithMessage($message, '' . $debugTrace , true);
}
}
diff --git a/core/PluginsManager.php b/core/PluginsManager.php
index 99f3a7ae37..bbfec52d9a 100644
--- a/core/PluginsManager.php
+++ b/core/PluginsManager.php
@@ -43,6 +43,7 @@ class PluginsManager
'CoreUpdater',
'CoreAdminHome',
'CorePluginsAdmin',
+ 'CoreVisualizations',
'Installation',
'SitesManager',
'UsersManager',
diff --git a/core/Tracker/Request.php b/core/Tracker/Request.php
index 668d23fa1e..595c3e9f09 100644
--- a/core/Tracker/Request.php
+++ b/core/Tracker/Request.php
@@ -27,6 +27,8 @@ class Request
*/
protected $params;
+ protected $forcedVisitorId = false;
+
public function __construct($params, $tokenAuth = false)
{
if (!is_array($params)) {
@@ -434,7 +436,9 @@ class Request
public function setForceIp($ip)
{
- $this->enforcedIp = $ip;
+ if(!empty($ip)) {
+ $this->enforcedIp = $ip;
+ }
}
public function setForceDateTime($dateTime)
@@ -442,12 +446,16 @@ class Request
if (!is_numeric($dateTime)) {
$dateTime = strtotime($dateTime);
}
- $this->timestamp = $dateTime;
+ if(!empty($dateTime)) {
+ $this->timestamp = $dateTime;
+ }
}
public function setForcedVisitorId($visitorId)
{
- $this->forcedVisitorId = $visitorId;
+ if(!empty($visitorId)) {
+ $this->forcedVisitorId = $visitorId;
+ }
}
public function getForcedVisitorId()
diff --git a/core/Twig.php b/core/Twig.php
index f8325a1ce5..4b32e4931c 100644
--- a/core/Twig.php
+++ b/core/Twig.php
@@ -73,6 +73,15 @@ class Twig
$this->addFunction_loadJavascriptTranslations();
$this->addFunction_sparkline();
$this->addFunction_postEvent();
+ $this->addFunction_isPluginLoaded();
+ }
+
+ protected function addFunction_isPluginLoaded()
+ {
+ $isPluginLoadedFunction = new Twig_SimpleFunction('isPluginLoaded', function ($pluginName) {
+ return PluginsManager::getInstance()->isPluginLoaded($pluginName);
+ });
+ $this->twig->addFunction($isPluginLoadedFunction);
}
protected function addFunction_includeAssets()
diff --git a/core/ViewDataTable.php b/core/ViewDataTable.php
index e47bb0d3e8..952feab283 100644
--- a/core/ViewDataTable.php
+++ b/core/ViewDataTable.php
@@ -25,6 +25,7 @@ use Piwik\ViewDataTable\Properties;
use Piwik\ViewDataTable\VisualizationPropertiesProxy;
use Piwik_API_API;
use Piwik\PluginsManager;
+use Piwik\DataTableVisualization;
/**
* This class is used to load (from the API) and customize the output of a given DataTable.
@@ -61,10 +62,11 @@ use Piwik\PluginsManager;
class ViewDataTable
{
/**
- * TODO
- * TODO: change to private
+ * The class name of the visualization to use.
+ *
+ * @var string|null
*/
- protected $visualizationClass;
+ private $visualizationClass;
/**
* Cache for getAllReportDisplayProperties result.
@@ -74,13 +76,6 @@ class ViewDataTable
public static $reportPropertiesCache = null;
/**
- * Flag used to make sure the main() is only executed once
- *
- * @var bool
- */
- protected $mainAlreadyExecuted = false;
-
- /**
* Array of properties that are available in the view
* Used to store UI properties, eg. "show_footer", "show_search", etc.
*
@@ -125,68 +120,55 @@ class ViewDataTable
/**
* Default constructor.
*/
- public function __construct($visualizationClass = null)
+ public function __construct($currentControllerAction,
+ $apiMethodToRequestDataTable,
+ $viewProperties = array(),
+ $visualizationId = null)
{
+ $visualizationClass = $visualizationId ? DataTableVisualization::getClassFromId($visualizationId) : null;
$this->visualizationClass = $visualizationClass;
- $this->viewProperties['visualization_properties'] = new VisualizationPropertiesProxy(null);
- $this->viewProperties['datatable_template'] = '@CoreHome/_dataTable';
- $this->viewProperties['show_goals'] = false;
- $this->viewProperties['show_ecommerce'] = false;
- $this->viewProperties['show_search'] = true;
- $this->viewProperties['show_table'] = true;
- $this->viewProperties['show_table_all_columns'] = true;
- $this->viewProperties['show_all_views_icons'] = true;
- $this->viewProperties['show_active_view_icon'] = true;
- $this->viewProperties['hide_annotations_view'] = true;
- $this->viewProperties['show_bar_chart'] = true;
- $this->viewProperties['show_pie_chart'] = true;
- $this->viewProperties['show_tag_cloud'] = true;
- $this->viewProperties['show_export_as_image_icon'] = false;
- $this->viewProperties['show_export_as_rss_feed'] = true;
- $this->viewProperties['show_exclude_low_population'] = true;
- $this->viewProperties['show_offset_information'] = true;
- $this->viewProperties['show_pagination_control'] = true;
- $this->viewProperties['show_limit_control'] = false;
- $this->viewProperties['show_footer'] = true;
- $this->viewProperties['show_related_reports'] = true;
- $this->viewProperties['exportLimit'] = Config::getInstance()->General['API_datatable_default_limit'];
- $this->viewProperties['highlight_summary_row'] = false;
+ $this->viewProperties['visualization_properties'] = new VisualizationPropertiesProxy($visualizationClass);
$this->viewProperties['metadata'] = array();
- $this->viewProperties['relatedReports'] = array();
- $this->viewProperties['title'] = 'unknown';
- $this->viewProperties['tooltip_metadata_name'] = false;
- $this->viewProperties['enable_sort'] = true;
- $this->viewProperties['disable_generic_filters'] = false;
- $this->viewProperties['disable_queued_filters'] = false;
- $this->viewProperties['keep_summary_row'] = false;
- $this->viewProperties['filter_excludelowpop'] = false;
- $this->viewProperties['filter_excludelowpop_value'] = false;
- $this->viewProperties['filter_pattern'] = false;
- $this->viewProperties['filter_column'] = false;
- $this->viewProperties['filter_limit'] = false;
- $this->viewProperties['filter_sort_column'] = false;
- $this->viewProperties['filter_sort_order'] = false;
- $this->viewProperties['custom_parameters'] = array();
- $this->viewProperties['translations'] = array_merge(
- Metrics::getDefaultMetrics(),
- Metrics::getDefaultProcessedMetrics()
- );
- $this->viewProperties['request_parameters_to_modify'] = array();
- $this->viewProperties['documentation'] = false;
- $this->viewProperties['subtable_controller_action'] = false;
- $this->viewProperties['datatable_css_class'] = $this->getDefaultDataTableCssClass();
- $this->viewProperties['selectable_columns'] = array(); // TODO: only valid for graphs... shouldn't be here.
+ $this->viewProperties['translations'] = array();
$this->viewProperties['filters'] = array();
- $this->viewProperties['show_series_picker'] = true; // TODO: only for graphs.
- $this->viewProperties['graph_limit'] = false; // TODO: only for graph.
- $this->viewProperties['columns_to_display'] = array();
-
- $columns = Common::getRequestVar('columns', false);
- if ($columns !== false) {
- $this->viewProperties['columns_to_display'] = Piwik::getArrayFromApiParameter($columns);
- array_unshift($this->viewProperties['columns_to_display'], 'label');
+ $this->viewProperties['related_reports'] = array();
+
+ list($currentControllerName, $currentControllerAction) = explode('.', $currentControllerAction);
+ $this->currentControllerName = $currentControllerName;
+ $this->currentControllerAction = $currentControllerAction;
+
+ $this->setDefaultProperties();
+
+ foreach ($viewProperties as $name => $value) {
+ $this->setViewProperty($name, $value);
}
+
+ $queryParams = Url::getArrayFromCurrentQueryString();
+ foreach ($this->getClientSideProperties() as $name) {
+ if (isset($queryParams[$name])) {
+ $this->setViewProperty($name, $queryParams[$name]);
+ }
+ }
+
+ $this->idSubtable = Common::getRequestVar('idSubtable', false, 'int');
+ $this->viewProperties['show_footer_icons'] = ($this->idSubtable == false);
+ $this->viewProperties['apiMethodToRequestDataTable'] = $apiMethodToRequestDataTable;
+
+ $this->viewProperties['report_id'] = $currentControllerName . '.' . $currentControllerAction;
+ $this->viewProperties['self_url'] = $this->getBaseReportUrl($currentControllerName, $currentControllerAction);
+
+ // the exclude low population threshold value is sometimes obtained by requesting data.
+ // to avoid issuing unecessary requests when display properties are determined by metadata,
+ // we allow it to be a closure.
+ if (isset($this->viewProperties['filter_excludelowpop_value'])
+ && $this->viewProperties['filter_excludelowpop_value'] instanceof \Closure
+ ) {
+ $function = $this->viewProperties['filter_excludelowpop_value'];
+ $this->viewProperties['filter_excludelowpop_value'] = $function();
+ }
+
+ $this->loadDocumentation();
}
/**
@@ -219,30 +201,11 @@ class ViewDataTable
}
/**
- * TODO
+ * Hack to allow property access in Twig (w/ property name checking).
*/
- public function main()
+ public function __call($name, $arguments)
{
- if ($this->mainAlreadyExecuted) {
- return;
- }
- $this->mainAlreadyExecuted = true;
-
- $visualization = new $this->visualizationClass($this);
-
- try {
- $this->loadDataTableFromAPI();
- } catch (NoAccessException $e) {
- throw $e;
- } catch (\Exception $e) {
- Piwik::log("Failed to get data from API: " . $e->getMessage());
-
- $this->loadingError = array('message' => $e->getMessage());
- }
-
- $this->postDataTableLoadedFromAPI();
-
- $this->view = $this->buildView($visualization);
+ return $this->$name;
}
/**
@@ -250,7 +213,7 @@ class ViewDataTable
*
* @return string
*/
- protected function getViewDataTableId()
+ public function getViewDataTableId()
{
$klass = $this->visualizationClass;
return $klass::getViewDataTableId($this);
@@ -268,81 +231,36 @@ class ViewDataTable
* @param string|bool $controllerAction
* @return ViewDataTable
*/
- static public function factory($defaultType = null, $apiAction = false, $controllerAction = false)
+ static public function factory($defaultType = null, $apiAction = false, $controllerAction = false, $forceDefault = false)
{
- if ($apiAction !== false) {
- $defaultProperties = self::getDefaultPropertiesForReport($apiAction);
- if (isset($defaultProperties['default_view_type'])) {
- $defaultType = $defaultProperties['default_view_type'];
- }
-
- if ($controllerAction === false) {
- $controllerAction = $apiAction;
- }
+ if ($controllerAction === false) {
+ $controllerAction = $apiAction;
}
- if ($defaultType === null) {
- $defaultType = 'table';
+ $defaultProperties = self::getDefaultPropertiesForReport($apiAction);
+ if (!empty($defaultProperties['default_view_type'])
+ && !$forceDefault
+ ) {
+ $defaultType = $defaultProperties['default_view_type'];
}
- $type = Common::getRequestVar('viewDataTable', $defaultType, 'string');
- switch ($type) {
- case 'cloud':
- $result = new ViewDataTable\Cloud();
- break;
-
- case 'graphPie':
- $result = new ViewDataTable('\\Piwik\\Visualization\\JqplotGraph\\Pie');
- break;
-
- case 'graphVerticalBar':
- $result = new ViewDataTable('\\Piwik\\Visualization\\JqplotGraph\\Bar');
- break;
-
- case 'graphEvolution':
- $result = new ViewDataTable('\\Piwik\\Visualization\\JqplotGraph\\Evolution');
- break;
-
- case 'sparkline':
- $result = new ViewDataTable\Sparkline();
- break;
-
- case 'tableAllColumns': // for backwards compatibility TODO: shouldn't require this viewdatatable... (same for Goals)
- $result = new ViewDataTable('\\Piwik\\Visualization\\HtmlTable');
- $result->show_extra_columns = true;
- break;
-
- case 'tableGoals': // for backwards compatibility
- $result = new ViewDataTable('\\Piwik\\Visualization\\HtmlTable');
- $result->show_goals_columns = true;
- break;
-
- case 'table':
- default:
- $result = new ViewDataTable('\\Piwik\\Visualization\\HtmlTable');
- break;
- }
-
- if ($apiAction !== false) {
- list($plugin, $controllerAction) = explode('.', $controllerAction);
-
- $subtableAction = $controllerAction;
- if (isset($defaultProperties['subtable_action'])) {
- $subtableAction = $defaultProperties['subtable_action'];
- }
-
- $result->init($plugin, $controllerAction, $apiAction, $subtableAction, $defaultProperties);
+ $type = Common::getRequestVar('viewDataTable', $defaultType ?: 'table', 'string');
+
+ if ($type == 'sparkline') {
+ $result = new ViewDataTable\Sparkline($controllerAction, $apiAction, $defaultProperties);
+ } else {
+ $result = new ViewDataTable($controllerAction, $apiAction, $defaultProperties, $type);
}
return $result;
}
/**
- * Returns the list of view properties that can be overridden by query parameters.
+ * TODO
*
* @return array
*/
- public function getOverridableProperties()
+ public function getClientSideProperties()
{
$result = array(
'show_search',
@@ -350,7 +268,6 @@ class ViewDataTable
'show_table_all_columns',
'show_all_views_icons',
'show_active_view_icon',
- 'hide_annotations_view',
'show_barchart',
'show_piechart',
'show_tag_cloud',
@@ -361,12 +278,12 @@ class ViewDataTable
'show_pagination_control',
'show_footer',
'show_related_reports',
- 'columns'
+ 'keep_summary_row',
);
if ($this->visualizationClass) {
$klass = $this->visualizationClass;
- $result = array_merge($result, $klass::getOverridableProperties());
+ $result = array_merge($result, $klass::getClientSideProperties());
}
return $result;
@@ -378,13 +295,12 @@ class ViewDataTable
*
* @return array
*/
- public function getJavaScriptProperties()
+ public function getClientSideParameters()
{
$result = array(
'enable_sort',
'disable_generic_filters',
'disable_queued_filters',
- 'keep_summary_row',
'filter_excludelowpop',
'filter_excludelowpop_value',
'filter_pattern',
@@ -396,103 +312,12 @@ class ViewDataTable
if ($this->visualizationClass) {
$klass = $this->visualizationClass;
- $result = array_merge($result, $klass::getJavaScriptProperties());
+ $result = array_merge($result, $klass::getClientSideParameters());
}
return $result;
}
- /**
- * Inits the object given the $currentControllerName, $currentControllerAction of
- * the calling controller action, eg. 'Referers' 'getLongListOfKeywords'.
- * The initialization also requires the $apiMethodToRequestDataTable of the API method
- * to call in order to get the DataTable, eg. 'Referers.getKeywords'.
- * The optional $controllerActionCalledWhenRequestSubTable defines the method name of the API to call when there is a idSubtable.
- * This value would be used by the javascript code building the GET request to the API.
- *
- * Example:
- * For the keywords listing, a click on the row loads the subTable of the Search Engines for this row.
- * In this case $controllerActionCalledWhenRequestSubTable = 'getSearchEnginesFromKeywordId'.
- * The GET request will hit 'Referers.getSearchEnginesFromKeywordId'.
- *
- * @param string $currentControllerName eg. 'Referers'
- * @param string $currentControllerAction eg. 'getKeywords'
- * @param string $apiMethodToRequestDataTable eg. 'Referers.getKeywords'
- * @param string $controllerActionCalledWhenRequestSubTable eg. 'getSearchEnginesFromKeywordId'
- * @param array $defaultProperties
- */
- public function init($currentControllerName,
- $currentControllerAction,
- $apiMethodToRequestDataTable,
- $controllerActionCalledWhenRequestSubTable = null,
- $defaultProperties = array())
- {
- $this->currentControllerName = $currentControllerName;
- $this->currentControllerAction = $currentControllerAction;
- $this->viewProperties['subtable_controller_action'] = $controllerActionCalledWhenRequestSubTable;
- $this->idSubtable = Common::getRequestVar('idSubtable', false, 'int');
-
- foreach ($defaultProperties as $name => $value) {
- $this->setViewProperty($name, $value);
- }
-
- $queryParams = Url::getArrayFromCurrentQueryString();
- foreach ($this->getOverridableProperties() as $name) {
- if (isset($queryParams[$name])) {
- $this->setViewProperty($name, $queryParams[$name]);
- }
- }
-
- $this->viewProperties['show_footer_icons'] = ($this->idSubtable == false);
- $this->viewProperties['apiMethodToRequestDataTable'] = $apiMethodToRequestDataTable;
-
- $this->viewProperties['report_id'] = $currentControllerName . '.' . $currentControllerAction;
- $this->viewProperties['self_url'] = $this->getBaseReportUrl($currentControllerName, $currentControllerAction);
-
- // the exclude low population threshold value is sometimes obtained by requesting data.
- // to avoid issuing unecessary requests when display properties are determined by metadata,
- // we allow it to be a closure.
- if (isset($this->viewProperties['filter_excludelowpop_value'])
- && $this->viewProperties['filter_excludelowpop_value'] instanceof \Closure
- ) {
- $function = $this->viewProperties['filter_excludelowpop_value'];
- $this->viewProperties['filter_excludelowpop_value'] = $function();
- }
-
- $this->loadDocumentation();
- }
-
- /**
- * Forces the View to use a given template.
- * Usually the template to use is set in the specific ViewDataTable_*
- * eg. 'CoreHome/templates/cloud'
- * But some users may want to force this template to some other value
- *
- * TODO: after visualization refactor, should remove this.
- *
- * @param string $tpl eg .'@MyPlugin/templateToUse'
- */
- public function setTemplate($tpl)
- {
- $this->viewProperties['datatable_template'] = $tpl;
- }
-
- /**
- * Returns the View_Interface.
- * You can then call render() on this object.
- *
- * @return View\ViewInterface
- * @throws \Exception if the view object was not created
- */
- public function getView()
- {
- if (is_null($this->view)) {
- throw new \Exception('The $this->view object has not been created.
- It should be created in the main() method of the ViewDataTable_* subclass you are using.');
- }
- return $this->view;
- }
-
public function getCurrentControllerAction()
{
return $this->currentControllerAction;
@@ -561,7 +386,7 @@ class ViewDataTable
/**
* Sets a view property by name. This function handles special view properties
- * like 'translations' & 'relatedReports' that store arrays.
+ * like 'translations' & 'related_reports' that store arrays.
*
* @param string $name
* @param mixed $value For array properties, $value can be a comma separated string.
@@ -579,10 +404,40 @@ class ViewDataTable
|| $name == 'filters'
) {
$this->viewProperties[$name] = array_merge($this->viewProperties[$name], $value);
- } else if ($name == 'relatedReports') {
+ } else if ($name == 'related_reports') { // TODO: should process after (in overrideViewProperties)
$this->addRelatedReports($value);
- } else {
+ } else if ($name == 'visualization_properties') {
+ $this->setVisualizationPropertiesFromMetadata($value);
+ } else if (Properties::isCoreViewProperty($name)) {
$this->viewProperties[$name] = $value;
+ } else {
+ $report = $this->currentControllerName . '.' . $this->currentControllerAction;
+ throw new \Exception("Invalid view property '$name' specified in view property metadata for '$report'.");
+ }
+ }
+
+ /**
+ * TODO
+ */
+ private function setVisualizationPropertiesFromMetadata($properties)
+ {
+ if ($this->visualizationClass === null) {
+ return null;
+ }
+
+ $visualizationIds = DataTableVisualization::getVisualizationIdsWithInheritance($this->visualizationClass);
+ foreach ($visualizationIds as $visualizationId) {
+ if (empty($properties[$visualizationId])) {
+ continue;
+ }
+
+ foreach ($properties[$visualizationId] as $key => $value) {
+ if (Properties::isCoreViewProperty($key)) {
+ $this->viewProperties[$key] = $value;
+ } else {
+ $this->viewProperties['visualization_properties']->$key = $value;
+ }
+ }
}
}
@@ -658,8 +513,6 @@ class ViewDataTable
*/
protected function postDataTableLoadedFromAPI()
{
- $this->overrideViewProperties();
-
if (empty($this->dataTable)) {
return false;
}
@@ -899,7 +752,7 @@ class ViewDataTable
// case of the filter without default values and parameters set directly in this class
// for example setExcludeLowPopulation
// we go through all the $this->viewProperties array and set the variables not set yet
- foreach ($this->getJavaScriptProperties() as $name) {
+ foreach ($this->getClientSideParameters() as $name) {
if (!isset($javascriptVariablesToSet[$name])
&& !empty($this->viewProperties[$name])
) {
@@ -962,6 +815,20 @@ class ViewDataTable
}
/**
+ * TODO
+ */
+ private function getClientSidePropertiesToSet()
+ {
+ $result = array();
+ foreach ($this->getClientSideProperties() as $name) {
+ if (isset($this->viewProperties[$name])) {
+ $result[$name] = $this->viewProperties[$name];
+ }
+ }
+ return $result;
+ }
+
+ /**
* Returns, for a given parameter, the value of this parameter in the REQUEST array.
* If not set, returns the default value for this parameter @see getDefault()
*
@@ -1038,7 +905,7 @@ class ViewDataTable
}
$url = $this->getBaseReportUrl($module, $action, $queryParams);
- $this->viewProperties['relatedReports'][$url] = $title;
+ $this->viewProperties['related_reports'][$url] = $title;
}
private function addRelatedReports($relatedReports)
@@ -1148,8 +1015,8 @@ class ViewDataTable
*/
public function render()
{
- $this->main();
- return $this->getView()->render();
+ $this->buildView();
+ return $this->view->render();
}
/**
@@ -1173,21 +1040,28 @@ class ViewDataTable
$this->viewProperties['show_goals'] = false;
}
- if (!PluginsManager::getInstance()->isPluginLoaded('Annotations')) {
- $this->viewProperties['hide_annotations_view'] = true;
- }
-
- if ($this->idSubtable) {
- $this->viewProperties['datatable_template'] = $this->viewProperties['subtable_template'];
- }
-
if ($this->viewProperties['filter_limit'] == 0) { // TODO: should be possible to set limit to 0 (for whatever reason)
$this->viewProperties['filter_limit'] = false;
}
}
- protected function buildView($visualization)
+ protected function buildView()
{
+ $visualization = new $this->visualizationClass($this);
+
+ try {
+ $this->loadDataTableFromAPI();
+ $this->postDataTableLoadedFromAPI();
+ } catch (NoAccessException $e) {
+ throw $e;
+ } catch (\Exception $e) {
+ Piwik::log("Failed to get data from API: " . $e->getMessage());
+
+ $this->loadingError = array('message' => $e->getMessage());
+ }
+
+ $this->overrideViewProperties();
+
$template = $this->viewProperties['datatable_template'];
$view = new View($template);
@@ -1196,7 +1070,8 @@ class ViewDataTable
}
$view->visualization = $visualization;
-
+ $view->visualizationCssClass = $this->getDefaultDataTableCssClass();
+
if (!$this->dataTable === null) {
$view->dataTable = null;
} else {
@@ -1208,8 +1083,12 @@ class ViewDataTable
$view->deleteReportsOlderThan = Piwik_GetOption('delete_reports_older_than');
}
$view->javascriptVariablesToSet = $this->getJavascriptVariablesToSet();
- $view->properties = $this->viewProperties;
- return $view;
+ $view->clientSidePropertiesToSet = $this->getClientSidePropertiesToSet();
+ $view->properties = $this->viewProperties; // TODO: should be $this. need to move non-view properties from the class
+
+ $nonCoreVisualizations = DataTableVisualization::getNonCoreVisualizations();
+ $view->nonCoreVisualizations = DataTableVisualization::getVisualizationInfoFor($nonCoreVisualizations);
+ $this->view = $view;
}
public function getDefaultDataTableCssClass()
@@ -1217,22 +1096,24 @@ class ViewDataTable
return 'dataTableViz' . Piwik::getUnnamespacedClassName($this->visualizationClass);
}
- /**
- * Sets view properties if they have not been set already.
- */
- public function defaultPropertiesTo($defaultValues)
+ private function setViewProperties($values)
{
- // TODO: This approach won't work. Will require more typing, but allow there to be a static
- // getDefaultProperties function for visualizations. used by constructor.
- $defaultView = new ViewDataTable(); // bit of a hack...
-
- foreach ($defaultValues as $name => $value) {
- if (!array_key_exists($name, $this->viewProperties)
- || (isset($defaultView->viewProperties[$name])
- && $this->viewProperties[$name] === $defaultView->viewProperties[$name])
- ) {
- $this->viewProperties[$name] = $value;
- }
+ foreach ($values as $name => $value) {
+ $this->setViewProperty($name, $value);
}
}
+
+ private function setDefaultProperties()
+ {
+ // set core default properties
+ $this->setViewProperties(Properties::getDefaultPropertyValues());
+
+ // set visualization default properties
+ if ($this->visualizationClass === null) {
+ return;
+ }
+
+ $visualizationClass = $this->visualizationClass;
+ $this->setViewProperties($visualizationClass::getDefaultPropertyValues());
+ }
} \ No newline at end of file
diff --git a/core/ViewDataTable/Cloud.php b/core/ViewDataTable/Cloud.php
deleted file mode 100644
index 653cc8c022..0000000000
--- a/core/ViewDataTable/Cloud.php
+++ /dev/null
@@ -1,81 +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
- *
- * @category Piwik
- * @package Piwik
- */
-namespace Piwik\ViewDataTable;
-
-use Exception;
-use Piwik\ViewDataTable;
-use Piwik\View;
-use Piwik;
-use Piwik\Visualization;
-
-/**
- * Reads the requested DataTable from the API, and prepares the data to give
- * to Cloud that will display the tag cloud (via the template _dataTable_cloud.twig).
- *
- * @package Piwik
- * @subpackage ViewDataTable
- */
-class Cloud extends ViewDataTable
-{
- /**
- * @param bool $bool
- */
- public function setDisplayLogoInTagCloud($bool)
- {
- $this->viewProperties['display_logo_instead_of_label'] = $bool;
- }
-
- /**
- * Returns the dataTable id for the view
- *
- * @return string
- */
- protected function getViewDataTableId()
- {
- return 'cloud';
- }
-
- public function __construct()
- {
- parent::__construct();
-
- $this->viewProperties['show_offset_information'] = false;
- $this->viewProperties['show_exclude_low_population'] = false;
- $this->viewProperties['display_logo_instead_of_label'] = false;
- }
-
- /**
- * @see ViewDataTable::main()
- *
- * @return null
- */
- public function main()
- {
- if ($this->mainAlreadyExecuted) {
- return;
- }
- $this->mainAlreadyExecuted = true;
-
- try {
- $this->loadDataTableFromAPI();
- } catch (Exception $e) {
- Piwik\Piwik::log("Failed to get data from API: " . $e->getMessage());
-
- $this->loadingError = array('message' => $e->getMessage());
- }
-
- $this->checkStandardDataTable();
- $this->postDataTableLoadedFromAPI();
-
- $visualization = new Visualization\Cloud();
- $this->view = $this->buildView($visualization);
- }
-}
diff --git a/core/ViewDataTable/Properties.php b/core/ViewDataTable/Properties.php
index 8d55d5a926..457069dbb7 100644
--- a/core/ViewDataTable/Properties.php
+++ b/core/ViewDataTable/Properties.php
@@ -13,18 +13,29 @@ namespace Piwik\ViewDataTable;
use Exception;
use ReflectionClass;
+use Piwik\Piwik;
+use Piwik\Config;
+use Piwik\Metrics;
+use Piwik\Common;
/**
* Contains the list of all core DataTable display properties for use with ViewDataTable.
*
* @see ViewDataTable - for more info.
*
- * TODO: change the names of properties to match the const names where appropriate.
* TODO: list default value for each property
*/
class Properties
{
/**
+ * The default viewDataTable ID to use when determining which visualization to use.
+ * This property is only valid for reports whose properties are determined by the
+ * ViewDataTable.getReportDisplayProperties event. When manually creating ViewDataTables,
+ * setting this property will have no effect.
+ */
+ const DEFAULT_VIEW_TYPE = 'default_view_type';
+
+ /**
* This property determines which Twig template to use when rendering a ViewDataTable.
*
* TODO: shouldn't have this property. should only use visualization classes.
@@ -54,13 +65,6 @@ class Properties
const SORT_ORDER = 'filter_sort_order';
/**
- * The limit used when rendering a jqPlot graph.
- *
- * TODO: either replace w/ filter_limit, or make it a visualization property.
- */
- const GRAPH_LIMIT = 'graph_limit';
-
- /**
* The number of items to truncate the data set to before rendering the DataTable view.
*/
const LIMIT = 'filter_limit';
@@ -118,23 +122,13 @@ class Properties
const SHOW_ACTIVE_VIEW_ICON = 'show_active_view_icon';
/**
- * TODO: this property is specific ONLY to the row evolution popup. Need to move it.
- */
- const EXTERNAL_SERIES_TOGGLE = 'external_series_toggle';
-
- /**
- * TODO: this property is specific ONLY to the row evolution popup. Need to move it.
- */
- const EXTERNAL_SERIES_TOGGLE_SHOW_ALL = 'external_series_toggle_show_all';
-
- /**
* Related reports are listed below a datatable view. When clicked, the original report will
* change to the clicked report and the list will change so the original report can be
* navigated back to.
*
* @see also self::TITLE. Both must be set if associating related reports.
*/
- const RELATED_REPORTS = 'relatedReports';
+ const RELATED_REPORTS = 'related_reports';
/**
* The report title. Used with related reports so report headings can be changed when switching
@@ -150,13 +144,6 @@ class Properties
const SHOW_RELATED_REPORTS = 'show_related_reports';
/**
- * Array property that contains the names of columns that can be selected in the Series Picker.
- *
- * TODO: this is only applicable to graph views. move this.
- */
- const SELECTABLE_COLUMNS = 'selectable_columns';
-
- /**
* Contains the documentation for a report.
*/
const REPORT_DOCUMENTATION = 'documentation';
@@ -196,7 +183,7 @@ class Properties
*
* @see self::ROW_PICKER_VISIBLE_VALUES
*/
- const ROW_PICKER_VALUE_COLUMN = 'row_picker_mach_rows_by';
+ const ROW_PICKER_VALUE_COLUMN = 'row_picker_match_rows_by';
/**
* Contains the list of values available for the Row Picker.
@@ -228,13 +215,6 @@ class Properties
const ALWAYS_SHOW_LIMIT_DROPDOWN = 'show_limit_control';
/**
- * Controls whether offset information (ie, '5-10 of 20') is shown under the datatable.
- *
- * @see TODO
- */
- const SHOW_OFFSET_INFORMATION = 'show_offset_information';
-
- /**
* Controls whether the search box under the datatable is shown.
*/
const SHOW_SEARCH_BOX = 'show_search';
@@ -245,12 +225,6 @@ class Properties
const ENABLE_SORT = 'enable_sort';
/**
- * Controls whether annotations are shown or not.
- * TODO: This is only appropriate for evolution graphs. Move it.
- */
- const HIDE_ANNOTATIONS_VIEW = 'hide_annotations_view';
-
- /**
* Controls whether the footer icon that allows users to view data as a bar chart is shown.
*/
const SHOW_BAR_CHART_ICON = 'show_bar_chart';
@@ -339,18 +313,8 @@ class Properties
const VISUALIZATION_PROPERTIES = 'visualization_properties';
/**
- * Custom template used if displaying a subtable.
- *
- * TODO: This is specific to HtmlTable and should be replaced w/ allowing custom visualization for
- * subtables. Should not directly touch template.
- */
- const SUBTABLE_TEMPLATE = 'subtable_template';
-
- /**
- * CSS class to use in the output HTML div.
- *
- * TODO: This only changes based on the visualization type. Would be good if it didn't need to be
- * set at all...
+ * CSS class to use in the output HTML div. This is added in addition to the visualization CSS
+ * class.
*/
const DATATABLE_CSS_CLASS = 'datatable_css_class';
@@ -361,14 +325,6 @@ class Properties
const DATATABLE_JS_TYPE = 'datatable_js_type';
/**
- * Controls whether the entire DataTable should be rendered (including subtables) or just one
- * specific table in the tree.
- *
- * TODO: specific to htmltable. make a visualization property.
- */
- const SHOW_EXPANDED = 'show_expanded';
-
- /**
* If true, searching through the DataTable will search through all subtables.
*
* @see also self::FILTER_PATTERN
@@ -376,81 +332,16 @@ class Properties
const DO_RECURSIVE_SEARCH = 'search_recursive';
/**
- * Controls whether the row evolution DataTable Row Action icon is shown or not.
- *
- * TODO: specific to HtmlTable. move.
- *
- * @see also self::DISABLE_ROW_ACTIONS
- */
- const DISABLE_ROW_EVOLUTION = 'disable_row_evolution';
-
- /**
- * Controls whether any DataTable Row Action icons are shown. If true, no icons are shown.
- *
- * TODO: specific to HtmlTable. move.
- *
- * @see also self::DISABLE_ROW_EVOLUTION
- */
- const DISABLE_ROW_ACTIONS = 'disable_row_actions';
-
- /**
* The unit of the displayed column. Valid if only one non-label column is displayed.
*/
const DISPLAYED_COLUMN_UNIT = 'y_axis_unit';
/**
- * Controls whether the percentage of the total is displayed as a tooltip in Jqplot graphs.
- *
- * NOTE: Sometimes this percentage is meaningless (when the total of the column values is
- * not the total number of elements in the set). In this case the tooltip should not be
- * displayed.
- *
- * TODO: only valid for graphs... move it.
- */
- const DISPLAY_PERCENTAGE_IN_TOOLTIP = 'display_percentage_in_tooltip';
-
- /**
* Controls whether to show the 'Export as Image' footer icon.
*/
const SHOW_EXPORT_AS_IMAGE_ICON = 'show_export_as_image_icon';
/**
- * Controls whether all ticks & labels are shown on a graph's x-axis or just some.
- *
- * TODO: only for jqplot graphs.
- */
- const SHOW_ALL_TICKS = 'show_all_ticks';
-
- /**
- * If true, a row with totals of each DataTable column is added.
- *
- * TODO: only for jqplot graphs. also doesn't seem necessary w/ AddSummaryRow
- */
- const ADD_TOTAL_ROW = 'add_total_row';
-
- /**
- * If true, the 'label', 'nb_visits', 'nb_uniq_visitors' (if present), 'nb_actions',
- * 'nb_actions_per_visit', 'avg_time_on_site', 'bounce_rate' and 'conversion_rate' (if
- * goals view is not allowed) are displayed.
- *
- * TODO: HtmlTable property, only. Move.
- */
- const SHOW_EXTRA_COLUMNS = 'show_extra_columns';
-
- /**
- * If true, conversions for each existing goal will be displayed for the visits in
- * each row.
- *
- * TODO: HtmlTable property, only. Move.
- */
- const SHOW_GOALS_COLUMNS = 'show_goals_columns';
-
- /**
- * TODO: HtmlTable property, only. Move.
- */
- const DISABLE_SUBTABLE_IN_GOALS_VIEW = 'disable_subtable_when_show_goals';
-
- /**
* Array of DataTable filters that should be run before displaying a DataTable. Elements
* of this array can either be a closure or an array with at most three elements, including:
* - the filter name (or a closure)
@@ -470,23 +361,38 @@ class Properties
const SUBTABLE_CONTROLLER_ACTION = 'subtable_controller_action';
/**
- * TODO: specific only to jqplot graphs. change to just 'width'?
+ * Controls whether the 'prev'/'next' links are shown in the DataTable footer. These links
+ * change the 'filter_offset' query parameter, thus allowing pagination.
+ *
+ * @see self::SHOW_OFFSET_INFORMATION
+ */
+ const SHOW_PAGINATION_CONTROL = 'show_pagination_control';
+
+ /**
+ * Controls whether offset information (ie, '5-10 of 20') is shown under the datatable.
+ *
+ * @see self::SHOW_PAGINATION_CONTROL
+ */
+ const SHOW_OFFSET_INFORMATION = 'show_offset_information';
+
+ /**
+ * Controls whether annotations are shown or not.
*/
- const GRAPH_WIDTH = 'graph_width';
+ const HIDE_ANNOTATIONS_VIEW = 'hide_annotations_view';
/**
- * TODO: same as GRAPH_WIDTH
+ * The filter_limit query parameter value to use in export links.
*/
- const GRAPH_HEIGHT = 'graph_height';
+ const EXPORT_LIMIT = 'export_limit';
/**
- * TODO: only valid for jqplot graphs.
+ * Controls whether non-Core DataTable visualizations are shown or not.
*/
- const SHOW_SERIES_PICKER = 'show_series_picker';
+ const SHOW_NON_CORE_VISUALIZATIONS = 'show_non_core_visualizations';
/**
* Returns the set of all valid ViewDataTable properties. The result is an array with property
- * name as a key. Values of the array are undefined.
+ * names as keys. Values of the array are undefined.
*
* @return array
*/
@@ -495,14 +401,53 @@ class Properties
static $propertiesCache = null;
if ($propertiesCache === null) {
- $klass = new ReflectionClass(__CLASS__);
- $propertiesCache = array_flip($klass->getConstants());
+ $propertiesCache = self::getFlippedClassConstantMap(__CLASS__);
}
return $propertiesCache;
}
/**
+ * Returns the set of all valid properties for the given visualization class. The result is an
+ * array with property names as keys. Values of the array are undefined.
+ *
+ * @return array
+ */
+ public static function getVisualizationProperties($visualizationClass)
+ {
+ static $propertiesCache = array();
+
+ if ($visualizationClass === null) {
+ return array();
+ }
+
+ if (!isset($propertiesCache[$visualizationClass])) {
+ $properties = self::getFlippedClassConstantMap($visualizationClass);
+
+ $parentClass = get_parent_class($visualizationClass);
+ if ($parentClass != 'Piwik\\DataTableVisualization') {
+ $properties += self::getVisualizationProperties($parentClass);
+ }
+
+ $propertiesCache[$visualizationClass] = $properties;
+ }
+
+ return $propertiesCache[$visualizationClass];
+ }
+
+ /**
+ * Returns true if $name is a core ViewDataTable property, false if not.
+ *
+ * @param string $name
+ * @return bool
+ */
+ public static function isCoreViewProperty($name)
+ {
+ $properties = self::getAllProperties();
+ return isset($properties[$name]);
+ }
+
+ /**
* Checks if a property is a valid ViewDataTable property, and if not, throws an exception.
*
* @param string $name The property name.
@@ -510,10 +455,101 @@ class Properties
*/
public static function checkValidPropertyName($name)
{
- $properties = self::getAllProperties();
+ if (!self::isCoreViewProperty($name)) {
+ throw new Exception("Invalid ViewDataTable display property '$name'.");
+ }
+ }
+
+ /**
+ * Checks if a property is a valid visualization property for the given visualization class,
+ * and if not, throws an exception.
+ *
+ * @param string $visualizationClass
+ * @param string $name The property name.
+ * @throws Exception
+ */
+ public static function checkValidVisualizationProperty($visualizationClass, $name)
+ {
+ $properties = self::getVisualizationProperties($visualizationClass);
if (!isset($properties[$name])) {
- throw new Exception("Invalid ViewDataTable display property '$name'. Is this a visualization property? "
- . "If so, set it with \$view->visualization_properties->$name = ...");
+ throw new Exception("Invalid Visualization display property '$name' for '$visualizationClass'.");
}
}
+
+ /**
+ * Returns the default values for each core view property.
+ *
+ * @return array
+ */
+ public static function getDefaultPropertyValues()
+ {
+ $result = array(
+ 'datatable_template' => '@CoreHome/_dataTable',
+ 'show_goals' => false,
+ 'show_ecommerce' => false,
+ 'show_search' => true,
+ 'show_table' => true,
+ 'show_table_all_columns' => true,
+ 'show_all_views_icons' => true,
+ 'show_active_view_icon' => true,
+ 'show_bar_chart' => true,
+ 'show_pie_chart' => true,
+ 'show_tag_cloud' => true,
+ 'show_export_as_image_icon' => false,
+ 'show_export_as_rss_feed' => true,
+ 'show_exclude_low_population' => true,
+ 'show_offset_information' => true,
+ 'show_pagination_control' => true,
+ 'show_limit_control' => false,
+ 'show_footer' => true,
+ 'show_related_reports' => true,
+ 'show_non_core_visualizations' => true,
+ 'export_limit' => Config::getInstance()->General['API_datatable_default_limit'],
+ 'highlight_summary_row' => false,
+ 'related_reports' => array(),
+ 'title' => 'unknown',
+ 'tooltip_metadata_name' => false,
+ 'enable_sort' => true,
+ 'disable_generic_filters' => false,
+ 'disable_queued_filters' => false,
+ 'keep_summary_row' => false,
+ 'filter_excludelowpop' => false,
+ 'filter_excludelowpop_value' => false,
+ 'filter_pattern' => false,
+ 'filter_column' => false,
+ 'filter_limit' => false,
+ 'filter_sort_column' => false,
+ 'filter_sort_order' => false,
+ 'custom_parameters' => array(),
+ 'translations' => array_merge(
+ Metrics::getDefaultMetrics(),
+ Metrics::getDefaultProcessedMetrics()
+ ),
+ 'request_parameters_to_modify' => array(),
+ 'documentation' => false,
+ 'subtable_controller_action' => false,
+ 'datatable_css_class' => false,
+ 'filters' => array(),
+ 'hide_annotations_view' => true,
+ 'columns_to_display' => array(),
+ );
+
+ $columns = Common::getRequestVar('columns', false);
+ if ($columns !== false) {
+ $result['columns_to_display'] = Piwik::getArrayFromApiParameter($columns);
+ array_unshift($result['columns_to_display'], 'label');
+ }
+
+ return $result;
+ }
+
+ private static function getFlippedClassConstantMap($klass)
+ {
+ $klass = new ReflectionClass($klass);
+ $constants = $klass->getConstants();
+ unset($constants['ID']);
+ unset($constants['FOOTER_ICON']);
+ unset($constants['FOOTER_ICON_TITLE']);
+ return array_flip($constants);
+ }
} \ No newline at end of file
diff --git a/core/ViewDataTable/Sparkline.php b/core/ViewDataTable/Sparkline.php
index 02988a86dd..c3fd116114 100644
--- a/core/ViewDataTable/Sparkline.php
+++ b/core/ViewDataTable/Sparkline.php
@@ -28,7 +28,7 @@ class Sparkline extends ViewDataTable
*
* @return string
*/
- protected function getViewDataTableId()
+ public function getViewDataTableId()
{
return 'sparkline';
}
@@ -37,13 +37,8 @@ class Sparkline extends ViewDataTable
* @see ViewDataTable::main()
* @return mixed
*/
- public function main()
+ protected function buildView()
{
- if ($this->mainAlreadyExecuted) {
- return;
- }
- $this->mainAlreadyExecuted = true;
-
// If period=range, we force the sparkline to draw daily data points
$period = Common::getRequestVar('period');
if ($period == 'range') {
diff --git a/core/ViewDataTable/VisualizationPropertiesProxy.php b/core/ViewDataTable/VisualizationPropertiesProxy.php
index c6ef3f079e..6a39bf8a4d 100644
--- a/core/ViewDataTable/VisualizationPropertiesProxy.php
+++ b/core/ViewDataTable/VisualizationPropertiesProxy.php
@@ -20,11 +20,11 @@ use Piwik\ViewDataTable\Properties;
class VisualizationPropertiesProxy
{
/**
- * The visualization instance.
+ * The visualization class name.
*
- * @var array
+ * @var string
*/
- private $visualization;
+ private $visualizationClass;
/**
* Stores visualization properties.
@@ -36,11 +36,19 @@ class VisualizationPropertiesProxy
/**
* Constructor.
*
- * @param \Piwik\Visualization\ $visualization The visualization to get/set properties of.
+ * @param string $visualizationClass The visualization class to get/set properties of.
+ */
+ public function __construct($visualizationClass)
+ {
+ $this->visualizationClass = $visualizationClass;
+ }
+
+ /**
+ * Hack to allow property access in Twig (w/ property name checking).
*/
- public function __construct($visualization)
+ public function __call($name, $arguments)
{
- $this->visualization = $visualization;
+ return $this->$name;
}
/**
@@ -52,7 +60,10 @@ class VisualizationPropertiesProxy
*/
public function &__get($name)
{
- Properties::checkValidVisualizationProperty($this->visualization, $name);
+ if ($this->visualizationClass !== null) {
+ Properties::checkValidVisualizationProperty($this->visualizationClass, $name);
+ }
+
return $this->visualizationProperties[$name];
}
@@ -66,7 +77,10 @@ class VisualizationPropertiesProxy
*/
public function __set($name, $value)
{
- Properties::checkValidVisualizationProperty($this->visualization, $name);
+ if ($this->visualizationClass !== null) {
+ Properties::checkValidVisualizationProperty($this->visualizationClass, $name);
+ }
+
return $this->visualizationProperties[$name] = $value;
}
} \ No newline at end of file
diff --git a/core/Visualization/JqplotGraph.php b/core/Visualization/JqplotGraph.php
deleted file mode 100644
index caa125f702..0000000000
--- a/core/Visualization/JqplotGraph.php
+++ /dev/null
@@ -1,132 +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
- *
- * @category Piwik
- * @package Piwik
- */
-
-namespace Piwik\Visualization;
-
-use Piwik\Common;
-use Piwik\View;
-use Piwik\JqplotDataGenerator;
-use Piwik\DataTable;
-use Piwik\DataTableVisualization;
-
-/**
- * DataTable visualization that displays DataTable data in a JQPlot graph.
- * TODO: should merge all this logic w/ jqplotdatagenerator & 'Chart' visualizations.
- */
-class JqplotGraph extends DataTableVisualization
-{
- const DEFAULT_GRAPH_HEIGHT = 250;
-
- /**
- * TODO
- */
- public function __construct($view)
- {
- // Graphs require the full dataset, so no filters
- $this->request_parameters_to_modify['disable_generic_filters'] = true;
-
- // 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->request_parameters_to_modify['disable_queued_filters'] = true;
-
- $view->defaultPropertiesTo($this->getDefaultPropertyValues($view));
-
- if ($view->show_goals) {
- $goalMetrics = array('nb_conversions', 'revenue');
- $view->selectable_columns = array_merge($view->selectable_columns, $goalMetrics);
-
- $view->translations['nb_conversions'] = Piwik_Translate('Goals_ColumnConversions');
- $view->translations['revenue'] = Piwik_Translate('General_TotalRevenue');
- }
-
- $view->datatable_css_class = 'dataTableGraph'; // TODO: should be different css per visualization
- }
-
- /**
- * TODO
- */
- protected function getDefaultPropertyValues($view)
- {
- $result = array(
- 'show_offset_information' => false,
- 'show_pagination_control' => false,
- 'show_exclude_low_population' => false,
- 'show_search' => false,
- 'show_export_as_image_icon' => true,
- 'display_percentage_in_tooltip' => true,
- 'display_percentage_in_tooltip' => true,
- 'y_axis_unit' => '',
- 'show_all_ticks' => 0,
- 'add_total_row' => 0,
- 'allow_multi_select_series_picker' => true,
- 'row_picker_mach_rows_by' => false,
- 'row_picker_visible_rows' => array(),
- 'selectable_columns' => array(),
- 'graph_width' => '100%',
- 'graph_height' => self::DEFAULT_GRAPH_HEIGHT . 'px'
- );
-
- // do not sort if sorted column was initially "label" or eg. it would make "Visits by Server time" not pretty
- if ($view->filter_sort_column != 'label') {
- $columns = $view->columns_to_display;
-
- $firstColumn = reset($columns);
- if ($firstColumn == 'label') {
- $firstColumn = next($columns);
- }
-
- $result['filter_sort_column'] = $firstColumn;
- $result['filter_sort_order'] = 'desc';
- }
-
- // selectable columns
- $selectableColumns = array('nb_visits', 'nb_actions');
- if (Common::getRequestVar('period', false) == 'day') {
- $selectableColumns[] = 'nb_uniq_visitors';
- }
- $result['selectable_columns'] = $selectableColumns;
-
- return $result;
- }
-
- /**
- * Renders this visualization.
- *
- * @param DataTable $dataTable
- * @param array $properties View Properties.
- * @return string
- */
- public function render($dataTable, $properties)
- {
- $view = new View("@CoreHome/_dataTableViz_jqplotGraph.twig");
- $view->properties = $properties;
- $view->dataTable = $dataTable;
- $view->data = $this->getGraphData($dataTable, $properties);
- return $view->render();
- }
-
- /**
- * Generats JQPlot graph data for a DataTable.
- */
- private function getGraphData($dataTable, $properties)
- {
- $properties = array_merge($properties, $properties['request_parameters_to_modify']);
- $dataGenerator = $this->makeDataGenerator($properties);
-
- $jsonData = $dataGenerator->generate($dataTable);
- return str_replace(array("\r", "\n"), '', $jsonData);
- }
-
- protected function makeDataGenerator($properties)
- {
- return JqplotDataGenerator::factory($properties['graph_type'], $properties);
- }
-} \ No newline at end of file
diff --git a/core/Visualization/JqplotGraph/Bar.php b/core/Visualization/JqplotGraph/Bar.php
deleted file mode 100644
index 72de0beb8a..0000000000
--- a/core/Visualization/JqplotGraph/Bar.php
+++ /dev/null
@@ -1,35 +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
- *
- * @category Piwik
- * @package Piwik
- */
-
-namespace Piwik\Visualization\JqplotGraph;
-
-use Piwik\Visualization\JqplotGraph;
-use Piwik\JqplotDataGenerator;
-
-/**
- * TODO
- */
-class Bar extends JqplotGraph
-{
- const ID = 'graphVerticalBar';
-
- protected function getDefaultPropertyValues($view)
- {
- $result = parent::getDefaultPropertyValues($view);
- $result['graph_limit'] = 6;
- return $result;
- }
-
- protected function makeDataGenerator($properties)
- {
- return JqplotDataGenerator::factory('bar', $properties);
- }
-} \ No newline at end of file
diff --git a/core/Visualization/JqplotGraph/Pie.php b/core/Visualization/JqplotGraph/Pie.php
deleted file mode 100644
index b7fbcf4b4d..0000000000
--- a/core/Visualization/JqplotGraph/Pie.php
+++ /dev/null
@@ -1,36 +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
- *
- * @category Piwik
- * @package Piwik
- */
-
-namespace Piwik\Visualization\JqplotGraph;
-
-use Piwik\Visualization\JqplotGraph;
-use Piwik\JqplotDataGenerator;
-
-/**
- * TODO
- */
-class Pie extends JqplotGraph
-{
- const ID = 'graphPie';
-
- protected function getDefaultPropertyValues($view)
- {
- $result = parent::getDefaultPropertyValues($view);
- $result['graph_limit'] = 6;
- $result['allow_multi_select_series_picker'] = false;
- return $result;
- }
-
- protected function makeDataGenerator($properties)
- {
- return JqplotDataGenerator::factory('pie', $properties);
- }
-} \ No newline at end of file
diff --git a/plugins/Actions/API.php b/plugins/Actions/API.php
index 768389f8c0..538adccc8b 100644
--- a/plugins/Actions/API.php
+++ b/plugins/Actions/API.php
@@ -122,9 +122,11 @@ class Piwik_Actions_API
*
* @return DataTable|DataTable\Map
*/
- public function getPageUrls($idSite, $period, $date, $segment = false, $expanded = false, $idSubtable = false)
+ public function getPageUrls($idSite, $period, $date, $segment = false, $expanded = false, $idSubtable = false,
+ $depth = false)
{
- $dataTable = Archive::getDataTableFromArchive('Actions_actions_url', $idSite, $period, $date, $segment, $expanded, $idSubtable);
+ $dataTable = Archive::getDataTableFromArchive(
+ 'Actions_actions_url', $idSite, $period, $date, $segment, $expanded, $idSubtable, $depth);
$this->filterPageDatatable($dataTable);
$this->filterActionsDataTable($dataTable, $expanded);
return $dataTable;
diff --git a/plugins/Actions/Actions.php b/plugins/Actions/Actions.php
index 2d78cf9959..20b3985e14 100644
--- a/plugins/Actions/Actions.php
+++ b/plugins/Actions/Actions.php
@@ -60,9 +60,15 @@ class Piwik_Actions extends Plugin
'API.getReportMetadata' => 'getReportMetadata',
'API.getSegmentsMetadata' => 'getSegmentsMetadata',
'ViewDataTable.getReportDisplayProperties' => 'getReportDisplayProperties',
+ 'AssetManager.getCssFiles' => 'getCssFiles',
);
return $hooks;
}
+
+ public function getCssFiles(&$cssFiles)
+ {
+ $cssFiles[] = "plugins/Actions/stylesheets/dataTableActions.less";
+ }
public function getSegmentsMetadata(&$segments)
{
@@ -647,9 +653,9 @@ class Piwik_Actions extends Plugin
private function addBaseDisplayProperties(&$result)
{
- $result['datatable_css_class'] = 'dataTableActions';
$result['datatable_js_type'] = 'actionDataTable';
- $result['subtable_template'] = '@CoreHome/_dataTableActions_subDataTable.twig';
+ $result['visualization_properties']['HtmlTable']['subtable_template'] =
+ '@CoreHome/_dataTableActions_subDataTable.twig';
$result['search_recursive'] = true;
$result['show_all_views_icons'] = false;
$result['show_table_all_columns'] = false;
@@ -660,13 +666,19 @@ class Piwik_Actions extends Plugin
$result['custom_parameters'] = array('flat' => 0);
if (ViewDataTable::shouldLoadExpanded()) {
- $result['show_expanded'] = true;
+ $result['visualization_properties']['HtmlTable']['show_expanded'] = true;
$result['filters'][] = function ($dataTable) {
Piwik_Actions::setDataTableRowLevels($dataTable);
};
}
-
+
+ $result['filters'][] = function ($dataTable, $view) {
+ if ($view->getViewDataTableId() == 'table') {
+ $view->datatable_css_class = 'dataTableActions';
+ }
+ };
+
return $result;
}
@@ -780,7 +792,7 @@ class Piwik_Actions extends Plugin
'filter_sort_column' => 'entry_nb_visits',
'filter_sort_order' => 'desc',
'title' => Piwik_Translate('Actions_SubmenuPagesEntry'),
- 'relatedReports' => array(
+ 'related_reports' => array(
'Actions.getEntryPageTitles' => Piwik_Translate('Actions_EntryPageTitles')
),
'self_url' => $reportUrl
@@ -808,7 +820,7 @@ class Piwik_Actions extends Plugin
'filter_sort_column' => 'exit_nb_visits',
'filter_sort_order' => 'desc',
'title' => Piwik_Translate('Actions_SubmenuPagesExit'),
- 'relatedReports' => array(
+ 'related_reports' => array(
'Actions.getExitPageTitles' => Piwik_Translate('Actions_ExitPageTitles')
),
'self_url' => $reportUrl,
@@ -866,7 +878,11 @@ class Piwik_Actions extends Plugin
'columns_to_display' => array('label', 'nb_visits', 'nb_pages_per_search'),
'show_table_all_columns' => false,
'show_bar_chart' => false,
- 'disable_row_evolution' => false,
+ 'visualization_properties' => array(
+ 'HtmlTable' => array(
+ 'disable_row_evolution' => false,
+ )
+ )
);
}
@@ -891,7 +907,7 @@ class Piwik_Actions extends Plugin
'filter_sort_order' => 'desc',
'show_exclude_low_population' => false,
'title' => $title,
- 'relatedReports' => $relatedReports
+ 'related_reports' => $relatedReports
);
$this->addExcludeLowPopDisplayProperties($result);
@@ -914,7 +930,7 @@ class Piwik_Actions extends Plugin
'columns_to_display' => array('label', 'nb_hits', 'nb_visits', 'bounce_rate',
'avg_time_on_page', 'exit_rate', 'avg_time_generation'),
'title' => Piwik_Translate('Actions_SubmenuPageTitles'),
- 'relatedReports' => array(
+ 'related_reports' => array(
'Actions.getEntryPageTitles' => Piwik_Translate('Actions_EntryPageTitles'),
'Actions.getExitPageTitles' => Piwik_Translate('Actions_ExitPageTitles'),
),
@@ -940,7 +956,7 @@ class Piwik_Actions extends Plugin
),
'columns_to_display' => array('label', 'entry_nb_visits', 'entry_bounce_count', 'bounce_rate'),
'title' => Piwik_Translate('Actions_EntryPageTitles'),
- 'relatedReports' => array(
+ 'related_reports' => array(
'Actions.getPageTitles' => Piwik_Translate('Actions_SubmenuPageTitles'),
"Actions.$entryPageUrlAction" => Piwik_Translate('Actions_SubmenuPagesEntry')
),
@@ -964,7 +980,7 @@ class Piwik_Actions extends Plugin
),
'columns_to_display' => array('label', 'exit_nb_visits', 'nb_visits', 'exit_rate'),
'title' => Piwik_Translate('Actions_ExitPageTitles'),
- 'relatedReports' => array(
+ 'related_reports' => array(
'Actions.getPageTitles' => Piwik_Translate('Actions_SubmenuPageTitles'),
"Actions.$exitPageUrlAction" => Piwik_Translate('Actions_SubmenuPagesExit'),
),
diff --git a/plugins/Actions/stylesheets/dataTableActions.less b/plugins/Actions/stylesheets/dataTableActions.less
new file mode 100644
index 0000000000..7c059d948b
--- /dev/null
+++ b/plugins/Actions/stylesheets/dataTableActions.less
@@ -0,0 +1,4 @@
+.dataTableActions > .dataTableWrapper {
+ width: 500px;
+ min-height: 1px;
+} \ No newline at end of file
diff --git a/plugins/Annotations/API.php b/plugins/Annotations/API.php
index b1abd3c480..ec34c1f127 100755
--- a/plugins/Annotations/API.php
+++ b/plugins/Annotations/API.php
@@ -13,6 +13,8 @@ use Piwik\Period\Range;
use Piwik\Piwik;
use Piwik\Date;
use Piwik\ViewDataTable;
+use Piwik\Plugins\CoreVisualizations\Visualizations\JqplotGraph\Evolution as EvolutionViz;
+
/**
* @see plugins/Annotations/AnnotationList.php
*/
@@ -328,7 +330,7 @@ class Piwik_Annotations_API
$endDate = $oPeriod->getDateEnd();
} else // if the range includes the last N periods
{
- list($date, $lastN) = \Piwik\Visualization\JqplotGraph\Evolution::getDateRangeAndLastN($period, $date, $lastN);
+ list($date, $lastN) = EvolutionViz::getDateRangeAndLastN($period, $date, $lastN);
list($startDate, $endDate) = explode(',', $date);
$startDate = Date::factory($startDate);
diff --git a/plugins/CoreHome/CoreHome.php b/plugins/CoreHome/CoreHome.php
index c21c3168f7..1ffec819ff 100644
--- a/plugins/CoreHome/CoreHome.php
+++ b/plugins/CoreHome/CoreHome.php
@@ -47,9 +47,7 @@ class Piwik_CoreHome extends Plugin
$cssFiles[] = "plugins/CoreHome/stylesheets/dataTable.less";
$cssFiles[] = "plugins/CoreHome/stylesheets/cloud.less";
$cssFiles[] = "plugins/CoreHome/stylesheets/jquery.ui.autocomplete.css";
- $cssFiles[] = "plugins/CoreHome/stylesheets/jqplot.css";
$cssFiles[] = "plugins/CoreHome/stylesheets/jqplotColors.less";
- $cssFiles[] = "plugins/CoreHome/stylesheets/sparklineColors.less";
$cssFiles[] = "plugins/CoreHome/stylesheets/promo.less";
$cssFiles[] = "plugins/CoreHome/stylesheets/color_manager.css";
}
@@ -77,10 +75,8 @@ class Piwik_CoreHome extends Plugin
$jsFiles[] = "plugins/CoreHome/javascripts/corehome.js";
$jsFiles[] = "plugins/CoreHome/javascripts/dataTable_manager.js";
$jsFiles[] = "plugins/CoreHome/javascripts/donate.js";
- $jsFiles[] = "plugins/CoreHome/javascripts/jqplot.js";
$jsFiles[] = "libs/jqplot/jqplot-custom.min.js";
$jsFiles[] = "plugins/CoreHome/javascripts/promo.js";
$jsFiles[] = "plugins/CoreHome/javascripts/color_manager.js";
}
-
-}
+} \ No newline at end of file
diff --git a/plugins/CoreHome/DataTableRowAction/RowEvolution.php b/plugins/CoreHome/DataTableRowAction/RowEvolution.php
index d60b54c4ab..46654c531e 100644
--- a/plugins/CoreHome/DataTableRowAction/RowEvolution.php
+++ b/plugins/CoreHome/DataTableRowAction/RowEvolution.php
@@ -16,6 +16,7 @@ use Piwik\Date;
use Piwik\ViewDataTable;
use Piwik\Url;
use Piwik\Visualization\Chart\Evolution;
+use Piwik\Plugins\CoreVisualizations\Visualizations\JqplotGraph\Evolution as EvolutionViz;
/**
* ROW EVOLUTION
@@ -97,8 +98,7 @@ class Piwik_CoreHome_DataTableRowAction_RowEvolution
if ($this->period != 'range') {
// handle day, week, month and year: display last X periods
$end = $date->toString();
- list($this->date, $lastN) =
- \Piwik\Visualization\JqplotGraph\Evolution::getDateRangeAndLastN($this->period, $end);
+ list($this->date, $lastN) = EvolutionViz::getDateRangeAndLastN($this->period, $end);
}
$this->segment = \Piwik\API\Request::getRawSegmentFromRequest();
@@ -186,25 +186,26 @@ class Piwik_CoreHome_DataTableRowAction_RowEvolution
public function getRowEvolutionGraph($graphType = false, $metrics = false)
{
// set up the view data table
- $view = ViewDataTable::factory(
- $graphType ?: $this->graphType, $this->apiMethod, $controllerAction = 'CoreHome.getRowEvolutionGraph');
+ $view = ViewDataTable::factory($graphType ?: $this->graphType, $this->apiMethod,
+ $controllerAction = 'CoreHome.getRowEvolutionGraph', $forceDefault = true);
$view->setDataTable($this->dataTable);
if (!empty($this->graphMetrics)) { // In row Evolution popover, this is empty
$view->columns_to_display = array_keys($metrics ?: $this->graphMetrics);
}
+ $view->show_goals = false;
$view->show_all_views_icons = false;
$view->show_active_view_icon = false;
$view->show_related_reports = false;
- $view->show_series_picker = false;
+ $view->visualization_properties->show_series_picker = false;
foreach ($this->availableMetrics as $metric => $metadata) {
$view->translations[$metric] = $metadata['name'];
}
- $view->external_series_toggle = 'RowEvolutionSeriesToggle';
- $view->external_series_toggle_show_all = $this->initiallyShowAllMetrics;
+ $view->visualization_properties->external_series_toggle = 'RowEvolutionSeriesToggle';
+ $view->visualization_properties->external_series_toggle_show_all = $this->initiallyShowAllMetrics;
return $view;
}
@@ -271,10 +272,9 @@ class Piwik_CoreHome_DataTableRowAction_RowEvolution
{
// sparkline is always echoed, so we need to buffer the output
$view = $this->getRowEvolutionGraph($graphType = 'sparkline', $metrics = array($metric => $metric));
- $view->main();
ob_start();
- $view->getView()->render();
+ $view->render();
$spark = ob_get_contents();
ob_end_clean();
diff --git a/plugins/CoreHome/javascripts/dataTable.js b/plugins/CoreHome/javascripts/dataTable.js
index e269027e9d..a607e642c9 100644
--- a/plugins/CoreHome/javascripts/dataTable.js
+++ b/plugins/CoreHome/javascripts/dataTable.js
@@ -457,7 +457,7 @@ dataTable.prototype =
var totalRows = Number(self.param.totalRows);
var offsetEndDisp = offsetEnd;
- if (self.param.keep_summary_row == 1) --totalRows;
+ if (self.props.keep_summary_row == 1) --totalRows;
if (offsetEnd > totalRows) offsetEndDisp = totalRows;
@@ -475,7 +475,7 @@ dataTable.prototype =
var offsetEnd = Number(self.param.filter_offset)
+ Number(self.param.filter_limit);
var totalRows = Number(self.param.totalRows);
- if (self.param.keep_summary_row == 1) --totalRows;
+ if (self.props.keep_summary_row == 1) --totalRows;
if (offsetEnd < totalRows) {
$(this).css('display', 'inline');
}
diff --git a/plugins/CoreHome/javascripts/dataTable_manager.js b/plugins/CoreHome/javascripts/dataTable_manager.js
index a1ea816484..e2f81250ca 100644
--- a/plugins/CoreHome/javascripts/dataTable_manager.js
+++ b/plugins/CoreHome/javascripts/dataTable_manager.js
@@ -51,10 +51,8 @@
$('div.dataTable').each(function () {
if (!$(this).attr('id')) {
var params = JSON.parse($(this).attr('data-params') || '{}');
- var tableType = $(this).attr('data-table-type');
- if (!tableType) {
- tableType = 'dataTable';
- }
+ var props = JSON.parse($(this).attr('data-props') || '{}');
+ var tableType = $(this).attr('data-table-type') || 'dataTable';
// convert values in params that are arrays to comma separated string lists
for (var key in params) {
@@ -63,7 +61,7 @@
}
}
- self.initSingleDataTable(this, window[tableType], params);
+ self.initSingleDataTable(this, window[tableType], params, props);
}
});
},
@@ -74,8 +72,9 @@
* @param {Element} domElem The DataTable div element.
* @param {Function} klass The DataTable's JS class.
* @param {Object} params The request params used.
+ * @param {Object} props The view properties that should be visible to the JS.
*/
- initSingleDataTable: function (domElem, klass, params) {
+ initSingleDataTable: function (domElem, klass, params, props) {
var newId = this.getNextId();
$(domElem).attr('id', newId);
@@ -84,6 +83,7 @@
$(domElem).data('dataTableInstance', table);
table.param = params;
+ table.props = props;
table.init(newId);
// if the datatable has a graph, init the graph
diff --git a/plugins/CoreHome/stylesheets/dataTable/_dataTable.less b/plugins/CoreHome/stylesheets/dataTable/_dataTable.less
index 909014db32..6083dd1cca 100644
--- a/plugins/CoreHome/stylesheets/dataTable/_dataTable.less
+++ b/plugins/CoreHome/stylesheets/dataTable/_dataTable.less
@@ -1,8 +1,3 @@
-/*Overriding some dataTable css for better dashboard display*/
-.widget .dataTableWrapper {
- width: 100%;
-}
-
/* main data table */
.dataTable {
border: 0;
@@ -145,28 +140,12 @@ table.dataTable img {
margin-left: 0;
}
-/* container of each table */
-.dataTableVizHtmlTable > .dataTableWrapper {
+.dataTable > .dataTableWrapper {
width: 450px;
- /* not more than 450px to make sure 2 tables can fit horizontally on a 1024 screen */
}
-.dataTableVizAllColumns > .dataTableWrapper {
- width: 535px;
-}
-
-.dataTableActions > .dataTableWrapper,
-.dataTableGraph > .dataTableWrapper {
- width: 500px;
- min-height: 1px;
-}
-
-.dataTableEvolutionGraph > .dataTableWrapper {
- width: 100%;
-}
-
-.ui-dialog-content .dataTableWrapper {
- width: 100%;
+.subDataTable > .dataTableWrapper {
+ width: 95%;
}
.sortIconContainer {
diff --git a/plugins/CoreHome/templates/_dataTable.twig b/plugins/CoreHome/templates/_dataTable.twig
index 72ba84326c..c95fd78b56 100644
--- a/plugins/CoreHome/templates/_dataTable.twig
+++ b/plugins/CoreHome/templates/_dataTable.twig
@@ -1,8 +1,9 @@
{% set summaryRowId = constant('Piwik\\DataTable::ID_SUMMARY_ROW') %}{# ID_SUMMARY_ROW #}
{% set isSubtable = javascriptVariablesToSet.idSubtable is defined and javascriptVariablesToSet.idSubtable != 0 %}
-<div class="dataTable {{ properties.datatable_css_class }} {% if isSubtable %}subDataTable{% endif %}"
+<div class="dataTable {{ visualizationCssClass }} {{ properties.datatable_css_class|default('') }} {% if isSubtable %}subDataTable{% endif %}"
data-table-type="{{ properties.datatable_js_type|default('dataTable') }}"
data-report="{{ properties.report_id }}"
+ data-props="{{ clientSidePropertiesToSet|json_encode }}"
data-params="{{ javascriptVariablesToSet|json_encode }}">
<div class="reportDocumentation">
{% if properties.documentation|default is not empty %}<p>{{ properties.documentation|raw }}</p>{% endif %}
diff --git a/plugins/CoreHome/templates/_dataTableActions_subDataTable.twig b/plugins/CoreHome/templates/_dataTableActions_subDataTable.twig
index 72bf6607c1..696c4a5a72 100644
--- a/plugins/CoreHome/templates/_dataTableActions_subDataTable.twig
+++ b/plugins/CoreHome/templates/_dataTableActions_subDataTable.twig
@@ -1,14 +1,14 @@
{% if error is defined %}
{{ error.message }}
{% else %}
- {% if (dataTable is empty or dataTable.getRowsCount() == 0) and not properties.show_expanded|default(false) %}
+ {% if (dataTable is empty or dataTable.getRowsCount() == 0) and not properties.visualization_properties.show_expanded|default(false) %}
<tr>
<td colspan="{{ properties.columns_to_display|length }}">{{ 'CoreHome_CategoryNoData'|translate }}</td>
</tr>
{% else %}
{% for row in dataTable.getRows() %}
{# display this row if it doesn't have a subtable or if we don't replace the row with the subtable #}
- {% if not row.getIdSubDataTable() or not properties.show_expanded|default(false) or not properties.replace_row_with_subtable|default(false) %}
+ {% if not row.getIdSubDataTable() or not properties.visualization_properties.show_expanded|default(false) or not properties.replace_row_with_subtable|default(false) %}
<tr {% if row.getIdSubDataTable() %}id="{{ row.getIdSubDataTable() }}"{% endif %}
class="{{ row.getMetadata('css_class') }} {% if row.getIdSubDataTable() %}subDataTable{% endif %}">
{% for column in properties.columns_to_display %}
@@ -20,8 +20,8 @@
{% endif %}
{# display subtable if present and showing expanded datatable #}
- {% if properties.show_expanded|default(false) and row.getIdSubDataTable() %}
- {% include properties.subtable_template|default("@CoreHome/_dataTable.twig") with {'dataTable': row.getSubtable()} %}
+ {% if properties.visualization_properties.show_expanded|default(false) and row.getIdSubDataTable() %}
+ {% include properties.visualization_properties.subtable_template|default("@CoreHome/_dataTable.twig") with {'dataTable': row.getSubtable()} %}
{% endif %}
{% endfor %}
{% endif %}
diff --git a/plugins/CoreHome/templates/_dataTableFooter.twig b/plugins/CoreHome/templates/_dataTableFooter.twig
index 676cf3ef9a..44b776b31d 100644
--- a/plugins/CoreHome/templates/_dataTableFooter.twig
+++ b/plugins/CoreHome/templates/_dataTableFooter.twig
@@ -77,6 +77,13 @@
<img width="16" height="16" src="plugins/Zeitgeist/images/tagcloud.png" title="{{ 'General_TagCloud'|translate }}"/>
</a>
{% endif %}
+ {% if properties.show_non_core_visualizations %}
+ {% for format, info in nonCoreVisualizations %}
+ <a class="tableIcon" format="{{ format }}" var="{{ format }}">
+ <img width="16" height="16" src="{{ info.table_icon }}" title="{{ info.title|translate }}"/>
+ </a>
+ {% endfor %}
+ {% endif %}
</span>
</div>
{% endif %}
@@ -88,14 +95,14 @@
</span>
<span class="exportToFormatItems" style="display:none">
{{ 'General_Export'|translate }}:
- <a target="_blank" methodToCall="{{ properties.apiMethodToRequestDataTable }}" format="CSV" filter_limit="{{ properties.exportLimit }}">CSV</a> |
- <a target="_blank" methodToCall="{{ properties.apiMethodToRequestDataTable }}" format="TSV" filter_limit="{{ properties.exportLimit }}">TSV (Excel)</a> |
- <a target="_blank" methodToCall="{{ properties.apiMethodToRequestDataTable }}" format="XML" filter_limit="{{ properties.exportLimit }}">XML</a> |
- <a target="_blank" methodToCall="{{ properties.apiMethodToRequestDataTable }}" format="JSON" filter_limit="{{ properties.exportLimit }}">Json</a> |
- <a target="_blank" methodToCall="{{ properties.apiMethodToRequestDataTable }}" format="PHP" filter_limit="{{ properties.exportLimit }}">Php</a>
+ <a target="_blank" methodToCall="{{ properties.apiMethodToRequestDataTable }}" format="CSV" filter_limit="{{ properties.export_limit }}">CSV</a> |
+ <a target="_blank" methodToCall="{{ properties.apiMethodToRequestDataTable }}" format="TSV" filter_limit="{{ properties.export_limit }}">TSV (Excel)</a> |
+ <a target="_blank" methodToCall="{{ properties.apiMethodToRequestDataTable }}" format="XML" filter_limit="{{ properties.export_limit }}">XML</a> |
+ <a target="_blank" methodToCall="{{ properties.apiMethodToRequestDataTable }}" format="JSON" filter_limit="{{ properties.export_limit }}">Json</a> |
+ <a target="_blank" methodToCall="{{ properties.apiMethodToRequestDataTable }}" format="PHP" filter_limit="{{ properties.export_limit }}">Php</a>
{% if properties.show_export_as_rss_feed %}
|
- <a target="_blank" methodToCall="{{ properties.apiMethodToRequestDataTable }}" format="RSS" filter_limit="{{ properties.exportLimit }}" date="last10">
+ <a target="_blank" methodToCall="{{ properties.apiMethodToRequestDataTable }}" format="RSS" filter_limit="{{ properties.export_limit }}" date="last10">
<img border="0" src="plugins/Zeitgeist/images/feed.png"/>
</a>
{% endif %}
@@ -130,7 +137,7 @@
{% endif %}
</ul>
</div>
- {% if not properties.hide_annotations_view %}
+ {% if isPluginLoaded('Annotations') and not properties.hide_annotations_view %}
<div class="annotationView" title="{{ 'Annotations_IconDesc_js'|translate }}">
<a class="tableIcon">
<img width="16" height="16" src="plugins/Zeitgeist/images/grey_marker.png"/>
@@ -142,16 +149,16 @@
{% endif %}
<div class="datatableRelatedReports">
- {% if (properties.relatedReports is not empty) and properties.show_related_reports %}
- {% if properties.relatedReports|length == 1 %}
+ {% if (properties.related_reports is not empty) and properties.show_related_reports %}
+ {% if properties.related_reports|length == 1 %}
{{ 'General_RelatedReport'|translate }}:
{% else %}
{{ 'General_RelatedReports'|translate }}:
{% endif %}
- <ul style="list-style:none;{% if properties.relatedReports|length == 1 %}display:inline-block;{% endif %}}">
+ <ul style="list-style:none;{% if properties.related_reports|length == 1 %}display:inline-block;{% endif %}}">
<li><span href="{{ properties.self_url }}" style="display:none;">{{ properties.title }}</span></li>
- {% for reportUrl,reportTitle in properties.relatedReports %}
+ {% for reportUrl,reportTitle in properties.related_reports %}
<li><span href="{{ reportUrl }}">{{ reportTitle }}</span></li>
{% endfor %}
</ul>
diff --git a/plugins/CoreHome/templates/_dataTableViz_jqplotGraph.twig b/plugins/CoreHome/templates/_dataTableViz_jqplotGraph.twig
deleted file mode 100644
index 65e9f7a43c..0000000000
--- a/plugins/CoreHome/templates/_dataTableViz_jqplotGraph.twig
+++ /dev/null
@@ -1,10 +0,0 @@
-<div class="jqplot-graph">
- <div class="piwik-graph"
- style="width: {{ properties.graph_width }}; height: {{ properties.graph_height }};"
- data-data="{{ data|e('html') }}"
- {% if properties.external_series_toggle is defined and properties.external_series_toggle %}
- data-external-series-toggle="{{ properties.external_series_toggle }}"
- data-external-series-show-all="{% if properties.external_series_toggle_show_all %}1{% else %}0{% endif %}"
- {% endif %}>
- </div>
-</div> \ No newline at end of file
diff --git a/plugins/CoreHome/templates/getMultiRowEvolutionPopover.twig b/plugins/CoreHome/templates/getMultiRowEvolutionPopover.twig
index 16ef990aa6..c0a043aac8 100644
--- a/plugins/CoreHome/templates/getMultiRowEvolutionPopover.twig
+++ b/plugins/CoreHome/templates/getMultiRowEvolutionPopover.twig
@@ -1,4 +1,4 @@
-{% set seriesColorCount = constant("Evolution::SERIES_COLOR_COUNT") %}
+{% set seriesColorCount = constant("Piwik\\Plugins\\CoreVisualizations\\Visualizations\\JqplotGraph\\Evolution::SERIES_COLOR_COUNT") %}
<div class="rowevolution multirowevolution">
<div class="popover-title">{{ 'RowEvolution_MultiRowEvolutionTitle'|translate }}</div>
<div class="graph">
diff --git a/plugins/CoreHome/templates/getRowEvolutionPopover.twig b/plugins/CoreHome/templates/getRowEvolutionPopover.twig
index fab9fb2437..74b6cbbfe4 100644
--- a/plugins/CoreHome/templates/getRowEvolutionPopover.twig
+++ b/plugins/CoreHome/templates/getRowEvolutionPopover.twig
@@ -1,4 +1,4 @@
-{% set seriesColorCount = constant("Evolution::SERIES_COLOR_COUNT") %}
+{% set seriesColorCount = constant("Piwik\\Plugins\\CoreVisualizations\\Visualizations\\JqplotGraph\\Evolution::SERIES_COLOR_COUNT") %}
<div class="rowevolution">
<div class="popover-title">{{ popoverTitle | raw }}</div>
<div class="graph">
diff --git a/plugins/CoreVisualizations/CoreVisualizations.php b/plugins/CoreVisualizations/CoreVisualizations.php
new file mode 100644
index 0000000000..00330377a2
--- /dev/null
+++ b/plugins/CoreVisualizations/CoreVisualizations.php
@@ -0,0 +1,58 @@
+<?php
+/**
+ * Piwik - Open source web analytics
+ *
+ * @link http://piwik.org
+ * @license http://www.gnu.org/licenses/gpl-3.0.html GPL v3 or later
+ *
+ * @category Piwik_Plugins
+ * @package Piwik_CoreVisualizations
+ */
+
+use Piwik\Plugin;
+
+require_once PIWIK_INCLUDE_PATH . '/plugins/CoreVisualizations/JqplotDataGenerator.php';
+require_once PIWIK_INCLUDE_PATH . '/plugins/CoreVisualizations/Visualizations/Cloud.php';
+require_once PIWIK_INCLUDE_PATH . '/plugins/CoreVisualizations/Visualizations/HtmlTable.php';
+require_once PIWIK_INCLUDE_PATH . '/plugins/CoreVisualizations/Visualizations/JqplotGraph.php';
+
+/**
+ * This plugin contains all core visualizations, such as the normal HTML table and
+ * jqPlot graphs.
+ */
+class Piwik_CoreVisualizations extends Plugin
+{
+ /**
+ * @see Piwik_Plugin::getListHooksRegistered
+ */
+ public function getListHooksRegistered()
+ {
+ return array(
+ 'AssetManager.getCssFiles' => 'getCssFiles',
+ 'AssetManager.getJsFiles' => 'getJsFiles',
+ 'DataTableVisualization.getAvailable' => 'getAvailableDataTableVisualizations',
+ );
+ }
+
+ public function getAvailableDataTableVisualizations(&$visualizations)
+ {
+ $visualizations[] = 'Piwik\\Plugins\\CoreVisualizations\\Visualizations\\HtmlTable';
+ $visualizations[] = 'Piwik\\Plugins\\CoreVisualizations\\Visualizations\\HtmlTable\\AllColumns';
+ $visualizations[] = 'Piwik\\Plugins\\CoreVisualizations\\Visualizations\\HtmlTable\\Goals';
+ $visualizations[] = 'Piwik\\Plugins\\CoreVisualizations\\Visualizations\\Cloud';
+ $visualizations[] = 'Piwik\\Plugins\\CoreVisualizations\\Visualizations\\JqplotGraph\\Pie';
+ $visualizations[] = 'Piwik\\Plugins\\CoreVisualizations\\Visualizations\\JqplotGraph\\Bar';
+ $visualizations[] = 'Piwik\\Plugins\\CoreVisualizations\\Visualizations\\JqplotGraph\\Evolution';
+ }
+
+ public function getCssFiles(&$cssFiles)
+ {
+ $cssFiles[] = "plugins/CoreVisualizations/stylesheets/dataTableVisualizations.less";
+ $cssFiles[] = "plugins/CoreVisualizations/stylesheets/jqplot.css";
+ }
+
+ public function getJsFiles(&$jsFiles)
+ {
+ $jsFiles[] = "plugins/CoreVisualizations/javascripts/jqplot.js";
+ }
+} \ No newline at end of file
diff --git a/core/JqplotDataGenerator.php b/plugins/CoreVisualizations/JqplotDataGenerator.php
index 039370b251..6e9d707224 100644
--- a/core/JqplotDataGenerator.php
+++ b/plugins/CoreVisualizations/JqplotDataGenerator.php
@@ -9,7 +9,7 @@
* @package Piwik
*/
-namespace Piwik;
+namespace Piwik\Plugins\CoreVisualizations;
use Exception;
use Piwik\Common;
@@ -17,6 +17,8 @@ use Piwik\Metrics;
use Piwik\DataTable;
use Piwik\Visualization;
+require_once PIWIK_INCLUDE_PATH . '/plugins/CoreVisualizations/JqplotDataGenerator/Evolution.php';
+
/**
* Generates JSON data used to configure and populate JQPlot graphs.
*
@@ -82,8 +84,8 @@ class JqplotDataGenerator
*/
public function generate($dataTable)
{
- if (!empty($this->properties['graph_limit'])) {
- $offsetStartSummary = $this->properties['graph_limit'] - 1;
+ if (!empty($this->properties['visualization_properties']->max_graph_elements)) {
+ $offsetStartSummary = $this->properties['visualization_properties']->max_graph_elements - 1;
$sortColumn = !empty($this->properties['filter_sort_column'])
? $this->properties['filter_sort_column']
: Metrics::INDEX_NB_VISITS;
@@ -95,7 +97,7 @@ class JqplotDataGenerator
if ($dataTable->getRowsCount() > 0) {
// if addTotalRow was called in GenerateGraphHTML, add a row containing totals of
// different metrics
- if (!empty($this->properties['add_total_row'])) {
+ if (!empty($this->properties['visualization_properties']->add_total_row)) {
$dataTable->queueFilter('AddSummaryRow', array(0, Piwik_Translate('General_Total'), null, false));
}
@@ -136,10 +138,11 @@ class JqplotDataGenerator
$visualization->setAxisYValues($columnNameToValue);
$visualization->setAxisYLabels($columnNameToTranslation);
$visualization->setAxisYUnit($this->properties['y_axis_unit']);
- $visualization->setDisplayPercentageInTooltip($this->properties['display_percentage_in_tooltip']);
+ $visualization->setDisplayPercentageInTooltip(
+ $this->properties['visualization_properties']->display_percentage_in_tooltip);
// show_all_ticks is not real query param, it is set by GenerateGraphHTML.
- if ($this->properties['show_all_ticks']) {
+ if ($this->properties['visualization_properties']->show_all_ticks) {
$visualization->showAllTicks();
}
@@ -186,11 +189,12 @@ class JqplotDataGenerator
*/
protected function addSeriesPickerToView()
{
- if (count($this->properties['selectable_columns'])
- && Common::getRequestVar('showSeriesPicker', $this->properties['show_series_picker']) == 1
+ $defaultShowSeriesPicker = $this->properties['visualization_properties']->show_series_picker;
+ if (count($this->properties['visualization_properties']->selectable_columns)
+ && Common::getRequestVar('showSeriesPicker', $defaultShowSeriesPicker) == 1
) {
$selectableColumns = array();
- foreach ($this->properties['selectable_columns'] as $column) {
+ foreach ($this->properties['visualization_properties']->selectable_columns as $column) {
$selectableColumns[] = array(
'column' => $column,
'translation' => @$this->properties['translations'][$column],
@@ -199,7 +203,7 @@ class JqplotDataGenerator
}
$this->visualization->setSelectableColumns(
- $selectableColumns, $this->properties['allow_multi_select_series_picker']);
+ $selectableColumns, $this->properties['visualization_properties']->allow_multi_select_series_picker);
}
}
}
diff --git a/core/JqplotDataGenerator/Evolution.php b/plugins/CoreVisualizations/JqplotDataGenerator/Evolution.php
index dab684cb0a..c24ddbb279 100644
--- a/core/JqplotDataGenerator/Evolution.php
+++ b/plugins/CoreVisualizations/JqplotDataGenerator/Evolution.php
@@ -8,14 +8,14 @@
* @category Piwik
* @package Piwik
*/
-namespace Piwik\JqplotDataGenerator;
+namespace Piwik\Plugins\CoreVisualizations\JqplotDataGenerator;
use Piwik\Piwik;
use Piwik\Common;
use Piwik\DataTable;
use Piwik\ViewDataTable;
use Piwik\Url;
-use Piwik\JqplotDataGenerator;
+use Piwik\Plugins\CoreVisualizations\JqplotDataGenerator;
/**
* Generates JQPlot JSON data/config for evolution graphs.
@@ -70,7 +70,7 @@ class Evolution extends JqplotDataGenerator
// put together configuration for row picker.
// do this for every data table in the array because rows do not
// have to present for each date.
- if ($this->properties['row_picker_mach_rows_by'] !== false) {
+ if ($this->properties['row_picker_match_rows_by'] !== false) {
$rowVisible = $this->handleRowForRowPicker($rowLabel);
if (!$rowVisible) {
continue;
@@ -146,7 +146,7 @@ class Evolution extends JqplotDataGenerator
$this->addSeriesPickerToView();
// configure the row picker
- if ($this->properties['row_picker_mach_rows_by'] !== false) {
+ if ($this->properties['row_picker_match_rows_by'] !== false) {
$visualization->setSelectableRows(array_values($this->rowPickerConfig));
}
}
@@ -162,7 +162,7 @@ class Evolution extends JqplotDataGenerator
{
// determine whether row is visible
$isVisible = true;
- if ($this->properties['row_picker_mach_rows_by'] == 'label') {
+ if ($this->properties['row_picker_match_rows_by'] == 'label') {
$isVisible = in_array($rowLabel, $this->properties['row_picker_visible_rows']);
}
diff --git a/core/Visualization/Cloud.php b/plugins/CoreVisualizations/Visualizations/Cloud.php
index 1a12f4061c..a9a8eb7364 100644
--- a/core/Visualization/Cloud.php
+++ b/plugins/CoreVisualizations/Visualizations/Cloud.php
@@ -8,7 +8,7 @@
* @category Piwik
* @package Piwik
*/
-namespace Piwik\Visualization;
+namespace Piwik\Plugins\CoreVisualizations\Visualizations;
use Piwik\Common;
use Piwik\View;
@@ -26,12 +26,23 @@ use Piwik\DataTableVisualization;
*/
class Cloud extends DataTableVisualization
{
+ const ID = 'cloud';
+
/** Used by integration tests to make sure output is consistent. */
public static $debugDisableShuffle = false;
protected $wordsArray = array();
public $truncatingLimit = 50;
+ public static function getDefaultPropertyValues()
+ {
+ return array(
+ 'show_offset_information' => false,
+ 'show_exclude_low_population' => false,
+ 'display_logo_instead_of_label' => false,
+ );
+ }
+
/**
* Assign word to array
* @param string $word
@@ -56,7 +67,7 @@ class Cloud extends DataTableVisualization
*/
public function render($dataTable, $properties)
{
- $view = new View("@CoreHome/_dataTableViz_tagCloud.twig");
+ $view = new View("@CoreVisualizations/_dataTableViz_tagCloud.twig");
$view->properties = $properties;
$columnToDisplay = $properties['columns_to_display'][1];
diff --git a/core/Visualization/HtmlTable.php b/plugins/CoreVisualizations/Visualizations/HtmlTable.php
index 04519ae922..8fd87fc638 100644
--- a/core/Visualization/HtmlTable.php
+++ b/plugins/CoreVisualizations/Visualizations/HtmlTable.php
@@ -8,8 +8,7 @@
* @category Piwik
* @package Piwik
*/
-
-namespace Piwik\Visualization;
+namespace Piwik\Plugins\CoreVisualizations\Visualizations;
use Piwik\Piwik;
use Piwik\DataTable;
@@ -21,6 +20,9 @@ use Piwik\DataTableVisualization;
use Piwik\DataTable\Filter\AddColumnsProcessedMetricsGoal;
use \Piwik_Goals_API;
+require_once PIWIK_INCLUDE_PATH . '/plugins/CoreVisualizations/Visualizations/HtmlTable/AllColumns.php';
+require_once PIWIK_INCLUDE_PATH . '/plugins/CoreVisualizations/Visualizations/HtmlTable/Goals.php';
+
/**
* DataTable visualization that shows DataTable data in an HTML table.
*/
@@ -28,16 +30,64 @@ class HtmlTable extends DataTableVisualization
{
const ID = 'table';
- // TODO: names for these types of properties are inappropriate. JS properties are actually properties
- // that get passed for each request. Overridable properties are properties that do not get passed on,
- // but are visible to client side JS. (change to clientSideProperties & clientSideParameters)
- static public $javaScriptProperties = array(
- 'search_recursive'
+ /**
+ * Custom template used if displaying a subtable.
+ *
+ * TODO: Should be replaced w/ allowing custom visualization for
+ * subtables. Should not directly touch template.
+ */
+ const SUBTABLE_TEMPLATE = 'subtable_template';
+
+ /**
+ * Controls whether the entire DataTable should be rendered (including subtables) or just one
+ * specific table in the tree.
+ */
+ const SHOW_EXPANDED = 'show_expanded';
+
+ /**
+ * Controls whether any DataTable Row Action icons are shown. If true, no icons are shown.
+ *
+ * @see also self::DISABLE_ROW_EVOLUTION
+ */
+ const DISABLE_ROW_ACTIONS = 'disable_row_actions';
+
+ /**
+ * Controls whether the row evolution DataTable Row Action icon is shown or not.
+ *
+ * @see also self::DISABLE_ROW_ACTIONS
+ */
+ const DISABLE_ROW_EVOLUTION = 'disable_row_evolution';
+
+ /**
+ * If true, the 'label', 'nb_visits', 'nb_uniq_visitors' (if present), 'nb_actions',
+ * 'nb_actions_per_visit', 'avg_time_on_site', 'bounce_rate' and 'conversion_rate' (if
+ * goals view is not allowed) are displayed.
+ */
+ const SHOW_EXTRA_COLUMNS = 'show_extra_columns';
+
+ /**
+ * If true, conversions for each existing goal will be displayed for the visits in
+ * each row.
+ */
+ const SHOW_GOALS_COLUMNS = 'show_goals_columns';
+
+ /**
+ * If true, subtables will not be loaded when rows are clicked, but only if the
+ * 'show_goals_columns' property is also true.
+ *
+ * @see also self::SHOW_GOALS_COLUMNS
+ */
+ const DISABLE_SUBTABLE_IN_GOALS_VIEW = 'disable_subtable_when_show_goals';
+
+ static public $clientSideParameters = array(
+ 'search_recursive',
);
- static public $overridableProperties = array(
+ static public $clientSideProperties = array(
'show_extra_columns',
- 'show_goals_columns'
+ 'show_goals_columns',
+ 'disable_row_evolution',
+ 'disable_row_actions'
);
/**
@@ -45,15 +95,19 @@ class HtmlTable extends DataTableVisualization
*/
public function __construct($view)
{
- if ($view->show_extra_columns) {
+ if (Common::getRequestVar('idSubtable', false)
+ && $view->visualization_properties->subtable_template
+ ) {
+ $view->datatable_template = $view->visualization_properties->subtable_template;
+ }
+
+ if ($view->visualization_properties->show_extra_columns) {
$this->setShowExtraColumnsProperties($view);
}
- if ($view->show_goals_columns) {
+ if ($view->visualization_properties->show_goals_columns) {
$this->setShowGoalsColumnsProperties($view);
}
-
- $view->defaultPropertiesTo($this->getDefaultPropertyValues());
}
/**
@@ -65,34 +119,26 @@ class HtmlTable extends DataTableVisualization
*/
public function render($dataTable, $properties) // TODO: $properties should be a viewdatatable, I think.
{
- $view = new View("@CoreHome/_dataTableViz_htmlTable.twig");
+ $view = new View("@CoreVisualizations/_dataTableViz_htmlTable.twig");
$view->properties = $properties;
$view->dataTable = $dataTable;
return $view->render();
}
- public static function getViewDataTableId($view) // TODO: shouldn't need this override
- {
- if ($view->show_extra_columns) {
- return 'tableAllColumns';
- } else if ($view->show_goals_columns) {
- return 'tableGoals';
- } else {
- return self::ID;
- }
- }
-
- private function getDefaultPropertyValues()
+ public static function getDefaultPropertyValues()
{
$defaults = array(
'enable_sort' => true,
- 'disable_row_evolution' => false,
- 'disable_row_actions' => false,
- 'subtable_template' => "@CoreHome/_dataTable.twig",
'datatable_js_type' => 'dataTable',
'filter_limit' => Config::getInstance()->General['datatable_default_limit'],
- 'show_extra_columns' => false,
- 'disable_subtable_when_show_goals' => false
+ 'visualization_properties' => array(
+ 'disable_row_evolution' => false,
+ 'disable_row_actions' => false,
+ 'subtable_template' => "@CoreHome/_dataTable.twig",
+ 'show_extra_columns' => false,
+ 'show_goals_columns' => false,
+ 'disable_subtable_when_show_goals' => false,
+ ),
);
if (Common::getRequestVar('enable_filter_excludelowpop', false) == '1') {
@@ -153,7 +199,7 @@ class HtmlTable extends DataTableVisualization
array('<br />', '<br />', '<a href="http://piwik.org/docs/tracking-goals-web-analytics/" target="_blank">', '</a>'));
}
- if (!$view->disable_subtable_when_show_goals) {
+ if (!$view->visualization_properties->disable_subtable_when_show_goals) {
$view->subtable_controller_action = null;
}
diff --git a/plugins/CoreVisualizations/Visualizations/HtmlTable/AllColumns.php b/plugins/CoreVisualizations/Visualizations/HtmlTable/AllColumns.php
new file mode 100644
index 0000000000..9078c999d9
--- /dev/null
+++ b/plugins/CoreVisualizations/Visualizations/HtmlTable/AllColumns.php
@@ -0,0 +1,34 @@
+<?php
+/**
+ * Piwik - Open source web analytics
+ *
+ * @link http://piwik.org
+ * @license http://www.gnu.org/licenses/gpl-3.0.html GPL v3 or later
+ *
+ * @category Piwik
+ * @package Piwik
+ */
+
+namespace Piwik\Plugins\CoreVisualizations\Visualizations\HtmlTable;
+
+use Piwik\Plugins\CoreVisualizations\Visualizations\HtmlTable;
+
+/**
+ * TODO
+ */
+class AllColumns extends HtmlTable
+{
+ const ID = 'tableAllColumns';
+
+ /**
+ * Constructor.
+ *
+ * @param ViewDataTable $view
+ */
+ public function __construct($view)
+ {
+ $view->visualization_properties->show_extra_columns = true;
+
+ parent::__construct($view);
+ }
+} \ No newline at end of file
diff --git a/plugins/CoreVisualizations/Visualizations/HtmlTable/Goals.php b/plugins/CoreVisualizations/Visualizations/HtmlTable/Goals.php
new file mode 100644
index 0000000000..f1da411fb4
--- /dev/null
+++ b/plugins/CoreVisualizations/Visualizations/HtmlTable/Goals.php
@@ -0,0 +1,34 @@
+<?php
+/**
+ * Piwik - Open source web analytics
+ *
+ * @link http://piwik.org
+ * @license http://www.gnu.org/licenses/gpl-3.0.html GPL v3 or later
+ *
+ * @category Piwik
+ * @package Piwik
+ */
+
+namespace Piwik\Plugins\CoreVisualizations\Visualizations\HtmlTable;
+
+use Piwik\Plugins\CoreVisualizations\Visualizations\HtmlTable;
+
+/**
+ * TODO
+ */
+class Goals extends HtmlTable
+{
+ const ID = 'tableGoals';
+
+ /**
+ * Constructor.
+ *
+ * @param ViewDataTable $view
+ */
+ public function __construct($view)
+ {
+ $view->visualization_properties->show_goals_columns = true;
+
+ parent::__construct($view);
+ }
+} \ No newline at end of file
diff --git a/plugins/CoreVisualizations/Visualizations/JqplotGraph.php b/plugins/CoreVisualizations/Visualizations/JqplotGraph.php
new file mode 100644
index 0000000000..8ed5f24840
--- /dev/null
+++ b/plugins/CoreVisualizations/Visualizations/JqplotGraph.php
@@ -0,0 +1,206 @@
+<?php
+/**
+ * Piwik - Open source web analytics
+ *
+ * @link http://piwik.org
+ * @license http://www.gnu.org/licenses/gpl-3.0.html GPL v3 or later
+ *
+ * @category Piwik
+ * @package Piwik
+ */
+namespace Piwik\Plugins\CoreVisualizations\Visualizations;
+
+use Piwik\Common;
+use Piwik\View;
+use Piwik\DataTable;
+use Piwik\DataTableVisualization;
+use Piwik\Plugins\CoreVisualizations\JqplotDataGenerator;
+
+require_once PIWIK_INCLUDE_PATH . '/plugins/CoreVisualizations/Visualizations/JqplotGraph/Bar.php';
+require_once PIWIK_INCLUDE_PATH . '/plugins/CoreVisualizations/Visualizations/JqplotGraph/Pie.php';
+require_once PIWIK_INCLUDE_PATH . '/plugins/CoreVisualizations/Visualizations/JqplotGraph/Evolution.php';
+
+/**
+ * DataTable visualization that displays DataTable data in a JQPlot graph.
+ * TODO: should merge all this logic w/ jqplotdatagenerator & 'Chart' visualizations.
+ */
+class JqplotGraph extends DataTableVisualization
+{
+ const DEFAULT_GRAPH_HEIGHT = 250;
+
+ /**
+ * Whether the series picker should allow picking more than one series or not.
+ */
+ const ALLOW_MULTI_SELECT_SERIES_PICKER = 'allow_multi_select_series_picker';
+
+ /**
+ * The maximum number of elements to render when rendering a jqPlot graph. All other elements
+ * will be aggregated in an 'Others' element.
+ */
+ const MAX_GRAPH_ELEMENTS = 'max_graph_elements';
+
+ /**
+ * The name of the JavaScript class to use as this graph's external series toggle. The class
+ * must be a subclass of JQPlotExternalSeriesToggle.
+ *
+ * @see self::EXTERNAL_SERIES_TOGGLE_SHOW_ALL
+ */
+ const EXTERNAL_SERIES_TOGGLE = 'external_series_toggle';
+
+ /**
+ * Whether the graph should show all loaded series upon initial display.
+ *
+ * @see self::EXTERNAL_SERIES_TOGGLE
+ */
+ const EXTERNAL_SERIES_TOGGLE_SHOW_ALL = 'external_series_toggle_show_all';
+
+ /**
+ * Array property that contains the names of columns that can be selected in the Series Picker.
+ */
+ const SELECTABLE_COLUMNS = 'selectable_columns';
+
+ /**
+ * Controls whether all ticks & labels are shown on a graph's x-axis or just some.
+ */
+ const SHOW_ALL_TICKS = 'show_all_ticks';
+
+ /**
+ * If true, a row with totals of each DataTable column is added.
+ */
+ const ADD_TOTAL_ROW = 'add_total_row';
+
+ /**
+ * The CSS width of the graph. (eg, '100px').
+ */
+ const GRAPH_WIDTH = 'graph_width';
+
+ /**
+ * The CSS height of the graph. (eg, '100px').
+ */
+ const GRAPH_HEIGHT = 'graph_height';
+
+ /**
+ * Controls whether the Series Picker is shown or not. The Series Picker allows users to
+ * choose between displaying data of different columns.
+ */
+ const SHOW_SERIES_PICKER = 'show_series_picker';
+
+ /**
+ * Controls whether the percentage of the total is displayed as a tooltip in Jqplot graphs.
+ *
+ * NOTE: Sometimes this percentage is meaningless (when the total of the column values is
+ * not the total number of elements in the set). In this case the tooltip should not be
+ * displayed.
+ */
+ const DISPLAY_PERCENTAGE_IN_TOOLTIP = 'display_percentage_in_tooltip';
+
+ /**
+ * Constructor.
+ *
+ * @param Piwik\ViewDataTable $view
+ */
+ public function __construct($view)
+ {
+ // Graphs require the full dataset, so no filters
+ $this->request_parameters_to_modify['disable_generic_filters'] = true;
+
+ // 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->request_parameters_to_modify['disable_queued_filters'] = true;
+
+ if ($view->show_goals) {
+ $goalMetrics = array('nb_conversions', 'revenue');
+ $view->visualization_properties->selectable_columns = array_merge(
+ $view->visualization_properties->selectable_columns, $goalMetrics);
+
+ $view->translations['nb_conversions'] = Piwik_Translate('Goals_ColumnConversions');
+ $view->translations['revenue'] = Piwik_Translate('General_TotalRevenue');
+ }
+
+ // do not sort if sorted column was initially "label" or eg. it would make "Visits by Server time" not pretty
+ if ($view->filter_sort_column != 'label') {
+ $columns = $view->columns_to_display;
+
+ $firstColumn = reset($columns);
+ if ($firstColumn == 'label') {
+ $firstColumn = next($columns);
+ }
+
+ $result['filter_sort_column'] = $firstColumn;
+ $result['filter_sort_order'] = 'desc';
+ }
+ }
+
+ /**
+ * Returns an array mapping property names with default values for this visualization.
+ *
+ * @return array
+ */
+ public static function getDefaultPropertyValues()
+ {
+ // selectable columns
+ $selectableColumns = array('nb_visits', 'nb_actions');
+ if (Common::getRequestVar('period', false) == 'day') { // TODO: should depend on columns datatable has.
+ $selectableColumns[] = 'nb_uniq_visitors';
+ }
+
+ return array(
+ 'show_offset_information' => false,
+ 'show_pagination_control' => false,
+ 'show_exclude_low_population' => false,
+ 'show_search' => false,
+ 'show_export_as_image_icon' => true,
+ 'y_axis_unit' => '',
+ 'row_picker_match_rows_by' => false,
+ 'row_picker_visible_rows' => array(),
+ 'visualization_properties' => array(
+ 'JqplotGraph' => array(
+ 'add_total_row' => 0,
+ 'show_all_ticks' => false,
+ 'allow_multi_select_series_picker' => true,
+ 'max_graph_elements' => false,
+ 'selectable_columns' => $selectableColumns,
+ 'graph_width' => '100%',
+ 'graph_height' => self::DEFAULT_GRAPH_HEIGHT . 'px',
+ 'external_series_toggle' => false,
+ 'external_series_toggle_show_all' => false,
+ 'show_series_picker' => true,
+ 'display_percentage_in_tooltip' => true,
+ )
+ )
+ );
+ }
+
+ /**
+ * Renders this visualization.
+ *
+ * @param DataTable $dataTable
+ * @param array $properties View Properties.
+ * @return string
+ */
+ public function render($dataTable, $properties)
+ {
+ $view = new View("@CoreVisualizations/_dataTableViz_jqplotGraph.twig");
+ $view->properties = $properties;
+ $view->dataTable = $dataTable;
+ $view->data = $this->getGraphData($dataTable, $properties);
+ return $view->render();
+ }
+
+ /**
+ * Generats JQPlot graph data for a DataTable.
+ */
+ private function getGraphData($dataTable, $properties)
+ {
+ $properties = array_merge($properties, $properties['request_parameters_to_modify']);
+ $dataGenerator = $this->makeDataGenerator($properties);
+
+ $jsonData = $dataGenerator->generate($dataTable);
+ return str_replace(array("\r", "\n"), '', $jsonData);
+ }
+
+ protected function makeDataGenerator($properties)
+ {
+ return JqplotDataGenerator::factory($properties['graph_type'], $properties);
+ }
+} \ No newline at end of file
diff --git a/plugins/CoreVisualizations/Visualizations/JqplotGraph/Bar.php b/plugins/CoreVisualizations/Visualizations/JqplotGraph/Bar.php
new file mode 100644
index 0000000000..dffe7393f2
--- /dev/null
+++ b/plugins/CoreVisualizations/Visualizations/JqplotGraph/Bar.php
@@ -0,0 +1,35 @@
+<?php
+/**
+ * Piwik - Open source web analytics
+ *
+ * @link http://piwik.org
+ * @license http://www.gnu.org/licenses/gpl-3.0.html GPL v3 or later
+ *
+ * @category Piwik
+ * @package Piwik
+ */
+
+namespace Piwik\Plugins\CoreVisualizations\Visualizations\JqplotGraph;
+
+use Piwik\Plugins\CoreVisualizations\Visualizations\JqplotGraph;
+use Piwik\Plugins\CoreVisualizations\JqplotDataGenerator;
+
+/**
+ * Visualization that renders HTML for a Bar graph using jqPlot.
+ */
+class Bar extends JqplotGraph
+{
+ const ID = 'graphVerticalBar';
+
+ public static function getDefaultPropertyValues()
+ {
+ $result = parent::getDefaultPropertyValues();
+ $result['visualization_properties']['max_graph_elements'] = 6;
+ return $result;
+ }
+
+ protected function makeDataGenerator($properties)
+ {
+ return JqplotDataGenerator::factory('bar', $properties);
+ }
+} \ No newline at end of file
diff --git a/core/Visualization/JqplotGraph/Evolution.php b/plugins/CoreVisualizations/Visualizations/JqplotGraph/Evolution.php
index 5d7734061b..684b3fb524 100644
--- a/core/Visualization/JqplotGraph/Evolution.php
+++ b/plugins/CoreVisualizations/Visualizations/JqplotGraph/Evolution.php
@@ -9,29 +9,30 @@
* @package Piwik
*/
-namespace Piwik\Visualization\JqplotGraph;
+namespace Piwik\Plugins\CoreVisualizations\Visualizations\JqplotGraph;
use Piwik\Common;
use Piwik\Site;
use Piwik\Controller;
use Piwik\Period\Range;
-use Piwik\Visualization\JqplotGraph;
-use Piwik\JqplotDataGenerator;
+use Piwik\Plugins\CoreVisualizations\Visualizations\JqplotGraph;
+use Piwik\Plugins\CoreVisualizations\JqplotDataGenerator;
/**
- * TODO
+ * Visualization that renders HTML for a line graph using jqPlot.
*/
class Evolution extends JqplotGraph
{
- const GRAPH_HEIGHT = 170;
const ID = 'graphEvolution';
+
+ const GRAPH_HEIGHT = 170;
+ const SERIES_COLOR_COUNT = 8;
public function __construct($view)
{
parent::__construct($view);
- $view->datatable_css_class = 'dataTableEvolutionGraph';
- // period will be overridden when 'range' is requested in the UI // TODO: this code probably shouldn't be here...
+ // period will be overridden when 'range' is requested in the UI
// but the graph will display for each day of the range.
// Default 'range' behavior is to return the 'sum' for the range
if (Common::getRequestVar('period', false) == 'range') {
@@ -41,15 +42,15 @@ class Evolution extends JqplotGraph
$this->calculateEvolutionDateRange($view);
}
- protected function getDefaultPropertyValues($view)
+ public static function getDefaultPropertyValues()
{
- $result = parent::getDefaultPropertyValues($view);
- $result['graph_height'] = self::GRAPH_HEIGHT . 'px';
+ $result = parent::getDefaultPropertyValues();
$result['show_all_views_icons'] = false;
$result['show_table'] = false;
$result['show_table'] = false;
$result['show_table_all_columns'] = false;
$result['hide_annotations_view'] = false;
+ $result['visualization_properties']['Evolution']['graph_height'] = self::GRAPH_HEIGHT . 'px';
return $result;
}
diff --git a/plugins/CoreVisualizations/Visualizations/JqplotGraph/Pie.php b/plugins/CoreVisualizations/Visualizations/JqplotGraph/Pie.php
new file mode 100644
index 0000000000..8ca39659b1
--- /dev/null
+++ b/plugins/CoreVisualizations/Visualizations/JqplotGraph/Pie.php
@@ -0,0 +1,36 @@
+<?php
+/**
+ * Piwik - Open source web analytics
+ *
+ * @link http://piwik.org
+ * @license http://www.gnu.org/licenses/gpl-3.0.html GPL v3 or later
+ *
+ * @category Piwik
+ * @package Piwik
+ */
+
+namespace Piwik\Plugins\CoreVisualizations\Visualizations\JqplotGraph;
+
+use Piwik\Plugins\CoreVisualizations\Visualizations\JqplotGraph;
+use Piwik\Plugins\CoreVisualizations\JqplotDataGenerator;
+
+/**
+ * Visualization that renders HTML for a Pie graph using jqPlot.
+ */
+class Pie extends JqplotGraph
+{
+ const ID = 'graphPie';
+
+ public static function getDefaultPropertyValues()
+ {
+ $result = parent::getDefaultPropertyValues();
+ $result['visualization_properties']['max_graph_elements'] = 6;
+ $result['visualization_properties']['allow_multi_select_series_picker'] = false;
+ return $result;
+ }
+
+ protected function makeDataGenerator($properties)
+ {
+ return JqplotDataGenerator::factory('pie', $properties);
+ }
+} \ No newline at end of file
diff --git a/plugins/CoreHome/javascripts/jqplot.js b/plugins/CoreVisualizations/javascripts/jqplot.js
index dde65a3977..f8888dbd0f 100644
--- a/plugins/CoreHome/javascripts/jqplot.js
+++ b/plugins/CoreVisualizations/javascripts/jqplot.js
@@ -68,21 +68,17 @@ JQPlot.prototype = {
/** Generic render function */
render: function (targetDivId, lang) {
- var type = $('#' + targetDivId).closest('div.dataTable').data('dataTableInstance').param['viewDataTable'];
+ var dataTableDiv = $('#' + targetDivId).closest('div.dataTable');
// preapare the appropriate chart type
- switch (type) {// TODO: should rely on CSS, not viewDataTable. otherwise ecommerceOrder row evolution will fail
- case 'graphEvolution':
- this.prepareEvolutionChart(targetDivId, lang);
- break;
- case 'graphVerticalBar':
- this.prepareBarChart(targetDivId, lang);
- break;
- case 'graphPie':
- this.preparePieChart(targetDivId, lang);
- break;
- default:
- return;
+ if (dataTableDiv.hasClass('dataTableVizEvolution')) {
+ this.prepareEvolutionChart(targetDivId, lang);
+ } else if (dataTableDiv.hasClass('dataTableVizBar')) {
+ this.prepareBarChart(targetDivId, lang);
+ } else if (dataTableDiv.hasClass('dataTableVizPie')) {
+ this.preparePieChart(targetDivId, lang);
+ } else {
+ return;
}
// handle replot
@@ -620,7 +616,8 @@ JQPlot.prototype = {
var namespace = graphType + '-graph-colors';
- this.params.seriesColors = colorManager.getColors(namespace, seriesColorNames, true);
+ this.originalData.params.seriesColors = this.params.seriesColors =
+ colorManager.getColors(namespace, seriesColorNames, true);
this.params.grid.background = colorManager.getColor(namespace, 'grid-background');
this.params.grid.borderColor = colorManager.getColor(namespace, 'grid-border');
this.tickColor = colorManager.getColor(namespace, 'ticks');
diff --git a/plugins/CoreVisualizations/stylesheets/dataTableVisualizations.less b/plugins/CoreVisualizations/stylesheets/dataTableVisualizations.less
new file mode 100644
index 0000000000..5ae202f36f
--- /dev/null
+++ b/plugins/CoreVisualizations/stylesheets/dataTableVisualizations.less
@@ -0,0 +1,18 @@
+/* container of each table */
+.dataTableVizHtmlTable > .dataTableWrapper {
+ width: 450px;
+ /* not more than 450px to make sure 2 tables can fit horizontally on a 1024 screen */
+}
+
+.dataTableVizAllColumns > .dataTableWrapper {
+ width: 535px;
+}
+
+.dataTableVizPie > .dataTableWrapper, .dataTableVizBar > .dataTableWrapper {
+ width: 500px;
+ min-height: 1px;
+}
+
+.dataTableVizEvolution > .dataTableWrapper {
+ width: 100%;
+} \ No newline at end of file
diff --git a/plugins/CoreHome/stylesheets/jqplot.css b/plugins/CoreVisualizations/stylesheets/jqplot.css
index bd5dec8e59..bd5dec8e59 100644
--- a/plugins/CoreHome/stylesheets/jqplot.css
+++ b/plugins/CoreVisualizations/stylesheets/jqplot.css
diff --git a/plugins/CoreHome/templates/_dataTableViz_htmlTable.twig b/plugins/CoreVisualizations/templates/_dataTableViz_htmlTable.twig
index aa3911f628..1347218af0 100644
--- a/plugins/CoreHome/templates/_dataTableViz_htmlTable.twig
+++ b/plugins/CoreVisualizations/templates/_dataTableViz_htmlTable.twig
@@ -7,7 +7,7 @@
{%- set shouldHighlightRow = rowId == constant('Piwik\\DataTable::ID_SUMMARY_ROW') and properties.highlight_summary_row -%}
{# display this row if it doesn't have a subtable or if we don't replace the row with the subtable #}
- {% if not rowHasSubtable or not properties.show_expanded|default(false) or not properties.replace_row_with_subtable|default(false) %}
+ {% if not rowHasSubtable or not properties.visualization_properties.show_expanded|default(false) or not properties.replace_row_with_subtable|default(false) %}
<tr {% if rowHasSubtable %}id="{{ row.getIdSubDataTable() }}"{% endif %}
class="{{ row.getMetadata('css_class') }} {% if rowHasSubtable %}subDataTable{% endif %}{% if shouldHighlightRow %} highlight{% endif %}">
{% for column in properties.columns_to_display %}
@@ -19,8 +19,8 @@
{% endif %}
{# display subtable if present and showing expanded datatable #}
- {% if properties.show_expanded|default(false) and rowHasSubtable %}
- {% include properties.subtable_template with {'dataTable': row.getSubtable()} %}
+ {% if properties.visualization_properties.show_expanded|default(false) and rowHasSubtable %}
+ {% include properties.visualization_properties.subtable_template with {'dataTable': row.getSubtable()} %}
{% endif %}
{% endfor %}
</tbody>
diff --git a/plugins/CoreVisualizations/templates/_dataTableViz_jqplotGraph.twig b/plugins/CoreVisualizations/templates/_dataTableViz_jqplotGraph.twig
new file mode 100644
index 0000000000..e980275ac6
--- /dev/null
+++ b/plugins/CoreVisualizations/templates/_dataTableViz_jqplotGraph.twig
@@ -0,0 +1,10 @@
+<div class="jqplot-graph">
+ <div class="piwik-graph"
+ style="width: {{ properties.visualization_properties.graph_width }}; height: {{ properties.visualization_properties.graph_height }};"
+ data-data="{{ data|e('html') }}"
+ {% if properties.visualization_properties.external_series_toggle %}
+ data-external-series-toggle="{{ properties.visualization_properties.external_series_toggle }}"
+ data-external-series-show-all="{% if properties.visualization_properties.external_series_toggle_show_all %}1{% else %}0{% endif %}"
+ {% endif %}>
+ </div>
+</div> \ No newline at end of file
diff --git a/plugins/CoreHome/templates/_dataTableViz_tagCloud.twig b/plugins/CoreVisualizations/templates/_dataTableViz_tagCloud.twig
index 1513daca34..1513daca34 100644
--- a/plugins/CoreHome/templates/_dataTableViz_tagCloud.twig
+++ b/plugins/CoreVisualizations/templates/_dataTableViz_tagCloud.twig
diff --git a/plugins/DBStats/DBStats.php b/plugins/DBStats/DBStats.php
index def12d84a4..593f2a9b64 100644
--- a/plugins/DBStats/DBStats.php
+++ b/plugins/DBStats/DBStats.php
@@ -105,7 +105,7 @@ class Piwik_DBStats extends Plugin
$result['show_offset_information'] = false;
$result['show_pagination_control'] = false;
- $result['show_all_ticks'] = true;
+ $result['visualization_properties']['JqplotGraph']['show_all_ticks'] = true;
// translate the labels themselves
$valueToTranslationStr = array(
@@ -146,7 +146,7 @@ class Piwik_DBStats extends Plugin
$this->addPresentationFilters($result);
$result['title'] = Piwik_Translate('DBStats_MetricTables');
- $result['relatedReports'] = array(
+ $result['related_reports'] = array(
'DBStats.getMetricDataSummaryByYear' => Piwik_Translate('DBStats_MetricDataByYear')
);
@@ -161,7 +161,7 @@ class Piwik_DBStats extends Plugin
$result['translations']['label'] = Piwik_Translate('CoreHome_PeriodYear');
$result['title'] = Piwik_Translate('DBStats_MetricDataByYear');
- $result['relatedReports'] = array(
+ $result['related_reports'] = array(
'DBStats.getMetricDataSummary' => Piwik_Translate('DBStats_MetricTables')
);
@@ -175,7 +175,7 @@ class Piwik_DBStats extends Plugin
$this->addPresentationFilters($result);
$result['title'] = Piwik_Translate('DBStats_ReportTables');
- $result['relatedReports'] = array(
+ $result['related_reports'] = array(
'DBStats.getReportDataSummaryByYear' => Piwik_Translate('DBStats_ReportDataByYear')
);
@@ -190,7 +190,7 @@ class Piwik_DBStats extends Plugin
$result['translations']['label'] = Piwik_Translate('CoreHome_PeriodYear');
$result['title'] = Piwik_Translate('DBStats_ReportDataByYear');
- $result['relatedReports'] = array(
+ $result['related_reports'] = array(
'DBStats.getReportDataSummary' => Piwik_Translate('DBStats_ReportTables')
);
@@ -256,7 +256,7 @@ class Piwik_DBStats extends Plugin
$properties['show_tag_cloud'] = false;
$properties['show_table_all_columns'] = false;
$properties['keep_summary_row'] = true;
- $properties['disable_row_evolution'] = true;
+ $properties['visualization_properties']['HtmlTable']['disable_row_evolution'] = true;
$properties['translations'] = array(
'label' => Piwik_Translate('DBStats_Table'),
'year' => Piwik_Translate('CoreHome_PeriodYear'),
diff --git a/plugins/Dashboard/stylesheets/dashboard.less b/plugins/Dashboard/stylesheets/dashboard.less
index 376a160f72..f00fe46366 100644
--- a/plugins/Dashboard/stylesheets/dashboard.less
+++ b/plugins/Dashboard/stylesheets/dashboard.less
@@ -135,6 +135,11 @@
text-shadow: 1px 1px 2px #7e7363;
}
+// Overriding some dataTable css for better dashboard display
+.widget .dataTableWrapper {
+ width: 100% !important;
+}
+
.button {
cursor: pointer;
}
diff --git a/plugins/DevicesDetection/DevicesDetection.php b/plugins/DevicesDetection/DevicesDetection.php
index 8adc51141c..35fb148866 100644
--- a/plugins/DevicesDetection/DevicesDetection.php
+++ b/plugins/DevicesDetection/DevicesDetection.php
@@ -318,7 +318,7 @@ class Piwik_DevicesDetection extends Plugin
'show_exclude_low_population' => false,
'translations' => array('label' => Piwik_Translate("DevicesDetection_dataTableLabelSystemFamily")),
'title' => Piwik_Translate('DeviceDetection_OperatingSystemFamilies'),
- 'relatedReports' => $this->getOsRelatedReports()
+ 'related_reports' => $this->getOsRelatedReports()
);
}
@@ -329,7 +329,7 @@ class Piwik_DevicesDetection extends Plugin
'show_exclude_low_population' => false,
'translations' => array('label' => Piwik_Translate("DevicesDetection_dataTableLabelSystemVersion")),
'title' => Piwik_Translate('DeviceDetection_OperatingSystemVersions'),
- 'relatedReports' => $this->getOsRelatedReports()
+ 'related_reports' => $this->getOsRelatedReports()
);
}
@@ -340,7 +340,7 @@ class Piwik_DevicesDetection extends Plugin
'show_exclude_low_population' => false,
'translations' => array('label' => Piwik_Translate("DevicesDetection_dataTableLabelBrowserFamily")),
'title' => Piwik_Translate('DevicesDetection_BrowsersFamily'),
- 'relatedReports' => $this->getBrowserRelatedReports()
+ 'related_reports' => $this->getBrowserRelatedReports()
);
}
@@ -350,7 +350,7 @@ class Piwik_DevicesDetection extends Plugin
'show_search' => false,
'show_exclude_low_population' => false,
'translations' => array('label' => Piwik_Translate("DevicesDetection_dataTableLabelBrowserVersion")),
- 'relatedReports' => $this->getBrowserRelatedReports()
+ 'related_reports' => $this->getBrowserRelatedReports()
);
}
@@ -369,4 +369,4 @@ class Piwik_DevicesDetection extends Plugin
'DevicesDetection.getBrowserVersions' => Piwik_Translate('DevicesDetection_BrowserVersions')
);
}
-}
+} \ No newline at end of file
diff --git a/plugins/ExampleUI/Controller.php b/plugins/ExampleUI/Controller.php
index 5660190aaa..1c35d6b498 100644
--- a/plugins/ExampleUI/Controller.php
+++ b/plugins/ExampleUI/Controller.php
@@ -25,11 +25,11 @@ class Piwik_ExampleUI_Controller extends Controller
$view->translations['label'] = "Hour of day";
$view->filter_sort_column = 'label';
$view->filter_sort_order = 'asc';
- $view->graph_limit = 24;
+ $view->visualization_properties->max_graph_elements = 24;
$view->filter_limit = 24;
$view->show_exclude_low_population = false;
$view->show_table_all_columns = false;
- $view->disable_row_evolution = true;
+ $view->visualization_properties->disable_row_evolution = true;
$view->y_axis_unit = '°C'; // useful if the user requests the bar graph
echo $view->render();
}
@@ -56,7 +56,7 @@ class Piwik_ExampleUI_Controller extends Controller
'graphVerticalBar', 'ExampleUI.getTemperatures', $controllerAction = 'ExampleUI.barGraph');
$view->translations['value'] = "Temperature";
$view->y_axis_unit = '°C';
- $view->graph_limit = 24;
+ $view->visualization_properties->max_graph_elements = 24;
$view->show_footer = false;
echo $view->render();
}
@@ -67,7 +67,7 @@ class Piwik_ExampleUI_Controller extends Controller
'graphPie', 'ExampleUI.getPlanetRatios', $controllerAction = 'ExampleUI.pieGraph');
$view->columns_to_display = array('value');
$view->translations['value'] = "times the diameter of Earth";
- $view->graph_limit = 10;
+ $view->visualization_properties->max_graph_elements = 10;
$view->show_footer_icons = false;
echo $view->render();
}
diff --git a/plugins/ExtraVisualizations/ExtraVisualizations.php b/plugins/ExtraVisualizations/ExtraVisualizations.php
new file mode 100644
index 0000000000..540183802e
--- /dev/null
+++ b/plugins/ExtraVisualizations/ExtraVisualizations.php
@@ -0,0 +1,47 @@
+<?php
+/**
+ * Piwik - Open source web analytics
+ *
+ * @link http://piwik.org
+ * @license http://www.gnu.org/licenses/gpl-3.0.html GPL v3 or later
+ *
+ * @category Piwik_Plugins
+ * @package Piwik_ExtraVisualizations
+ */
+
+use Piwik\Plugin;
+
+require_once PIWIK_INCLUDE_PATH . '/plugins/ExtraVisualizations/Visualizations/Treemap.php';
+
+/**
+ * This plugin contains spme extra DataTable visualizations, such as Treemap.
+ */
+class Piwik_ExtraVisualizations extends Plugin
+{
+ /**
+ * @see Piwik_Plugin::getListHooksRegistered
+ */
+ public function getListHooksRegistered()
+ {
+ return array(
+ 'AssetManager.getCssFiles' => 'getCssFiles',
+ 'AssetManager.getJsFiles' => 'getJsFiles',
+ 'DataTableVisualization.getAvailable' => 'getAvailableDataTableVisualizations',
+ );
+ }
+
+ public function getAvailableDataTableVisualizations(&$visualizations)
+ {
+ $visualizations[] = "Piwik\\Plugins\\ExtraVisualizations\\Visualizations\\Treemap";
+ }
+
+ public function getCssFiles(&$cssFiles)
+ {
+ $cssFiles[] = "plugins/CoreVisualizations/stylesheets/dataTableVisualizations.less";
+ }
+
+ public function getJsFiles(&$jsFiles)
+ {
+ //$jsFiles[] = "";
+ }
+} \ No newline at end of file
diff --git a/plugins/ExtraVisualizations/Visualizations/Treemap.php b/plugins/ExtraVisualizations/Visualizations/Treemap.php
new file mode 100644
index 0000000000..f469be9a61
--- /dev/null
+++ b/plugins/ExtraVisualizations/Visualizations/Treemap.php
@@ -0,0 +1,31 @@
+<?php
+/**
+ * Piwik - Open source web analytics
+ *
+ * @link http://piwik.org
+ * @license http://www.gnu.org/licenses/gpl-3.0.html GPL v3 or later
+ *
+ * @category Piwik
+ * @package Piwik
+ */
+namespace Piwik\Plugins\ExtraVisualizations\Visualizations;
+
+use Piwik\Plugins\CoreVisualizations\Visualizations\HtmlTable;
+
+/**
+ * TODO
+ */
+class Treemap extends HtmlTable
+{
+ const ID = 'treemap';
+ const FOOTER_ICON = 'plugins/Zeitgeist/images/table.png';
+ const FOOTER_ICON_TITLE = 'General_DisplaySimpleTable';
+
+ /**
+ * TODO
+ */
+ public function __construct($view)
+ {
+ // TODO
+ }
+} \ No newline at end of file
diff --git a/plugins/ExtraVisualizations/stylesheets/dataTableVisualizations.less b/plugins/ExtraVisualizations/stylesheets/dataTableVisualizations.less
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/plugins/ExtraVisualizations/stylesheets/dataTableVisualizations.less
diff --git a/plugins/Goals/Controller.php b/plugins/Goals/Controller.php
index 17a5e38fae..0bca7f1403 100644
--- a/plugins/Goals/Controller.php
+++ b/plugins/Goals/Controller.php
@@ -286,7 +286,7 @@ class Piwik_Goals_Controller extends Controller
$view->translations[$columnName] = $columnTranslation;
}
$view->columns_to_display = $columns;
- $view->selectable_columns = $selectableColumns;
+ $view->visualization_properties->selectable_columns = $selectableColumns;
$langString = $idGoal ? 'Goals_SingleGoalOverviewDocumentation' : 'Goals_GoalsOverviewDocumentation';
$view->documentation = Piwik_Translate($langString, '<br />');
diff --git a/plugins/Goals/Goals.php b/plugins/Goals/Goals.php
index 4dc4685c59..010f1a6623 100644
--- a/plugins/Goals/Goals.php
+++ b/plugins/Goals/Goals.php
@@ -96,7 +96,7 @@ class Piwik_Goals extends Plugin
'Menu.add' => 'addMenus',
'SitesManager.deleteSite' => 'deleteSiteGoals',
'Goals.getReportsWithGoalMetrics' => 'getActualReportsWithGoalMetrics',
- 'ViewDataTable.getReportDisplayProperties' => 'getReportDisplayProperties', // TODO: ViewDataTable should get ALL once
+ 'ViewDataTable.getReportDisplayProperties' => 'getReportDisplayProperties',
);
return $hooks;
}
diff --git a/plugins/Live/Live.php b/plugins/Live/Live.php
index dfa08ce8c5..dc199fe9d5 100644
--- a/plugins/Live/Live.php
+++ b/plugins/Live/Live.php
@@ -74,7 +74,6 @@ class Piwik_Live extends Plugin
'show_all_views_icons' => false,
'show_table_all_columns' => false,
'show_export_as_rss_feed' => false,
- 'disable_row_actions' => true,
'documentation' => Piwik_Translate('Live_VisitorLogDocumentation', array('<br />', '<br />')),
'custom_parameters' => array(
// set a very high row count so that the next link in the footer of the data table is always shown
@@ -83,6 +82,11 @@ class Piwik_Live extends Plugin
'filterEcommerce' => Common::getRequestVar('filterEcommerce', 0, 'int'),
'pageUrlNotDefined' => Piwik_Translate('General_NotDefined', Piwik_Translate('Actions_ColumnPageURL'))
),
+ 'visualization_properties' => array(
+ 'HtmlTable' => array(
+ 'disable_row_actions' => true,
+ )
+ )
);
}
}
diff --git a/plugins/PleineLune/stylesheets/_menuDashboard.less b/plugins/PleineLune/stylesheets/_menuDashboard.less
index 8b5ded920e..060995b2c9 100644
--- a/plugins/PleineLune/stylesheets/_menuDashboard.less
+++ b/plugins/PleineLune/stylesheets/_menuDashboard.less
@@ -44,6 +44,7 @@
.nav_sep {
border-color: @theme-color-box-border;
border-width: 1px 0;
+ border-radius: 0;
background: @theme-color-box-active;
padding: 0 10px;
margin-left: -10px;
diff --git a/plugins/Referers/Controller.php b/plugins/Referers/Controller.php
index c9362f4a01..1e31b6dd41 100644
--- a/plugins/Referers/Controller.php
+++ b/plugins/Referers/Controller.php
@@ -263,7 +263,7 @@ class Piwik_Referers_Controller extends Controller
{
$view = $this->getLastUnitGraph($this->pluginName, __FUNCTION__, 'Referers.getRefererType');
- $view->add_total_row = true;
+ $view->visualization_properties->add_total_row = true;
// configure displayed columns
if (empty($columns)) {
@@ -279,7 +279,7 @@ class Piwik_Referers_Controller extends Controller
} else {
$selectable = array('nb_visits', 'nb_actions');
}
- $view->selectable_columns = $selectable;
+ $view->visualization_properties->selectable_columns = $selectable;
// configure displayed rows
$visibleRows = Common::getRequestVar('rows', false);
@@ -299,7 +299,7 @@ class Piwik_Referers_Controller extends Controller
$visibleRows = array($label, $total);
$view->request_parameters_to_modify['rows'] = $label . ',' . $total;
}
- $view->row_picker_mach_rows_by = 'label';
+ $view->row_picker_match_rows_by = 'label';
$view->row_picker_visible_rows = $visibleRows;
$view->documentation = Piwik_Translate('Referers_EvolutionDocumentation') . '<br />'
diff --git a/plugins/Referers/Referers.php b/plugins/Referers/Referers.php
index 4f72e81d93..36c4b85d08 100644
--- a/plugins/Referers/Referers.php
+++ b/plugins/Referers/Referers.php
@@ -332,10 +332,14 @@ class Piwik_Referers extends Plugin
'show_offset_information' => false,
'show_pagination_control' => false,
'show_exclude_low_population' => false,
- 'disable_subtable_when_show_goals' => true,
'show_goals' => true,
'filter_limit' => 10,
- 'translations' => array('label' => $labelColumnTitle)
+ 'translations' => array('label' => $labelColumnTitle),
+ 'visualization_properties' => array(
+ 'HtmlTable' => array(
+ 'disable_subtable_when_show_goals' => true,
+ )
+ ),
);
}
@@ -347,7 +351,11 @@ class Piwik_Referers extends Plugin
'translations' => array('label' => Piwik_Translate('Referers_Referrer')),
'show_goals' => true,
'filter_limit' => 20,
- 'custom_parameters' => array('disable_row_actions' => '1'),
+ 'visualization_properties' => array(
+ 'HtmlTable' => array(
+ 'disable_row_actions' => true
+ )
+ ),
'filters' => array(
array('MetadataCallbackAddMetadata', array('referrer_type', 'html_label_prefix', $setGetAllHtmlPrefix))
)
@@ -362,7 +370,11 @@ class Piwik_Referers extends Plugin
'translations' => array('label' => Piwik_Translate('Referers_ColumnKeyword')),
'show_goals' => true,
'filter_limit' => 25,
- 'disable_subtable_when_show_goals' => true,
+ 'visualization_properties' => array(
+ 'HtmlTable' => array(
+ 'disable_subtable_when_show_goals' => true,
+ )
+ ),
);
}
@@ -383,8 +395,12 @@ class Piwik_Referers extends Plugin
'show_exclude_low_population' => false,
'show_goals' => true,
'filter_limit' => 25,
- 'disable_subtable_when_show_goals' => true,
- 'translations' => array('label' => Piwik_Translate('Referers_ColumnSearchEngine'))
+ 'translations' => array('label' => Piwik_Translate('Referers_ColumnSearchEngine')),
+ 'visualization_properties' => array(
+ 'HtmlTable' => array(
+ 'disable_subtable_when_show_goals' => true,
+ )
+ ),
);
}
@@ -404,8 +420,12 @@ class Piwik_Referers extends Plugin
'show_exclude_low_population' => false,
'show_goals' => true,
'filter_limit' => 25,
- 'disable_subtable_when_show_goals' => true,
- 'translations' => array('label' => Piwik_Translate('Referers_ColumnWebsite'))
+ 'translations' => array('label' => Piwik_Translate('Referers_ColumnWebsite')),
+ 'visualization_properties' => array(
+ 'HtmlTable' => array(
+ 'disable_subtable_when_show_goals' => true,
+ )
+ ),
);
}
@@ -417,8 +437,12 @@ class Piwik_Referers extends Plugin
'show_exclude_low_population' => false,
'filter_limit' => 10,
'show_goals' => true,
- 'disable_subtable_when_show_goals' => true,
- 'translations' => array('label' => Piwik_Translate('Referers_ColumnSocial'))
+ 'translations' => array('label' => Piwik_Translate('Referers_ColumnSocial')),
+ 'visualization_properties' => array(
+ 'HtmlTable' => array(
+ 'disable_subtable_when_show_goals' => true,
+ )
+ ),
);
$widget = Common::getRequestVar('widget', false);
diff --git a/plugins/UserSettings/UserSettings.php b/plugins/UserSettings/UserSettings.php
index 3795d0d6fd..5d82f05a25 100644
--- a/plugins/UserSettings/UserSettings.php
+++ b/plugins/UserSettings/UserSettings.php
@@ -172,86 +172,110 @@ class Piwik_UserSettings extends Plugin
);
return $hooks;
}
-
+
public function getReportDisplayProperties(&$properties)
{
- $basicUserSettingsProperties = array('show_search' => false,
- 'show_exclude_low_population' => false,
- 'filter_limit' => 5,
- 'graph_limit' => 5);
-
- $osRelatedReports = array(
- 'UserSettings.getOSFamily' => Piwik_Translate('UserSettings_OperatingSystemFamily'),
- 'UserSettings.getOS' => Piwik_Translate('UserSettings_OperatingSystems')
- );
-
- $browserRelatedReports = array(
- 'UserSettings.getBrowser' => Piwik_Translate('UserSettings_Browsers'),
- 'UserSettings.getBrowserVersion' => Piwik_Translate('UserSettings_ColumnBrowserVersion')
- );
-
- $wideScreenDeviceTypeRelatedReports = array(
- 'UserSettings.getMobileVsDesktop' => Piwik_Translate('UserSettings_MobileVsDesktop'),
- 'UserSettings.getWideScreen' => Piwik_Translate('UserSettings_ColumnTypeOfScreen')
- );
-
- $properties['UserSettings.getResolution'] = array_merge($basicUserSettingsProperties, array(
+ $properties['UserSettings.getResolution'] = $this->getDisplayPropertiesForGetResolution();
+ $properties['UserSettings.getConfiguration'] = $this->getDisplayPropertiesForGetConfiguration();
+ $properties['UserSettings.getOS'] = $this->getDisplayPropertiesForGetOS();
+ $properties['UserSettings.getOSFamily'] = $this->getDisplayPropertiesForGetOSFamily();
+ $properties['UserSettings.getBrowserVersion'] = $this->getDisplayPropertiesForGetBrowserVersion();
+ $properties['UserSettings.getBrowser'] = $this->getDisplayPropertiesForGetBrowser();
+ $properties['UserSettings.getBrowserType'] = $this->getDisplayPropertiesForGetBrowserType();
+ $properties['UserSettings.getWideScreen'] = $this->getDisplayPropertiesForGetWideScreen();
+ $properties['UserSettings.getMobileVsDesktop'] = $this->getDisplayPropertiesForGetMobileVsDesktop();
+ $properties['UserSettings.getPlugin'] = $this->getDisplayPropertiesForGetPlugin();
+ $properties['UserSettings.getLanguage'] = $this->getDisplayPropertiesForGetLanguage();
+ }
+
+ private function getDisplayPropertiesForGetResolution()
+ {
+ return array_merge($this->getBasicUserSettingsDisplayProperties(), array(
'translations' => array('label' => Piwik_Translate('UserSettings_ColumnResolution'))
));
-
- $properties['UserSettings.getConfiguration'] = array_merge($basicUserSettingsProperties, array(
+ }
+
+ private function getDisplayPropertiesForGetConfiguration()
+ {
+ return array_merge($this->getBasicUserSettingsDisplayProperties(), array(
'filter_limit' => 3,
'translations' => array('label' => Piwik_Translate('UserSettings_ColumnConfiguration'))
));
-
- $properties['UserSettings.getOS'] = array_merge($basicUserSettingsProperties, array(
+ }
+
+ private function getDisplayPropertiesForGetOS()
+ {
+ return array_merge($this->getBasicUserSettingsDisplayProperties(), array(
'translations' => array('label' => Piwik_Translate('UserSettings_ColumnOperatingSystem')),
'title' => Piwik_Translate('UserSettings_OperatingSystems'),
- 'relatedReports' => $osRelatedReports
+ 'related_reports' => $this->getOsRelatedReports()
));
-
- $properties['UserSettings.getOSFamily'] = array_merge($basicUserSettingsProperties, array(
+ }
+
+ private function getDisplayPropertiesForGetOSFamily()
+ {
+ return array_merge($this->getBasicUserSettingsDisplayProperties(), array(
'translations' => array('label' => Piwik_Translate('UserSettings_OperatingSystemFamily')),
'title' => Piwik_Translate('UserSettings_OperatingSystemFamily'),
- 'relatedReports' => $osRelatedReports
+ 'related_reports' => $this->getOsRelatedReports()
));
-
- $properties['UserSettings.getBrowserVersion'] = array_merge($basicUserSettingsProperties, array(
+ }
+
+ private function getDisplayPropertiesForGetBrowserVersion()
+ {
+ $result = array_merge($this->getBasicUserSettingsDisplayProperties(), array(
'translations' => array('label' => Piwik_Translate('UserSettings_ColumnBrowserVersion')),
- 'graph_limit' => 7,
'title' => Piwik_Translate('UserSettings_ColumnBrowserVersion'),
- 'relatedReports' => $browserRelatedReports
+ 'related_reports' => $this->getBrowserRelatedReports()
));
-
- $properties['UserSettings.getBrowser'] = array_merge($basicUserSettingsProperties, array(
+ $result['visualization_properties']['JqplotGraph']['max_graph_elements'] = 7;
+ return $result;
+ }
+
+ private function getDisplayPropertiesForGetBrowser()
+ {
+ $result = array_merge($this->getBasicUserSettingsDisplayProperties(), array(
'translations' => array('label' => Piwik_Translate('UserSettings_ColumnBrowser')),
- 'graph_limit' => 7,
'title' => Piwik_Translate('UserSettings_Browsers'),
- 'relatedReports' => $browserRelatedReports
+ 'related_reports' => $this->getBrowserRelatedReports()
));
-
- $properties['UserSettings.getBrowserType'] = array_merge($basicUserSettingsProperties, array(
+ $result['visualization_properties']['JqplotGraph']['max_graph_elements'] = 7;
+ return $result;
+ }
+
+ private function getDisplayPropertiesForGetBrowserType()
+ {
+ return array_merge($this->getBasicUserSettingsDisplayProperties(), array(
'translations' => array('label' => Piwik_Translate('UserSettings_ColumnBrowserFamily')),
'show_offset_information' => false,
'show_pagination_control' => false,
'default_view_type' => 'graphPie',
));
-
- $properties['UserSettings.getWideScreen'] = array_merge($basicUserSettingsProperties, array(
+ }
+
+ private function getDisplayPropertiesForGetWideScreen()
+ {
+ return array_merge($this->getBasicUserSettingsDisplayProperties(), array(
'translations' => array('label' => Piwik_Translate('UserSettings_ColumnTypeOfScreen')),
'show_offset_information' => false,
'show_pagination_control' => false,
'title' => Piwik_Translate('UserSettings_ColumnTypeOfScreen'),
- 'relatedReports' => $wideScreenDeviceTypeRelatedReports
+ 'related_reports' => $this->getWideScreenDeviceTypeRelatedReports()
));
-
- $properties['UserSettings.getMobileVsDesktop'] = array_merge($basicUserSettingsProperties, array(
+ }
+
+ private function getDisplayPropertiesForGetMobileVsDesktop()
+ {
+ return array_merge($this->getBasicUserSettingsDisplayProperties(), array(
'translations' => array('label' => Piwik_Translate('UserSettings_MobileVsDesktop')),
'title' => Piwik_Translate('UserSettings_MobileVsDesktop'),
- 'relatedReports' => $wideScreenDeviceTypeRelatedReports
+ 'related_reports' => $this->getWideScreenDeviceTypeRelatedReports()
));
-
- $properties['UserSettings.getPlugin'] = array_merge($basicUserSettingsProperties, array(
+ }
+
+ private function getDisplayPropertiesForGetPlugin()
+ {
+ return array_merge($this->getBasicUserSettingsDisplayProperties(), array(
'translations' => array(
'label' => Piwik_Translate('UserSettings_ColumnPlugin'),
'nb_visits_percentage' =>
@@ -267,18 +291,58 @@ class Piwik_UserSettings extends Plugin
'filter_limit' => 10,
'show_footer_message' => Piwik_Translate('UserSettings_PluginDetectionDoesNotWorkInIE'),
));
-
- $properties['UserSettings.getLanguage'] = array(
+ }
+
+ private function getDisplayPropertiesForGetLanguage()
+ {
+ return array(
'translations' => array('label' => Piwik_Translate('General_Language')),
'filter_sort_column' => 'nb_visits',
'filter_sort_order' => 'desc',
'show_search' => false,
- 'filter_limit' => false,
'columns_to_display' => array('label', 'nb_visits'),
'show_exclude_low_population' => false,
);
}
+ private function getWideScreenDeviceTypeRelatedReports()
+ {
+ return array(
+ 'UserSettings.getMobileVsDesktop' => Piwik_Translate('UserSettings_MobileVsDesktop'),
+ 'UserSettings.getWideScreen' => Piwik_Translate('UserSettings_ColumnTypeOfScreen')
+ );
+ }
+
+ private function getBrowserRelatedReports()
+ {
+ return array(
+ 'UserSettings.getBrowser' => Piwik_Translate('UserSettings_Browsers'),
+ 'UserSettings.getBrowserVersion' => Piwik_Translate('UserSettings_ColumnBrowserVersion')
+ );
+ }
+
+ private function getOsRelatedReports()
+ {
+ return array(
+ 'UserSettings.getOSFamily' => Piwik_Translate('UserSettings_OperatingSystemFamily'),
+ 'UserSettings.getOS' => Piwik_Translate('UserSettings_OperatingSystems')
+ );
+ }
+
+ private function getBasicUserSettingsDisplayProperties()
+ {
+ return array(
+ 'show_search' => false,
+ 'show_exclude_low_population' => false,
+ 'filter_limit' => 5,
+ 'visualization_properties' => array(
+ 'JqplotGraph' => array(
+ 'max_graph_elements' => 5
+ )
+ )
+ );
+ }
+
/**
* Registers reports metadata
*
diff --git a/plugins/VisitTime/VisitTime.php b/plugins/VisitTime/VisitTime.php
index 9b652577d3..3273daf3ea 100644
--- a/plugins/VisitTime/VisitTime.php
+++ b/plugins/VisitTime/VisitTime.php
@@ -131,34 +131,44 @@ class Piwik_VisitTime extends Plugin
$properties['VisitTime.getVisitInformationPerServerTime'] = array_merge($commonProperties, array(
'filter_limit' => 24,
- 'graph_limit' => null,
'show_goals' => true,
'translations' => array('label' => Piwik_Translate('VisitTime_ColumnServerTime')),
-
- // custom parameter
- 'hideFutureHoursWhenToday' => 1,
+ 'request_parameters_to_modify' => array('hideFutureHoursWhenToday' => 1),
+ 'visualization_properties' => array(
+ 'JqplotGraph' => array(
+ 'max_graph_elements' => false,
+ )
+ )
));
$properties['VisitTime.getVisitInformationPerLocalTime'] = array_merge($commonProperties, array(
'filter_limit' => 24,
- 'graph_limit' => null,
'title' => Piwik_Translate('VisitTime_ColumnLocalTime'),
'translations' => array('label' => Piwik_Translate('VisitTime_LocalTime')),
+ 'visualization_properties' => array(
+ 'JqplotGraph' => array(
+ 'max_graph_elements' => false,
+ )
+ )
));
$properties['VisitTime.getByDayOfWeek'] = array_merge($commonProperties, array(
'filter_limit' => 7,
- 'graph_limit' => null,
'enable_sort' => false,
- 'show_all_ticks' => true,
'show_footer_message' =>
Piwik_Translate('General_ReportGeneratedFrom', self::getDateRangeForFooterMessage()),
'translations' => array('label' => Piwik_Translate('VisitTime_DayOfWeek')),
+ 'visualization_properties' => array(
+ 'JqplotGraph' => array(
+ 'show_all_ticks' => true,
+ 'max_graph_elements' => false,
+ )
+ )
));
// add the visits by day of week as a related report, if the current period is not 'day'
if (Common::getRequestVar('period', 'day') != 'day') {
- $properties['VisitTime.getVisitInformationPerLocalTime']['relatedReports'] = array(
+ $properties['VisitTime.getVisitInformationPerLocalTime']['related_reports'] = array(
'VisitTime.getByDayOfWeek' => Piwik_Translate('VisitTime_VisitsByDayOfWeek')
);
}
diff --git a/plugins/VisitorInterest/VisitorInterest.php b/plugins/VisitorInterest/VisitorInterest.php
index a656e73804..6ea2c4eb69 100644
--- a/plugins/VisitorInterest/VisitorInterest.php
+++ b/plugins/VisitorInterest/VisitorInterest.php
@@ -166,13 +166,17 @@ class Piwik_VisitorInterest extends Plugin
'filter_sort_column' => 'label',
'filter_sort_order' => 'asc',
'translations' => array('label' => Piwik_Translate('VisitorInterest_ColumnVisitDuration')),
- 'graph_limit' => 10,
'enable_sort' => false,
'show_exclude_low_population' => false,
'show_offset_information' => false,
'show_pagination_control' => false,
'show_search' => false,
'show_table_all_columns' => false,
+ 'visualization_properties' => array(
+ 'JqplotGraph' => array(
+ 'max_graph_elements' => 10
+ )
+ )
);
}
@@ -183,13 +187,17 @@ class Piwik_VisitorInterest extends Plugin
'filter_sort_column' => 'label',
'filter_sort_order' => 'asc',
'translations' => array('label' => Piwik_Translate('VisitorInterest_ColumnPagesPerVisit')),
- 'graph_limit' => 10,
'enable_sort' => false,
'show_exclude_low_population' => false,
'show_offset_information' => false,
'show_pagination_control' => false,
'show_search' => false,
'show_table_all_columns' => false,
+ 'visualization_properties' => array(
+ 'JqplotGraph' => array(
+ 'max_graph_elements' => 10
+ )
+ )
);
}
diff --git a/tests/PHPUnit/Integration/FlattenReportsTest.php b/tests/PHPUnit/Integration/FlattenReportsTest.php
index 48ecdad576..19d9ed1414 100644
--- a/tests/PHPUnit/Integration/FlattenReportsTest.php
+++ b/tests/PHPUnit/Integration/FlattenReportsTest.php
@@ -88,6 +88,14 @@ class Test_Piwik_Integration_FlattenReports extends IntegrationTestCase
'testSuffix' => '_expandedSubtable',
'otherRequestParameters' => array('expanded' => '1')));
+ // test expanded=1 & depth=1
+ $return[] = array('Actions.getPageUrls', array('idSite' => $idSite,
+ 'date' => $dateTime,
+ 'periods' => array('week'),
+ 'testSuffix' => '_expandedWithDepth',
+ 'otherRequestParameters' => array('expanded' => '1',
+ 'depth' => '1')));
+
// test flat=1 w/ filter_pattern_recursive
$return[] = array('Actions.getPageUrls', array('idSite' => $idSite,
'date' => $dateTime,
diff --git a/tests/PHPUnit/Integration/expected/test_FlattenReports_expandedWithDepth__Actions.getPageUrls_week.xml b/tests/PHPUnit/Integration/expected/test_FlattenReports_expandedWithDepth__Actions.getPageUrls_week.xml
new file mode 100644
index 0000000000..3f3d4a7509
--- /dev/null
+++ b/tests/PHPUnit/Integration/expected/test_FlattenReports_expandedWithDepth__Actions.getPageUrls_week.xml
@@ -0,0 +1,155 @@
+<?xml version="1.0" encoding="utf-8" ?>
+<result>
+ <row>
+ <label>dir1</label>
+ <nb_visits>6</nb_visits>
+ <nb_hits>6</nb_hits>
+ <sum_time_spent>0</sum_time_spent>
+ <nb_hits_with_time_generation>6</nb_hits_with_time_generation>
+ <min_time_generation>0.1</min_time_generation>
+ <max_time_generation>0.6</max_time_generation>
+ <entry_nb_visits>2</entry_nb_visits>
+ <entry_nb_actions>6</entry_nb_actions>
+ <entry_sum_visit_length>2</entry_sum_visit_length>
+ <entry_bounce_count>0</entry_bounce_count>
+ <exit_nb_visits>2</exit_nb_visits>
+ <avg_time_on_page>0</avg_time_on_page>
+ <bounce_rate>0%</bounce_rate>
+ <exit_rate>33%</exit_rate>
+ <avg_time_generation>0.3</avg_time_generation>
+ <subtable>
+ <row>
+ <label>sub</label>
+ <nb_visits>6</nb_visits>
+ <nb_hits>6</nb_hits>
+ <sum_time_spent>0</sum_time_spent>
+ <nb_hits_with_time_generation>6</nb_hits_with_time_generation>
+ <min_time_generation>0.1</min_time_generation>
+ <max_time_generation>0.6</max_time_generation>
+ <entry_nb_visits>2</entry_nb_visits>
+ <entry_nb_actions>6</entry_nb_actions>
+ <entry_sum_visit_length>2</entry_sum_visit_length>
+ <entry_bounce_count>0</entry_bounce_count>
+ <exit_nb_visits>2</exit_nb_visits>
+ <avg_time_on_page>0</avg_time_on_page>
+ <bounce_rate>0%</bounce_rate>
+ <exit_rate>33%</exit_rate>
+ <avg_time_generation>0.3</avg_time_generation>
+ </row>
+ </subtable>
+ </row>
+ <row>
+ <label>dir2</label>
+ <nb_visits>6</nb_visits>
+ <nb_hits>6</nb_hits>
+ <sum_time_spent>0</sum_time_spent>
+ <nb_hits_with_time_generation>6</nb_hits_with_time_generation>
+ <min_time_generation>0.2</min_time_generation>
+ <max_time_generation>1.2</max_time_generation>
+ <entry_nb_visits>2</entry_nb_visits>
+ <entry_nb_actions>6</entry_nb_actions>
+ <entry_sum_visit_length>2</entry_sum_visit_length>
+ <entry_bounce_count>0</entry_bounce_count>
+ <exit_nb_visits>2</exit_nb_visits>
+ <avg_time_on_page>0</avg_time_on_page>
+ <bounce_rate>0%</bounce_rate>
+ <exit_rate>33%</exit_rate>
+ <avg_time_generation>0.6</avg_time_generation>
+ <subtable>
+ <row>
+ <label>sub</label>
+ <nb_visits>6</nb_visits>
+ <nb_hits>6</nb_hits>
+ <sum_time_spent>0</sum_time_spent>
+ <nb_hits_with_time_generation>6</nb_hits_with_time_generation>
+ <min_time_generation>0.2</min_time_generation>
+ <max_time_generation>1.2</max_time_generation>
+ <entry_nb_visits>2</entry_nb_visits>
+ <entry_nb_actions>6</entry_nb_actions>
+ <entry_sum_visit_length>2</entry_sum_visit_length>
+ <entry_bounce_count>0</entry_bounce_count>
+ <exit_nb_visits>2</exit_nb_visits>
+ <avg_time_on_page>0</avg_time_on_page>
+ <bounce_rate>0%</bounce_rate>
+ <exit_rate>33%</exit_rate>
+ <avg_time_generation>0.6</avg_time_generation>
+ </row>
+ </subtable>
+ </row>
+ <row>
+ <label>dir3</label>
+ <nb_visits>6</nb_visits>
+ <nb_hits>6</nb_hits>
+ <sum_time_spent>0</sum_time_spent>
+ <nb_hits_with_time_generation>6</nb_hits_with_time_generation>
+ <min_time_generation>0.3</min_time_generation>
+ <max_time_generation>1.8</max_time_generation>
+ <entry_nb_visits>2</entry_nb_visits>
+ <entry_nb_actions>6</entry_nb_actions>
+ <entry_sum_visit_length>2</entry_sum_visit_length>
+ <entry_bounce_count>0</entry_bounce_count>
+ <exit_nb_visits>2</exit_nb_visits>
+ <avg_time_on_page>0</avg_time_on_page>
+ <bounce_rate>0%</bounce_rate>
+ <exit_rate>33%</exit_rate>
+ <avg_time_generation>0.9</avg_time_generation>
+ <subtable>
+ <row>
+ <label>sub</label>
+ <nb_visits>6</nb_visits>
+ <nb_hits>6</nb_hits>
+ <sum_time_spent>0</sum_time_spent>
+ <nb_hits_with_time_generation>6</nb_hits_with_time_generation>
+ <min_time_generation>0.3</min_time_generation>
+ <max_time_generation>1.8</max_time_generation>
+ <entry_nb_visits>2</entry_nb_visits>
+ <entry_nb_actions>6</entry_nb_actions>
+ <entry_sum_visit_length>2</entry_sum_visit_length>
+ <entry_bounce_count>0</entry_bounce_count>
+ <exit_nb_visits>2</exit_nb_visits>
+ <avg_time_on_page>0</avg_time_on_page>
+ <bounce_rate>0%</bounce_rate>
+ <exit_rate>33%</exit_rate>
+ <avg_time_generation>0.9</avg_time_generation>
+ </row>
+ </subtable>
+ </row>
+ <row>
+ <label>sub</label>
+ <nb_visits>1</nb_visits>
+ <nb_hits>1</nb_hits>
+ <sum_time_spent>0</sum_time_spent>
+ <nb_hits_with_time_generation>0</nb_hits_with_time_generation>
+ <min_time_generation />
+ <max_time_generation>0</max_time_generation>
+ <entry_nb_visits>1</entry_nb_visits>
+ <entry_nb_actions>1</entry_nb_actions>
+ <entry_sum_visit_length>0</entry_sum_visit_length>
+ <entry_bounce_count>1</entry_bounce_count>
+ <exit_nb_visits>1</exit_nb_visits>
+ <avg_time_on_page>0</avg_time_on_page>
+ <bounce_rate>100%</bounce_rate>
+ <exit_rate>100%</exit_rate>
+ <avg_time_generation>0</avg_time_generation>
+ <subtable>
+ <row>
+ <label>dir</label>
+ <nb_visits>1</nb_visits>
+ <nb_hits>1</nb_hits>
+ <sum_time_spent>0</sum_time_spent>
+ <nb_hits_with_time_generation>0</nb_hits_with_time_generation>
+ <min_time_generation />
+ <max_time_generation>0</max_time_generation>
+ <entry_nb_visits>1</entry_nb_visits>
+ <entry_nb_actions>1</entry_nb_actions>
+ <entry_sum_visit_length>0</entry_sum_visit_length>
+ <entry_bounce_count>1</entry_bounce_count>
+ <exit_nb_visits>1</exit_nb_visits>
+ <avg_time_on_page>0</avg_time_on_page>
+ <bounce_rate>100%</bounce_rate>
+ <exit_rate>100%</exit_rate>
+ <avg_time_generation>0</avg_time_generation>
+ </row>
+ </subtable>
+ </row>
+</result> \ No newline at end of file
diff --git a/tests/PHPUnit/IntegrationTestCase.php b/tests/PHPUnit/IntegrationTestCase.php
index 0fdb16c32d..a9f183652e 100755
--- a/tests/PHPUnit/IntegrationTestCase.php
+++ b/tests/PHPUnit/IntegrationTestCase.php
@@ -243,9 +243,6 @@ abstract class IntegrationTestCase extends PHPUnit_Framework_TestCase
$_GET = $_REQUEST = array();
Translate::getInstance()->unloadEnglishTranslation();
-
- // re-enable tag cloud shuffling
- Cloud::$debugDisableShuffle = true;
}
public function setUp()
diff --git a/tests/PHPUnit/TestingEnvironment.php b/tests/PHPUnit/TestingEnvironment.php
index 6e015ab681..99d2822ef6 100644
--- a/tests/PHPUnit/TestingEnvironment.php
+++ b/tests/PHPUnit/TestingEnvironment.php
@@ -20,5 +20,8 @@ class Piwik_TestingEnvironment
Piwik_AddAction('Config.createConfigSingleton', function($config) {
$config->setTestEnvironment();
});
+ Piwik_AddAction('FrontController.dispatch', function() {
+ \Piwik\Plugins\CoreVisualizations\Visualizations\Cloud::$debugDisableShuffle = true;
+ });
}
} \ No newline at end of file
diff --git a/tests/PHPUnit/UI/UIIntegrationTest.php b/tests/PHPUnit/UI/UIIntegrationTest.php
index 066f8502e0..4571227247 100644
--- a/tests/PHPUnit/UI/UIIntegrationTest.php
+++ b/tests/PHPUnit/UI/UIIntegrationTest.php
@@ -21,6 +21,7 @@ use Piwik\AssetManager;
class Test_Piwik_Integration_UIIntegrationTest extends IntegrationTestCase
{
const IMAGE_TYPE = 'png';
+ const CUTYCAPT_DELAY = 1000;
public static $fixture = null; // initialized below class definition
private static $useXvfb = false;
@@ -203,14 +204,14 @@ class Test_Piwik_Integration_UIIntegrationTest extends IntegrationTestCase
$this->runCutyCapt($urlQuery, $processedScreenshotPath);
// compare processed w/ expected
- $this->compareScreenshot($name, $expectedScreenshotPath, $processedScreenshotPath);
+ $this->compareScreenshot($name, $expectedScreenshotPath, $processedScreenshotPath, $urlQuery);
}
private function runCutyCapt($urlQuery, $processedPath)
{
$url = self::getProxyUrl() . $urlQuery;
- $cmd = "cutycapt --url=\"$url\" --out=\"$processedPath\" --min-width=1366 --delay=1000 2>&1";
+ $cmd = "cutycapt --url=\"$url\" --out=\"$processedPath\" --min-width=1366 --delay=".self::CUTYCAPT_DELAY." 2>&1";
if (self::$useXvfb) {
$cmd = 'xvfb-run --server-args="-screen 0, 1024x768x24" ' . $cmd;
}
@@ -224,7 +225,7 @@ class Test_Piwik_Integration_UIIntegrationTest extends IntegrationTestCase
return $output;
}
- private function compareScreenshot($name, $expectedPath, $processedPath)
+ private function compareScreenshot($name, $expectedPath, $processedPath, $urlQuery)
{
$processed = file_get_contents($processedPath);
@@ -233,6 +234,9 @@ class Test_Piwik_Integration_UIIntegrationTest extends IntegrationTestCase
}
$expected = file_get_contents($expectedPath);
+ if ($expected != $processed) {
+ echo "\nFail: '$processedPath' for '$urlQuery'\n";
+ }
$this->assertTrue($expected == $processed, "screenshot compare failed for '$processedPath'");
}
@@ -260,5 +264,4 @@ class Test_Piwik_Integration_UIIntegrationTest extends IntegrationTestCase
}
}
-Test_Piwik_Integration_UIIntegrationTest::$fixture = new Test_Piwik_Fixture_ManySitesImportedLogsWithXssAttempts();
-
+Test_Piwik_Integration_UIIntegrationTest::$fixture = new Test_Piwik_Fixture_ManySitesImportedLogsWithXssAttempts(); \ No newline at end of file
diff --git a/tests/PHPUnit/proxy/index.php b/tests/PHPUnit/proxy/index.php
index 12f5e0b2a9..14c0d7593d 100644
--- a/tests/PHPUnit/proxy/index.php
+++ b/tests/PHPUnit/proxy/index.php
@@ -6,7 +6,6 @@
// make sure the test environment is loaded
use Piwik\Tracker\Cache;
-use Piwik\Visualization\Cloud;
// Wrapping the request inside ob_start() calls to ensure that the Test
// calling us waits for the full request to process before unblocking
@@ -23,8 +22,6 @@ require_once realpath(dirname(__FILE__)) . '/../../../core/functions.php';
require_once realpath(dirname(__FILE__)) . "/../../../tests/PHPUnit/TestingEnvironment.php";
Piwik_TestingEnvironment::addHooks();
-Cloud::$debugDisableShuffle = true;
-
\Piwik\Tracker::setTestEnvironment();
Cache::deleteTrackerCache();