From 9af4e95aa976f3a6533e95b776b5298f73e5f916 Mon Sep 17 00:00:00 2001 From: Thomas Steur Date: Wed, 4 Oct 2017 09:22:01 +1300 Subject: Better segment editor and fixes (#12040) * column tweak * fix install * more tweaks * rename column to dimension * various fixes * added new control expandable select * starting to refactor segment selector * make segment editor work again * use translation keys * defined some metrics * set types * simplify * simplify * fix join generator * add possibility to use custom join table names when using query builder and it uses an inner query * fix bug in query selector when selecting same field name from different tables twice * more metadata * more tweaks * improve selector * add possibility to use custom entity names * also processed archived metrics * generate sql filter, suggested values callback, and accept values automatically for columns with enums * several tweaks * focus search field when opening it * various tweaks * added missing method * format and fix more metadata * more fixes * better definition * define custom filter * fix definition * fix various tests * fix more tests * fix bug in logquery builder * fix referrerurl segment was missing * fix some tests * fix more tests * add group * refactor for better definition * fix a bug in log query builder when similar columns are used in archiver * add goal metrics * various fixes * make datatable row more flexible * various fixes and visualization enhancements * simply segment editor and make it smaller * remove trailing comma * various fixes and added new dimension * fix formatting of returning customer * added missing primary key * fixes * various fixes and improvements * make sure to update segment definition when selecting a value from auto complete list * various fixes and more metrics * more metrics * more dimensions and fixes * fix some tests * fix some integration tests * update submodule * fix some system tests * fix ui tests * trigger new test run * fix more ui tests * fix system tests * update submodule * fix categories * sort segments by category for more consistency * add custom variables * some translations and fixes * add minute segment * more segments * added plurals * added some docs * fix test * fix tests * fix tests * added suggested values * fix some tests * various fixes * fix more tests * allow to select segments on any site * make sure to include file * added doc block * fix some system tests * fix most system tests * fix ui test * fix system test * adjust examples * added more tests and docs * no metrics for these dimensions * added developer changelog and made some classes public api * some fixes for entity names * add possibility to set format metrics in test * more consistency in defining the name * get idsites only if provided * fix integration tests * added another segment for visit start hour and visit start minute * more clear name for segment * use old segment name to not break bc * various fixes * more test fixes * fix no suggested values for new segment * add event value * for boolean dimensions only sum metric * update available widgets when updating reporting menu * Add new segments in developer changelog + typo * fix system tests * fix screenshot test --- plugins/API/API.php | 22 +- plugins/API/ProcessedReport.php | 14 + plugins/API/RowEvolution.php | 29 +- plugins/API/SegmentMetadata.php | 38 +- plugins/Actions/Columns/ActionType.php | 52 +-- plugins/Actions/Columns/ActionUrl.php | 5 +- plugins/Actions/Columns/ClickedUrl.php | 26 +- plugins/Actions/Columns/DestinationPage.php | 6 +- plugins/Actions/Columns/DownloadUrl.php | 26 +- plugins/Actions/Columns/EntryPageTitle.php | 27 +- plugins/Actions/Columns/EntryPageUrl.php | 27 +- plugins/Actions/Columns/ExitPageTitle.php | 27 +- plugins/Actions/Columns/ExitPageUrl.php | 33 +- plugins/Actions/Columns/IdPageview.php | 8 +- plugins/Actions/Columns/InteractionPosition.php | 7 +- plugins/Actions/Columns/Keyword.php | 6 +- .../Actions/Columns/KeywordwithNoSearchResult.php | 6 +- .../Columns/Metrics/AveragePageGenerationTime.php | 1 - plugins/Actions/Columns/PageGenerationTime.php | 50 ++ plugins/Actions/Columns/PageTitle.php | 23 +- plugins/Actions/Columns/PageUrl.php | 24 +- plugins/Actions/Columns/SearchCategory.php | 6 +- plugins/Actions/Columns/SearchDestinationPage.php | 6 +- plugins/Actions/Columns/SearchKeyword.php | 24 +- plugins/Actions/Columns/SearchNoResultKeyword.php | 6 +- plugins/Actions/Columns/TimeSpentRefAction.php | 1 + plugins/Actions/Columns/VisitTotalActions.php | 33 +- plugins/Actions/Columns/VisitTotalInteractions.php | 16 +- plugins/Actions/Columns/VisitTotalSearches.php | 16 +- plugins/Actions/lang/en.json | 11 +- plugins/Contents/Columns/ContentInteraction.php | 25 +- plugins/Contents/Columns/ContentName.php | 27 +- plugins/Contents/Columns/ContentPiece.php | 25 +- plugins/Contents/Columns/ContentTarget.php | 25 +- plugins/Contents/Contents.php | 4 +- plugins/Contents/lang/en.json | 3 + plugins/CoreHome/Columns/IdSite.php | 9 +- plugins/CoreHome/Columns/LinkVisitActionId.php | 42 ++ plugins/CoreHome/Columns/ServerMinute.php | 35 ++ plugins/CoreHome/Columns/ServerTime.php | 21 +- plugins/CoreHome/Columns/UserId.php | 21 +- .../CoreHome/Columns/VisitFirstActionMinute.php | 45 ++ plugins/CoreHome/Columns/VisitFirstActionTime.php | 22 +- plugins/CoreHome/Columns/VisitGoalBuyer.php | 48 +- plugins/CoreHome/Columns/VisitGoalConverted.php | 24 +- plugins/CoreHome/Columns/VisitId.php | 31 +- plugins/CoreHome/Columns/VisitIp.php | 31 +- plugins/CoreHome/Columns/VisitLastActionMinute.php | 51 ++ plugins/CoreHome/Columns/VisitLastActionTime.php | 15 +- plugins/CoreHome/Columns/VisitTotalTime.php | 12 +- plugins/CoreHome/Columns/VisitorDaysSinceFirst.php | 13 +- plugins/CoreHome/Columns/VisitorDaysSinceOrder.php | 15 +- plugins/CoreHome/Columns/VisitorId.php | 33 +- plugins/CoreHome/Columns/VisitorReturning.php | 47 +- plugins/CoreHome/Columns/VisitsCount.php | 14 +- plugins/CoreHome/CoreHome.php | 24 +- plugins/CoreHome/Tracker/LogTable/Conversion.php | 5 + .../CoreHome/Tracker/LogTable/ConversionItem.php | 7 +- .../CoreHome/Tracker/LogTable/LinkVisitAction.php | 5 + plugins/CoreHome/Tracker/LogTable/Visit.php | 4 + .../angularjs/common/services/piwik-api.js | 2 +- .../reporting-menu/reportingmenu.controller.js | 6 + plugins/CoreHome/lang/en.json | 4 + plugins/CoreHome/templates/_dataTableActions.twig | 5 + plugins/CorePluginsAdmin/CorePluginsAdmin.php | 1 + .../angularjs/field/field.directive.js | 6 + .../form-field/field-expandable-select.html | 24 + .../form-field/field-expandable-select.less | 88 ++++ .../angularjs/form-field/field-multiselect.html | 2 +- .../angularjs/form-field/field-radio.html | 2 +- .../angularjs/form-field/form-field.directive.js | 33 ++ plugins/CustomDimensions | 2 +- .../Categories/CustomVariablesCategory.php | 18 + plugins/CustomVariables/Columns/SearchCategory.php | 26 ++ plugins/CustomVariables/CustomDimension.php | 36 ++ plugins/CustomVariables/CustomVariables.php | 19 + plugins/CustomVariables/Model.php | 29 +- plugins/CustomVariables/lang/en.json | 1 + .../tests/Integration/ModelTest.php | 20 + plugins/DevicePlugins/Columns/Plugin.php | 5 +- plugins/DevicePlugins/Columns/PluginCookie.php | 1 + plugins/DevicePlugins/Columns/PluginDirector.php | 1 + plugins/DevicePlugins/Columns/PluginFlash.php | 1 + plugins/DevicePlugins/Columns/PluginGears.php | 1 + plugins/DevicePlugins/Columns/PluginJava.php | 1 + plugins/DevicePlugins/Columns/PluginPdf.php | 1 + plugins/DevicePlugins/Columns/PluginQuickTime.php | 1 + plugins/DevicePlugins/Columns/PluginRealPlayer.php | 1 + .../DevicePlugins/Columns/PluginSilverlight.php | 1 + .../DevicePlugins/Columns/PluginWindowsMedia.php | 1 + plugins/DevicesDetection/Columns/BrowserEngine.php | 25 +- plugins/DevicesDetection/Columns/BrowserName.php | 21 +- .../DevicesDetection/Columns/BrowserVersion.php | 21 +- plugins/DevicesDetection/Columns/DeviceBrand.php | 23 +- plugins/DevicesDetection/Columns/DeviceModel.php | 9 +- plugins/DevicesDetection/Columns/DeviceType.php | 32 +- plugins/DevicesDetection/Columns/Os.php | 15 +- plugins/DevicesDetection/Columns/OsVersion.php | 21 +- plugins/DevicesDetection/Segment.php | 21 - plugins/DevicesDetection/lang/en.json | 3 + plugins/Ecommerce/Columns/Items.php | 18 + plugins/Ecommerce/Columns/Order.php | 37 ++ plugins/Ecommerce/Columns/ProductCategory.php | 7 +- plugins/Ecommerce/Columns/ProductName.php | 21 +- plugins/Ecommerce/Columns/ProductPrice.php | 21 + plugins/Ecommerce/Columns/ProductQuantity.php | 21 + plugins/Ecommerce/Columns/ProductSku.php | 21 +- plugins/Ecommerce/Columns/Revenue.php | 9 + plugins/Ecommerce/Columns/RevenueDiscount.php | 3 + plugins/Ecommerce/Columns/RevenueShipping.php | 3 + plugins/Ecommerce/Columns/RevenueSubtotal.php | 3 + plugins/Ecommerce/Columns/RevenueTax.php | 3 + plugins/Ecommerce/Ecommerce.php | 52 +++ plugins/Ecommerce/lang/en.json | 4 + plugins/Events/Categories/EventsCategory.php | 19 + plugins/Events/Columns/EventAction.php | 23 +- plugins/Events/Columns/EventCategory.php | 23 +- plugins/Events/Columns/EventName.php | 23 +- plugins/Events/Columns/EventValue.php | 56 +++ plugins/Events/Columns/TotalEvents.php | 21 +- plugins/Events/Segment.php | 22 - .../Columns/ExampleActionDimension.php | 33 +- .../Columns/ExampleConversionDimension.php | 29 +- .../ExampleTracker/Columns/ExampleDimension.php | 6 +- .../Columns/ExampleVisitDimension.php | 29 +- plugins/Goals/Columns/DaysToConversion.php | 6 +- plugins/Goals/Columns/IdGoal.php | 23 +- plugins/Goals/Columns/Revenue.php | 20 + plugins/Goals/Columns/VisitsUntilConversion.php | 7 +- plugins/Goals/GoalDimension.php | 41 ++ plugins/Goals/Goals.php | 71 ++- plugins/Goals/lang/en.json | 6 + plugins/Morpheus/stylesheets/main.less | 20 +- plugins/Morpheus/stylesheets/ui/_components.less | 26 -- plugins/Morpheus/templates/demo.twig | 16 + plugins/Provider/Columns/Provider.php | 23 +- plugins/Referrers/Columns/Campaign.php | 6 +- plugins/Referrers/Columns/Keyword.php | 22 +- plugins/Referrers/Columns/Referrer.php | 6 +- plugins/Referrers/Columns/ReferrerName.php | 15 +- plugins/Referrers/Columns/ReferrerType.php | 29 +- plugins/Referrers/Columns/ReferrerUrl.php | 16 +- plugins/Referrers/Columns/SearchEngine.php | 6 +- plugins/Referrers/Columns/SocialNetwork.php | 6 +- plugins/Referrers/Columns/Website.php | 8 +- plugins/Referrers/Columns/WebsitePage.php | 6 +- plugins/Referrers/Segment.php | 21 - plugins/Referrers/functions.php | 4 + plugins/Referrers/lang/en.json | 2 + plugins/Resolution/Columns/Configuration.php | 5 +- plugins/Resolution/Columns/Resolution.php | 19 +- plugins/Resolution/Segment.php | 21 - plugins/SegmentEditor/SegmentEditor.php | 19 + .../segment-generator/segmentgenerator-model.js | 69 +++ .../segmentgenerator.controller.js | 319 +++++++++++++ .../segmentgenerator.directive.html | 61 +++ .../segmentgenerator.directive.js | 64 +++ .../segmentgenerator.directive.less | 204 ++++++++ plugins/SegmentEditor/javascripts/Segmentation.js | 516 +-------------------- .../SegmentEditor/stylesheets/segmentation.less | 264 +---------- .../SegmentEditor/templates/_segmentSelector.twig | 100 +--- .../tests/Integration/SegmentEditorTest.php | 2 +- .../UserCountry/Categories/LocationsCategory.php | 17 + plugins/UserCountry/Columns/City.php | 22 +- plugins/UserCountry/Columns/Continent.php | 23 +- plugins/UserCountry/Columns/Country.php | 30 +- plugins/UserCountry/Columns/Latitude.php | 22 +- plugins/UserCountry/Columns/Longitude.php | 22 +- plugins/UserCountry/Columns/Provider.php | 2 + plugins/UserCountry/Columns/Region.php | 22 +- plugins/UserCountry/Segment.php | 21 - plugins/UserCountry/lang/en.json | 4 + plugins/UserId/Columns/UserId.php | 9 +- plugins/UserLanguage/Columns/Language.php | 21 +- plugins/VisitTime/Columns/DayOfTheWeek.php | 5 +- plugins/VisitTime/Columns/LocalMinute.php | 43 ++ plugins/VisitTime/Columns/LocalTime.php | 24 +- plugins/VisitTime/Columns/ServerTime.php | 33 -- .../Reports/GetVisitInformationPerServerTime.php | 6 +- plugins/VisitTime/Segment.php | 21 - plugins/VisitTime/lang/en.json | 8 + plugins/VisitorInterest/Columns/PagesPerVisit.php | 5 +- plugins/VisitorInterest/Columns/VisitDuration.php | 7 +- .../Columns/VisitsByDaysSinceLastVisit.php | 14 +- .../Columns/VisitsbyVisitNumber.php | 5 +- 185 files changed, 2821 insertions(+), 1930 deletions(-) create mode 100644 plugins/Actions/Columns/PageGenerationTime.php create mode 100644 plugins/CoreHome/Columns/LinkVisitActionId.php create mode 100644 plugins/CoreHome/Columns/ServerMinute.php create mode 100644 plugins/CoreHome/Columns/VisitFirstActionMinute.php create mode 100644 plugins/CoreHome/Columns/VisitLastActionMinute.php create mode 100644 plugins/CorePluginsAdmin/angularjs/form-field/field-expandable-select.html create mode 100644 plugins/CorePluginsAdmin/angularjs/form-field/field-expandable-select.less create mode 100644 plugins/CustomVariables/Categories/CustomVariablesCategory.php create mode 100644 plugins/CustomVariables/Columns/SearchCategory.php create mode 100644 plugins/CustomVariables/CustomDimension.php delete mode 100644 plugins/DevicesDetection/Segment.php create mode 100644 plugins/Ecommerce/Columns/Items.php create mode 100644 plugins/Ecommerce/Columns/Order.php create mode 100644 plugins/Ecommerce/Columns/ProductPrice.php create mode 100644 plugins/Ecommerce/Columns/ProductQuantity.php create mode 100644 plugins/Ecommerce/Ecommerce.php create mode 100644 plugins/Events/Categories/EventsCategory.php create mode 100644 plugins/Events/Columns/EventValue.php delete mode 100644 plugins/Events/Segment.php create mode 100644 plugins/Goals/Columns/Revenue.php create mode 100644 plugins/Goals/GoalDimension.php delete mode 100644 plugins/Referrers/Segment.php delete mode 100644 plugins/Resolution/Segment.php create mode 100644 plugins/SegmentEditor/angularjs/segment-generator/segmentgenerator-model.js create mode 100644 plugins/SegmentEditor/angularjs/segment-generator/segmentgenerator.controller.js create mode 100644 plugins/SegmentEditor/angularjs/segment-generator/segmentgenerator.directive.html create mode 100644 plugins/SegmentEditor/angularjs/segment-generator/segmentgenerator.directive.js create mode 100644 plugins/SegmentEditor/angularjs/segment-generator/segmentgenerator.directive.less create mode 100644 plugins/UserCountry/Categories/LocationsCategory.php delete mode 100644 plugins/UserCountry/Segment.php create mode 100644 plugins/VisitTime/Columns/LocalMinute.php delete mode 100644 plugins/VisitTime/Columns/ServerTime.php delete mode 100644 plugins/VisitTime/Segment.php (limited to 'plugins') diff --git a/plugins/API/API.php b/plugins/API/API.php index 2100ea825f..4e27e5e663 100644 --- a/plugins/API/API.php +++ b/plugins/API/API.php @@ -29,6 +29,7 @@ use Piwik\Plugin\SettingsProvider; use Piwik\Plugins\API\DataTable\MergeDataTables; use Piwik\Plugins\CoreAdminHome\CustomLogo; use Piwik\Plugins\CorePluginsAdmin\SettingsMetadata; +use Piwik\Site; use Piwik\Translation\Translator; use Piwik\Measurable\Type\TypeManager; use Piwik\Version; @@ -152,6 +153,7 @@ class API extends \Piwik\Plugin\API if (empty($idSites)) { Piwik::checkUserHasSomeViewAccess(); } else { + $idSites = Site::getIdSitesFromIdSitesString($idSites); Piwik::checkUserHasViewAccess($idSites); } @@ -433,9 +435,27 @@ class API extends \Piwik\Plugin\API { Piwik::checkUserHasViewAccess($idSite); + $apiParameters = array(); + $entityNames = StaticContainer::get('entities.idNames'); + foreach ($entityNames as $entityName) { + if ($entityName === 'idGoal' && $idGoal) { + $apiParameters['idGoal'] = $idGoal; + } elseif ($entityName === 'idDimension' && $idDimension) { + $apiParameters['idDimension'] = $idDimension; + } else { + // ideally it would get the value from API params but dynamic params is not possible yet in API. If this + // method is called eg in Request::processRequest, it could in theory pick up a param from the original request + // and not from the API request within the original request. + $idEntity = Common::getRequestVar($entityName, 0, 'int'); + if ($idEntity > 0) { + $apiParameters[$entityName] = $idEntity; + } + } + } + $rowEvolution = new RowEvolution(); return $rowEvolution->getRowEvolution($idSite, $period, $date, $apiModule, $apiAction, $label, $segment, $column, - $language, $idGoal, $legendAppendMetric, $labelUseAbsoluteUrl, $idDimension); + $language, $apiParameters, $legendAppendMetric, $labelUseAbsoluteUrl); } /** diff --git a/plugins/API/ProcessedReport.php b/plugins/API/ProcessedReport.php index 360d6b7ddf..1cd327c8c7 100644 --- a/plugins/API/ProcessedReport.php +++ b/plugins/API/ProcessedReport.php @@ -14,6 +14,7 @@ use Piwik\Archive\DataTableFactory; use Piwik\CacheId; use Piwik\Cache as PiwikCache; use Piwik\Common; +use Piwik\Container\StaticContainer; use Piwik\DataTable; use Piwik\DataTable\Row; use Piwik\DataTable\Simple; @@ -48,6 +49,18 @@ class ProcessedReport { $reportsMetadata = $this->getReportMetadata($idSite, $period, $date, $hideMetricsDoc, $showSubtableReports); + $entityNames = StaticContainer::get('entities.idNames'); + foreach ($entityNames as $entityName) { + if ($entityName === 'idGoal' || $entityName === 'idDimension') { + continue; // idGoal and idDimension is passed directly but for other entities we need to "workaround" and + // check for eg idFoo from GET/POST because we cannot add parameters to API dynamically + } + $idEntity = Common::getRequestVar($entityName, 0, 'int'); + if ($idEntity > 0) { + $apiParameters[$entityName] = $idEntity; + } + } + foreach ($reportsMetadata as $report) { // See ArchiveProcessor/Aggregator.php - unique visitors are not processed for period != day // todo: should use SettingsPiwik::isUniqueVisitorsEnabled instead @@ -73,6 +86,7 @@ class ProcessedReport } } } + return false; } diff --git a/plugins/API/RowEvolution.php b/plugins/API/RowEvolution.php index f7af6b93b1..41c75bffde 100644 --- a/plugins/API/RowEvolution.php +++ b/plugins/API/RowEvolution.php @@ -36,7 +36,7 @@ class RowEvolution 'getPageUrl' ); - public function getRowEvolution($idSite, $period, $date, $apiModule, $apiAction, $label = false, $segment = false, $column = false, $language = false, $idGoal = false, $legendAppendMetric = true, $labelUseAbsoluteUrl = true, $idDimension = false) + public function getRowEvolution($idSite, $period, $date, $apiModule, $apiAction, $label = false, $segment = false, $column = false, $language = false, $apiParameters = array(), $legendAppendMetric = true, $labelUseAbsoluteUrl = true) { // validation of requested $period & $date if ($period == 'range') { @@ -51,9 +51,9 @@ class RowEvolution $label = DataTablePostProcessor::unsanitizeLabelParameter($label); $labels = Piwik::getArrayFromApiParameter($label); - $metadata = $this->getRowEvolutionMetaData($idSite, $period, $date, $apiModule, $apiAction, $language, $idGoal, $idDimension); + $metadata = $this->getRowEvolutionMetaData($idSite, $period, $date, $apiModule, $apiAction, $language, $apiParameters); - $dataTable = $this->loadRowEvolutionDataFromAPI($metadata, $idSite, $period, $date, $apiModule, $apiAction, $labels, $segment, $idGoal, $idDimension); + $dataTable = $this->loadRowEvolutionDataFromAPI($metadata, $idSite, $period, $date, $apiModule, $apiAction, $labels, $segment, $apiParameters); if (empty($labels)) { $labels = $this->getLabelsFromDataTable($dataTable, $labels); @@ -244,11 +244,11 @@ class RowEvolution * @param string $apiAction * @param string|bool $label * @param string|bool $segment - * @param int|bool $idGoal + * @param array $apiParameters * @throws Exception * @return DataTable\Map|DataTable */ - private function loadRowEvolutionDataFromAPI($metadata, $idSite, $period, $date, $apiModule, $apiAction, $label = false, $segment = false, $idGoal = false, $idDimension = false) + private function loadRowEvolutionDataFromAPI($metadata, $idSite, $period, $date, $apiModule, $apiAction, $label = false, $segment = false, $apiParameters) { if (!is_array($label)) { $label = array($label); @@ -264,9 +264,6 @@ class RowEvolution 'format' => 'original', 'serialize' => '0', 'segment' => $segment, - 'idGoal' => $idGoal, - 'idDimension' => $idDimension, - // data for row evolution should NOT be limited 'filter_limit' => -1, @@ -275,6 +272,11 @@ class RowEvolution // can be sorted in a different order) 'labelFilterAddLabelIndex' => count($label) > 1 ? 1 : 0, ); + if (!empty($apiParameters) && is_array($apiParameters)) { + foreach ($apiParameters as $param => $value) { + $parameters[$param] = $value; + } + } // add "processed metrics" like actions per visit or bounce rate // note: some reports should not be filtered with AddColumnProcessedMetrics @@ -306,19 +308,12 @@ class RowEvolution * @param $apiModule * @param $apiAction * @param $language - * @param $idGoal + * @param $apiParameters * @throws Exception * @return array */ - private function getRowEvolutionMetaData($idSite, $period, $date, $apiModule, $apiAction, $language, $idGoal = false, $idDimension = false) + private function getRowEvolutionMetaData($idSite, $period, $date, $apiModule, $apiAction, $language, $apiParameters) { - $apiParameters = array(); - if (!empty($idGoal) && $idGoal > 0) { - $apiParameters = array('idGoal' => $idGoal); - } - if (!empty($idDimension) && $idDimension > 0) { - $apiParameters = array('idDimension' => (int) $idDimension); - } $reportMetadata = API::getInstance()->getMetadata($idSite, $apiModule, $apiAction, $apiParameters, $language, $period, $date, $hideMetricsDoc = false, $showSubtableReports = true); diff --git a/plugins/API/SegmentMetadata.php b/plugins/API/SegmentMetadata.php index 1cce5fd3dd..03f6f64336 100644 --- a/plugins/API/SegmentMetadata.php +++ b/plugins/API/SegmentMetadata.php @@ -8,12 +8,19 @@ */ namespace Piwik\Plugins\API; +use Piwik\Category\CategoryList; use Piwik\Columns\Dimension; use Piwik\Piwik; use Piwik\Plugin\Segment; class SegmentMetadata { + /** + * Map of category name to order + * @var array + */ + private $categoryOrder = array(); + public function getSegmentsMetadata($idSites = array(), $_hideImplementationData = true, $isAuthenticatedWithViewAccess) { $segments = array(); @@ -55,9 +62,21 @@ class SegmentMetadata $segments[] = $segment->toArray(); } + $categoryList = CategoryList::get(); + foreach ($segments as &$segment) { + $categoryId = $segment['category']; $segment['name'] = Piwik::translate($segment['name']); - $segment['category'] = Piwik::translate($segment['category']); + $segment['category'] = Piwik::translate($categoryId); + + if (!isset($this->categoryOrder[$segment['category']])) { + $category = $categoryList->getCategory($categoryId); + if (!empty($category)) { + $this->categoryOrder[$segment['category']] = $category->getOrder(); + } else { + $this->categoryOrder[$segment['category']] = 999; + } + } if ($_hideImplementationData) { unset($segment['sqlFilter']); @@ -81,12 +100,25 @@ class SegmentMetadata { $customVarCategory = Piwik::translate('CustomVariables_CustomVariables'); - $columns = array('type', 'category', 'name', 'segment'); + $columns = array('category', 'type', 'name', 'segment'); foreach ($columns as $column) { // Keep segments ordered alphabetically inside categories.. $type = -1; - if ($column == 'name') $type = 1; + if ($column == 'name') { + $type = 1; + } + + if ($column === 'category') { + $idOrder1 = $this->categoryOrder[$row1[$column]]; + $idOrder2 = $this->categoryOrder[$row2[$column]]; + + if ($idOrder1 === $idOrder2) { + continue; + } + + return $idOrder1 > $idOrder2 ? 1 : -1; + } $compare = $type * strcmp($row1[$column], $row2[$column]); diff --git a/plugins/Actions/Columns/ActionType.php b/plugins/Actions/Columns/ActionType.php index 59f09c87e9..c407403588 100644 --- a/plugins/Actions/Columns/ActionType.php +++ b/plugins/Actions/Columns/ActionType.php @@ -8,9 +8,9 @@ */ namespace Piwik\Plugins\Actions\Columns; -use Piwik\Piwik; +use Piwik\Columns\DimensionMetricFactory; +use Piwik\Columns\MetricsList; use Piwik\Plugin\Dimension\ActionDimension; -use Piwik\Plugins\Actions\Segment; use Piwik\Tracker\Action; use Exception; @@ -30,41 +30,27 @@ class ActionType extends ActionDimension Action::TYPE_DOWNLOAD => 'downloads' ); - /** - * The name of the dimension which will be visible for instance in the UI of a related report and in the mobile app. - * @return string - */ - public function getName() + protected $columnName = 'type'; + protected $dbTableName = 'log_action'; + protected $segmentName = 'actionType'; + protected $type = self::TYPE_ENUM; + protected $nameSingular = 'Actions_ActionType'; + protected $namePlural = 'Actions_ActionTypes'; + protected $category = 'General_Actions'; + + public function __construct() { - return Piwik::translate('Actions_ActionType'); + $this->acceptValues = sprintf('A type of action, such as: %s', implode(', ', $this->types)); } - protected function configureSegments() + public function getEnumColumnValues() { - $types = $this->types; - - $segment = new Segment(); - $segment->setSegment('actionType'); - $segment->setName('Actions_ActionType'); - $segment->setSqlSegment('log_action.type'); - $segment->setType(Segment::TYPE_DIMENSION); - $segment->setAcceptedValues(sprintf('A type of action, such as: %s', implode(', ', $types))); - $segment->setSqlFilter(function ($type) use ($types) { - if (array_key_exists($type, $types)) { - return $type; - } - - $index = array_search(strtolower(trim(urldecode($type))), $types); - - if ($index === false) { - throw new Exception("actionType must be one of: " . implode(', ', $types)); - } + return $this->types; + } - return $index; - }); - $segment->setSuggestedValuesCallback(function ($idSite, $maxSuggestionsToReturn) use ($types) { - return array_slice(array_values($types), 0, $maxSuggestionsToReturn); - }); - $this->addSegment($segment); + public function configureMetrics(MetricsList $metricsList, DimensionMetricFactory $dimensionMetricFactory) + { + // do not genereate any metric for this } + } \ No newline at end of file diff --git a/plugins/Actions/Columns/ActionUrl.php b/plugins/Actions/Columns/ActionUrl.php index 5fa80d1efa..13fdecc033 100644 --- a/plugins/Actions/Columns/ActionUrl.php +++ b/plugins/Actions/Columns/ActionUrl.php @@ -14,10 +14,7 @@ use Piwik\Plugins\Actions\Segment; class ActionUrl extends ActionDimension { - public function getName() - { - return Piwik::translate('Actions_ColumnActionURL'); - } + protected $nameSingular = 'Actions_ColumnActionURL'; protected function configureSegments() { diff --git a/plugins/Actions/Columns/ClickedUrl.php b/plugins/Actions/Columns/ClickedUrl.php index cd9bc3b7dc..861b6d5202 100644 --- a/plugins/Actions/Columns/ClickedUrl.php +++ b/plugins/Actions/Columns/ClickedUrl.php @@ -8,24 +8,28 @@ */ namespace Piwik\Plugins\Actions\Columns; -use Piwik\Piwik; +use Piwik\Columns\Discriminator; +use Piwik\Columns\Join\ActionNameJoin; use Piwik\Plugin\Dimension\ActionDimension; -use Piwik\Plugins\Actions\Segment; +use Piwik\Tracker\Action; class ClickedUrl extends ActionDimension { - public function getName() + protected $columnName = 'idaction_url'; + protected $segmentName = 'outlinkUrl'; + protected $nameSingular = 'Actions_ColumnClickedURL'; + protected $namePlural = 'Actions_ColumnClickedURLs'; + protected $category = 'General_Actions'; + protected $sqlFilter = '\\Piwik\\Tracker\\TableLogAction::getIdActionFromSegment'; + protected $type = self::TYPE_URL; + + public function getDbColumnJoin() { - return Piwik::translate('Actions_ColumnClickedURL'); + return new ActionNameJoin(); } - protected function configureSegments() + public function getDbDiscriminator() { - $segment = new Segment(); - $segment->setSegment('outlinkUrl'); - $segment->setName('Actions_ColumnClickedURL'); - $segment->setSqlSegment('log_link_visit_action.idaction_url'); - $this->addSegment($segment); + return new Discriminator('log_action', 'type', Action::TYPE_OUTLINK); } - } diff --git a/plugins/Actions/Columns/DestinationPage.php b/plugins/Actions/Columns/DestinationPage.php index e47b7195be..4b2b3eb184 100644 --- a/plugins/Actions/Columns/DestinationPage.php +++ b/plugins/Actions/Columns/DestinationPage.php @@ -13,8 +13,6 @@ use Piwik\Piwik; class DestinationPage extends Dimension { - public function getName() - { - return Piwik::translate('General_ColumnDestinationPage'); - } + protected $type = self::TYPE_TEXT; + protected $nameSingular = 'General_ColumnDestinationPage'; } \ No newline at end of file diff --git a/plugins/Actions/Columns/DownloadUrl.php b/plugins/Actions/Columns/DownloadUrl.php index d611e86f21..6375bba69b 100644 --- a/plugins/Actions/Columns/DownloadUrl.php +++ b/plugins/Actions/Columns/DownloadUrl.php @@ -8,24 +8,28 @@ */ namespace Piwik\Plugins\Actions\Columns; -use Piwik\Piwik; +use Piwik\Columns\Discriminator; +use Piwik\Columns\Join\ActionNameJoin; use Piwik\Plugin\Dimension\ActionDimension; -use Piwik\Plugins\Actions\Segment; +use Piwik\Tracker\Action; class DownloadUrl extends ActionDimension { - public function getName() + protected $segmentName = 'downloadUrl'; + protected $nameSingular = 'Actions_ColumnDownloadURL'; + protected $namePlural = 'Actions_ColumnDownloadURLs'; + protected $columnName = 'idaction_url'; + protected $category = 'General_Actions'; + protected $sqlFilter = '\\Piwik\\Tracker\\TableLogAction::getIdActionFromSegment'; + protected $type = self::TYPE_URL; + + public function getDbColumnJoin() { - return Piwik::translate('Actions_ColumnDownloadURL'); + return new ActionNameJoin(); } - protected function configureSegments() + public function getDbDiscriminator() { - $segment = new Segment(); - $segment->setSegment('downloadUrl'); - $segment->setName('Actions_ColumnDownloadURL'); - $segment->setSqlSegment('log_link_visit_action.idaction_url'); - $this->addSegment($segment); + return new Discriminator('log_action', 'type', Action::TYPE_DOWNLOAD); } - } diff --git a/plugins/Actions/Columns/EntryPageTitle.php b/plugins/Actions/Columns/EntryPageTitle.php index 30445f9549..5034f72408 100644 --- a/plugins/Actions/Columns/EntryPageTitle.php +++ b/plugins/Actions/Columns/EntryPageTitle.php @@ -8,8 +8,8 @@ */ namespace Piwik\Plugins\Actions\Columns; -use Piwik\Piwik; -use Piwik\Plugins\Actions\Segment; +use Piwik\Columns\Discriminator; +use Piwik\Columns\Join\ActionNameJoin; use Piwik\Plugin\Dimension\VisitDimension; use Piwik\Tracker\Action; use Piwik\Tracker\Request; @@ -19,13 +19,21 @@ class EntryPageTitle extends VisitDimension { protected $columnName = 'visit_entry_idaction_name'; protected $columnType = 'INTEGER(10) UNSIGNED NULL'; + protected $type = self::TYPE_TEXT; + protected $segmentName = 'entryPageTitle'; + protected $nameSingular = 'Actions_ColumnEntryPageTitle'; + protected $namePlural = 'Actions_WidgetEntryPageTitles'; + protected $category = 'General_Actions'; + protected $sqlFilter = '\\Piwik\\Tracker\\TableLogAction::getIdActionFromSegment'; - protected function configureSegments() + public function getDbColumnJoin() { - $segment = new Segment(); - $segment->setSegment('entryPageTitle'); - $segment->setName('Actions_ColumnEntryPageTitle'); - $this->addSegment($segment); + return new ActionNameJoin(); + } + + public function getDbDiscriminator() + { + return new Discriminator('log_action', 'type', Action::TYPE_PAGE_TITLE); } /** @@ -44,9 +52,4 @@ class EntryPageTitle extends VisitDimension return (int) $idActionName; } - - public function getName() - { - return Piwik::translate('Actions_ColumnEntryPageTitle'); - } } diff --git a/plugins/Actions/Columns/EntryPageUrl.php b/plugins/Actions/Columns/EntryPageUrl.php index 6b67b9a092..25750024da 100644 --- a/plugins/Actions/Columns/EntryPageUrl.php +++ b/plugins/Actions/Columns/EntryPageUrl.php @@ -8,8 +8,8 @@ */ namespace Piwik\Plugins\Actions\Columns; -use Piwik\Piwik; -use Piwik\Plugins\Actions\Segment; +use Piwik\Columns\Discriminator; +use Piwik\Columns\Join\ActionNameJoin; use Piwik\Plugin\Dimension\VisitDimension; use Piwik\Tracker\Action; use Piwik\Tracker\Request; @@ -19,13 +19,21 @@ class EntryPageUrl extends VisitDimension { protected $columnName = 'visit_entry_idaction_url'; protected $columnType = 'INTEGER(11) UNSIGNED NULL DEFAULT NULL'; + protected $segmentName = 'entryPageUrl'; + protected $nameSingular = 'Actions_ColumnEntryPageURL'; + protected $namePlural = 'Actions_ColumnEntryPageURLs'; + protected $category = 'General_Actions'; + protected $sqlFilter = '\\Piwik\\Tracker\\TableLogAction::getIdActionFromSegment'; + protected $type = self::TYPE_URL; - protected function configureSegments() + public function getDbColumnJoin() { - $segment = new Segment(); - $segment->setSegment('entryPageUrl'); - $segment->setName('Actions_ColumnEntryPageURL'); - $this->addSegment($segment); + return new ActionNameJoin(); + } + + public function getDbDiscriminator() + { + return new Discriminator('log_action', 'type', Action::TYPE_PAGE_URL); } /** @@ -69,9 +77,4 @@ class EntryPageUrl extends VisitDimension return false; } - public function getName() - { - return Piwik::translate('Actions_ColumnEntryPageURL'); - } - } diff --git a/plugins/Actions/Columns/ExitPageTitle.php b/plugins/Actions/Columns/ExitPageTitle.php index 97428d9ad9..6207eff5fd 100644 --- a/plugins/Actions/Columns/ExitPageTitle.php +++ b/plugins/Actions/Columns/ExitPageTitle.php @@ -8,8 +8,8 @@ */ namespace Piwik\Plugins\Actions\Columns; -use Piwik\Piwik; -use Piwik\Plugins\Actions\Segment; +use Piwik\Columns\Discriminator; +use Piwik\Columns\Join\ActionNameJoin; use Piwik\Plugin\Dimension\VisitDimension; use Piwik\Tracker\Action; use Piwik\Tracker\Request; @@ -19,13 +19,21 @@ class ExitPageTitle extends VisitDimension { protected $columnName = 'visit_exit_idaction_name'; protected $columnType = 'INTEGER(10) UNSIGNED NULL'; + protected $segmentName = 'exitPageTitle'; + protected $nameSingular = 'Actions_ColumnExitPageTitle'; + protected $namePlural = 'Actions_WidgetExitPageTitles'; + protected $category = 'General_Actions'; + protected $sqlFilter = '\\Piwik\\Tracker\\TableLogAction::getIdActionFromSegment'; + protected $type = self::TYPE_TEXT; - protected function configureSegments() + public function getDbColumnJoin() { - $segment = new Segment(); - $segment->setSegment('exitPageTitle'); - $segment->setName('Actions_ColumnExitPageTitle'); - $this->addSegment($segment); + return new ActionNameJoin(); + } + + public function getDbDiscriminator() + { + return new Discriminator('log_action', 'type', Action::TYPE_PAGE_TITLE); } /** @@ -59,9 +67,4 @@ class ExitPageTitle extends VisitDimension return $action->getIdActionNameForEntryAndExitIds(); } - - public function getName() - { - return Piwik::translate('Actions_ColumnExitPageTitle'); - } } diff --git a/plugins/Actions/Columns/ExitPageUrl.php b/plugins/Actions/Columns/ExitPageUrl.php index 094719bb75..c9e35e9da4 100644 --- a/plugins/Actions/Columns/ExitPageUrl.php +++ b/plugins/Actions/Columns/ExitPageUrl.php @@ -8,8 +8,11 @@ */ namespace Piwik\Plugins\Actions\Columns; +use Piwik\Columns\DimensionMetricFactory; +use Piwik\Columns\Discriminator; +use Piwik\Columns\Join; +use Piwik\Columns\MetricsList; use Piwik\Piwik; -use Piwik\Plugins\Actions\Segment; use Piwik\Plugin\Dimension\VisitDimension; use Piwik\Tracker\Action; use Piwik\Tracker\Request; @@ -19,13 +22,26 @@ class ExitPageUrl extends VisitDimension { protected $columnName = 'visit_exit_idaction_url'; protected $columnType = 'INTEGER(10) UNSIGNED NULL DEFAULT 0'; + protected $type = self::TYPE_URL; + protected $segmentName = 'exitPageUrl'; + protected $nameSingular = 'Actions_ColumnExitPageURL'; + protected $namePlural = 'Actions_ColumnExitPageURLs'; + protected $category = 'General_Actions'; + protected $sqlFilter = '\\Piwik\\Tracker\\TableLogAction::getIdActionFromSegment'; - protected function configureSegments() + public function configureMetrics(MetricsList $metricsList, DimensionMetricFactory $dimensionMetricFactory) { - $segment = new Segment(); - $segment->setSegment('exitPageUrl'); - $segment->setName('Actions_ColumnExitPageURL'); - $this->addSegment($segment); + parent::configureMetrics($metricsList, $dimensionMetricFactory); + } + + public function getDbColumnJoin() + { + return new Join\ActionNameJoin(); + } + + public function getDbDiscriminator() + { + return new Discriminator('log_action', 'type', Action::TYPE_PAGE_URL); } /** @@ -65,9 +81,4 @@ class ExitPageUrl extends VisitDimension return $id; } - - public function getName() - { - return Piwik::translate('Actions_ColumnExitPageURL'); - } } diff --git a/plugins/Actions/Columns/IdPageview.php b/plugins/Actions/Columns/IdPageview.php index c1d5352153..219fa7cbc0 100644 --- a/plugins/Actions/Columns/IdPageview.php +++ b/plugins/Actions/Columns/IdPageview.php @@ -8,6 +8,8 @@ */ namespace Piwik\Plugins\Actions\Columns; +use Piwik\Columns\DimensionMetricFactory; +use Piwik\Columns\MetricsList; use Piwik\Tracker\Action; use Piwik\Tracker\Request; use Piwik\Tracker\Visitor; @@ -18,6 +20,8 @@ class IdPageview extends ActionDimension { protected $columnName = 'idpageview'; protected $columnType = 'CHAR(6) NULL DEFAULT NULL'; + protected $type = self::TYPE_TEXT; + protected $nameSingular = 'Actions_ColumnIdPageview'; /** * @param Request $request @@ -32,9 +36,9 @@ class IdPageview extends ActionDimension return substr($request->getParam('pv_id'), 0, 6); } - public function getName() + public function configureMetrics(MetricsList $metricsList, DimensionMetricFactory $dimensionMetricFactory) { - return Piwik::translate('Actions_ColumnIdPageview'); + // metrics for idpageview do not really make any sense } } \ No newline at end of file diff --git a/plugins/Actions/Columns/InteractionPosition.php b/plugins/Actions/Columns/InteractionPosition.php index 13c85ede65..c825669450 100644 --- a/plugins/Actions/Columns/InteractionPosition.php +++ b/plugins/Actions/Columns/InteractionPosition.php @@ -19,6 +19,8 @@ class InteractionPosition extends ActionDimension { protected $columnName = 'interaction_position'; protected $columnType = 'SMALLINT UNSIGNED DEFAULT NULL'; + protected $nameSingular = 'Actions_ColumnInteractionPosition'; + protected $type = self::TYPE_NUMBER; /** * @param Request $request @@ -46,9 +48,4 @@ class InteractionPosition extends ActionDimension return false; } - public function getName() - { - return Piwik::translate('Actions_ColumnInteractionPosition'); - } - } \ No newline at end of file diff --git a/plugins/Actions/Columns/Keyword.php b/plugins/Actions/Columns/Keyword.php index 3d7051c451..7c7a5aa915 100644 --- a/plugins/Actions/Columns/Keyword.php +++ b/plugins/Actions/Columns/Keyword.php @@ -13,8 +13,6 @@ use Piwik\Piwik; class Keyword extends Dimension { - public function getName() - { - return Piwik::translate('General_ColumnKeyword'); - } + protected $type = self::TYPE_TEXT; + protected $nameSingular = 'General_ColumnKeyword'; } \ No newline at end of file diff --git a/plugins/Actions/Columns/KeywordwithNoSearchResult.php b/plugins/Actions/Columns/KeywordwithNoSearchResult.php index d6ffaf2044..e96e50eaa3 100644 --- a/plugins/Actions/Columns/KeywordwithNoSearchResult.php +++ b/plugins/Actions/Columns/KeywordwithNoSearchResult.php @@ -13,8 +13,6 @@ use Piwik\Piwik; class KeywordwithNoSearchResult extends Dimension { - public function getName() - { - return Piwik::translate('Actions_ColumnNoResultKeyword'); - } + protected $type = self::TYPE_TEXT; + protected $nameSingular = 'Actions_ColumnNoResultKeyword'; } \ No newline at end of file diff --git a/plugins/Actions/Columns/Metrics/AveragePageGenerationTime.php b/plugins/Actions/Columns/Metrics/AveragePageGenerationTime.php index 9b44e88943..ed89226ac0 100644 --- a/plugins/Actions/Columns/Metrics/AveragePageGenerationTime.php +++ b/plugins/Actions/Columns/Metrics/AveragePageGenerationTime.php @@ -13,7 +13,6 @@ use Piwik\Metrics; use Piwik\Metrics\Formatter; use Piwik\Piwik; use Piwik\Plugin\ProcessedMetric; -use Piwik\Plugin\Report; /** * The average amount of time it takes to generate a page. Calculated as diff --git a/plugins/Actions/Columns/PageGenerationTime.php b/plugins/Actions/Columns/PageGenerationTime.php new file mode 100644 index 0000000000..d7c8344db4 --- /dev/null +++ b/plugins/Actions/Columns/PageGenerationTime.php @@ -0,0 +1,50 @@ +createMetric(ArchivedMetric::AGGREGATION_SUM); + $metricsList->addMetric($metric1); + + $metric2 = $dimensionMetricFactory->createMetric(ArchivedMetric::AGGREGATION_MAX); + $metricsList->addMetric($metric2); + + $metric3 = $dimensionMetricFactory->createMetric(ArchivedMetric::AGGREGATION_COUNT_WITH_NUMERIC_VALUE); + $metric3->setName('pageviews_with_generation_time'); + $metric3->setTranslatedName(Piwik::translate('General_ColumnViewsWithGenerationTime')); + $metricsList->addMetric($metric3); + + $metric = $dimensionMetricFactory->createComputedMetric($metric1->getName(), $metric3->getName(), ComputedMetric::AGGREGATION_AVG); + $metric->setName('avg_page_generation_time'); + $metric->setTranslatedName(Piwik::translate('General_ColumnAverageGenerationTime')); + $metricsList->addMetric($metric); + } +} diff --git a/plugins/Actions/Columns/PageTitle.php b/plugins/Actions/Columns/PageTitle.php index 6517bede92..77bdac1099 100644 --- a/plugins/Actions/Columns/PageTitle.php +++ b/plugins/Actions/Columns/PageTitle.php @@ -8,26 +8,29 @@ */ namespace Piwik\Plugins\Actions\Columns; -use Piwik\Piwik; +use Piwik\Columns\Discriminator; +use Piwik\Columns\Join\ActionNameJoin; use Piwik\Plugin\Dimension\ActionDimension; -use Piwik\Plugins\Actions\Segment; +use Piwik\Tracker\Action; class PageTitle extends ActionDimension { protected $columnName = 'idaction_name'; protected $columnType = 'INTEGER(10) UNSIGNED'; + protected $type = self::TYPE_TEXT; + protected $segmentName = 'pageTitle'; + protected $nameSingular = 'Goals_PageTitle'; + protected $namePlural = 'Actions_WidgetPageTitles'; + protected $category = 'General_Actions'; + protected $sqlFilter = '\\Piwik\\Tracker\\TableLogAction::getIdActionFromSegment'; - protected function configureSegments() + public function getDbColumnJoin() { - $segment = new Segment(); - $segment->setSegment('pageTitle'); - $segment->setName('Actions_ColumnPageName'); - $this->addSegment($segment); + return new ActionNameJoin(); } - public function getName() + public function getDbDiscriminator() { - return Piwik::translate('Actions_ColumnPageName'); + return new Discriminator('log_action', 'type', Action::TYPE_PAGE_TITLE); } - } diff --git a/plugins/Actions/Columns/PageUrl.php b/plugins/Actions/Columns/PageUrl.php index 1f9a7035e5..a236f0e28e 100644 --- a/plugins/Actions/Columns/PageUrl.php +++ b/plugins/Actions/Columns/PageUrl.php @@ -8,26 +8,32 @@ */ namespace Piwik\Plugins\Actions\Columns; +use Piwik\Columns\Discriminator; +use Piwik\Columns\Join\ActionNameJoin; use Piwik\Piwik; use Piwik\Plugin\Dimension\ActionDimension; -use Piwik\Plugins\Actions\Segment; +use Piwik\Tracker\Action; class PageUrl extends ActionDimension { protected $columnName = 'idaction_url'; protected $columnType = 'INTEGER(10) UNSIGNED DEFAULT NULL'; + protected $segmentName = 'pageUrl'; + protected $nameSingular = 'Actions_ColumnPageURL'; + protected $namePlural = 'Actions_PageUrls'; + protected $type = self::TYPE_URL; + protected $acceptValues = 'All these segments must be URL encoded, for example: http%3A%2F%2Fexample.com%2Fpath%2Fpage%3Fquery'; + protected $category = 'General_Actions'; + protected $sqlFilter = '\\Piwik\\Tracker\\TableLogAction::getIdActionFromSegment'; - protected function configureSegments() + public function getDbColumnJoin() { - $segment = new Segment(); - $segment->setSegment('pageUrl'); - $segment->setName('Actions_ColumnPageURL'); - $segment->setAcceptedValues('All these segments must be URL encoded, for example: ' . urlencode('http://example.com/path/page?query')); - $this->addSegment($segment); + return new ActionNameJoin(); } - public function getName() + public function getDbDiscriminator() { - return Piwik::translate('Actions_ColumnPageURL'); + return new Discriminator('log_action', 'type', Action::TYPE_PAGE_URL); } + } diff --git a/plugins/Actions/Columns/SearchCategory.php b/plugins/Actions/Columns/SearchCategory.php index 6dc3c0b11b..e61ac25136 100644 --- a/plugins/Actions/Columns/SearchCategory.php +++ b/plugins/Actions/Columns/SearchCategory.php @@ -13,8 +13,6 @@ use Piwik\Piwik; class SearchCategory extends Dimension { - public function getName() - { - return Piwik::translate('Actions_ColumnSearchCategory'); - } + protected $type = self::TYPE_TEXT; + protected $nameSingular = 'Actions_ColumnSearchCategory'; } \ No newline at end of file diff --git a/plugins/Actions/Columns/SearchDestinationPage.php b/plugins/Actions/Columns/SearchDestinationPage.php index bf36621a9c..4e3271892d 100644 --- a/plugins/Actions/Columns/SearchDestinationPage.php +++ b/plugins/Actions/Columns/SearchDestinationPage.php @@ -13,8 +13,6 @@ use Piwik\Piwik; class SearchDestinationPage extends Dimension { - public function getName() - { - return Piwik::translate('General_ColumnDestinationPage'); - } + protected $type = self::TYPE_TEXT; + protected $nameSingular = 'General_ColumnDestinationPage'; } diff --git a/plugins/Actions/Columns/SearchKeyword.php b/plugins/Actions/Columns/SearchKeyword.php index f3248da5cf..48283eae02 100644 --- a/plugins/Actions/Columns/SearchKeyword.php +++ b/plugins/Actions/Columns/SearchKeyword.php @@ -8,23 +8,27 @@ */ namespace Piwik\Plugins\Actions\Columns; -use Piwik\Piwik; +use Piwik\Columns\Discriminator; +use Piwik\Columns\Join\ActionNameJoin; use Piwik\Plugin\Dimension\ActionDimension; -use Piwik\Plugins\Actions\Segment; +use Piwik\Tracker\Action; class SearchKeyword extends ActionDimension { - protected function configureSegments() + protected $columnName = 'idaction_name'; + protected $segmentName = 'siteSearchKeyword'; + protected $nameSingular = 'Actions_SiteSearchKeyword'; + protected $namePlural = 'Actions_SiteSearchKeywords'; + protected $type = self::TYPE_TEXT; + protected $sqlFilter = '\\Piwik\\Tracker\\TableLogAction::getIdActionFromSegment'; + + public function getDbColumnJoin() { - $segment = new Segment(); - $segment->setSegment('siteSearchKeyword'); - $segment->setName('Actions_SiteSearchKeyword'); - $segment->setSqlSegment('log_link_visit_action.idaction_name'); - $this->addSegment($segment); + return new ActionNameJoin(); } - public function getName() + public function getDbDiscriminator() { - return Piwik::translate('General_ColumnKeyword'); + return new Discriminator('log_action', 'type', Action::TYPE_SITE_SEARCH); } } diff --git a/plugins/Actions/Columns/SearchNoResultKeyword.php b/plugins/Actions/Columns/SearchNoResultKeyword.php index f4b57c6431..3245d31efc 100644 --- a/plugins/Actions/Columns/SearchNoResultKeyword.php +++ b/plugins/Actions/Columns/SearchNoResultKeyword.php @@ -13,8 +13,6 @@ use Piwik\Piwik; class SearchNoResultKeyword extends Dimension { - public function getName() - { - return Piwik::translate('Actions_ColumnNoResultKeyword'); - } + protected $type = self::TYPE_TEXT; + protected $nameSingular = 'Actions_ColumnNoResultKeyword'; } diff --git a/plugins/Actions/Columns/TimeSpentRefAction.php b/plugins/Actions/Columns/TimeSpentRefAction.php index a51cac9d59..2b0a8c2526 100644 --- a/plugins/Actions/Columns/TimeSpentRefAction.php +++ b/plugins/Actions/Columns/TimeSpentRefAction.php @@ -17,6 +17,7 @@ class TimeSpentRefAction extends ActionDimension { protected $columnName = 'time_spent_ref_action'; protected $columnType = 'INTEGER(10) UNSIGNED NULL'; + protected $type = self::TYPE_DURATION_S; public function onNewAction(Request $request, Visitor $visitor, Action $action) { diff --git a/plugins/Actions/Columns/VisitTotalActions.php b/plugins/Actions/Columns/VisitTotalActions.php index 750cfc8667..85ddc9336d 100644 --- a/plugins/Actions/Columns/VisitTotalActions.php +++ b/plugins/Actions/Columns/VisitTotalActions.php @@ -8,25 +8,42 @@ */ namespace Piwik\Plugins\Actions\Columns; +use Piwik\Columns\MetricsList; +use Piwik\Piwik; +use Piwik\Plugin\ArchivedMetric; +use Piwik\Plugin\ComputedMetric; use Piwik\Plugin\Dimension\VisitDimension; -use Piwik\Plugins\CoreHome\Segment; +use Piwik\Columns\DimensionMetricFactory; use Piwik\Tracker\Action; use Piwik\Tracker\Request; -use Piwik\Tracker; use Piwik\Tracker\Visitor; class VisitTotalActions extends VisitDimension { protected $columnName = 'visit_total_actions'; protected $columnType = 'INT(11) UNSIGNED NULL'; + protected $metricId = 'actions'; + protected $nameSingular = 'Actions_ActionsInVisit'; + protected $segmentName = 'actions'; + protected $type = self::TYPE_NUMBER; - protected function configureSegments() + public function configureMetrics(MetricsList $metricsList, DimensionMetricFactory $dimensionMetricFactory) { - $segment = new Segment(); - $segment->setType(Segment::TYPE_METRIC); - $segment->setSegment('actions'); - $segment->setName('General_NbActions'); - $this->addSegment($segment); + $metric1 = $dimensionMetricFactory->createCustomMetric('bounce_count', Piwik::translate('General_ColumnBounces'), 'sum(case %s when 1 then 1 when 0 then 1 else 0 end)'); + $metric1->setDocumentation(Piwik::translate('General_ColumnBouncesDocumentation')); + $metricsList->addMetric($metric1); + + $metric = $dimensionMetricFactory->createMetric(ArchivedMetric::AGGREGATION_SUM); + $metricsList->addMetric($metric); + + $metric = $dimensionMetricFactory->createMetric(ArchivedMetric::AGGREGATION_MAX); + $metricsList->addMetric($metric); + + $metric = $dimensionMetricFactory->createComputedMetric($metric1->getName(), 'nb_visits', ComputedMetric::AGGREGATION_RATE); + $metric->setTranslatedName(Piwik::translate('General_ColumnBounceRate')); + $metric->setName('bounce_rate'); + $metric->setDocumentation(Piwik::translate('General_ColumnBounceRateDocumentation')); + $metricsList->addMetric($metric); } /** diff --git a/plugins/Actions/Columns/VisitTotalInteractions.php b/plugins/Actions/Columns/VisitTotalInteractions.php index 9c10b1e03a..a41244211c 100644 --- a/plugins/Actions/Columns/VisitTotalInteractions.php +++ b/plugins/Actions/Columns/VisitTotalInteractions.php @@ -18,20 +18,18 @@ class VisitTotalInteractions extends VisitDimension { protected $columnName = 'visit_total_interactions'; protected $columnType = 'SMALLINT UNSIGNED DEFAULT 0'; + protected $type = self::TYPE_NUMBER; + protected $segmentName = 'interactions'; + protected $nameSingular = 'General_NbInteractions'; + protected $acceptValues = 'Any positive integer'; - protected function configureSegments() + public function __construct() { - $segment = new Segment(); - $segment->setType(Segment::TYPE_METRIC); - $segment->setSegment('interactions'); - $segment->setName('General_NbInteractions'); - $segment->setAcceptedValues('Any positive integer'); - $segment->setSuggestedValuesCallback(function ($idSite, $maxValuesToReturn) { + $this->suggestedValuesCallback = function ($idSite, $maxValuesToReturn) { $positions = range(1,50); return array_slice($positions, 0, $maxValuesToReturn); - }); - $this->addSegment($segment); + }; } /** diff --git a/plugins/Actions/Columns/VisitTotalSearches.php b/plugins/Actions/Columns/VisitTotalSearches.php index e3ebb83247..559b8090bf 100644 --- a/plugins/Actions/Columns/VisitTotalSearches.php +++ b/plugins/Actions/Columns/VisitTotalSearches.php @@ -9,26 +9,18 @@ namespace Piwik\Plugins\Actions\Columns; use Piwik\Plugin\Dimension\VisitDimension; -use Piwik\Plugins\CoreHome\Segment; use Piwik\Tracker\Action; use Piwik\Tracker\Request; -use Piwik\Tracker; use Piwik\Tracker\Visitor; class VisitTotalSearches extends VisitDimension { protected $columnName = 'visit_total_searches'; protected $columnType = 'SMALLINT(5) UNSIGNED NULL'; - - protected function configureSegments() - { - $segment = new Segment(); - $segment->setType(Segment::TYPE_METRIC); - $segment->setSegment('searches'); - $segment->setName('General_NbSearches'); - $segment->setAcceptedValues('To select all visits who used internal Site Search, use: &segment=searches>0'); - $this->addSegment($segment); - } + protected $segmentName = 'searches'; + protected $nameSingular = 'General_NbSearches'; + protected $acceptValues = 'To select all visits who used internal Site Search, use: &segment=searches>0'; + protected $type = self::TYPE_NUMBER; /** * @param Request $request diff --git a/plugins/Actions/lang/en.json b/plugins/Actions/lang/en.json index ab9fbff5f7..8725fc8e3f 100644 --- a/plugins/Actions/lang/en.json +++ b/plugins/Actions/lang/en.json @@ -2,14 +2,18 @@ "Actions": { "AvgGenerationTimeTooltip": "Average based on %1$s hit(s) %2$s between %3$s and %4$s", "ColumnClickedURL": "Clicked URL", + "ColumnClickedURLs": "Clicked URLs", "ColumnActionURL": "Action URL", "ColumnClicks": "Clicks", "ColumnClicksDocumentation": "The number of times this link was clicked.", "ColumnDownloadURL": "Download URL", + "ColumnDownloadURLs": "Download URLs", "ColumnEntryPageTitle": "Entry Page title", "ColumnEntryPageURL": "Entry Page URL", + "ColumnEntryPageURLs": "Entry Page URLs", "ColumnExitPageTitle": "Exit Page Title", "ColumnExitPageURL": "Exit Page URL", + "ColumnExitPageURLs": "Exit Page URLs", "ColumnNoResultKeyword": "Keyword with No Search Result", "ColumnPageName": "Page Name", "ColumnPagesPerSearch": "Search Results pages", @@ -28,6 +32,7 @@ "ColumnUniqueOutlinks": "Unique Outlinks", "ColumnIdPageview": "Pageview ID", "ColumnInteractionPosition": "Interaction Position", + "ActionsInVisit": "Actions In Visit", "DownloadsReportDocumentation": "In this report, you can see which files your visitors have downloaded. %s What Piwik counts as a download is the click on a download link. Whether the download was completed or not isn't known to Piwik.", "EntryPagesReportDocumentation": "This report contains information about the entry pages that were used during the specified period. An entry page is the first page that a user views during their visit. %s The entry URLs are displayed as a folder structure.", "EntryPageTitles": "Entry page titles", @@ -49,7 +54,10 @@ "SiteSearchCategories2": "For example, Ecommerce websites typically have a \"Category\" selector so that visitors can restrict their searches to all products in a specific Category.", "SiteSearchFollowingPagesDoc": "When visitors search on your website, they are looking for a particular page, content, product, or service. This report lists the pages that were clicked the most after an internal search. In other words, the list of pages the most searched for by visitors already on your website.", "SiteSearchIntro": "Tracking searches that visitors make on your website is a very effective way to learn more about what your audience is looking for, it can help find ideas for new content, new Ecommerce products that potential customers might be searching for, and generally improve the visitors' experience on your website.", + "SiteSearchCategory": "Category (Site Search)", + "SiteSearchCategories": "Categories (Site Search)", "SiteSearchKeyword": "Keyword (Site Search)", + "SiteSearchKeywords": "Keywords (Site Search)", "SiteSearchKeywordsDocumentation": "This report lists the Search Keywords that visitors searched for on your internal Search Engine.", "SiteSearchKeywordsNoResultDocumentation": "This report lists the Search Keywords that did not return any Search result: maybe the search engine algorithm can be improved, or maybe your visitors are looking for content that is not (yet) on your website?", "SubmenuPagesEntry": "Entry pages", @@ -66,6 +74,7 @@ "WidgetSearchCategories": "Search Categories", "WidgetSearchKeywords": "Site Search Keywords", "WidgetSearchNoResultKeywords": "Search Keywords with No Results", - "ActionType": "Action Type" + "ActionType": "Action Type", + "ActionTypes": "Action Types" } } \ No newline at end of file diff --git a/plugins/Contents/Columns/ContentInteraction.php b/plugins/Contents/Columns/ContentInteraction.php index a50467f9d6..e188fab521 100644 --- a/plugins/Contents/Columns/ContentInteraction.php +++ b/plugins/Contents/Columns/ContentInteraction.php @@ -8,9 +8,9 @@ */ namespace Piwik\Plugins\Contents\Columns; -use Piwik\Piwik; +use Piwik\Columns\Discriminator; +use Piwik\Columns\Join\ActionNameJoin; use Piwik\Plugin\Dimension\ActionDimension; -use Piwik\Plugins\Actions\Segment; use Piwik\Plugins\Contents\Actions\ActionContent; use Piwik\Tracker\Action; use Piwik\Tracker\Request; @@ -19,19 +19,22 @@ class ContentInteraction extends ActionDimension { protected $columnName = 'idaction_content_interaction'; protected $columnType = 'INTEGER(10) UNSIGNED DEFAULT NULL'; - - protected function configureSegments() + protected $type = self::TYPE_TEXT; + protected $acceptValues = 'The type of interaction with the content. For instance "click" or "submit".'; + protected $segmentName = 'contentInteraction'; + protected $nameSingular = 'Contents_ContentInteraction'; + protected $namePlural = 'Contents_ContentInteractions'; + protected $category = 'General_Actions'; + protected $sqlFilter = '\\Piwik\\Tracker\\TableLogAction::getIdActionFromSegment'; + + public function getDbColumnJoin() { - $segment = new Segment(); - $segment->setSegment('contentInteraction'); - $segment->setName('Contents_ContentInteraction'); - $segment->setAcceptedValues('The type of interaction with the content. For instance "click" or "submit".'); - $this->addSegment($segment); + return new ActionNameJoin(); } - public function getName() + public function getDbDiscriminator() { - return Piwik::translate('Contents_ContentInteraction'); + return new Discriminator('log_action', 'type', $this->getActionId()); } public function getActionId() diff --git a/plugins/Contents/Columns/ContentName.php b/plugins/Contents/Columns/ContentName.php index 6168a48725..47255787d6 100644 --- a/plugins/Contents/Columns/ContentName.php +++ b/plugins/Contents/Columns/ContentName.php @@ -8,10 +8,10 @@ */ namespace Piwik\Plugins\Contents\Columns; -use Piwik\Exception\InvalidRequestParameterException; -use Piwik\Piwik; +use Piwik\Columns\Discriminator; +use Piwik\Columns\Join\ActionNameJoin; use Piwik\Plugin\Dimension\ActionDimension; -use Piwik\Plugins\Actions\Segment; +use Piwik\Exception\InvalidRequestParameterException; use Piwik\Plugins\Contents\Actions\ActionContent; use Piwik\Tracker\Action; use Piwik\Tracker\Request; @@ -20,19 +20,22 @@ class ContentName extends ActionDimension { protected $columnName = 'idaction_content_name'; protected $columnType = 'INTEGER(10) UNSIGNED DEFAULT NULL'; - - protected function configureSegments() + protected $segmentName = 'contentName'; + protected $nameSingular = 'Contents_ContentName'; + protected $namePlural = 'Contents_ContentNames'; + protected $acceptValues = 'The name of a content block, for instance "Ad Sale"'; + protected $type = self::TYPE_TEXT; + protected $category = 'General_Actions'; + protected $sqlFilter = '\\Piwik\\Tracker\\TableLogAction::getIdActionFromSegment'; + + public function getDbColumnJoin() { - $segment = new Segment(); - $segment->setSegment('contentName'); - $segment->setName('Contents_ContentName'); - $segment->setAcceptedValues('The name of a content block, for instance "Ad Sale"'); - $this->addSegment($segment); + return new ActionNameJoin(); } - public function getName() + public function getDbDiscriminator() { - return Piwik::translate('Contents_ContentName'); + return new Discriminator('log_action', 'type', $this->getActionId()); } public function getActionId() diff --git a/plugins/Contents/Columns/ContentPiece.php b/plugins/Contents/Columns/ContentPiece.php index 4cd0722e5a..0bf5464611 100644 --- a/plugins/Contents/Columns/ContentPiece.php +++ b/plugins/Contents/Columns/ContentPiece.php @@ -8,9 +8,9 @@ */ namespace Piwik\Plugins\Contents\Columns; -use Piwik\Piwik; +use Piwik\Columns\Discriminator; +use Piwik\Columns\Join\ActionNameJoin; use Piwik\Plugin\Dimension\ActionDimension; -use Piwik\Plugins\Actions\Segment; use Piwik\Plugins\Contents\Actions\ActionContent; use Piwik\Tracker\Action; use Piwik\Tracker\Request; @@ -19,19 +19,22 @@ class ContentPiece extends ActionDimension { protected $columnName = 'idaction_content_piece'; protected $columnType = 'INTEGER(10) UNSIGNED DEFAULT NULL'; - - protected function configureSegments() + protected $segmentName = 'contentPiece'; + protected $nameSingular = 'Contents_ContentPiece'; + protected $namePlural = 'Contents_ContentPieces'; + protected $acceptValues = 'The actual content. For instance "ad.jpg" or "My text ad"'; + protected $type = self::TYPE_TEXT; + protected $category = 'General_Actions'; + protected $sqlFilter = '\\Piwik\\Tracker\\TableLogAction::getIdActionFromSegment'; + + public function getDbColumnJoin() { - $segment = new Segment(); - $segment->setSegment('contentPiece'); - $segment->setName('Contents_ContentPiece'); - $segment->setAcceptedValues('The actual content. For instance "ad.jpg" or "My text ad"'); - $this->addSegment($segment); + return new ActionNameJoin(); } - public function getName() + public function getDbDiscriminator() { - return Piwik::translate('Contents_ContentPiece'); + return new Discriminator('log_action', 'type', $this->getActionId()); } public function getActionId() diff --git a/plugins/Contents/Columns/ContentTarget.php b/plugins/Contents/Columns/ContentTarget.php index 9e81c687f3..7448770749 100644 --- a/plugins/Contents/Columns/ContentTarget.php +++ b/plugins/Contents/Columns/ContentTarget.php @@ -8,9 +8,9 @@ */ namespace Piwik\Plugins\Contents\Columns; -use Piwik\Piwik; +use Piwik\Columns\Discriminator; +use Piwik\Columns\Join\ActionNameJoin; use Piwik\Plugin\Dimension\ActionDimension; -use Piwik\Plugins\Actions\Segment; use Piwik\Plugins\Contents\Actions\ActionContent; use Piwik\Tracker\Action; use Piwik\Tracker\Request; @@ -19,19 +19,22 @@ class ContentTarget extends ActionDimension { protected $columnName = 'idaction_content_target'; protected $columnType = 'INTEGER(10) UNSIGNED DEFAULT NULL'; - - protected function configureSegments() + protected $type = self::TYPE_URL; + protected $nameSingular = 'Contents_ContentTarget'; + protected $namePlural = 'Contents_ContentTargets'; + protected $segmentName = 'contentTarget'; + protected $category = 'General_Actions'; + protected $sqlFilter = '\\Piwik\\Tracker\\TableLogAction::getIdActionFromSegment'; + protected $acceptValues = 'For instance the URL of a landing page: "http://landingpage.example.com"'; + + public function getDbColumnJoin() { - $segment = new Segment(); - $segment->setSegment('contentTarget'); - $segment->setName('Contents_ContentTarget'); - $segment->setAcceptedValues('For instance the URL of a landing page: "http://landingpage.example.com"'); - $this->addSegment($segment); + return new ActionNameJoin(); } - public function getName() + public function getDbDiscriminator() { - return Piwik::translate('Contents_ContentTarget'); + return new Discriminator('log_action', 'type', $this->getActionId()); } public function getActionId() diff --git a/plugins/Contents/Contents.php b/plugins/Contents/Contents.php index 289bdb25ec..580b752a53 100644 --- a/plugins/Contents/Contents.php +++ b/plugins/Contents/Contents.php @@ -14,7 +14,7 @@ use Piwik\Piwik; class Contents extends \Piwik\Plugin { /** - * @see Piwik\Plugin::registerEvents + * @see \Piwik\Plugin::registerEvents */ public function registerEvents() { @@ -59,4 +59,4 @@ class Contents extends \Piwik\Plugin $joins[] = 'LEFT JOIN ' . Common::prefixTable('log_action') . ' AS log_action_content_interaction ON log_link_visit_action.idaction_content_interaction = log_action_content_interaction.idaction'; } -} +} \ No newline at end of file diff --git a/plugins/Contents/lang/en.json b/plugins/Contents/lang/en.json index 0947590f69..e4bef887a0 100644 --- a/plugins/Contents/lang/en.json +++ b/plugins/Contents/lang/en.json @@ -7,8 +7,11 @@ "ContentInteractions": "Content Interactions", "InteractionRate": "Interaction Rate", "ContentName": "Content Name", + "ContentNames": "Content Names", "ContentPiece": "Content Piece", + "ContentPieces": "Content Pieces", "ContentTarget": "Content Target", + "ContentTargets": "Content Targets", "Contents": "Contents", "InteractionsMetricDocumentation": "The number of times a content block was interacted with (eg, a 'click' on a banner or ad).", "ImpressionsMetricDocumentation": "The number of times a content block, such as a banner or an ad, was displayed on a page.", diff --git a/plugins/CoreHome/Columns/IdSite.php b/plugins/CoreHome/Columns/IdSite.php index 996cae629b..f757b5bf1c 100644 --- a/plugins/CoreHome/Columns/IdSite.php +++ b/plugins/CoreHome/Columns/IdSite.php @@ -8,10 +8,10 @@ */ namespace Piwik\Plugins\CoreHome\Columns; +use Piwik\Columns\Join\SiteNameJoin; use Piwik\Plugin\Dimension\VisitDimension; use Piwik\Tracker\Action; use Piwik\Tracker\Request; -use Piwik\Tracker; use Piwik\Tracker\Visitor; class IdSite extends VisitDimension @@ -23,6 +23,13 @@ class IdSite extends VisitDimension // INDEX(idsite, config_id, visit_last_action_time) and we maybe not be sure whether config_id already exists at // installing point (we do not know whether visit_last_action_time or idsite column would be added first). + protected $type = self::TYPE_TEXT; + + public function getDbColumnJoin() + { + return new SiteNameJoin(); + } + /** * @param Request $request * @param Visitor $visitor diff --git a/plugins/CoreHome/Columns/LinkVisitActionId.php b/plugins/CoreHome/Columns/LinkVisitActionId.php new file mode 100644 index 0000000000..6cc55c04bb --- /dev/null +++ b/plugins/CoreHome/Columns/LinkVisitActionId.php @@ -0,0 +1,42 @@ +createMetric(ArchivedMetric::AGGREGATION_UNIQUE); + $metric->setTranslatedName(Piwik::translate('General_ColumnHits')); + $metric->setName('hits'); + $metricsList->addMetric($metric); + + $metric = $dimensionMetricFactory->createMetric(ArchivedMetric::AGGREGATION_UNIQUE); + $metric->setTranslatedName(Piwik::translate('General_ColumnPageviews')); + $metric->setDocumentation(Piwik::translate('General_ColumnPageviewsDocumentation')); + $metric->setName('pageviews'); + $metricsList->addMetric($metric); + } +} \ No newline at end of file diff --git a/plugins/CoreHome/Columns/ServerMinute.php b/plugins/CoreHome/Columns/ServerMinute.php new file mode 100644 index 0000000000..ee095dcb3c --- /dev/null +++ b/plugins/CoreHome/Columns/ServerMinute.php @@ -0,0 +1,35 @@ +suggestedValuesCallback = function ($idSite, $maxValuesToReturn) { + return range(0, min(59, $maxValuesToReturn)); + }; + } + + public function formatValue($value, $idSite, Formatter $formatter) + { + return $value; + } + +} diff --git a/plugins/CoreHome/Columns/ServerTime.php b/plugins/CoreHome/Columns/ServerTime.php index 297c410058..4e308786f1 100644 --- a/plugins/CoreHome/Columns/ServerTime.php +++ b/plugins/CoreHome/Columns/ServerTime.php @@ -9,17 +9,34 @@ namespace Piwik\Plugins\CoreHome\Columns; use Piwik\Date; -use Piwik\Db; +use Piwik\Metrics\Formatter; use Piwik\Plugin\Dimension\ActionDimension; use Piwik\Tracker\Action; use Piwik\Tracker\Request; use Piwik\Tracker\Visitor; -use Piwik\Tracker; + +require_once PIWIK_INCLUDE_PATH . '/plugins/VisitTime/functions.php'; class ServerTime extends ActionDimension { protected $columnName = 'server_time'; protected $columnType = 'DATETIME NOT NULL'; + protected $segmentName = 'actionServerHour'; + protected $sqlSegment = 'HOUR(log_link_visit_action.server_time)'; + protected $nameSingular = 'VisitTime_ColumnServerHour'; + protected $type = self::TYPE_DATETIME; + + public function __construct() + { + $this->suggestedValuesCallback = function ($idSite, $maxValuesToReturn) { + return range(0, min(23, $maxValuesToReturn)); + }; + } + + public function formatValue($value, $idSite, Formatter $formatter) + { + return \Piwik\Plugins\VisitTime\getTimeLabel($value); + } public function install() { diff --git a/plugins/CoreHome/Columns/UserId.php b/plugins/CoreHome/Columns/UserId.php index 50d1be09bc..c5423ae93a 100644 --- a/plugins/CoreHome/Columns/UserId.php +++ b/plugins/CoreHome/Columns/UserId.php @@ -12,9 +12,7 @@ use Piwik\Cache; use Piwik\DataTable; use Piwik\DataTable\Map; use Piwik\Metrics; -use Piwik\Piwik; use Piwik\Plugin\Dimension\VisitDimension; -use Piwik\Plugin\Segment; use Piwik\Plugins\VisitsSummary\API as VisitsSummaryApi; use Piwik\Tracker\Request; use Piwik\Tracker\Visitor; @@ -29,25 +27,18 @@ class UserId extends VisitDimension * @var string */ protected $columnName = 'user_id'; + protected $type = self::TYPE_TEXT; + protected $allowAnonymous = false; + protected $segmentName = 'userId'; + protected $nameSingular = 'General_UserId'; + protected $namePlural = 'General_UserIds'; + protected $acceptValues = 'any non empty unique string identifying the user (such as an email address or a username).'; /** * @var string */ protected $columnType = 'VARCHAR(200) NULL'; - protected function configureSegments() - { - $segment = new Segment(); - $segment->setType('dimension'); - $segment->setSegment('userId'); - $segment->setCategory(Piwik::translate('General_Visit')); - $segment->setName('General_UserId'); - $segment->setAcceptedValues('any non empty unique string identifying the user (such as an email address or a username).'); - $segment->setSqlSegment('log_visit.user_id'); - $segment->setRequiresAtLeastViewAccess(true); - $this->addSegment($segment); - } - /** * @param Request $request * @param Visitor $visitor diff --git a/plugins/CoreHome/Columns/VisitFirstActionMinute.php b/plugins/CoreHome/Columns/VisitFirstActionMinute.php new file mode 100644 index 0000000000..c3e16a9215 --- /dev/null +++ b/plugins/CoreHome/Columns/VisitFirstActionMinute.php @@ -0,0 +1,45 @@ +suggestedValuesCallback = function ($idSite, $maxValuesToReturn) { + return range(0, min(59, $maxValuesToReturn)); + }; + } + + public function configureMetrics(MetricsList $metricsList, DimensionMetricFactory $dimensionMetricFactory) + { + // no metrics to be generated + } + + public function formatValue($value, $idSite, Formatter $formatter) + { + return $value; + } + +} \ No newline at end of file diff --git a/plugins/CoreHome/Columns/VisitFirstActionTime.php b/plugins/CoreHome/Columns/VisitFirstActionTime.php index 3985d53339..f9318d6771 100644 --- a/plugins/CoreHome/Columns/VisitFirstActionTime.php +++ b/plugins/CoreHome/Columns/VisitFirstActionTime.php @@ -12,13 +12,33 @@ use Piwik\Date; use Piwik\Plugin\Dimension\VisitDimension; use Piwik\Tracker\Action; use Piwik\Tracker\Request; -use Piwik\Tracker; use Piwik\Tracker\Visitor; +use Piwik\Metrics\Formatter; + +require_once PIWIK_INCLUDE_PATH . '/plugins/VisitTime/functions.php'; class VisitFirstActionTime extends VisitDimension { protected $columnName = 'visit_first_action_time'; protected $columnType = 'DATETIME NOT NULL'; + protected $type = self::TYPE_DATETIME; + + protected $sqlSegment = 'HOUR(log_visit.visit_first_action_time)'; + protected $segmentName = 'visitStartServerHour'; + protected $acceptValues = '0, 1, 2, 3, ..., 20, 21, 22, 23'; + protected $nameSingular = 'VisitTime_ColumnVisitStartServerHour'; + + public function __construct() + { + $this->suggestedValuesCallback = function ($idSite, $maxValuesToReturn) { + return range(0, min(23, $maxValuesToReturn)); + }; + } + + public function formatValue($value, $idSite, Formatter $formatter) + { + return $value; + } /** * @param Request $request diff --git a/plugins/CoreHome/Columns/VisitGoalBuyer.php b/plugins/CoreHome/Columns/VisitGoalBuyer.php index 779d5fd5be..5c6f908173 100644 --- a/plugins/CoreHome/Columns/VisitGoalBuyer.php +++ b/plugins/CoreHome/Columns/VisitGoalBuyer.php @@ -8,6 +8,7 @@ */ namespace Piwik\Plugins\CoreHome\Columns; +use Piwik\Metrics\Formatter; use Piwik\Piwik; use Piwik\Plugin\Dimension\VisitDimension; use Piwik\Plugins\CoreHome\Segment; @@ -33,19 +34,39 @@ class VisitGoalBuyer extends VisitDimension protected $columnName = 'visit_goal_buyer'; protected $columnType = 'TINYINT(1) NULL'; + protected $segmentName = 'visitEcommerceStatus'; + protected $nameSingular = 'General_EcommerceVisitStatusDesc'; + protected $type = self::TYPE_ENUM; - protected function configureSegments() + public function __construct() { $example = Piwik::translate('General_EcommerceVisitStatusEg', '"&segment=visitEcommerceStatus==ordered,visitEcommerceStatus==orderedThenAbandonedCart"'); - $acceptedValues = implode(", ", self::$visitEcommerceStatus) . '. ' . $example; + $this->acceptValues = implode(", ", self::$visitEcommerceStatus) . '. ' . $example; + } + + public function formatValue($value, $idSite, Formatter $formatter) + { + switch ($value) { + case 'ordered': + case self::TYPE_BUYER_ORDERED: + return Piwik::translate('CoreHome_VisitStatusOrdered'); + case 'abandonedCart': + case self::TYPE_BUYER_OPEN_CART: + return Piwik::translate('Goals_AbandonedCart'); + case 'orderedThenAbandonedCart': + case self::TYPE_BUYER_ORDERED_AND_OPEN_CART: + return Piwik::translate('CoreHome_VisitStatusOrderedThenAbandoned'); + case 'none'; + case self::TYPE_BUYER_NONE: + return Piwik::translate('UserCountryMap_None'); + } - $segment = new Segment(); - $segment->setSegment('visitEcommerceStatus'); - $segment->setName('General_EcommerceVisitStatusDesc'); - $segment->setAcceptedValues($acceptedValues); - $segment->setSqlFilterValue(__NAMESPACE__ . '\VisitGoalBuyer::getVisitEcommerceStatus'); + return $value; + } - $this->addSegment($segment); + public function getEnumColumnValues() + { + return self::$visitEcommerceStatus; } /** @@ -83,17 +104,6 @@ class VisitGoalBuyer extends VisitDimension return false; } - public static function getVisitEcommerceStatus($status) - { - $id = array_search($status, self::$visitEcommerceStatus); - - if ($id === false) { - throw new \Exception("Invalid 'visitEcommerceStatus' segment value $status"); - } - - return $id; - } - /** * @ignore */ diff --git a/plugins/CoreHome/Columns/VisitGoalConverted.php b/plugins/CoreHome/Columns/VisitGoalConverted.php index 1c0cc40e65..26d87b7835 100644 --- a/plugins/CoreHome/Columns/VisitGoalConverted.php +++ b/plugins/CoreHome/Columns/VisitGoalConverted.php @@ -8,8 +8,11 @@ */ namespace Piwik\Plugins\CoreHome\Columns; +use Piwik\Columns\DimensionMetricFactory; +use Piwik\Columns\MetricsList; +use Piwik\Piwik; +use Piwik\Plugin\ComputedMetric; use Piwik\Plugin\Dimension\VisitDimension; -use Piwik\Plugins\CoreHome\Segment; use Piwik\Tracker\Action; use Piwik\Tracker\Request; use Piwik\Tracker\Visitor; @@ -18,14 +21,21 @@ class VisitGoalConverted extends VisitDimension { protected $columnName = 'visit_goal_converted'; protected $columnType = 'TINYINT(1) NULL'; + protected $type = self::TYPE_BOOL; + protected $segmentName = 'visitConverted'; + protected $nameSingular = 'General_VisitConvertedGoal'; + protected $acceptValues = '0, 1'; - protected function configureSegments() + public function configureMetrics(MetricsList $metricsList, DimensionMetricFactory $dimensionMetricFactory) { - $segment = new Segment(); - $segment->setSegment('visitConverted'); - $segment->setName('General_VisitConvertedGoal'); - $segment->setAcceptedValues('0, 1'); - $this->addSegment($segment); + $metric1 = $dimensionMetricFactory->createCustomMetric('nb_visits_converted', Piwik::translate('General_ColumnVisitsWithConversions'), 'sum(case %s when 1 then 1 else 0 end)'); + $metricsList->addMetric($metric1); + + $metric = $dimensionMetricFactory->createComputedMetric($metric1->getName(), 'nb_visits', ComputedMetric::AGGREGATION_RATE); + $metric->setTranslatedName(Piwik::translate('General_ColumnConversionRate')); + $metric->setDocumentation(Piwik::translate('General_ColumnConversionRateDocumentation')); + $metric->setName('visits_conversion_rate'); + $metricsList->addMetric($metric); } /** diff --git a/plugins/CoreHome/Columns/VisitId.php b/plugins/CoreHome/Columns/VisitId.php index 9add50888a..b87f1b58d4 100644 --- a/plugins/CoreHome/Columns/VisitId.php +++ b/plugins/CoreHome/Columns/VisitId.php @@ -8,7 +8,10 @@ namespace Piwik\Plugins\CoreHome\Columns; +use Piwik\Columns\DimensionMetricFactory; +use Piwik\Columns\MetricsList; use Piwik\Piwik; +use Piwik\Plugin\ArchivedMetric; use Piwik\Plugin\Dimension\VisitDimension; use Piwik\Plugin\Segment; @@ -18,18 +21,28 @@ use Piwik\Plugin\Segment; */ class VisitId extends VisitDimension { + protected $columnName = 'idvisit'; + protected $acceptValues = 'Any integer.'; + protected $nameSingular = 'General_Visit'; + protected $namePlural = 'General_ColumnNbVisits'; + protected $segmentName = 'visitId'; + protected $allowAnonymous = false; + protected $metricId = 'visits'; + protected $type = self::TYPE_TEXT; + protected function configureSegments() { - parent::configureSegments(); - $segment = new Segment(); - $segment->setType('dimension'); - $segment->setCategory(Piwik::translate('General_Visit')); - $segment->setName(Piwik::translate('General_Visit') . " ID"); - $segment->setSegment('visitId'); - $segment->setAcceptedValues('Any integer.'); - $segment->setSqlSegment('log_visit.idvisit'); - $segment->setRequiresAtLeastViewAccess(true); + $segment->setName('General_VisitId'); $this->addSegment($segment); } + + public function configureMetrics(MetricsList $metricsList, DimensionMetricFactory $dimensionMetricFactory) + { + $metric = $dimensionMetricFactory->createMetric(ArchivedMetric::AGGREGATION_UNIQUE); + $metric->setTranslatedName(Piwik::translate('General_ColumnNbVisits')); + $metric->setDocumentation(Piwik::translate('General_ColumnNbVisitsDocumentation')); + $metric->setName('nb_visits'); + $metricsList->addMetric($metric); + } } \ No newline at end of file diff --git a/plugins/CoreHome/Columns/VisitIp.php b/plugins/CoreHome/Columns/VisitIp.php index 6dd2e5d6b9..ed8b196fd2 100644 --- a/plugins/CoreHome/Columns/VisitIp.php +++ b/plugins/CoreHome/Columns/VisitIp.php @@ -8,7 +8,9 @@ namespace Piwik\Plugins\CoreHome\Columns; -use Piwik\Piwik; +use Piwik\Common; +use Piwik\Metrics\Formatter; +use Piwik\Network\IPUtils; use Piwik\Plugin\Dimension\VisitDimension; use Piwik\Plugin\Segment; @@ -18,19 +20,26 @@ use Piwik\Plugin\Segment; */ class VisitIp extends VisitDimension { - protected function configureSegments() + protected $columnName = 'location_ip'; + protected $type = self::TYPE_BINARY; + protected $allowAnonymous = false; + protected $segmentName = 'visitIp'; + protected $nameSingular = 'General_VisitorIP'; + protected $namePlural = 'General_VisitorIPs'; + protected $acceptValues = '13.54.122.1. Select IP ranges with notation: visitIp>13.54.122.0;visitIp<13.54.122.255'; + protected $sqlFilterValue = array('Piwik\Network\IPUtils', 'stringToBinaryIP'); + + public function formatValue($value, $idSite, Formatter $formatter) { - parent::configureSegments(); + $value = Common::hex2bin($value); + $value = IPUtils::binaryToStringIP($value); + return $value; + } + protected function configureSegments() + { $segment = new Segment(); - $segment->setType('metric'); - $segment->setCategory(Piwik::translate('General_Visit')); - $segment->setName('General_VisitorIP'); - $segment->setSegment('visitIp'); - $segment->setAcceptedValues('13.54.122.1. Select IP ranges with notation: visitIp>13.54.122.0;visitIp<13.54.122.255'); - $segment->setSqlSegment('log_visit.location_ip'); - $segment->setSqlFilterValue(array('Piwik\Network\IPUtils', 'stringToBinaryIP')); - $segment->setRequiresAtLeastViewAccess(true); + $segment->setType(Segment::TYPE_METRIC); // we cannot remove this for now as it would assign dimension based on text type $this->addSegment($segment); } } diff --git a/plugins/CoreHome/Columns/VisitLastActionMinute.php b/plugins/CoreHome/Columns/VisitLastActionMinute.php new file mode 100644 index 0000000000..06611fb2fc --- /dev/null +++ b/plugins/CoreHome/Columns/VisitLastActionMinute.php @@ -0,0 +1,51 @@ +suggestedValuesCallback = function ($idSite, $maxValuesToReturn) { + return range(0, min(59, $maxValuesToReturn)); + }; + } + + public function configureMetrics(MetricsList $metricsList, DimensionMetricFactory $dimensionMetricFactory) + { + // no metrics for this dimension + } + + public function formatValue($value, $idSite, Formatter $formatter) + { + return $value; + } +} \ No newline at end of file diff --git a/plugins/CoreHome/Columns/VisitLastActionTime.php b/plugins/CoreHome/Columns/VisitLastActionTime.php index 4ba0761c2a..3b297fb68b 100644 --- a/plugins/CoreHome/Columns/VisitLastActionTime.php +++ b/plugins/CoreHome/Columns/VisitLastActionTime.php @@ -12,8 +12,10 @@ use Piwik\Date; use Piwik\Plugin\Dimension\VisitDimension; use Piwik\Tracker\Action; use Piwik\Tracker\Request; -use Piwik\Tracker; use Piwik\Tracker\Visitor; +use Piwik\Metrics\Formatter; + +require_once PIWIK_INCLUDE_PATH . '/plugins/VisitTime/functions.php'; /** * This dimension holds the best guess for a visit's end time. It is set the last action @@ -26,6 +28,17 @@ use Piwik\Tracker\Visitor; class VisitLastActionTime extends VisitDimension { protected $columnName = 'visit_last_action_time'; + protected $type = self::TYPE_DATETIME; + protected $nameSingular = 'VisitTime_ColumnVisitEndServerHour'; + protected $sqlSegment = 'HOUR(log_visit.visit_last_action_time)'; + protected $segmentName = 'visitServerHour'; + protected $acceptValues = '0, 1, 2, 3, ..., 20, 21, 22, 23'; + + public function formatValue($value, $idSite, Formatter $formatter) + { + return \Piwik\Plugins\VisitTime\getTimeLabel($value); + } + // we do not install or define column definition here as we need to create this column when installing as there is // an index on it. Currently we do not define the index here... although we could overwrite the install() method // and add column 'visit_last_action_time' and add index. Problem is there is also an index diff --git a/plugins/CoreHome/Columns/VisitTotalTime.php b/plugins/CoreHome/Columns/VisitTotalTime.php index 87025a90f9..44bdc39958 100644 --- a/plugins/CoreHome/Columns/VisitTotalTime.php +++ b/plugins/CoreHome/Columns/VisitTotalTime.php @@ -19,15 +19,9 @@ class VisitTotalTime extends VisitDimension { protected $columnName = 'visit_total_time'; protected $columnType = 'INT(11) UNSIGNED NOT NULL'; - - protected function configureSegments() - { - $segment = new Segment(); - $segment->setSegment('visitDuration'); - $segment->setName('General_ColumnVisitDuration'); - $segment->setType(Segment::TYPE_METRIC); - $this->addSegment($segment); - } + protected $segmentName = 'visitDuration'; + protected $nameSingular = 'General_ColumnVisitDuration'; + protected $type = self::TYPE_DURATION_S; /** * @param Request $request diff --git a/plugins/CoreHome/Columns/VisitorDaysSinceFirst.php b/plugins/CoreHome/Columns/VisitorDaysSinceFirst.php index 3445f21f59..e0ce8fa5be 100644 --- a/plugins/CoreHome/Columns/VisitorDaysSinceFirst.php +++ b/plugins/CoreHome/Columns/VisitorDaysSinceFirst.php @@ -9,7 +9,6 @@ namespace Piwik\Plugins\CoreHome\Columns; use Piwik\Plugin\Dimension\VisitDimension; -use Piwik\Plugins\CoreHome\Segment; use Piwik\Tracker\Action; use Piwik\Tracker\Request; use Piwik\Tracker\Visitor; @@ -18,15 +17,9 @@ class VisitorDaysSinceFirst extends VisitDimension { protected $columnName = 'visitor_days_since_first'; protected $columnType = 'SMALLINT(5) UNSIGNED NULL'; - - protected function configureSegments() - { - $segment = new Segment(); - $segment->setType(Segment::TYPE_METRIC); - $segment->setSegment('daysSinceFirstVisit'); - $segment->setName('General_DaysSinceFirstVisit'); - $this->addSegment($segment); - } + protected $segmentName = 'daysSinceFirstVisit'; + protected $nameSingular = 'General_DaysSinceFirstVisit'; + protected $type = self::TYPE_NUMBER; /** * @param Request $request diff --git a/plugins/CoreHome/Columns/VisitorDaysSinceOrder.php b/plugins/CoreHome/Columns/VisitorDaysSinceOrder.php index c126b5957c..ad6334e838 100644 --- a/plugins/CoreHome/Columns/VisitorDaysSinceOrder.php +++ b/plugins/CoreHome/Columns/VisitorDaysSinceOrder.php @@ -9,7 +9,6 @@ namespace Piwik\Plugins\CoreHome\Columns; use Piwik\Plugin\Dimension\VisitDimension; -use Piwik\Plugins\CoreHome\Segment; use Piwik\Tracker\Action; use Piwik\Tracker\Request; use Piwik\Tracker\Visitor; @@ -18,16 +17,10 @@ class VisitorDaysSinceOrder extends VisitDimension { protected $columnName = 'visitor_days_since_order'; protected $columnType = 'SMALLINT(5) UNSIGNED NULL'; - - protected function configureSegments() - { - $segment = new Segment(); - $segment->setSegment('daysSinceLastEcommerceOrder'); - $segment->setName('General_DaysSinceLastEcommerceOrder'); - $segment->setType(Segment::TYPE_METRIC); - - $this->addSegment($segment); - } + protected $segmentName = 'daysSinceLastEcommerceOrder'; + protected $nameSingular = 'General_DaysSinceLastEcommerceOrder'; + protected $category = 'General_Visitors'; // todo put into ecommerce category? + protected $type = self::TYPE_NUMBER; /** * @param Request $request diff --git a/plugins/CoreHome/Columns/VisitorId.php b/plugins/CoreHome/Columns/VisitorId.php index ce797ae57a..728e1e3d94 100644 --- a/plugins/CoreHome/Columns/VisitorId.php +++ b/plugins/CoreHome/Columns/VisitorId.php @@ -8,9 +8,12 @@ namespace Piwik\Plugins\CoreHome\Columns; +use Piwik\Columns\DimensionMetricFactory; +use Piwik\Columns\MetricsList; +use Piwik\Metrics\Formatter; use Piwik\Piwik; +use Piwik\Plugin\ArchivedMetric; use Piwik\Plugin\Dimension\VisitDimension; -use Piwik\Plugin\Segment; /** * Dimension for the log_visit.idvisitor column. This column is added in the CREATE TABLE @@ -18,19 +21,21 @@ use Piwik\Plugin\Segment; */ class VisitorId extends VisitDimension { - protected function configureSegments() - { - parent::configureSegments(); + protected $columnName = 'idvisitor'; + protected $metricId = 'visitors'; + protected $nameSingular = 'General_VisitorID'; + protected $namePlural = 'General_Visitors'; + protected $segmentName = 'visitorId'; + protected $acceptValues = '34c31e04394bdc63 - any 16 Hexadecimal chars ID, which can be fetched using the Tracking API function getVisitorId()'; + protected $allowAnonymous = false; + protected $sqlFilterValue = array('Piwik\Common', 'convertVisitorIdToBin'); + protected $type = self::TYPE_BINARY; - $segment = new Segment(); - $segment->setType('dimension'); - $segment->setCategory(Piwik::translate('General_Visit')); - $segment->setName('General_VisitorID'); - $segment->setSegment('visitorId'); - $segment->setAcceptedValues('34c31e04394bdc63 - any 16 Hexadecimal chars ID, which can be fetched using the Tracking API function getVisitorId()'); - $segment->setSqlSegment('log_visit.idvisitor'); - $segment->setSqlFilterValue(array('Piwik\Common', 'convertVisitorIdToBin')); - $segment->setRequiresAtLeastViewAccess(true); - $this->addSegment($segment); + public function configureMetrics(MetricsList $metricsList, DimensionMetricFactory $dimensionMetricFactory) + { + $metric = $dimensionMetricFactory->createMetric(ArchivedMetric::AGGREGATION_UNIQUE); + $metric->setTranslatedName(Piwik::translate('General_ColumnNbUniqVisitors')); + $metric->setName('nb_uniq_visitors'); + $metricsList->addMetric($metric); } } diff --git a/plugins/CoreHome/Columns/VisitorReturning.php b/plugins/CoreHome/Columns/VisitorReturning.php index ca1ef11652..862fb12c6e 100644 --- a/plugins/CoreHome/Columns/VisitorReturning.php +++ b/plugins/CoreHome/Columns/VisitorReturning.php @@ -8,9 +8,9 @@ */ namespace Piwik\Plugins\CoreHome\Columns; +use Piwik\Metrics\Formatter; use Piwik\Piwik; use Piwik\Plugin\Dimension\VisitDimension; -use Piwik\Plugins\CoreHome\Segment; use Piwik\Tracker\Action; use Piwik\Tracker\Request; use Piwik\Tracker\Visitor; @@ -23,22 +23,44 @@ class VisitorReturning extends VisitDimension protected $columnName = 'visitor_returning'; protected $columnType = 'TINYINT(1) NULL'; + protected $segmentName = 'visitorType'; + protected $nameSingular = 'General_VisitType'; + protected $namePlural = 'General_VisitTypes'; protected $conversionField = true; + protected $type = self::TYPE_ENUM; - protected function configureSegments() + public function __construct() { - $acceptedValues = 'new, returning, returningCustomer. '; - $acceptedValues .= Piwik::translate('General_VisitTypeExample', '"&segment=visitorType==returning,visitorType==returningCustomer"'); - - $segment = new Segment(); - $segment->setSegment('visitorType'); - $segment->setName('General_VisitType'); - $segment->setAcceptedValues($acceptedValues); - $segment->setSqlFilterValue(function ($type) { + $this->acceptValues = 'new, returning, returningCustomer. '; + $this->acceptValues .= Piwik::translate('General_VisitTypeExample', '"&segment=visitorType==returning,visitorType==returningCustomer"'); + $this->sqlFilterValue = function ($type) { + if (is_numeric($type)) { + return $type; + } return $type == "new" ? 0 : ($type == "returning" ? 1 : 2); - }); + }; + } + + public function formatValue($value, $idSite, Formatter $formatter) + { + if ($value === 1 || $value === '1' || $value === 'returning') { + return Piwik::translate('CoreHome_VisitTypeReturning'); + } elseif ($value === 2 || $value === '2' || $value === 'returningCustomer'){ + return Piwik::translate('CoreHome_VisitTypeReturningCustomer'); + } elseif ($value === 0 || $value === '0' || $value === 'new'){ + return Piwik::translate('General_New'); + } - $this->addSegment($segment); + return $value; + } + + public function getEnumColumnValues() + { + return array( + self::IS_RETURNING_CUSTOMER => 'returningCustomer', + self::IS_RETURNING => 'returning', + self::IS_NEW => 'new', + ); } /** @@ -49,7 +71,6 @@ class VisitorReturning extends VisitDimension */ public function onNewVisit(Request $request, Visitor $visitor, $action) { - $daysSinceLastOrder = $request->getDaysSinceLastOrder(); $isReturningCustomer = ($daysSinceLastOrder !== false); diff --git a/plugins/CoreHome/Columns/VisitsCount.php b/plugins/CoreHome/Columns/VisitsCount.php index 584b242ae4..c334f175bb 100644 --- a/plugins/CoreHome/Columns/VisitsCount.php +++ b/plugins/CoreHome/Columns/VisitsCount.php @@ -8,8 +8,9 @@ */ namespace Piwik\Plugins\CoreHome\Columns; +use Piwik\Columns\DimensionMetricFactory; +use Piwik\Columns\MetricsList; use Piwik\Plugin\Dimension\VisitDimension; -use Piwik\Plugins\CoreHome\Segment; use Piwik\Tracker\Action; use Piwik\Tracker\Request; use Piwik\Tracker\Visitor; @@ -18,14 +19,13 @@ class VisitsCount extends VisitDimension { protected $columnName = 'visitor_count_visits'; protected $columnType = 'INT(11) UNSIGNED NOT NULL'; + protected $segmentName = 'visitCount'; + protected $nameSingular = 'General_NumberOfVisits'; + protected $type = self::TYPE_NUMBER; - protected function configureSegments() + public function configureMetrics(MetricsList $metricsList, DimensionMetricFactory $dimensionMetricFactory) { - $segment = new Segment(); - $segment->setType(Segment::TYPE_METRIC); - $segment->setSegment('visitCount'); - $segment->setName('General_NumberOfVisits'); - $this->addSegment($segment); + // no metrics for this dimension, it would be rather confusing I think } /** diff --git a/plugins/CoreHome/CoreHome.php b/plugins/CoreHome/CoreHome.php index be56c144f8..ff800ebe1e 100644 --- a/plugins/CoreHome/CoreHome.php +++ b/plugins/CoreHome/CoreHome.php @@ -7,6 +7,10 @@ * */ namespace Piwik\Plugins\CoreHome; +use Piwik\Columns\ComputedMetricFactory; +use Piwik\Columns\MetricsList; +use Piwik\Plugin\ArchivedMetric; +use Piwik\Plugin\ComputedMetric; /** * @@ -21,7 +25,7 @@ class CoreHome extends \Piwik\Plugin const WIDGET_CONTAINER_LAYOUT_BY_DIMENSION = 'ByDimension'; /** - * @see Piwik\Plugin::registerEvents + * @see \Piwik\Plugin::registerEvents */ public function registerEvents() { @@ -30,9 +34,27 @@ class CoreHome extends \Piwik\Plugin 'AssetManager.getJavaScriptFiles' => 'getJsFiles', 'AssetManager.filterMergedJavaScripts' => 'filterMergedJavaScripts', 'Translate.getClientSideTranslationKeys' => 'getClientSideTranslationKeys', + 'Metric.addComputedMetrics' => 'addComputedMetrics' ); } + public function addComputedMetrics(MetricsList $list, ComputedMetricFactory $computedMetricFactory) + { + $metrics = $list->getMetrics(); + foreach ($metrics as $metric) { + if ($metric instanceof ArchivedMetric && $metric->getDimension()) { + $metricName = $metric->getName(); + if ($metric->getDbTableName() === 'log_visit' + && $metricName !== 'nb_uniq_visitors' + && $metricName !== 'nb_visits' + && strpos($metricName, ArchivedMetric::AGGREGATION_SUM_PREFIX) === 0) { + $metric = $computedMetricFactory->createComputedMetric($metric->getName(), 'nb_visits', ComputedMetric::AGGREGATION_AVG); + $list->addMetric($metric); + } + } + } + } + public function filterMergedJavaScripts(&$mergedContent) { $mergedContent = preg_replace('/(sourceMappingURL=(.*?).map)/', '', $mergedContent); diff --git a/plugins/CoreHome/Tracker/LogTable/Conversion.php b/plugins/CoreHome/Tracker/LogTable/Conversion.php index b579b32d81..2a75d52c41 100644 --- a/plugins/CoreHome/Tracker/LogTable/Conversion.php +++ b/plugins/CoreHome/Tracker/LogTable/Conversion.php @@ -26,4 +26,9 @@ class Conversion extends LogTable { return 'idvisit'; } + + public function getPrimaryKey() + { + return array('idvisit', 'idgoal', 'buster'); + } } \ No newline at end of file diff --git a/plugins/CoreHome/Tracker/LogTable/ConversionItem.php b/plugins/CoreHome/Tracker/LogTable/ConversionItem.php index cf24614458..8423ff8010 100644 --- a/plugins/CoreHome/Tracker/LogTable/ConversionItem.php +++ b/plugins/CoreHome/Tracker/LogTable/ConversionItem.php @@ -26,5 +26,10 @@ class ConversionItem extends LogTable { return 'idvisit'; } - + + public function getPrimaryKey() + { + return array('idvisit', 'idorder', 'idaction_sku'); + } + } diff --git a/plugins/CoreHome/Tracker/LogTable/LinkVisitAction.php b/plugins/CoreHome/Tracker/LogTable/LinkVisitAction.php index 8dabf66a66..c2090a1c8c 100644 --- a/plugins/CoreHome/Tracker/LogTable/LinkVisitAction.php +++ b/plugins/CoreHome/Tracker/LogTable/LinkVisitAction.php @@ -31,4 +31,9 @@ class LinkVisitAction extends LogTable { return 'idvisit'; } + + public function getPrimaryKey() + { + return array('idlink_va'); + } } diff --git a/plugins/CoreHome/Tracker/LogTable/Visit.php b/plugins/CoreHome/Tracker/LogTable/Visit.php index a72fb24d11..62877f1cd1 100644 --- a/plugins/CoreHome/Tracker/LogTable/Visit.php +++ b/plugins/CoreHome/Tracker/LogTable/Visit.php @@ -32,4 +32,8 @@ class Visit extends LogTable return true; } + public function getPrimaryKey() + { + return array('idvisit'); + } } \ No newline at end of file diff --git a/plugins/CoreHome/angularjs/common/services/piwik-api.js b/plugins/CoreHome/angularjs/common/services/piwik-api.js index 67f9756f4f..65127ece8a 100644 --- a/plugins/CoreHome/angularjs/common/services/piwik-api.js +++ b/plugins/CoreHome/angularjs/common/services/piwik-api.js @@ -214,7 +214,7 @@ var hasBlockedContent = false; } for (var key in defaultParams) { - if (!getParamsToMixin[key] && !postParams[key] && defaultParams[key]) { + if (!(key in getParamsToMixin) && !(key in postParams) && defaultParams[key]) { getParamsToMixin[key] = defaultParams[key]; } } diff --git a/plugins/CoreHome/angularjs/reporting-menu/reportingmenu.controller.js b/plugins/CoreHome/angularjs/reporting-menu/reportingmenu.controller.js index 1c94136827..d284034cd6 100644 --- a/plugins/CoreHome/angularjs/reporting-menu/reportingmenu.controller.js +++ b/plugins/CoreHome/angularjs/reporting-menu/reportingmenu.controller.js @@ -133,6 +133,12 @@ } } }); + if ('object' === typeof widgetsHelper && widgetsHelper.availableWidgets) { + // lets also update widgetslist so will be easier to update list of available widgets in dashboard selector + // immediately + delete widgetsHelper.availableWidgets; + widgetsHelper.getAvailableWidgets(); + } }); $rootScope.$on('$locationChangeSuccess', function () { diff --git a/plugins/CoreHome/lang/en.json b/plugins/CoreHome/lang/en.json index a013ab30ae..1677e05d28 100644 --- a/plugins/CoreHome/lang/en.json +++ b/plugins/CoreHome/lang/en.json @@ -29,6 +29,10 @@ "InjectedHostSuperUserWarning": "Piwik may be misconfigured (for example, if Piwik was recently moved to a new server or URL). You can either %1$sclick here and add %2$s as the valid Piwik hostname (if you trust it)%3$s, or %4$sclick here and go to %5$s to access Piwik safely%6$s.", "InjectedHostWarningIntro": "You are now accessing Piwik from %1$s, but Piwik has been configured to run at this address: %2$s.", "JavascriptDisabled": "JavaScript must be enabled in order for you to use Piwik in standard view.
However, it seems JavaScript is either disabled or not supported by your browser.
To use standard view, enable JavaScript by changing your browser options, then %1$stry again%2$s.
", + "VisitStatusOrdered": "Ordered", + "VisitStatusOrderedThenAbandoned": "Ordered then Abandoned Cart", + "VisitTypeReturning": "Returning", + "VisitTypeReturningCustomer": "Returning Customer", "MainNavigation": "Main navigation", "MakeOneTimeDonation": "Make a one time donation, instead.", "Menu": "Menu", diff --git a/plugins/CoreHome/templates/_dataTableActions.twig b/plugins/CoreHome/templates/_dataTableActions.twig index dca99c47c7..537fdffd97 100644 --- a/plugins/CoreHome/templates/_dataTableActions.twig +++ b/plugins/CoreHome/templates/_dataTableActions.twig @@ -46,9 +46,11 @@ {{ visualizationIcons|raw }} {% endif %} + {% if properties.show_export %} + {% endif %} {% if isPluginLoaded('Annotations') and not properties.hide_annotations_view %} {% endif %} + {% if properties.show_export %} + {% endif %} +