diff options
author | Thomas Steur <tsteur@users.noreply.github.com> | 2015-11-23 00:31:22 +0300 |
---|---|---|
committer | Thomas Steur <tsteur@users.noreply.github.com> | 2015-11-23 00:31:22 +0300 |
commit | f9c851190ed680eb430d9d52040b72c7cf73f62a (patch) | |
tree | a8f33abed580daa5e2e8c21b6a01a1689a75ce0a /plugins | |
parent | 741397e51065b29e0a2602b63cd5d93b8a1b924e (diff) | |
parent | ada836d750a74ddfda03b48baf2fa1c1173e39ff (diff) |
Merge pull request #9228 from piwik/9224
Add new segment ActionUrl + new operators starts with and ends with
Diffstat (limited to 'plugins')
-rw-r--r-- | plugins/API/API.php | 85 | ||||
-rw-r--r-- | plugins/Actions/Columns/ActionUrl.php | 32 | ||||
-rw-r--r-- | plugins/Actions/lang/en.json | 1 | ||||
-rw-r--r-- | plugins/CustomVariables/Columns/Base.php | 12 | ||||
-rw-r--r-- | plugins/CustomVariables/Columns/CustomVariableName.php | 2 | ||||
-rw-r--r-- | plugins/CustomVariables/Columns/CustomVariableValue.php | 2 | ||||
-rw-r--r-- | plugins/SegmentEditor/SegmentSelectorControl.php | 2 | ||||
-rw-r--r-- | plugins/SegmentEditor/javascripts/Segmentation.js | 4 | ||||
-rw-r--r-- | plugins/SegmentEditor/lang/en.json | 3 | ||||
-rw-r--r-- | plugins/SegmentEditor/templates/_segmentSelector.twig | 14 |
10 files changed, 120 insertions, 37 deletions
diff --git a/plugins/API/API.php b/plugins/API/API.php index 4ea0cb4055..e5d9fbcd2a 100644 --- a/plugins/API/API.php +++ b/plugins/API/API.php @@ -493,30 +493,20 @@ class API extends \Piwik\Plugin\API if (empty(Config::getInstance()->General['enable_segment_suggested_values'])) { return array(); } + Piwik::checkUserHasViewAccess($idSite); $maxSuggestionsToReturn = 30; - $segmentsMetadata = $this->getSegmentsMetadata($idSite, $_hideImplementationData = false); - - $segmentFound = false; - foreach ($segmentsMetadata as $segmentMetadata) { - if ($segmentMetadata['segment'] == $segmentName) { - $segmentFound = $segmentMetadata; - break; - } - } - if (empty($segmentFound)) { - throw new \Exception("Requested segment not found."); - } + $segment = $this->findSegment($segmentName, $idSite); // if segment has suggested values callback then return result from it instead $suggestedValuesCallbackRequiresTable = false; - if (isset($segmentFound['suggestedValuesCallback'])) { + if (isset($segment['suggestedValuesCallback'])) { $suggestedValuesCallbackRequiresTable = $this->doesSuggestedValuesCallbackNeedData( - $segmentFound['suggestedValuesCallback']); + $segment['suggestedValuesCallback']); if (!$suggestedValuesCallbackRequiresTable) { - return call_user_func($segmentFound['suggestedValuesCallback'], $idSite, $maxSuggestionsToReturn); + return call_user_func($segment['suggestedValuesCallback'], $idSite, $maxSuggestionsToReturn); } } @@ -525,6 +515,57 @@ class API extends \Piwik\Plugin\API return array(); } + if (!empty($segment['unionOfSegments'])) { + $values = array(); + foreach ($segment['unionOfSegments'] as $unionSegmentName) { + $unionSegment = $this->findSegment($unionSegmentName, $idSite); + + try { + $result = $this->getSuggestedValuesForSegmentName($idSite, $unionSegment, $maxSuggestionsToReturn); + if (!empty($result)) { + $values = array_merge($result, $values); + } + } catch (\Exception $e) { + // we ignore if there was no data found for $unionSegmentName + } + } + + if (empty($values)) { + throw new \Exception("There was no data to suggest for $segmentName"); + } + + } else { + $values = $this->getSuggestedValuesForSegmentName($idSite, $segment, $maxSuggestionsToReturn); + } + + $values = $this->getMostFrequentValues($values); + $values = array_slice($values, 0, $maxSuggestionsToReturn); + $values = array_map(array('Piwik\Common', 'unsanitizeInputValue'), $values); + + return $values; + } + + private function findSegment($segmentName, $idSite) + { + $segmentsMetadata = $this->getSegmentsMetadata($idSite, $_hideImplementationData = false); + + $segmentFound = false; + foreach ($segmentsMetadata as $segmentMetadata) { + if ($segmentMetadata['segment'] == $segmentName) { + $segmentFound = $segmentMetadata; + break; + } + } + + if (empty($segmentFound)) { + throw new \Exception("Requested segment $segmentName not found."); + } + + return $segmentFound; + } + + private function getSuggestedValuesForSegmentName($idSite, $segment, $maxSuggestionsToReturn) + { $startDate = Date::now()->subDay(60)->toString(); $requestLastVisits = "method=Live.getLastVisitsDetails &idSite=$idSite @@ -534,6 +575,8 @@ class API extends \Piwik\Plugin\API &serialize=0 &flat=1"; + $segmentName = $segment['segment']; + // Select non empty fields only // Note: this optimization has only a very minor impact $requestLastVisits .= "&segment=$segmentName" . urlencode('!='); @@ -548,22 +591,18 @@ class API extends \Piwik\Plugin\API $request = new Request($requestLastVisits); $table = $request->process(); + if (empty($table)) { throw new \Exception("There was no data to suggest for $segmentName"); } - if ($suggestedValuesCallbackRequiresTable) { - $values = call_user_func($segmentFound['suggestedValuesCallback'], $idSite, $maxSuggestionsToReturn, $table); + if (isset($segment['suggestedValuesCallback']) && + $this->doesSuggestedValuesCallbackNeedData($segment['suggestedValuesCallback'])) { + $values = call_user_func($segment['suggestedValuesCallback'], $idSite, $maxSuggestionsToReturn, $table); } else { $values = $this->getSegmentValuesFromVisitorLog($segmentName, $table); } - $values = $this->getMostFrequentValues($values); - - $values = array_slice($values, 0, $maxSuggestionsToReturn); - - $values = array_map(array('Piwik\Common', 'unsanitizeInputValue'), $values); - return $values; } diff --git a/plugins/Actions/Columns/ActionUrl.php b/plugins/Actions/Columns/ActionUrl.php new file mode 100644 index 0000000000..5fa80d1efa --- /dev/null +++ b/plugins/Actions/Columns/ActionUrl.php @@ -0,0 +1,32 @@ +<?php +/** + * Piwik - free/libre analytics platform + * + * @link http://piwik.org + * @license http://www.gnu.org/licenses/gpl-3.0.html GPL v3 or later + * + */ +namespace Piwik\Plugins\Actions\Columns; + +use Piwik\Piwik; +use Piwik\Plugin\Dimension\ActionDimension; +use Piwik\Plugins\Actions\Segment; + +class ActionUrl extends ActionDimension +{ + public function getName() + { + return Piwik::translate('Actions_ColumnActionURL'); + } + + protected function configureSegments() + { + $segment = new Segment(); + $segment->setSegment('actionUrl'); + $segment->setName('Actions_ColumnActionURL'); + $segment->setUnionOfSegments(array('pageUrl', 'downloadUrl', 'outlinkUrl')); + + $this->addSegment($segment); + } + +} diff --git a/plugins/Actions/lang/en.json b/plugins/Actions/lang/en.json index 5a31efee34..b4853e18f5 100644 --- a/plugins/Actions/lang/en.json +++ b/plugins/Actions/lang/en.json @@ -2,6 +2,7 @@ "Actions": { "AvgGenerationTimeTooltip": "Average based on %s hit(s) %s between %s and %s", "ColumnClickedURL": "Clicked URL", + "ColumnActionURL": "Action URL", "ColumnClicks": "Clicks", "ColumnClicksDocumentation": "The number of times this link was clicked.", "ColumnDownloadURL": "Download URL", diff --git a/plugins/CustomVariables/Columns/Base.php b/plugins/CustomVariables/Columns/Base.php index 1818ca3145..4c6a4ea542 100644 --- a/plugins/CustomVariables/Columns/Base.php +++ b/plugins/CustomVariables/Columns/Base.php @@ -16,7 +16,7 @@ use Piwik\Plugins\CustomVariables\CustomVariables; class Base extends VisitDimension { - protected function configureSegmentsFor($fieldPrefix, $segmentNameSuffix) + protected function configureSegmentsFor($segmentNameSuffix) { $numCustomVariables = CustomVariables::getNumUsableCustomVariables(); @@ -25,10 +25,7 @@ class Base extends VisitDimension $segment->setSegment('customVariable' . $segmentNameSuffix); $segment->setName($this->getName() . ' (' . Piwik::translate('CustomVariables_ScopeVisit') . ')'); $segment->setCategory('CustomVariables_CustomVariables'); - $segment->setSqlSegment($this->getSegmentColumns('log_visit.' . $fieldPrefix, $numCustomVariables)); - $segment->setSuggestedValuesCallback(function ($idSite, $ignore, DataTable $table) use ($segmentNameSuffix) { - return $table->getColumnsStartingWith('customVariable' . $segmentNameSuffix); - }); + $segment->setUnionOfSegments($this->getSegmentColumns('customVariable' . $segmentNameSuffix, $numCustomVariables)); $this->addSegment($segment); $segment = new Segment(); @@ -36,10 +33,7 @@ class Base extends VisitDimension $segment->setSegment('customVariablePage' . $segmentNameSuffix); $segment->setName($this->getName() . ' (' . Piwik::translate('CustomVariables_ScopePage') . ')'); $segment->setCategory('CustomVariables_CustomVariables'); - $segment->setSqlSegment($this->getSegmentColumns('log_link_visit_action.' . $fieldPrefix, $numCustomVariables)); - $segment->setSuggestedValuesCallback(function ($idSite, $ignore, DataTable $table) use ($segmentNameSuffix) { - return $table->getColumnsStartingWith('customVariablePage' . $segmentNameSuffix); - }); + $segment->setUnionOfSegments($this->getSegmentColumns('customVariablePage' . $segmentNameSuffix, $numCustomVariables)); $this->addSegment($segment); } diff --git a/plugins/CustomVariables/Columns/CustomVariableName.php b/plugins/CustomVariables/Columns/CustomVariableName.php index 85aa46436f..b42f2e8ae7 100644 --- a/plugins/CustomVariables/Columns/CustomVariableName.php +++ b/plugins/CustomVariables/Columns/CustomVariableName.php @@ -14,7 +14,7 @@ class CustomVariableName extends Base { protected function configureSegments() { - $this->configureSegmentsFor('custom_var_k', 'Name'); + $this->configureSegmentsFor('Name'); } public function getName() diff --git a/plugins/CustomVariables/Columns/CustomVariableValue.php b/plugins/CustomVariables/Columns/CustomVariableValue.php index 03046758cf..a565a8136c 100644 --- a/plugins/CustomVariables/Columns/CustomVariableValue.php +++ b/plugins/CustomVariables/Columns/CustomVariableValue.php @@ -14,7 +14,7 @@ class CustomVariableValue extends Base { protected function configureSegments() { - $this->configureSegmentsFor('custom_var_v', 'Value'); + $this->configureSegmentsFor('Value'); } public function getName() diff --git a/plugins/SegmentEditor/SegmentSelectorControl.php b/plugins/SegmentEditor/SegmentSelectorControl.php index e37354e1cd..9dc2659660 100644 --- a/plugins/SegmentEditor/SegmentSelectorControl.php +++ b/plugins/SegmentEditor/SegmentSelectorControl.php @@ -115,6 +115,8 @@ class SegmentSelectorControl extends UIControl 'General_OperationGreaterThan', 'General_OperationContains', 'General_OperationDoesNotContain', + 'General_OperationStartsWith', + 'General_OperationEndsWith', 'General_OperationIs', 'General_OperationIsNot', 'General_OperationContains', diff --git a/plugins/SegmentEditor/javascripts/Segmentation.js b/plugins/SegmentEditor/javascripts/Segmentation.js index 0e47bd7d19..ec1e8f23b8 100644 --- a/plugins/SegmentEditor/javascripts/Segmentation.js +++ b/plugins/SegmentEditor/javascripts/Segmentation.js @@ -49,6 +49,8 @@ Segmentation = (function($) { self.availableMatches["dimension"]["!="] = self.translations['General_OperationIsNot']; self.availableMatches["dimension"]["=@"] = self.translations['General_OperationContains']; self.availableMatches["dimension"]["!@"] = self.translations['General_OperationDoesNotContain']; + self.availableMatches["dimension"]["=^"] = self.translations['General_OperationStartsWith']; + self.availableMatches["dimension"]["=$"] = self.translations['General_OperationEndsWith']; segmentation.prototype.setAvailableSegments = function (segments) { this.availableSegments = segments; @@ -264,7 +266,7 @@ Segmentation = (function($) { }; var findAndExplodeByMatch = function(metric){ - var matches = ["==" , "!=" , "<=", ">=", "=@" , "!@","<",">"]; + var matches = ["==" , "!=" , "<=", ">=", "=@" , "!@","<",">", "=^", "=$"]; var newMetric = {}; var minPos = metric.length; var match, index; diff --git a/plugins/SegmentEditor/lang/en.json b/plugins/SegmentEditor/lang/en.json index 46bdf5fef2..933ac73884 100644 --- a/plugins/SegmentEditor/lang/en.json +++ b/plugins/SegmentEditor/lang/en.json @@ -26,6 +26,7 @@ "YouMayChangeSetting": "Alternatively you may change the setting in the config file (%s), or edit this Segment and choose '%s'.", "YouMustBeLoggedInToCreateSegments": "You must be logged in to create and edit custom visitor segments.", "YouDontHaveAccessToCreateSegments": "You don't have the required access level to create and edit segments.", - "AddingSegmentForAllWebsitesDisabled": "Adding segments for all websites has been disabled." + "AddingSegmentForAllWebsitesDisabled": "Adding segments for all websites has been disabled.", + "SegmentXIsAUnionOf": "%s is a union of these segments:" } }
\ No newline at end of file diff --git a/plugins/SegmentEditor/templates/_segmentSelector.twig b/plugins/SegmentEditor/templates/_segmentSelector.twig index 7a8019d37e..f2d53b60c7 100644 --- a/plugins/SegmentEditor/templates/_segmentSelector.twig +++ b/plugins/SegmentEditor/templates/_segmentSelector.twig @@ -61,6 +61,8 @@ <option value=">">{{ 'General_OperationGreaterThan'|translate }}</option> <option value="=@">{{ 'General_OperationContains'|translate }}</option> <option value="!@">{{ 'General_OperationDoesNotContain'|translate }}</option> + <option value="=^">{{ 'General_OperationStartsWith'|translate }}</option> + <option value="=$">{{ 'General_OperationEndsWith'|translate }}</option> </select> </div> <div class="segment-input metricValueBlock"> @@ -99,7 +101,17 @@ <a class="metric_category" href="#">{{ category }}</a> <ul style="display:none;"> {% for segmentInCategory in segmentsInCategory %} - <li data-metric="{{ segmentInCategory.segment }}"><a class="ddmetric" href="#">{{ segmentInCategory.name }}</a></li> + {% set title = segmentInCategory.name %} + {% if segmentInCategory.unionOfSegments is defined and segmentInCategory.unionOfSegments %} + {% set title = 'SegmentEditor_SegmentXIsAUnionOf'|translate(title) %} + {% for unionSegment in segmentInCategory.unionOfSegments %} + {% set title = title ~ ' ' ~ unionSegment %} + {% if not loop.last %} + {% set title = title ~ ',' %} + {% endif %} + {% endfor %} + {% endif %} + <li data-metric="{{ segmentInCategory.segment }}" title="{{ title|e('html_attr') }}"><a class="ddmetric" href="#">{{ segmentInCategory.name }}</a></li> {% endfor %} </ul> </li> |