diff --git a/lang/en.json b/lang/en.json index 95556d3c8d7219761c3f8c4b4311c4fa4997b7b6..131b224b4032fe6c199e2209171b44568b77e3a1 100644 --- a/lang/en.json +++ b/lang/en.json @@ -87,6 +87,7 @@ "Continue": "Continue", "ContinueToPiwik": "Continue to Piwik", "CurrentlyUsingUnsecureHttp": "You are currently using Piwik over unsecure HTTP, which can be risky. We recommend you set up Piwik to use SSL (HTTPS) for improved security.", + "CreatedByUser": "created by %s", "CurrentMonth": "Current Month", "CurrentWeek": "Current Week", "CurrentYear": "Current Year", diff --git a/plugins/CoreHome/CoreHome.php b/plugins/CoreHome/CoreHome.php index ba0f3edd822b39f2e1253ffab590666d33de457a..52cfa2de5d28dd343ccc3b0ddb1681c0a483bc1b 100644 --- a/plugins/CoreHome/CoreHome.php +++ b/plugins/CoreHome/CoreHome.php @@ -278,5 +278,6 @@ class CoreHome extends \Piwik\Plugin $translationKeys[] = 'CoreHome_MenuEntries'; $translationKeys[] = 'SitesManager_Sites'; $translationKeys[] = 'CoreHome_ChangeCurrentWebsite'; + $translationKeys[] = 'General_CreatedByUser'; } } diff --git a/plugins/Dashboard/stylesheets/dashboard.less b/plugins/Dashboard/stylesheets/dashboard.less index b45398379c23d2dde397c57ee0ff6c76cc36cf69..26120e1abb0e114cd1b08ca459ef7be53679db8e 100644 --- a/plugins/Dashboard/stylesheets/dashboard.less +++ b/plugins/Dashboard/stylesheets/dashboard.less @@ -257,7 +257,7 @@ ul.widgetpreview-widgetlist, ul.widgetpreview-categorylist { - color: #5d5342; + color: @theme-color-text-light; list-style: none; font-size: 11px; line-height: 20px; @@ -318,7 +318,7 @@ div.widgetpreview-preview { font-weight: normal; padding-top: 10px; margin-left: 10px; - color: #5D5342; + color: @theme-color-text-light; list-style: none; font-size: 11px; line-height: 20px; diff --git a/plugins/SegmentEditor/API.php b/plugins/SegmentEditor/API.php index 358f0d2b3e25d83ec91e5924a8efe65d9b103fb5..ad4098775ccd5f4bad4cd552bb1dea816de11447 100644 --- a/plugins/SegmentEditor/API.php +++ b/plugins/SegmentEditor/API.php @@ -351,15 +351,52 @@ class API extends \Piwik\Plugin\API $userLogin = Piwik::getCurrentUserLogin(); $model = $this->getModel(); - if (empty($idSite)) { - $segments = $model->getAllSegments($userLogin); + if(Piwik::hasUserSuperUserAccess()) { + $segments = $model->getAllSegmentsForAllUsers($idSite); } else { - $segments = $model->getAllSegmentsForSite($idSite, $userLogin); + if (empty($idSite)) { + $segments = $model->getAllSegments($userLogin); + } else { + $segments = $model->getAllSegmentsForSite($idSite, $userLogin); + } } + $segments = $this->sortSegmentsCreatedByUserFirst($segments); + return $segments; } + /** + * Sorts segment in a particular order: + * + * 1) my segments + * 2) segments created by the super user that were shared with all users + * 3) segments created by other users (which are visible to all super users) + * + * @param $segments + * @return array + */ + private function sortSegmentsCreatedByUserFirst($segments) + { + $orderedSegments = array(); + foreach($segments as $id => &$segment) { + if($segment['login'] == Piwik::getCurrentUserLogin()) { + $orderedSegments[] = $segment; + unset($segments[$id]); + } + } + foreach($segments as $id => &$segment) { + if($segment['enable_all_users'] == 1) { + $orderedSegments[] = $segment; + unset($segments[$id]); + } + } + foreach($segments as $id => &$segment) { + $orderedSegments[] = $segment; + } + return $orderedSegments; + } + /** * @return string */ diff --git a/plugins/SegmentEditor/Model.php b/plugins/SegmentEditor/Model.php index 7f312557f97b4a378d0c143d8ae8fe06ab58abb4..7e73b6a1ab7c1b0b1d9bd02669a41075b190aaf7 100644 --- a/plugins/SegmentEditor/Model.php +++ b/plugins/SegmentEditor/Model.php @@ -98,6 +98,27 @@ class Model return $segments; } + /** + * This should be used _only_ by Super Users + * @param $idSite + * @return array + */ + public function getAllSegmentsForAllUsers($idSite = false) + { + $bind = array(); + $sqlWhereCondition = ''; + + if(!empty($idSite)) { + $bind = array($idSite); + $sqlWhereCondition = '(enable_only_idsite = ? OR enable_only_idsite = 0) AND'; + } + + $sqlWhereCondition = $this->buildQuerySortedByName($sqlWhereCondition . ' deleted = 0'); + $segments = $this->getDb()->fetchAll($sqlWhereCondition, $bind); + + return $segments; + } + public function deleteSegment($idSegment) { $db = $this->getDb(); diff --git a/plugins/SegmentEditor/SegmentEditor.php b/plugins/SegmentEditor/SegmentEditor.php index 0d7c84ed7a1768a30d8bd741bfc0fe5777c35542..1e6e4d3ec7f7beef3a3d84cba8ed75d891136957 100644 --- a/plugins/SegmentEditor/SegmentEditor.php +++ b/plugins/SegmentEditor/SegmentEditor.php @@ -88,5 +88,7 @@ class SegmentEditor extends \Piwik\Plugin public function getClientSideTranslationKeys(&$translationKeys) { $translationKeys[] = 'SegmentEditor_CustomSegment'; + $translationKeys[] = 'SegmentEditor_VisibleToSuperUser'; + $translationKeys[] = 'SegmentEditor_SharedWithYou'; } } diff --git a/plugins/SegmentEditor/javascripts/Segmentation.js b/plugins/SegmentEditor/javascripts/Segmentation.js index 2ffd7dac57b062d00d24029bbe42aabf6bf659a7..d47a83b4a16630ec3a513c011a1cd317b3def67a 100644 --- a/plugins/SegmentEditor/javascripts/Segmentation.js +++ b/plugins/SegmentEditor/javascripts/Segmentation.js @@ -80,14 +80,14 @@ Segmentation = (function($) { var currentDecoded = piwikHelper.htmlDecode(current); var selector = 'div.segmentList ul li[data-definition="'+currentDecoded+'"]'; var foundItems = $(selector, this.target); - var title = $('<strong></strong>'); + if( foundItems.length > 0) { - var name = $(foundItems).first().find("span.segname").text(); - title.text(name); + var idSegment = $(foundItems).first().attr('data-idsegment'); + var title = getSegmentName( getSegmentFromId(idSegment)); } else { - title.text(_pk_translate('SegmentEditor_CustomSegment')); + title = _pk_translate('SegmentEditor_CustomSegment'); } - segmentationTitle.html(title); + segmentationTitle.html( "<strong>" + title + "</strong>"); } else { $(this.content).find(".segmentationTitle").text(this.translations['SegmentEditor_DefaultAllVisits']); @@ -199,14 +199,42 @@ Segmentation = (function($) { var html = self.editorTemplate.find("> .listHtml").clone(); var segment, injClass; var listHtml = '<li data-idsegment="" ' + - (self.currentSegmentStr == "" ? " class='segmentSelected' " : "") - + ' data-definition=""><span class="segname">' + self.translations['SegmentEditor_DefaultAllVisits'] - + ' ' + self.translations['General_DefaultAppended'] - + '</span></li> '; + (self.currentSegmentStr == "" ? " class='segmentSelected' " : "") + + ' data-definition=""><span class="segname">' + self.translations['SegmentEditor_DefaultAllVisits'] + + ' ' + self.translations['General_DefaultAppended'] + + '</span></li> '; + + var isVisibleToSuperUserNoticeAlreadyDisplayedOnce = false; + var isVisibleToSuperUserNoticeShouldBeClosed = false; + + var isSharedWithMeBySuperUserNoticeAlreadyDisplayedOnce = false; + var isSharedWithMeBySuperUserNoticeShouldBeClosed = false; + if(self.availableSegments.length > 0) { + for(var i = 0; i < self.availableSegments.length; i++) { segment = self.availableSegments[i]; + + if(isSegmentSharedWithMeBySuperUser(segment) && !isSharedWithMeBySuperUserNoticeAlreadyDisplayedOnce) { + isSharedWithMeBySuperUserNoticeAlreadyDisplayedOnce = true; + isSharedWithMeBySuperUserNoticeShouldBeClosed = true; + listHtml += '<span class="segmentsSharedWithMeBySuperUser"><hr> ' + _pk_translate('SegmentEditor_SharedWithYou') + ':<br/><br/>'; + } + + if(isSegmentVisibleToSuperUserOnly(segment) && !isVisibleToSuperUserNoticeAlreadyDisplayedOnce) { + // close <span class="segmentsSharedWithMeBySuperUser"> + if(isSharedWithMeBySuperUserNoticeShouldBeClosed) { + isSharedWithMeBySuperUserNoticeShouldBeClosed = false; + listHtml += '</span>'; + } + + isVisibleToSuperUserNoticeAlreadyDisplayedOnce = true; + isVisibleToSuperUserNoticeShouldBeClosed = true; + listHtml += '<span class="segmentsVisibleToSuperUser"><hr> ' + _pk_translate('SegmentEditor_VisibleToSuperUser') + ':<br/><br/>'; + } + + injClass = ""; var checkSelected = segment.definition; if(!$.browser.mozilla) { @@ -217,12 +245,21 @@ Segmentation = (function($) { injClass = 'class="segmentSelected"'; } listHtml += '<li data-idsegment="'+segment.idsegment+'" data-definition="'+ (segment.definition).replace(/"/g, '"') +'" ' - +injClass+' title="'+segment.name+'"><span class="segname">'+segment.name+'</span>'; + +injClass+' title="'+ getSegmentTooltipEnrichedWithUsername(segment) +'"><span class="segname">'+getSegmentName(segment)+'</span>'; if(self.segmentAccess == "write") { listHtml += '<span class="editSegment" title="'+ self.translations['General_Edit'].toLocaleLowerCase() +'"></span>'; } listHtml += '</li>'; } + + if(isVisibleToSuperUserNoticeShouldBeClosed) { + listHtml += '</span>'; + } + + if(isSharedWithMeBySuperUserNoticeShouldBeClosed) { + listHtml += '</span>'; + } + $(html).find(".segmentList > ul").append(listHtml); if(self.segmentAccess === "write"){ $(html).find(".add_new_segment").html(self.translations['SegmentEditor_AddNewSegment']); @@ -238,20 +275,58 @@ Segmentation = (function($) { return html; }; + var isSegmentVisibleToSuperUserOnly = function(segment) { + return hasSuperUserAccessAndSegmentCreatedByAnotherUser(segment) + && segment.enable_all_users == 0; + }; + + var isSegmentSharedWithMeBySuperUser = function(segment) { + return segment.login != piwik.userLogin + && segment.enable_all_users == 1; + }; + + var hasSuperUserAccessAndSegmentCreatedByAnotherUser = function(segment) { + return piwik.hasSuperUserAccess && segment.login != piwik.userLogin; + }; + + var getSegmentTooltipEnrichedWithUsername = function(segment) { + var segmentName = segment.name; + if(hasSuperUserAccessAndSegmentCreatedByAnotherUser(segment)) { + segmentName += ' ('; + segmentName += _pk_translate('General_CreatedByUser', [segment.login]); + + if(segment.enable_all_users == 0) { + segmentName += ', ' + _pk_translate('SegmentEditor_VisibleToSuperUser'); + } + + segmentName += ')'; + } + return sanitiseSegmentName(segmentName); + }; + + var getSegmentName = function(segment) { + return sanitiseSegmentName(segment.name); + }; + + var sanitiseSegmentName = function(segment) { + segment = piwikHelper.escape(segment); + return segment; + } + var getFormHtml = function() { var html = self.editorTemplate.find("> .segment-element").clone(); // set left margin to center form var segmentsDropdown = $(html).find(".available_segments_select"); var segment, newOption; newOption = '<option data-idsegment="" data-definition="" title="' - + self.translations['SegmentEditor_AddNewSegment'] - + '">' + self.translations['SegmentEditor_AddNewSegment'] - + '</option>'; + + self.translations['SegmentEditor_AddNewSegment'] + + '">' + self.translations['SegmentEditor_AddNewSegment'] + + '</option>'; segmentsDropdown.append(newOption); for(var i = 0; i < self.availableSegments.length; i++) { segment = self.availableSegments[i]; - newOption = '<option data-idsegment="'+segment.idsegment+'" data-definition="'+(segment.definition).replace(/"/g, '"')+'" title="'+segment.name+'">'+segment.name+'</option>'; + newOption = '<option data-idsegment="'+segment.idsegment+'" data-definition="'+(segment.definition).replace(/"/g, '"')+'" title="'+getSegmentTooltipEnrichedWithUsername(segment)+'">'+getSegmentName(segment)+'</option>'; segmentsDropdown.append(newOption); } $(html).find(".segment-content > h3").after(getInitialStateRowsHtml()).show(); @@ -324,10 +399,15 @@ Segmentation = (function($) { var openEditForm = function(segment){ addForm("edit", segment); - $(self.form).find(".segment-content > h3 > span").text(segment.name); + $(self.form).find(".segment-content > h3 > span") + .html( getSegmentName(segment) ) + .prop('title', getSegmentTooltipEnrichedWithUsername(segment)); + $(self.form).find('.available_segments_select > option[data-idsegment="'+segment.idsegment+'"]').prop("selected",true); - $(self.form).find('.available_segments a.dropList').text(segment.name); + $(self.form).find('.available_segments a.dropList') + .html( getSegmentName(segment) ) + .prop( 'title', getSegmentTooltipEnrichedWithUsername(segment)); if(segment.definition != ""){ revokeInitialStateRows(); @@ -360,6 +440,13 @@ Segmentation = (function($) { $(self.target).find(".segmentList li:first") .before("<li class=\"filterNoResults grayed\">" + self.translations['General_SearchNoResults'] + "</li>"); } + + if ($(self.target).find(".segmentList .segmentsVisibleToSuperUser li:visible").length == 0) { + $(self.target).find(".segmentList .segmentsVisibleToSuperUser").hide(); + } + if ($(self.target).find(".segmentList .segmentsSharedWithMeBySuperUser li:visible").length == 0) { + $(self.target).find(".segmentList .segmentsSharedWithMeBySuperUser").hide(); + } } var clearFilterSegmentList = function () { @@ -367,6 +454,8 @@ Segmentation = (function($) { $(self.target).find(".segmentList li").each(function () { $(this).show(); }); + $(self.target).find(".segmentList .segmentsVisibleToSuperUser").show(); + $(self.target).find(".segmentList .segmentsSharedWithMeBySuperUser").show(); } var bindEvents = function () { @@ -407,15 +496,13 @@ Segmentation = (function($) { self.target.on("click", ".segmentList li", function (e) { if ($(e.currentTarget).hasClass("grayed") !== true) { - var segment = {}; - segment.idsegment = $(this).attr("data-idsegment"); - segment.definition = $(this).data("definition"); - segment.name = $(this).attr("title"); + var idsegment = $(this).attr("data-idsegment"); + segmentDefinition = $(this).data("definition"); - self.setSegment(segment.definition); + self.setSegment(segmentDefinition); self.markCurrentSegment(); - self.segmentSelectMethod( segment.definition ); - toggleLoadingMessage(segment.definition.length); + self.segmentSelectMethod( segmentDefinition ); + toggleLoadingMessage(segmentDefinition.length); } }); @@ -748,16 +835,9 @@ Segmentation = (function($) { }; function openEditFormGivenSegment(option) { - var segment = {}; - segment.idsegment = option.attr("data-idsegment"); - - var segmentExtra = getSegmentFromId(segment.idsegment); - for(var item in segmentExtra) - { - segment[item] = segmentExtra[item]; - } + var idsegment = option.attr("data-idsegment"); - segment.name = option.attr("title"); + var segment = getSegmentFromId(idsegment); segment.definition = option.data("definition"); @@ -815,7 +895,7 @@ Segmentation = (function($) { // 1 - do most obvious selection -> mark whole categories matching search string // also expand whole category $(self.form).find('.segment-nav div > ul > li').each( function(){ - curStr = normalizeSearchString($(this).find("a.metric_category").text()); + curStr = normalizeSearchString($(this).find("a.metric_category").text()); if(curStr.indexOf(search) > -1) { $(this).addClass("searchFound"); $(this).find("ul").show(); @@ -823,7 +903,7 @@ Segmentation = (function($) { $(this).show(); } } - ); + ); // 2 - among all unselected categories find metrics which match and mark parent as search result $(self.form).find(".segment-nav div > ul > li:not(.searchFound)").each(function(){ @@ -872,8 +952,8 @@ Segmentation = (function($) { } search = search.replace(/[^a-z0-9 -]/g, '') // remove invalid chars - .replace(/\s+/g, '_') // collapse whitespace and replace by underscore - .replace(/-+/g, '-'); // collapse dashes + .replace(/\s+/g, '_') // collapse whitespace and replace by underscore + .replace(/-+/g, '-'); // collapse dashes return search; }; @@ -900,7 +980,12 @@ Segmentation = (function($) { placeSegmentationFormControls(); if(mode == "edit") { - $(self.form).find('.enable_all_users_select > option[value="'+segment.enable_all_users+'"]').prop("selected",true); + var userSelector = $(self.form).find('.enable_all_users_select > option[value="' + segment.enable_all_users + '"]').prop("selected",true); + + // Replace "Visible to me" by "Visible to $login" when user is super user + if(hasSuperUserAccessAndSegmentCreatedByAnotherUser(segment)) { + $(self.form).find('.enable_all_users_select > option[value="' + 0 + '"]').text(segment.login); + } $(self.form).find('.visible_to_website_select > option[value="'+segment.enable_only_idsite+'"]').prop("selected",true); $(self.form).find('.auto_archive_select > option[value="'+segment.auto_archive+'"]').prop("selected",true); @@ -991,43 +1076,43 @@ Segmentation = (function($) { var makeDropList = function(spanId, selectId){ var select = $(self.form).find(selectId).hide(); var dropList = $( '<a class="dropList dropdown">' ) - .insertAfter( select ) - .text( select.children(':selected').text() ) - .autocomplete({ - delay: 0, - minLength: 0, - appendTo: "body", - source: function( request, response ) { - response( select.children( "option" ).map(function() { - var text = $( this ).text(); - return { - label: text, - value: this.value, - option: this - }; - }) ); - }, - select: function( event, ui ) { - event.preventDefault(); - ui.item.option.selected = true; - // Mark original select>option - $(spanId + ' option[value="' + ui.item.value + '"]', self.editorTemplate).prop('selected', true); - dropList.text(ui.item.label); - $(self.form).find(selectId).trigger("change"); - } - }) - .click(function() { - // close all other droplists made by this form - $("a.dropList").autocomplete("close"); - // close if already visible - if ( $(this).autocomplete( "widget" ).is(":visible") ) { - $(this).autocomplete("close"); - return; - } - // pass empty string as value to search for, displaying all results - $(this).autocomplete( "search", "" ); + .insertAfter( select ) + .text( select.children(':selected').text() ) + .autocomplete({ + delay: 0, + minLength: 0, + appendTo: "body", + source: function( request, response ) { + response( select.children( "option" ).map(function() { + var text = $( this ).text(); + return { + label: text, + value: this.value, + option: this + }; + }) ); + }, + select: function( event, ui ) { + event.preventDefault(); + ui.item.option.selected = true; + // Mark original select>option + $(spanId + ' option[value="' + ui.item.value + '"]', self.editorTemplate).prop('selected', true); + dropList.text(ui.item.label); + $(self.form).find(selectId).trigger("change"); + } + }) + .click(function() { + // close all other droplists made by this form + $("a.dropList").autocomplete("close"); + // close if already visible + if ( $(this).autocomplete( "widget" ).is(":visible") ) { + $(this).autocomplete("close"); + return; + } + // pass empty string as value to search for, displaying all results + $(this).autocomplete( "search", "" ); - }); + }); $('body').on('mouseup',function (e) { if (!$(e.target).parents(spanId).length && !$(e.target).is(spanId) @@ -1166,7 +1251,7 @@ $(document).ready(function() { } } - self.props.availableSegments[idx] = params; + $.extend( self.props.availableSegments[idx], params); self.rebuild(); self.impl.setSegment(params.definition); @@ -1222,8 +1307,8 @@ $(document).ready(function() { }; var segmentFromRequest = encodeURIComponent(self.props.selectedSegment) - || broadcast.getValueFromHash('segment') - || broadcast.getValueFromUrl('segment'); + || broadcast.getValueFromHash('segment') + || broadcast.getValueFromUrl('segment'); if($.browser.mozilla) { segmentFromRequest = decodeURIComponent(segmentFromRequest); } diff --git a/plugins/SegmentEditor/lang/en.json b/plugins/SegmentEditor/lang/en.json index 8651afeecd041ca1d6b2fb16831199028ac8341b..6e7861e0c0927a7abd6e1912a9b791fe4d8f6ddb 100644 --- a/plugins/SegmentEditor/lang/en.json +++ b/plugins/SegmentEditor/lang/en.json @@ -20,10 +20,12 @@ "SegmentIsDisplayedForWebsite": "and displayed for", "SegmentNotApplied": "Segment '%s' not applied", "SegmentNotAppliedMessage": "You are requesting data for the Custom Segment '%s', this Piwik configuration currently prevents real time processing of reports for performance reasons.", - "SelectSegmentOfVisitors": "Select a segment of visitors:", + "SelectSegmentOfVisits": "Select a segment of visits:", "ThisSegmentIsVisibleTo": "This segment is visible to:", "VisibleToAllUsers": "all users", "VisibleToMe": "me", + "VisibleToSuperUser": "Visible to you because you have Super User access", + "SharedWithYou": "Shared with you", "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.", diff --git a/plugins/SegmentEditor/stylesheets/segmentation.less b/plugins/SegmentEditor/stylesheets/segmentation.less index 125a0c9f5639a22819afcd412ddd28de719adf2f..705c4ec2f9d8a6be790bea57cd35335fea8f0438 100644 --- a/plugins/SegmentEditor/stylesheets/segmentation.less +++ b/plugins/SegmentEditor/stylesheets/segmentation.less @@ -174,7 +174,7 @@ div.scrollable { } .segment-element .segment-nav div > ul > li a { - color: #5d5342; + color: @theme-color-text-light; font-size: 11px; font-weight: bold; text-decoration: none; @@ -454,7 +454,7 @@ div.scrollable { } .segmentationContainer .submenu ul { - color: #5D5342; + color: @theme-color-text-light; float: none; font-size: 11px; font-weight: normal; @@ -572,7 +572,7 @@ body > a.ddmetric { cursor: move; padding: 1px 0 2px 18px; background: #eae8e3 url(plugins/SegmentEditor/images/segment-move.png) 100% 50% no-repeat; - color: #5d5342; + color: @theme-color-text-light; font-weight: normal; font-size: 11px; text-decoration: none; @@ -759,3 +759,11 @@ a.metric_category { display: inline-block; vertical-align: sub; } + +.segmentsVisibleToSuperUser, .segmentsSharedWithMeBySuperUser { + font-style: italic; + + li { + font-style: normal; + } +} diff --git a/plugins/SegmentEditor/templates/_segmentSelector.twig b/plugins/SegmentEditor/templates/_segmentSelector.twig index 18c885919ac251c00fe4a88e7fc7eee1b5d339b6..c853f5211afa2b04dbf939fcdfcd0609cd03f40c 100644 --- a/plugins/SegmentEditor/templates/_segmentSelector.twig +++ b/plugins/SegmentEditor/templates/_segmentSelector.twig @@ -7,7 +7,7 @@ <span/> </div> <ul class="submenu"> - <li>{{ 'SegmentEditor_SelectSegmentOfVisitors'|translate }} + <li>{{ 'SegmentEditor_SelectSegmentOfVisits'|translate }} <div class="segmentList"> <ul> </ul> diff --git a/plugins/SegmentEditor/tests/Integration/ApiTest.php b/plugins/SegmentEditor/tests/Integration/ApiTest.php new file mode 100644 index 0000000000000000000000000000000000000000..c58ec7a8cd6e3d224a2afae2969556ae1687b703 --- /dev/null +++ b/plugins/SegmentEditor/tests/Integration/ApiTest.php @@ -0,0 +1,221 @@ +<?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\SegmentEditor\tests\Integration; + +use Piwik\Plugins\SegmentEditor\API; +use Piwik\Tests\Framework\Fixture; +use Piwik\Tests\Framework\Mock\FakeAccess; +use Piwik\Tests\Framework\TestCase\IntegrationTestCase; + +/** + * @group SegmentEditor + * @group ApiTest + * @group Plugins + */ +class ApiTest extends IntegrationTestCase +{ + /** + * @var API + */ + private $api; + + public function setUp() + { + parent::setUp(); + + $this->api = API::getInstance(); + + Fixture::createSuperUser(); + if (!Fixture::siteCreated(1)) { + Fixture::createWebsite('2012-01-01 00:00:00'); + } + if (!Fixture::siteCreated(2)) { + Fixture::createWebsite('2012-01-01 00:00:00'); + } + + } + + public function test_getAll_forOneWebsite_returnsSortedSegments() + { + $this->createAdminUser(); + $this->createSegments(); + $this->setAdminUser(); + + $expectedOrder = array( + // 1) my segments + 'segment 1', + 'segment 3', + 'segment 7', + + // 2) segments created by a super user that were shared with all users + 'segment 5', + 'segment 9', + + // 3) segments created by other users (which are visible to all super users) + // not a super user, so can't see those + ); + + $segments = $this->api->getAll($idSite = 1); + $segmentNames = $this->getNamesFromSegments($segments); + $this->assertSame($expectedOrder, $segmentNames); + } + + public function test_getAll_forAllWebsites_returnsSortedSegments() + { + $this->createAdminUser(); + $this->createSegments(); + $this->setAdminUser(); + + $expectedOrder = array( + // 1) my segments + 'segment 1', + 'segment 2', + 'segment 3', + 'segment 7', + + // 2) segments created by a super user that were shared with all users + 'segment 5', + 'segment 6', + 'segment 9', + + // 3) segments created by other users (which are visible to all super users) + // not a super user, so can't see those + ); + + $segments = $this->api->getAll(); + $segmentNames = $this->getNamesFromSegments($segments); + $this->assertSame($expectedOrder, $segmentNames); + } + + public function test_getAll_forAllWebsites_returnsSortedSegments_asSuperUser() + { + $this->createAdminUser(); + $this->createSegments(); + $this->setAnotherSuperUser(); + + $expectedOrder = array( + // 1) my segments + 'segment 9', + + // 2) segments created by a super user that were shared with all users + 'segment 5', + 'segment 6', + + // 3) segments created by other users (which are visible to all super users) + 'segment 1', + 'segment 2', + 'segment 3', + 'segment 4', + 'segment 7', + 'segment 8', + ); + + $segments = $this->api->getAll(); + $segmentNames = $this->getNamesFromSegments($segments); + $this->assertSame($expectedOrder, $segmentNames); + } + + public function test_getAll_forOneWebsite_returnsSortedSegments_asSuperUser() + { + $this->createAdminUser(); + $this->createSegments(); + $this->setAnotherSuperUser(); + + $expectedOrder = array( + // 1) my segments + 'segment 9', + + // 2) segments created by a super user that were shared with all users + 'segment 5', + + // 3) segments created by other users (which are visible to all super users) + 'segment 1', + 'segment 3', + 'segment 4', + 'segment 7', + 'segment 8', + ); + + $segments = $this->api->getAll($idSite = 1); + $segmentNames = $this->getNamesFromSegments($segments); + $this->assertSame($expectedOrder, $segmentNames); + } + + /** + * @return bool|int + */ + protected function createSegments() + { + $this->setAdminUser(); + $this->api->add('segment 1', 'visitCount<2', $idSite = 1, $autoArchive = true, $enableAllUsers = false); + $this->api->add('segment 2', 'countryCode==fr', $idSite = 2, $autoArchive = false, $enableAllUsers = false); + $this->api->add('segment 3', 'visitCount<2', $idSite = 1, $autoArchive = true, $enableAllUsers = false); + + $this->setSuperUser(); + $this->api->add('segment 4', 'countryCode!=fr', $idSite = false, $autoArchive = false, $enableAllUsers = false); + $this->api->add('segment 5', 'countryCode!=fr', $idSite = 1, $autoArchive = false, $enableAllUsers = true); + $this->api->add('segment 6', 'visitCount<2', $idSite = 2, $autoArchive = true, $enableAllUsers = true); + + $this->setAdminUser(); + $this->api->add('segment 7', 'visitCount<2', $idSite = 1, $autoArchive = true, $enableAllUsers = false); + + $this->setAnotherAdminUser(); + $this->api->add('segment 8', 'visitCount<2', $idSite = 1, $autoArchive = true, $enableAllUsers = false); + + $this->setAnotherSuperUser(); + $this->api->add('segment 9', 'countryCode!=fr', $idSite = false, $autoArchive = false, $enableAllUsers = true); + + } + + protected function setSuperUser($userName = 'superUserLogin') + { + FakeAccess::clearAccess($superUser = true, $idSitesAdmin = array(), $idSitesView = array(), $userName); + } + + protected function setAnotherSuperUser() + { + $this->setSuperUser('anotherSuperUser'); + } + + protected function setAdminUser($userName = 'myUserLogin') + { + FakeAccess::clearAccess($superUser = false, $idSitesAdmin = array(1,2), $idSitesView = array(1,2), $userName); + } + + protected function setAnotherAdminUser() + { + $this->setAdminUser('anotherUserWithAdmin'); + } + + public function provideContainerConfig() + { + return array( + 'Piwik\Access' => new FakeAccess() + ); + } + + protected function createAdminUser() + { + \Piwik\Plugins\UsersManager\API::getInstance()->addUser('myUserLogin', 'password', 'test@test.com'); + } + + /** + * @param $segments + * @return array + */ + protected function getNamesFromSegments($segments) + { + $segmentNames = array(); + foreach ($segments as $segment) { + $segmentNames[] = $segment['name']; + } + return $segmentNames; + } + +} diff --git a/tests/PHPUnit/Framework/Fixture.php b/tests/PHPUnit/Framework/Fixture.php index 3f66bd3a76cdfcc9632c3f6eaad98e377580694b..9ef26bbb6795c41cd6a57a494de61f9f0c9aead9 100644 --- a/tests/PHPUnit/Framework/Fixture.php +++ b/tests/PHPUnit/Framework/Fixture.php @@ -612,6 +612,7 @@ class Fixture extends \PHPUnit_Framework_Assert self::assertEquals($expectedResponse, $response, "Expected GIF beacon, got: <br/>\n" . var_export($response, true) . "\n If you are stuck, you can enable [Tracker] debug=1; in config.ini.php to get more debug info." + . "\n\n Also, please try to restart your webserver, and run the test again, this may help!" . base64_encode($response) . $url );