diff --git a/core/Segment.php b/core/Segment.php index 01e056bf68f4c823a5caada04f9372c354092bd0..e12b165028c1290bb0679243119f23cb5ade9d42 100644 --- a/core/Segment.php +++ b/core/Segment.php @@ -451,4 +451,14 @@ class Segment $query = $this->buildSelectQuery($select, $from, $where, $orderBy, $groupBy); return $query; } -} + + /** + * Returns the segment string. + * + * @return string + */ + public function __toString() + { + return (string) $this->getString(); + } +} \ 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 62625642488c0817c85a55e31590e8dd3e16be2a..d92bf0436c3bff20cb75dab3150b4cf007f2f117 100644 --- a/plugins/CoreHome/angularjs/common/services/piwik-api.js +++ b/plugins/CoreHome/angularjs/common/services/piwik-api.js @@ -37,11 +37,33 @@ angular.module('piwikApp.service').factory('piwikApi', function ($http, $q, $roo postParams = {}; } + function isErrorResponse(response) { + return response && response.result == 'error'; + } + + function createResponseErrorNotification(response, options) { + if (response.message) { + var UI = require('piwik/UI'); + var notification = new UI.Notification(); + notification.show(response.message, { + context: 'error', + type: 'toast', + id: 'ajaxHelper', + placeat: options.placeat + }); + notification.scrollToNotification(); + } + } + /** * Send the request * @return $promise */ - function send () { + function send (options) { + if (!options) { + options = {}; + } + var deferred = $q.defer(), requestPromise = deferred.promise; @@ -50,21 +72,10 @@ angular.module('piwikApp.service').factory('piwikApi', function ($http, $q, $roo }; var onSuccess = function (response) { - if (response && response.result == 'error') { - if (response.message) { - onError(response.message); - - var UI = require('piwik/UI'); - var notification = new UI.Notification(); - notification.show(response.message, { - context: 'error', - type: 'toast', - id: 'ajaxHelper' - }); - notification.scrollToNotification(); - } else { - onError(null); - } + if (isErrorResponse(response)) { + onError(response.message || null); + + createResponseErrorNotification(response, options); } else { deferred.resolve(response); } @@ -189,26 +200,26 @@ angular.module('piwikApp.service').factory('piwikApi', function ($http, $q, $roo * Perform a reading API request. * @param getParams */ - piwikApi.fetch = function (getParams) { + piwikApi.fetch = function (getParams, options) { getParams.module = getParams.module || 'API'; getParams.format = 'JSON2'; addParams(getParams, 'GET'); - var promise = send(); + var promise = send(options); reset(); return promise; }; - piwikApi.post = function (getParams, _postParams_) { + piwikApi.post = function (getParams, _postParams_, options) { if (_postParams_) { postParams = _postParams_; } - return this.fetch(getParams); + return this.fetch(getParams, options); }; /** @@ -216,22 +227,41 @@ angular.module('piwikApp.service').factory('piwikApi', function ($http, $q, $roo * Bulk requests allow you to execute multiple Piwik requests with one HTTP request. * * @param {object[]} requests + * @param {object} options * @return {HttpPromise} a promise that is resolved when the request finishes. The argument passed * to the .then(...) callback will be an array with one element per request * made. */ - piwikApi.bulkFetch = function (requests) { + piwikApi.bulkFetch = function (requests, options) { var bulkApiRequestParams = { urls: requests.map(function (requestObj) { return '?' + $.param(requestObj); }) }; - return this.post({method: "API.getBulkRequest"}, bulkApiRequestParams).then(function (response) { - if (!(response instanceof Array)) { - response = [response]; - } + var deferred = $q.defer(), + requestPromise = this.post({method: "API.getBulkRequest"}, bulkApiRequestParams, options).then(function (response) { + if (!(response instanceof Array)) { + response = [response]; + } - return response; - }); + // check for errors + for (var i = 0; i != response.length; ++i) { + var specificResponse = response[i]; + + if (isErrorResponse(specificResponse)) { + deferred.reject(specificResponse.message || null); + + createResponseErrorNotification(specificResponse, options || {}); + + return; + } + } + + deferred.resolve(response); + }).catch(function () { + deferred.reject.apply(deferred, arguments); + }); + + return deferred.promise; }; return piwikApi; diff --git a/plugins/CoreHome/angularjs/common/services/piwik-api_spec.js b/plugins/CoreHome/angularjs/common/services/piwik-api_spec.js index 803cfa30e7a5e1cdd3246046e6d50a53dda2a6d8..6e49c14ed1e06dfc71e574dc7d9533a2642c4a4d 100644 --- a/plugins/CoreHome/angularjs/common/services/piwik-api_spec.js +++ b/plugins/CoreHome/angularjs/common/services/piwik-api_spec.js @@ -9,8 +9,14 @@ describe('piwikApiClient', function () { var piwikApi, $httpBackend; - function extendHttpBackendMock($httpBackend) { - return $httpBackend; + if (!window.piwik) window.piwik = {}; + if (!window.piwik.UI) window.piwik.UI = {}; + if (!window.piwik.UI.Notification) { + window.piwik.UI.Notification = function () { + this.show = function () {}; + this.scrollToNotification = function () {}; + return this; + }; } beforeEach(module('piwikApp.service')); @@ -19,6 +25,15 @@ describe('piwikApiClient', function () { $httpBackend = $injector.get('$httpBackend'); + $httpBackend.when('POST', /.*getBulkRequest.*/, /.*errorAction.*/).respond(function (method, url, data, headers) { + url = url.replace(/date=[^&]+/, "date="); + + var errorResponse = {result: 'error', message: "error message"}, + successResponse= "Response #2: " + url + " - " + data; + + return [200, [errorResponse, successResponse]]; + }); + $httpBackend.when('POST', /.*getBulkRequest.*/).respond(function (method, url, data, headers) { url = url.replace(/date=[^&]+/, "date="); @@ -222,4 +237,42 @@ describe('piwikApiClient', function () { $httpBackend.flush(); }); + + it("should correctly handle errors in a bulk request response", function (done) { + piwikApi.bulkFetch([ + { + method: "SomePlugin.errorAction" + }, + { + method: "SomeOtherPlugin.whatever" + } + ]).then(function (response) { + done(new Error("promise resolved after bulkFetch request returned an error (response = " + JSON.stringify(response) + ")")); + }).catch(function (error) { + expect(error).to.equal("error message"); + + done(); + }); + + $httpBackend.flush(); + }); + + it("shuld correctly handle errors in a bulk request response, regardless of error location", function (done) { + piwikApi.bulkFetch([ + { + method: "SomeOtherPlugin.whatever" + }, + { + method: "SomePlugin.errorAction" + } + ]).then(function (response) { + done(new Error("promise resolved after bulkFetch request returned an error (response = " + JSON.stringify(response) + ")")); + }).catch(function (error) { + expect(error).to.equal("error message"); + + done(); + }); + + $httpBackend.flush(); + }); }); \ No newline at end of file diff --git a/plugins/CoreHome/angularjs/dialogtoggler/dialogtoggler-urllistener-service.js b/plugins/CoreHome/angularjs/dialogtoggler/dialogtoggler-urllistener-service.js index c1f07e2b829856a3dee594bfaa680c7590a3980c..dc8be42323a67e8f697636d8aa3ea1b88c995351 100644 --- a/plugins/CoreHome/angularjs/dialogtoggler/dialogtoggler-urllistener-service.js +++ b/plugins/CoreHome/angularjs/dialogtoggler/dialogtoggler-urllistener-service.js @@ -52,13 +52,11 @@ angular.module('piwikApp').factory('piwikDialogtogglerUrllistener', function ($r service.checkUrlForDialog = function () { var dialogParamValue = $location.search()[dialogQueryParamName]; - if (dialogParamValue - && directiveExists(dialogParamValue) - ) { + if (dialogParamValue && directiveExists(dialogParamValue)) { var dialog = ngDialog.open({ template: getHtmlFromDialogQueryParam(dialogParamValue), plain: true, - className: ''//'ngdialog-theme-default' + className: '' }); dialog.closePromise.then(function () {