From e7325c72565a92cc7ff6c6eabdbff885d9158f97 Mon Sep 17 00:00:00 2001
From: sgiehl <stefan@piwik.org>
Date: Mon, 8 Dec 2014 22:50:44 +0100
Subject: [PATCH] moved resolution and configuration reports to a new plugin

---
 CHANGELOG.md                                  |  2 +
 config/global.ini.php                         |  1 +
 core/Plugin/Segment.php                       |  2 +-
 core/Updates/2.10.0-b6.php                    | 43 ++++++++++++
 core/Version.php                              |  2 +-
 .../templates/_dataTableViz_visitorLog.twig   |  2 +-
 .../Live/templates/getLastVisitsStart.twig    |  2 +-
 .../Live/templates/getSingleVisitSummary.twig |  2 +-
 plugins/Resolution/API.php                    | 49 +++++++++++++
 plugins/Resolution/Archiver.php               | 68 +++++++++++++++++++
 .../Columns/Configuration.php                 |  4 +-
 .../Columns/Resolution.php                    |  8 +--
 plugins/Resolution/Reports/Base.php           | 32 +++++++++
 .../Reports/GetConfiguration.php              | 12 ++--
 .../Reports/GetResolution.php                 | 10 +--
 plugins/Resolution/Resolution.php             | 35 ++++++++++
 plugins/Resolution/Segment.php                | 21 ++++++
 plugins/Resolution/Visitor.php                | 28 ++++++++
 plugins/Resolution/functions.php              | 29 ++++++++
 plugins/Resolution/lang/en.json               | 12 ++++
 plugins/UserSettings/API.php                  | 13 ++--
 plugins/UserSettings/Archiver.php             | 24 -------
 plugins/UserSettings/Controller.php           |  4 +-
 plugins/UserSettings/UserSettings.php         |  7 +-
 plugins/UserSettings/Visitor.php              |  9 ---
 plugins/UserSettings/functions.php            | 17 -----
 plugins/UserSettings/lang/en.json             |  9 +--
 plugins/UserSettings/templates/index.twig     |  4 +-
 .../DataTable/Filter/PivotByDimensionTest.php |  6 +-
 tests/PHPUnit/Unit/DeprecatedMethodsTest.php  |  2 +
 30 files changed, 365 insertions(+), 94 deletions(-)
 create mode 100644 core/Updates/2.10.0-b6.php
 create mode 100644 plugins/Resolution/API.php
 create mode 100644 plugins/Resolution/Archiver.php
 rename plugins/{UserSettings => Resolution}/Columns/Configuration.php (71%)
 rename plugins/{UserSettings => Resolution}/Columns/Resolution.php (83%)
 create mode 100644 plugins/Resolution/Reports/Base.php
 rename plugins/{UserSettings => Resolution}/Reports/GetConfiguration.php (58%)
 rename plugins/{UserSettings => Resolution}/Reports/GetResolution.php (65%)
 create mode 100644 plugins/Resolution/Resolution.php
 create mode 100644 plugins/Resolution/Segment.php
 create mode 100644 plugins/Resolution/Visitor.php
 create mode 100644 plugins/Resolution/functions.php
 create mode 100644 plugins/Resolution/lang/en.json

diff --git a/CHANGELOG.md b/CHANGELOG.md
index 690e2cf71e..0c96421886 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -16,6 +16,8 @@ This is a changelog for Piwik platform developers. All changes for our HTTP API'
 * The API method `UserSettings.getOS` is deprecated and will be removed from May 1st 2015. Use `DevicesDetection.getOsVersions` instead
 * The API method `UserSettings.getMobileVsDesktop` is deprecated and will be removed from May 1st 2015. Use `DevicesDetection.getType` instead
 * The API method `UserSettings.getBrowserType` is deprecated and will be removed from May 1st 2015. Use `DevicesDetection.getBrowserEngines` instead
+* The API method `UserSettings.getResolution` is deprecated and will be removed from May 1st 2015. Use `Resolution.getResolution` instead
+* The API method `UserSettings.getConfiguration` is deprecated and will be removed from May 1st 2015. Use `Resolution.getConfiguration` instead
 * The API method `UserSettings.getWideScreen` has been removed
 
 ### Library updates
diff --git a/config/global.ini.php b/config/global.ini.php
index 2bab7b130d..c0bb519538 100644
--- a/config/global.ini.php
+++ b/config/global.ini.php
@@ -717,6 +717,7 @@ Plugins[] = Morpheus
 Plugins[] = Contents
 Plugins[] = TestRunner
 Plugins[] = BulkTracking
+Plugins[] = Resolution
 
 [PluginsInstalled]
 PluginsInstalled[] = Login
diff --git a/core/Plugin/Segment.php b/core/Plugin/Segment.php
index 795d4da157..f29f208059 100644
--- a/core/Plugin/Segment.php
+++ b/core/Plugin/Segment.php
@@ -96,7 +96,7 @@ class Segment
 
     /**
      * Set (overwrite) the segment display name. This name will be visible in the API and the UI. It should be a
-     * translation key such as 'Actions_ColumnEntryPageTitle' or 'UserSettings_ColumnResolution'.
+     * translation key such as 'Actions_ColumnEntryPageTitle' or 'Resolution_ColumnResolution'.
      * @param string $name
      * @api
      */
diff --git a/core/Updates/2.10.0-b6.php b/core/Updates/2.10.0-b6.php
new file mode 100644
index 0000000000..aac4e8b7e4
--- /dev/null
+++ b/core/Updates/2.10.0-b6.php
@@ -0,0 +1,43 @@
+<?php
+/**
+ * Piwik - free/libre analytics platform
+ *
+ * @link http://piwik.org
+ * @license http://www.gnu.org/licenses/gpl-3.0.html GPL v3 or later
+ *
+ */
+
+namespace Piwik\Updates;
+
+use Piwik\DataAccess\ArchiveTableCreator;
+use Piwik\Updater;
+use Piwik\Updates;
+
+class Updates_2_10_0_b6 extends Updates
+{
+
+    static function getSql()
+    {
+        $sqls = array();
+
+        $archiveTables = ArchiveTableCreator::getTablesArchivesInstalled();
+
+        $archiveBlobTables = array_filter($archiveTables, function($name) {
+            return ArchiveTableCreator::getTypeFromTableName($name) == ArchiveTableCreator::BLOB_TABLE;
+        });
+
+        foreach ($archiveBlobTables as $table) {
+
+            $sqls["UPDATE " . $table . " SET name = 'Resolution_resolution' WHERE name = 'UserSettings_resolution'"] = false;
+            $sqls["UPDATE " . $table . " SET name = 'Resolution_configuration' WHERE name = 'UserSettings_configuration'"] = false;
+        }
+
+        return $sqls;
+    }
+
+    static function update()
+    {
+        Updater::updateDatabase(__FILE__, self::getSql());
+    }
+
+}
diff --git a/core/Version.php b/core/Version.php
index 4c3de8b7df..6d2dea8e5a 100644
--- a/core/Version.php
+++ b/core/Version.php
@@ -20,5 +20,5 @@ final class Version
      * The current Piwik version.
      * @var string
      */
-    const VERSION = '2.10.0-b5';
+    const VERSION = '2.10.0-b6';
 }
diff --git a/plugins/Live/templates/_dataTableViz_visitorLog.twig b/plugins/Live/templates/_dataTableViz_visitorLog.twig
index a0a0d99716..535fd2a1ce 100644
--- a/plugins/Live/templates/_dataTableViz_visitorLog.twig
+++ b/plugins/Live/templates/_dataTableViz_visitorLog.twig
@@ -37,7 +37,7 @@
         {% endif %}
         {% if visitor.getColumn('operatingSystemIcon') %}&nbsp;
         <img src="{{ visitor.getColumn('operatingSystemIcon') }}"
-             title="{{ visitor.getColumn('operatingSystem') }}, {{ visitor.getColumn('resolution') }}"/>{% endif %}
+             title="{{ visitor.getColumn('operatingSystem') }}{% if visitor.getColumn('resolution') %}, {{ visitor.getColumn('resolution') }}{% endif %}"/>{% endif %}
         {% if visitor.getColumn('visitorTypeIcon') %}
             {% if visitor.getColumn('visitorTypeIcon') %}&nbsp;-
             <img src="{{ visitor.getColumn('visitorTypeIcon') }}"
diff --git a/plugins/Live/templates/getLastVisitsStart.twig b/plugins/Live/templates/getLastVisitsStart.twig
index 7b9f6a4d9d..ce7af8e36d 100644
--- a/plugins/Live/templates/getLastVisitsStart.twig
+++ b/plugins/Live/templates/getLastVisitsStart.twig
@@ -10,7 +10,7 @@
                 {{ visitor.serverDatePretty }} - {{ visitor.serverTimePretty }} {% if visitor.visitDuration > 0 %}<em>({{ visitor.visitDurationPretty|raw }})</em>{% endif %}
                 {% if visitor.countryFlag is defined %}&nbsp;<img src="{{ visitor.countryFlag }}" title="{{ visitor.location }}, {{ 'Provider_ColumnProvider'|translate }} {% if visitor.providerName is defined %}{{ visitor.providerName }}{% endif %}"/>{% endif %}
                 {% if visitor.browserIcon is defined %}&nbsp;<img src="{{ visitor.browserIcon }}" title="{{ visitor.browserName }}, {{ 'General_Plugins'|translate }}: {{ visitor.plugins }}"/>{% endif %}
-                {% if visitor.operatingSystemIcon is defined %}&nbsp;<img src="{{ visitor.operatingSystemIcon }}" title="{{ visitor.operatingSystem }}, {{ visitor.resolution }}"/>{% endif %}
+                {% if visitor.operatingSystemIcon is defined %}&nbsp;<img src="{{ visitor.operatingSystemIcon }}" title="{{ visitor.operatingSystem }}{% if visitor.resolution is defined %}, {{ visitor.resolution }}{% endif %}"/>{% endif %}
                 &nbsp;
                 {% if visitor.visitConverted %}
                 <span title="{{ 'General_VisitConvertedNGoals'|translate(visitor.goalConversions) }}" class='visitorRank'>
diff --git a/plugins/Live/templates/getSingleVisitSummary.twig b/plugins/Live/templates/getSingleVisitSummary.twig
index 77f1c8f2bb..a515b0dff6 100644
--- a/plugins/Live/templates/getSingleVisitSummary.twig
+++ b/plugins/Live/templates/getSingleVisitSummary.twig
@@ -34,7 +34,7 @@
                 {% if visitData.operatingSystemIcon is defined %}<img src="{{ visitData.operatingSystemIcon }}"/>{% endif %}{% if visitData.operatingSystem is defined %}<span>{{ visitData.operatingSystem }}</span>{% endif %}
             </div>
         </li>
-        {% if visitData.resolution is defined %}<li><span>{{ 'UserSettings_ColumnResolution'|translate }}</span><strong>{{ visitData.resolution }}</strong></li>{% endif %}
+        {% if visitData.resolution is defined %}<li><span>{{ 'Resolution_ColumnResolution'|translate }}</span><strong>{{ visitData.resolution }}</strong></li>{% endif %}
         {% if visitData.userId is not empty %}<li><span>{{ 'General_UserId'|translate }}</span><strong>{{ visitData.userId|raw }}</strong></li>{% endif %}
         {% if visitReferralSummary is defined %}
         {%- set keywordNotDefined = 'General_NotDefined'|translate('General_ColumnKeyword'|translate) -%}
diff --git a/plugins/Resolution/API.php b/plugins/Resolution/API.php
new file mode 100644
index 0000000000..8fc33efddb
--- /dev/null
+++ b/plugins/Resolution/API.php
@@ -0,0 +1,49 @@
+<?php
+/**
+ * Piwik - free/libre analytics platform
+ *
+ * @link http://piwik.org
+ * @license http://www.gnu.org/licenses/gpl-3.0.html GPL v3 or later
+ *
+ */
+namespace Piwik\Plugins\Resolution;
+
+use Piwik\Archive;
+use Piwik\DataTable;
+use Piwik\Metrics;
+use Piwik\Piwik;
+
+/**
+ * @see plugins/Resolution/functions.php
+ */
+require_once PIWIK_INCLUDE_PATH . '/plugins/Resolution/functions.php';
+
+/**
+ * @method static \Piwik\Plugins\Resolution\API getInstance()
+ */
+class API extends \Piwik\Plugin\API
+{
+    protected function getDataTable($name, $idSite, $period, $date, $segment)
+    {
+        Piwik::checkUserHasViewAccess($idSite);
+        $archive = Archive::build($idSite, $period, $date, $segment);
+        $dataTable = $archive->getDataTable($name);
+        $dataTable->filter('Sort', array(Metrics::INDEX_NB_VISITS));
+        $dataTable->queueFilter('ReplaceColumnNames');
+        $dataTable->queueFilter('ReplaceSummaryRowLabel');
+        return $dataTable;
+    }
+
+    public function getResolution($idSite, $period, $date, $segment = false)
+    {
+        $dataTable = $this->getDataTable(Archiver::RESOLUTION_RECORD_NAME, $idSite, $period, $date, $segment);
+        return $dataTable;
+    }
+
+    public function getConfiguration($idSite, $period, $date, $segment = false)
+    {
+        $dataTable = $this->getDataTable(Archiver::CONFIGURATION_RECORD_NAME, $idSite, $period, $date, $segment);
+        $dataTable->queueFilter('ColumnCallbackReplace', array('label', __NAMESPACE__ . '\getConfigurationLabel'));
+        return $dataTable;
+    }
+}
diff --git a/plugins/Resolution/Archiver.php b/plugins/Resolution/Archiver.php
new file mode 100644
index 0000000000..f44d744c53
--- /dev/null
+++ b/plugins/Resolution/Archiver.php
@@ -0,0 +1,68 @@
+<?php
+/**
+ * Piwik - free/libre analytics platform
+ *
+ * @link http://piwik.org
+ * @license http://www.gnu.org/licenses/gpl-3.0.html GPL v3 or later
+ *
+ */
+
+namespace Piwik\Plugins\Resolution;
+
+use Piwik\DataTable;
+use Piwik\Metrics;
+
+/**
+ * Archiver for Resolution Plugin
+ *
+ * @see PluginsArchiver
+ */
+class Archiver extends \Piwik\Plugin\Archiver
+{
+    const RESOLUTION_RECORD_NAME = 'Resolution_resolution';
+    const CONFIGURATION_RECORD_NAME = 'Resolution_configuration';
+    const RESOLUTION_DIMENSION = "log_visit.config_resolution";
+    const CONFIGURATION_DIMENSION = "CONCAT(log_visit.config_os, ';', log_visit.config_browser_name, ';', log_visit.config_resolution)";
+
+    public function aggregateDayReport()
+    {
+        $this->aggregateByResolution();
+        $this->aggregateByConfiguration();
+    }
+
+    /**
+     * Period archiving: simply sums up daily archives
+     */
+    public function aggregateMultipleReports()
+    {
+        $dataTableRecords = array(
+            self::RESOLUTION_RECORD_NAME,
+            self::CONFIGURATION_RECORD_NAME,
+        );
+        $this->getProcessor()->aggregateDataTableRecords($dataTableRecords, $this->maximumRows);
+    }
+
+    protected function aggregateByConfiguration()
+    {
+        $metrics = $this->getLogAggregator()->getMetricsFromVisitByDimension(self::CONFIGURATION_DIMENSION)->asDataTable();
+        $this->insertTable(self::CONFIGURATION_RECORD_NAME, $metrics);
+    }
+
+    protected function aggregateByResolution()
+    {
+        $table = $this->getLogAggregator()->getMetricsFromVisitByDimension(self::RESOLUTION_DIMENSION)->asDataTable();
+        $table->filter('ColumnCallbackDeleteRow', array('label', function ($value) {
+            return strlen($value) <= 5;
+        }));
+        $this->insertTable(self::RESOLUTION_RECORD_NAME, $table);
+        return $table;
+    }
+
+    protected function insertTable($recordName, DataTable $table)
+    {
+        $report = $table->getSerialized($this->maximumRows, null, Metrics::INDEX_NB_VISITS);
+        return $this->getProcessor()->insertBlobRecord($recordName, $report);
+    }
+
+}
+
diff --git a/plugins/UserSettings/Columns/Configuration.php b/plugins/Resolution/Columns/Configuration.php
similarity index 71%
rename from plugins/UserSettings/Columns/Configuration.php
rename to plugins/Resolution/Columns/Configuration.php
index 7577c06495..6929457495 100644
--- a/plugins/UserSettings/Columns/Configuration.php
+++ b/plugins/Resolution/Columns/Configuration.php
@@ -6,7 +6,7 @@
  * @license http://www.gnu.org/licenses/gpl-3.0.html GPL v3 or later
  *
  */
-namespace Piwik\Plugins\UserSettings\Columns;
+namespace Piwik\Plugins\Resolution\Columns;
 
 use Piwik\Columns\Dimension;
 use Piwik\Piwik;
@@ -15,6 +15,6 @@ class Configuration extends Dimension
 {
     public function getName()
     {
-        return Piwik::translate('UserSettings_ColumnConfiguration');
+        return Piwik::translate('Resolution_ColumnConfiguration');
     }
 }
\ No newline at end of file
diff --git a/plugins/UserSettings/Columns/Resolution.php b/plugins/Resolution/Columns/Resolution.php
similarity index 83%
rename from plugins/UserSettings/Columns/Resolution.php
rename to plugins/Resolution/Columns/Resolution.php
index 35aaf4a23e..3f1e357279 100644
--- a/plugins/UserSettings/Columns/Resolution.php
+++ b/plugins/Resolution/Columns/Resolution.php
@@ -6,11 +6,11 @@
  * @license http://www.gnu.org/licenses/gpl-3.0.html GPL v3 or later
  *
  */
-namespace Piwik\Plugins\UserSettings\Columns;
+namespace Piwik\Plugins\Resolution\Columns;
 
 use Piwik\Piwik;
 use Piwik\Plugin\Dimension\VisitDimension;
-use Piwik\Plugins\UserSettings\Segment;
+use Piwik\Plugins\Resolution\Segment;
 use Piwik\Tracker\Action;
 use Piwik\Tracker\Request;
 use Piwik\Tracker\Visitor;
@@ -24,7 +24,7 @@ class Resolution extends VisitDimension
     {
         $segment = new Segment();
         $segment->setSegment('resolution');
-        $segment->setName('UserSettings_ColumnResolution');
+        $segment->setName('Resolution_ColumnResolution');
         $segment->setAcceptedValues('1280x1024, 800x600, etc.');
         $this->addSegment($segment);
     }
@@ -48,6 +48,6 @@ class Resolution extends VisitDimension
 
     public function getName()
     {
-        return Piwik::translate('UserSettings_ColumnResolution');
+        return Piwik::translate('Resolution_ColumnResolution');
     }
 }
\ No newline at end of file
diff --git a/plugins/Resolution/Reports/Base.php b/plugins/Resolution/Reports/Base.php
new file mode 100644
index 0000000000..4b0e9a5a42
--- /dev/null
+++ b/plugins/Resolution/Reports/Base.php
@@ -0,0 +1,32 @@
+<?php
+/**
+ * Piwik - free/libre analytics platform
+ *
+ * @link http://piwik.org
+ * @license http://www.gnu.org/licenses/gpl-3.0.html GPL v3 or later
+ *
+ */
+namespace Piwik\Plugins\Resolution\Reports;
+
+use Piwik\Plugin\ViewDataTable;
+use Piwik\Plugins\CoreVisualizations\Visualizations\Graph;
+
+abstract class Base extends \Piwik\Plugin\Report
+{
+    protected function init()
+    {
+        $this->category = 'UserSettings_VisitorSettings';
+    }
+
+    protected function getBasicResolutionDisplayProperties(ViewDataTable $view)
+    {
+        $view->config->show_search = false;
+        $view->config->show_exclude_low_population = false;
+
+        $view->requestConfig->filter_limit = 5;
+
+        if ($view->isViewDataTableId(Graph::ID)) {
+            $view->config->max_graph_elements = 5;
+        }
+    }
+}
diff --git a/plugins/UserSettings/Reports/GetConfiguration.php b/plugins/Resolution/Reports/GetConfiguration.php
similarity index 58%
rename from plugins/UserSettings/Reports/GetConfiguration.php
rename to plugins/Resolution/Reports/GetConfiguration.php
index 67b00f8b7d..024efa844e 100644
--- a/plugins/UserSettings/Reports/GetConfiguration.php
+++ b/plugins/Resolution/Reports/GetConfiguration.php
@@ -6,11 +6,11 @@
  * @license http://www.gnu.org/licenses/gpl-3.0.html GPL v3 or later
  *
  */
-namespace Piwik\Plugins\UserSettings\Reports;
+namespace Piwik\Plugins\Resolution\Reports;
 
 use Piwik\Piwik;
 use Piwik\Plugin\ViewDataTable;
-use Piwik\Plugins\UserSettings\Columns\Configuration;
+use Piwik\Plugins\Resolution\Columns\Configuration;
 
 class GetConfiguration extends Base
 {
@@ -18,15 +18,15 @@ class GetConfiguration extends Base
     {
         parent::init();
         $this->dimension     = new Configuration();
-        $this->name          = Piwik::translate('UserSettings_WidgetGlobalVisitors');
-        $this->documentation = Piwik::translate('UserSettings_WidgetGlobalVisitorsDocumentation', '<br />');
+        $this->name          = Piwik::translate('Resolution_WidgetGlobalVisitors');
+        $this->documentation = Piwik::translate('Resolution_WidgetGlobalVisitorsDocumentation', '<br />');
         $this->order = 7;
-        $this->widgetTitle  = 'UserSettings_WidgetGlobalVisitors';
+        $this->widgetTitle  = 'Resolution_WidgetGlobalVisitors';
     }
 
     public function configureView(ViewDataTable $view)
     {
-        $this->getBasicUserSettingsDisplayProperties($view);
+        $this->getBasicResolutionDisplayProperties($view);
 
         $view->config->addTranslation('label', $this->dimension->getName());
 
diff --git a/plugins/UserSettings/Reports/GetResolution.php b/plugins/Resolution/Reports/GetResolution.php
similarity index 65%
rename from plugins/UserSettings/Reports/GetResolution.php
rename to plugins/Resolution/Reports/GetResolution.php
index 2c8012a8d1..fbb78eb878 100644
--- a/plugins/UserSettings/Reports/GetResolution.php
+++ b/plugins/Resolution/Reports/GetResolution.php
@@ -6,11 +6,11 @@
  * @license http://www.gnu.org/licenses/gpl-3.0.html GPL v3 or later
  *
  */
-namespace Piwik\Plugins\UserSettings\Reports;
+namespace Piwik\Plugins\Resolution\Reports;
 
 use Piwik\Piwik;
 use Piwik\Plugin\ViewDataTable;
-use Piwik\Plugins\UserSettings\Columns\Resolution;
+use Piwik\Plugins\Resolution\Columns\Resolution;
 
 class GetResolution extends Base
 {
@@ -18,15 +18,15 @@ class GetResolution extends Base
     {
         parent::init();
         $this->dimension     = new Resolution();
-        $this->name          = Piwik::translate('UserSettings_WidgetResolutions');
+        $this->name          = Piwik::translate('Resolution_WidgetResolutions');
         $this->documentation = ''; // TODO
         $this->order = 0;
-        $this->widgetTitle  = 'UserSettings_WidgetResolutions';
+        $this->widgetTitle  = 'Resolution_WidgetResolutions';
     }
 
     public function configureView(ViewDataTable $view)
     {
-        $this->getBasicUserSettingsDisplayProperties($view);
+        $this->getBasicResolutionDisplayProperties($view);
 
         $view->config->addTranslation('label', $this->dimension->getName());
     }
diff --git a/plugins/Resolution/Resolution.php b/plugins/Resolution/Resolution.php
new file mode 100644
index 0000000000..49b2d3a9a6
--- /dev/null
+++ b/plugins/Resolution/Resolution.php
@@ -0,0 +1,35 @@
+<?php
+/**
+ * Piwik - free/libre analytics platform
+ *
+ * @link http://piwik.org
+ * @license http://www.gnu.org/licenses/gpl-3.0.html GPL v3 or later
+ *
+ */
+namespace Piwik\Plugins\Resolution;
+
+use Piwik\Plugins\CoreVisualizations\Visualizations\Graph;
+use Piwik\Plugins\CoreVisualizations\Visualizations\HtmlTable;
+
+/**
+ *
+ */
+class Resolution extends \Piwik\Plugin
+{
+    /**
+     * @see Piwik\Plugin::getListHooksRegistered
+     */
+    public function getListHooksRegistered()
+    {
+        return array(
+            'Live.getAllVisitorDetails'            => 'extendVisitorDetails',
+        );
+    }
+
+    public function extendVisitorDetails(&$visitor, $details)
+    {
+        $instance = new Visitor($details);
+
+        $visitor['resolution']               = $instance->getResolution();
+    }
+}
diff --git a/plugins/Resolution/Segment.php b/plugins/Resolution/Segment.php
new file mode 100644
index 0000000000..e21a2973d7
--- /dev/null
+++ b/plugins/Resolution/Segment.php
@@ -0,0 +1,21 @@
+<?php
+/**
+ * Piwik - free/libre analytics platform
+ *
+ * @link http://piwik.org
+ * @license http://www.gnu.org/licenses/gpl-3.0.html GPL v3 or later
+ *
+ */
+namespace Piwik\Plugins\Resolution;
+
+/**
+ * Resolution segment base class.
+ *
+ */
+class Segment extends \Piwik\Plugin\Segment
+{
+    protected  function init()
+    {
+        $this->setCategory('General_Visit');
+    }
+}
diff --git a/plugins/Resolution/Visitor.php b/plugins/Resolution/Visitor.php
new file mode 100644
index 0000000000..47fd330868
--- /dev/null
+++ b/plugins/Resolution/Visitor.php
@@ -0,0 +1,28 @@
+<?php
+/**
+ * Piwik - free/libre analytics platform
+ *
+ * @link http://piwik.org
+ * @license http://www.gnu.org/licenses/gpl-3.0.html GPL v3 or later
+ *
+ */
+namespace Piwik\Plugins\Resolution;
+
+class Visitor
+{
+    private $details = array();
+
+    public function __construct($details)
+    {
+        $this->details = $details;
+    }
+
+    function getResolution()
+    {
+        if (!array_key_exists('config_resolution', $this->details)) {
+            return null;
+        }
+
+        return $this->details['config_resolution'];
+    }
+}
\ No newline at end of file
diff --git a/plugins/Resolution/functions.php b/plugins/Resolution/functions.php
new file mode 100644
index 0000000000..e71aaa907a
--- /dev/null
+++ b/plugins/Resolution/functions.php
@@ -0,0 +1,29 @@
+<?php
+/**
+ * Piwik - free/libre analytics platform
+ *
+ * @link http://piwik.org
+ * @license http://www.gnu.org/licenses/gpl-3.0.html GPL v3 or later
+ *
+ */
+
+namespace Piwik\Plugins\Resolution;
+
+use Piwik\Piwik;
+
+function getConfigurationLabel($str)
+{
+    if (strpos($str, ';') === false) {
+        return $str;
+    }
+    $values = explode(";", $str);
+
+    $os = \Piwik\Plugins\DevicesDetection\getOsFullName($values[0]);
+    $name = $values[1];
+    $browser = \Piwik\Plugins\DevicesDetection\getBrowserName($name);
+    if ($browser === false) {
+        $browser = Piwik::translate('General_Unknown');
+    }
+    $resolution = $values[2];
+    return $os . " / " . $browser . " / " . $resolution;
+}
diff --git a/plugins/Resolution/lang/en.json b/plugins/Resolution/lang/en.json
new file mode 100644
index 0000000000..90491dccae
--- /dev/null
+++ b/plugins/Resolution/lang/en.json
@@ -0,0 +1,12 @@
+{
+    "Resolution": {
+        "ColumnConfiguration": "Configuration",
+        "ColumnResolution": "Resolution",
+        "Configurations": "Configurations",
+        "PluginDescription": "Reports visitors resolution",
+        "Resolutions": "Resolutions",
+        "WidgetGlobalVisitors": "Visitor Configuration",
+        "WidgetGlobalVisitorsDocumentation": "This report shows the most common overall configurations that your visitors had. A configuration is the combination of an operating system, a browser type and a screen resolution.",
+        "WidgetResolutions": "Screen Resolution"
+    }
+}
\ No newline at end of file
diff --git a/plugins/UserSettings/API.php b/plugins/UserSettings/API.php
index 1a80da3e9f..9f3649d3ba 100644
--- a/plugins/UserSettings/API.php
+++ b/plugins/UserSettings/API.php
@@ -39,17 +39,20 @@ class API extends \Piwik\Plugin\API
         return $dataTable;
     }
 
+    /**
+     * @deprecated since 2.10.0   See {@link Piwik\Plugins\Resolution\API} for new implementation.
+     */
     public function getResolution($idSite, $period, $date, $segment = false)
     {
-        $dataTable = $this->getDataTable(Archiver::RESOLUTION_RECORD_NAME, $idSite, $period, $date, $segment);
-        return $dataTable;
+        return \Piwik\Plugins\Resolution\API::getInstance()->getResolution($idSite, $period, $date, $segment);
     }
 
+    /**
+     * @deprecated since 2.10.0   See {@link Piwik\Plugins\Resolution\API} for new implementation.
+     */
     public function getConfiguration($idSite, $period, $date, $segment = false)
     {
-        $dataTable = $this->getDataTable(Archiver::CONFIGURATION_RECORD_NAME, $idSite, $period, $date, $segment);
-        $dataTable->queueFilter('ColumnCallbackReplace', array('label', __NAMESPACE__ . '\getConfigurationLabel'));
-        return $dataTable;
+        return \Piwik\Plugins\Resolution\API::getInstance()->getConfiguration($idSite, $period, $date, $segment);
     }
 
     protected function getDevicesDetectorApi()
diff --git a/plugins/UserSettings/Archiver.php b/plugins/UserSettings/Archiver.php
index 740e5d4d94..a9b67a135c 100644
--- a/plugins/UserSettings/Archiver.php
+++ b/plugins/UserSettings/Archiver.php
@@ -26,12 +26,8 @@ class Archiver extends \Piwik\Plugin\Archiver
 {
     const LANGUAGE_RECORD_NAME = 'UserSettings_language';
     const PLUGIN_RECORD_NAME = 'UserSettings_plugin';
-    const RESOLUTION_RECORD_NAME = 'UserSettings_resolution';
-    const CONFIGURATION_RECORD_NAME = 'UserSettings_configuration';
 
     const LANGUAGE_DIMENSION = "log_visit.location_browser_lang";
-    const RESOLUTION_DIMENSION = "log_visit.config_resolution";
-    const CONFIGURATION_DIMENSION = "CONCAT(log_visit.config_os, ';', log_visit.config_browser_name, ';', log_visit.config_resolution)";
 
     /**
      * Daily archive of User Settings report. Processes reports for Visits by Resolution,
@@ -39,8 +35,6 @@ class Archiver extends \Piwik\Plugin\Archiver
      */
     public function aggregateDayReport()
     {
-        $this->aggregateByConfiguration();
-        $this->aggregateByResolution();
         $this->aggregateByPlugin();
         $this->aggregateByLanguage();
     }
@@ -51,30 +45,12 @@ class Archiver extends \Piwik\Plugin\Archiver
     public function aggregateMultipleReports()
     {
         $dataTableRecords = array(
-            self::CONFIGURATION_RECORD_NAME,
-            self::RESOLUTION_RECORD_NAME,
             self::PLUGIN_RECORD_NAME,
             self::LANGUAGE_RECORD_NAME,
         );
         $this->getProcessor()->aggregateDataTableRecords($dataTableRecords, $this->maximumRows);
     }
 
-    protected function aggregateByConfiguration()
-    {
-        $metrics = $this->getLogAggregator()->getMetricsFromVisitByDimension(self::CONFIGURATION_DIMENSION)->asDataTable();
-        $this->insertTable(self::CONFIGURATION_RECORD_NAME, $metrics);
-    }
-
-    protected function aggregateByResolution()
-    {
-        $table = $this->getLogAggregator()->getMetricsFromVisitByDimension(self::RESOLUTION_DIMENSION)->asDataTable();
-        $table->filter('ColumnCallbackDeleteRow', array('label', function ($value) {
-            return strlen($value) <= 5;
-        }));
-        $this->insertTable(self::RESOLUTION_RECORD_NAME, $table);
-        return $table;
-    }
-
     protected function aggregateByPlugin()
     {
         $selects = array(
diff --git a/plugins/UserSettings/Controller.php b/plugins/UserSettings/Controller.php
index a6154b5f29..8c64ede3da 100644
--- a/plugins/UserSettings/Controller.php
+++ b/plugins/UserSettings/Controller.php
@@ -8,10 +8,10 @@
  */
 namespace Piwik\Plugins\UserSettings;
 
-use Piwik\Plugins\UserSettings\Reports\GetConfiguration;
+use Piwik\Plugins\Resolution\Reports\GetConfiguration;
 use Piwik\Plugins\UserSettings\Reports\GetLanguage;
 use Piwik\Plugins\UserSettings\Reports\GetPlugin;
-use Piwik\Plugins\UserSettings\Reports\GetResolution;
+use Piwik\Plugins\Resolution\Reports\GetResolution;
 use Piwik\View;
 
 /**
diff --git a/plugins/UserSettings/UserSettings.php b/plugins/UserSettings/UserSettings.php
index 8158470544..da1e625af0 100644
--- a/plugins/UserSettings/UserSettings.php
+++ b/plugins/UserSettings/UserSettings.php
@@ -45,20 +45,23 @@ class UserSettings extends \Piwik\Plugin
             'getMobileVsDesktop' => 'getType',
             'getOS' => 'getOsVersions',
             'getOSFamily' => 'getOsFamilies',
-            'getBrowserType' => 'getBrowserEngines'
+            'getBrowserType' => 'getBrowserEngines',
         );
 
         if ($module == 'UserSettings' && array_key_exists($action, $movedMethods)) {
             $module = 'DevicesDetection';
             $action = $movedMethods[$action];
         }
+
+        if ($module == 'UserSettings' && $action == 'getResolution') {
+            $module = 'Resolution';
+        }
     }
 
     public function extendVisitorDetails(&$visitor, $details)
     {
         $instance = new Visitor($details);
 
-        $visitor['resolution']               = $instance->getResolution();
         $visitor['plugins']                  = $instance->getPlugins();
         $visitor['pluginsIcons']             = $instance->getPluginIcons();
     }
diff --git a/plugins/UserSettings/Visitor.php b/plugins/UserSettings/Visitor.php
index 33f3528487..e399cba3ac 100644
--- a/plugins/UserSettings/Visitor.php
+++ b/plugins/UserSettings/Visitor.php
@@ -62,13 +62,4 @@ class Visitor
 
         return null;
     }
-
-    function getResolution()
-    {
-        if (!array_key_exists('config_resolution', $this->details)) {
-            return null;
-        }
-
-        return $this->details['config_resolution'];
-    }
 }
\ No newline at end of file
diff --git a/plugins/UserSettings/functions.php b/plugins/UserSettings/functions.php
index eaab5557c7..c50e84146e 100644
--- a/plugins/UserSettings/functions.php
+++ b/plugins/UserSettings/functions.php
@@ -20,23 +20,6 @@ function getPluginsLogo($oldLabel)
     return 'plugins/UserSettings/images/plugins/' . $oldLabel . '.gif';
 }
 
-function getConfigurationLabel($str)
-{
-    if (strpos($str, ';') === false) {
-        return $str;
-    }
-    $values = explode(";", $str);
-
-    $os = \Piwik\Plugins\DevicesDetection\getOsFullName($values[0]);
-    $name = $values[1];
-    $browser = \Piwik\Plugins\DevicesDetection\getBrowserName($name);
-    if ($browser === false) {
-        $browser = Piwik::translate('General_Unknown');
-    }
-    $resolution = $values[2];
-    return $os . " / " . $browser . " / " . $resolution;
-}
-
 /**
  * Returns the given language code to translated language name
  *
diff --git a/plugins/UserSettings/lang/en.json b/plugins/UserSettings/lang/en.json
index c692af975c..f5240dc9e2 100644
--- a/plugins/UserSettings/lang/en.json
+++ b/plugins/UserSettings/lang/en.json
@@ -3,9 +3,6 @@
         "BrowserLanguage": "Browser language",
         "BrowserWithNoPluginsEnabled": "%1$s with no plugins enabled",
         "BrowserWithPluginsEnabled": "%1$s with plugins %2$s enabled",
-        "ColumnConfiguration": "Configuration",
-        "ColumnResolution": "Resolution",
-        "Configurations": "Configurations",
         "Language_aa": "Afar",
         "Language_ab": "Abkhazian",
         "Language_ae": "Avestan",
@@ -193,12 +190,8 @@
         "LanguageCode": "Language code",
         "PluginDescription": "Reports various User Settings: Browser, Browser Family, Operating System, Plugins, Resolution, Global Settings.",
         "PluginDetectionDoesNotWorkInIE": "Note: Plugins detection doesn't work in Internet Explorer. This report is only based on non-IE browsers.",
-        "Resolutions": "Resolutions",
         "VisitorSettings": "Visitor Settings",
-        "WidgetGlobalVisitors": "Visitor Configuration",
-        "WidgetGlobalVisitorsDocumentation": "This report shows the most common overall configurations that your visitors had. A configuration is the combination of an operating system, a browser type and a screen resolution.",
         "WidgetPlugins": "Browser Plugins",
-        "WidgetPluginsDocumentation": "This report shows which browser plugins your visitors had enabled. This information might be important for choosing the right way to deliver your content.",
-        "WidgetResolutions": "Screen Resolution"
+        "WidgetPluginsDocumentation": "This report shows which browser plugins your visitors had enabled. This information might be important for choosing the right way to deliver your content."
     }
 }
\ No newline at end of file
diff --git a/plugins/UserSettings/templates/index.twig b/plugins/UserSettings/templates/index.twig
index abf96de9e1..1ee1cf32a1 100644
--- a/plugins/UserSettings/templates/index.twig
+++ b/plugins/UserSettings/templates/index.twig
@@ -8,9 +8,9 @@
 
 <div id='rightcolumn'>
 
-    <h2 piwik-enriched-headline>{{ 'UserSettings_Resolutions'|translate }}</h2>
+    <h2 piwik-enriched-headline>{{ 'Resolution_Resolutions'|translate }}</h2>
     {{ dataTableResolution|raw }}
 
-    <h2 piwik-enriched-headline>{{ 'UserSettings_Configurations'|translate }}</h2>
+    <h2 piwik-enriched-headline>{{ 'Resolution_Configurations'|translate }}</h2>
     {{ dataTableConfiguration|raw }}
 </div>
diff --git a/tests/PHPUnit/Unit/DataTable/Filter/PivotByDimensionTest.php b/tests/PHPUnit/Unit/DataTable/Filter/PivotByDimensionTest.php
index f1faa99b88..fd85b3a010 100644
--- a/tests/PHPUnit/Unit/DataTable/Filter/PivotByDimensionTest.php
+++ b/tests/PHPUnit/Unit/DataTable/Filter/PivotByDimensionTest.php
@@ -90,13 +90,13 @@ class PivotByDimensionTest extends PHPUnit_Framework_TestCase
 
     /**
      * @expectedException Exception
-     * @expectedExceptionMessage Unsupported pivot: No segment for dimension of report 'UserSettings.UserSettings_WidgetGlobalVisitors'
+     * @expectedExceptionMessage Unsupported pivot: No segment for dimension of report 'Resolution.Resolution_WidgetGlobalVisitors'
      */
     public function test_construction_ShouldFail_WhenDimensionIsNotSubtableAndSegmentFetchingIsEnabledButThereIsNoSegment()
     {
-        $this->loadPlugins('Referrers', 'UserSettings');
+        $this->loadPlugins('Referrers', 'Resolution');
 
-        new PivotByDimension(new DataTable(), "UserSettings.GetConfiguration", "Referrers.Keyword", "nb_visits");
+        new PivotByDimension(new DataTable(), "Resolution.GetConfiguration", "Referrers.Keyword", "nb_visits");
     }
 
     /**
diff --git a/tests/PHPUnit/Unit/DeprecatedMethodsTest.php b/tests/PHPUnit/Unit/DeprecatedMethodsTest.php
index 2150dc32ba..25b9f46ee1 100644
--- a/tests/PHPUnit/Unit/DeprecatedMethodsTest.php
+++ b/tests/PHPUnit/Unit/DeprecatedMethodsTest.php
@@ -62,6 +62,8 @@ class DeprecatedMethodsTest extends \PHPUnit_Framework_TestCase
         $this->assertDeprecatedMethodIsRemoved('Piwik\Plugins\UserSettings\API', 'getOSFamily', $validTill);
         $this->assertDeprecatedMethodIsRemoved('Piwik\Plugins\UserSettings\API', 'getBrowserType', $validTill);
         $this->assertDeprecatedMethodIsRemoved('Piwik\Plugins\UserSettings\API', 'getMobileVsDesktop', $validTill);
+        $this->assertDeprecatedMethodIsRemoved('Piwik\Plugins\UserSettings\API', 'getResolution', $validTill);
+        $this->assertDeprecatedMethodIsRemoved('Piwik\Plugins\UserSettings\API', 'getConfiguration', $validTill);
         $this->assertDeprecatedMethodIsRemoved('Piwik\Plugins\UserSettings\UserSettings', 'mapDeprecatedActions', $validTill);
 
         $this->assertDeprecatedMethodIsRemovedInPiwik3('\Piwik\Menu\MenuAbstract', 'add');
-- 
GitLab