update Piwik to version 2.16 (fixes #91)

This commit is contained in:
oliver 2016-04-10 18:55:57 +02:00
commit d885a4baa9
5833 changed files with 418860 additions and 226988 deletions

View file

@ -0,0 +1,29 @@
/*!
* Piwik - free/libre analytics platform
*
* @link http://piwik.org
* @license http://www.gnu.org/licenses/gpl-3.0.html GPL v3 or later
*/
(function () {
// can probably be shared
angular.module('piwikApp').factory('coreAPI', CoreAPIFactory);
CoreAPIFactory.$inject = ['sitesManagerApiHelper'];
function CoreAPIFactory(api) {
return {
getIpFromHeader: getIpFromHeader(),
isPluginActivated: isPluginActivated()
};
function getIpFromHeader() {
return api.fetchApi('API.getIpFromHeader', api.valueAdaptor);
}
function isPluginActivated() {
return api.fetchApi('API.isPluginActivated', api.valueAdaptor);
}
}
})();

View file

@ -0,0 +1,74 @@
/*!
* Piwik - free/libre analytics platform
*
* @link http://piwik.org
* @license http://www.gnu.org/licenses/gpl-3.0.html GPL v3 or later
*/
(function () {
// can probably be renamed and shared
angular.module('piwikApp').factory('sitesManagerApiHelper', SitesManagerAPIHelperFactory);
SitesManagerAPIHelperFactory.$inject = ['piwikApi'];
function SitesManagerAPIHelperFactory(piwikApi) {
return {
fetch: fetch,
commaDelimitedFieldToArray: commaDelimitedFieldToArray,
fetchApi: fetchApi,
fetchAction: fetchAction,
singleObjectAdaptor: singleObjectAdaptor,
valueAdaptor: valueAdaptor,
noop: noop
};
function fetch (endpoint, jsonResponseAdaptor, params) {
return function (clientHandover, additionalParams) {
params = angular.extend(params || {}, additionalParams || {});
var requestDefinition = angular.extend(endpoint, params);
var responseHandler = function (response) {
response = jsonResponseAdaptor(response);
clientHandover(response);
};
piwikApi.fetch(requestDefinition).then(responseHandler);
};
}
function commaDelimitedFieldToArray (value) {
if(!value)
return [];
return value.split(',');
}
function fetchApi(apiMethod, jsonResponseAdaptor, params) {
return fetch({method: apiMethod}, jsonResponseAdaptor, params);
}
function fetchAction(module, action, jsonResponseAdaptor, params) {
return fetch({module: module, action: action}, jsonResponseAdaptor, params);
}
function singleObjectAdaptor(response) {
return response[0];
}
function valueAdaptor(response) {
return response.value;
}
function noop(response) {
return response;
}
}
})();

View file

@ -0,0 +1,44 @@
/*!
* Piwik - free/libre analytics platform
*
* @link http://piwik.org
* @license http://www.gnu.org/licenses/gpl-3.0.html GPL v3 or later
*/
(function () {
angular.module('piwikApp').factory('sitesManagerAPI', SitesManagerAPIFactory);
SitesManagerAPIFactory.$inject = ['sitesManagerApiHelper'];
function SitesManagerAPIFactory(api) {
return {
getCurrencyList: getCurrencyList(),
getTimezonesList: getTimezonesList(),
isTimezoneSupportEnabled: isTimezoneSupportEnabled(),
getGlobalSettings: getGlobalSettings(),
getSitesIdWithAdminAccess: getSitesIdWithAdminAccess()
};
function getSitesIdWithAdminAccess () {
return api.fetchApi('SitesManager.getSitesIdWithAdminAccess', api.noop, {
filter_limit: '-1',
});
}
function getCurrencyList () {
return api.fetchApi('SitesManager.getCurrencyList', api.noop);
}
function getTimezonesList () {
return api.fetchApi('SitesManager.getTimezonesList', api.noop);
}
function isTimezoneSupportEnabled () {
return api.fetchApi('SitesManager.isTimezoneSupportEnabled', api.valueAdaptor);
}
function getGlobalSettings () {
return api.fetchAction('SitesManager', 'getGlobalSettings', api.noop);
}
}
})();

View file

@ -0,0 +1,30 @@
/*!
* Piwik - free/libre analytics platform
*
* @link http://piwik.org
* @license http://www.gnu.org/licenses/gpl-3.0.html GPL v3 or later
*/
(function () {
angular.module('piwikApp').directive('sitesManagerEditTrigger', sitesManagerEditTrigger);
function sitesManagerEditTrigger() {
return {
restrict: 'A',
link: function (scope, element) {
element.bind('click', function(){
if(!scope.site.editMode)
scope.$apply(scope.editSite());
});
scope.$watch('site.editMode', function() {
element.toggleClass('editable-site-field', !scope.site.editMode);
});
}
};
}
})();

View file

@ -0,0 +1,7 @@
<textarea
cols="{{ cols }}"
rows="{{ rows }}"
ng-model="field.value"
ng-change="onChange()">
</textarea>

View file

@ -0,0 +1,49 @@
/*!
* Piwik - free/libre analytics platform
*
* @link http://piwik.org
* @license http://www.gnu.org/licenses/gpl-3.0.html GPL v3 or later
*/
(function () {
angular.module('piwikApp').directive('sitesManagerMultilineField', sitesManagerMultilineField);
function sitesManagerMultilineField() {
return {
restrict: 'A',
replace: true,
scope: {
managedValue: '=field',
rows: '@?',
cols: '@?'
},
templateUrl: 'plugins/SitesManager/angularjs/sites-manager/multiline-field.directive.html?cb=' + piwik.cacheBuster,
link: function (scope) {
var separator = '\n';
var init = function () {
scope.field = {};
scope.onChange = updateManagedScopeValue;
scope.$watch('managedValue', updateInputValue);
};
var updateManagedScopeValue = function () {
scope.managedValue = scope.field.value.trim().split(separator);
};
var updateInputValue = function () {
if(angular.isUndefined(scope.managedValue))
return;
scope.field.value = scope.managedValue.join(separator);
};
init();
}
};
}
})();

View file

@ -0,0 +1,115 @@
/**
* Model for Sites Manager. Fetches only sites one has at least Admin permission.
*/
(function () {
angular.module('piwikApp').factory('sitesManagerAdminSitesModel', sitesManagerAdminSitesModel);
sitesManagerAdminSitesModel.$inject = ['piwikApi'];
function sitesManagerAdminSitesModel(piwikApi)
{
var model = {
sites : [],
searchTerm : '',
isLoading : false,
pageSize : 10,
currentPage : 0,
offsetStart : 0,
offsetEnd : 10,
hasPrev : false,
hasNext : false,
previousPage: previousPage,
nextPage: nextPage,
searchSite: searchSite,
fetchLimitedSitesWithAdminAccess: fetchLimitedSitesWithAdminAccess
};
return model;
function onError ()
{
setSites([]);
}
function setSites(sites)
{
model.sites = sites;
var numSites = sites.length;
model.offsetStart = model.currentPage * model.pageSize;
model.offsetEnd = model.offsetStart + numSites;
model.hasPrev = model.currentPage >= 1;
model.hasNext = numSites === model.pageSize;
}
function setCurrentPage(page)
{
if (page < 0) {
page = 0;
}
model.currentPage = page;
}
function previousPage()
{
setCurrentPage(model.currentPage - 1);
fetchLimitedSitesWithAdminAccess();
}
function nextPage()
{
setCurrentPage(model.currentPage + 1);
fetchLimitedSitesWithAdminAccess();
}
function searchSite (term)
{
model.searchTerm = term;
setCurrentPage(0);
fetchLimitedSitesWithAdminAccess();
}
function fetchLimitedSitesWithAdminAccess(callback)
{
if (model.isLoading) {
piwikApi.abort();
}
model.isLoading = true;
var limit = model.pageSize;
var offset = model.currentPage * model.pageSize;
var params = {
method: 'SitesManager.getSitesWithAdminAccess',
fetchAliasUrls: true,
limit: limit + offset, // this is applied in SitesManager.getSitesWithAdminAccess API
filter_offset: offset, // filter_offset and filter_limit is applied in response builder
filter_limit: limit
};
if (model.searchTerm) {
params.pattern = model.searchTerm;
}
return piwikApi.fetch(params).then(function (sites) {
if (!sites) {
onError();
return;
}
setSites(sites);
}, onError)['finally'](function () {
if (callback) {
callback();
}
model.isLoading = false;
});
}
}
})();

View file

@ -0,0 +1,193 @@
/*!
* Piwik - free/libre analytics platform
*
* @link http://piwik.org
* @license http://www.gnu.org/licenses/gpl-3.0.html GPL v3 or later
*/
(function () {
angular.module('piwikApp').controller('SitesManagerSiteController', SitesManagerSiteController);
SitesManagerSiteController.$inject = ['$scope', '$filter', 'sitesManagerApiHelper', 'sitesManagerTypeModel'];
function SitesManagerSiteController($scope, $filter, sitesManagerApiHelper, sitesManagerTypeModel) {
var translate = $filter('translate');
var init = function () {
initModel();
initActions();
sitesManagerTypeModel.fetchTypeById($scope.site.type).then(function (type) {
if (type) {
$scope.currentType = type;
$scope.howToSetupUrl = type.howToSetupUrl;
$scope.isInternalSetupUrl = '?' === ('' + type.howToSetupUrl).substr(0, 1);
} else {
$scope.currentType = {name: $scope.site.type};
}
});
};
var initActions = function () {
$scope.editSite = editSite;
$scope.saveSite = saveSite;
$scope.openDeleteDialog = openDeleteDialog;
$scope.site['delete'] = deleteSite;
};
var initModel = function() {
if(siteIsNew())
initNewSite();
else
initExistingSite();
$scope.site.editDialog = {};
$scope.site.removeDialog = {};
};
var editSite = function () {
if ($scope.siteIsBeingEdited) {
$scope.site.editDialog.show = true;
$scope.site.editDialog.title = translate('SitesManager_OnlyOneSiteAtTime', '"' + $scope.lookupCurrentEditSite().name + '"');
} else {
$scope.site.editMode = true;
$scope.informSiteIsBeingEdited();
}
};
var saveSite = function() {
var sendSiteSearchKeywordParams = $scope.site.sitesearch == '1' && !$scope.site.useDefaultSiteSearchParams;
var sendSearchCategoryParameters = sendSiteSearchKeywordParams && $scope.customVariablesActivated;
var ajaxHandler = new ajaxHelper();
ajaxHandler.addParams({
module: 'API',
format: 'json'
}, 'GET');
if(siteIsNew()) {
ajaxHandler.addParams({
method: 'SitesManager.addSite'
}, 'GET');
} else {
ajaxHandler.addParams({
idSite: $scope.site.idsite,
method: 'SitesManager.updateSite'
}, 'GET');
}
var settings = $('.typeSettings fieldset').serializeArray();
var flatSettings = '';
if (settings.length) {
flatSettings = {};
angular.forEach(settings, function (setting) {
flatSettings[setting.name] = setting.value;
});
}
ajaxHandler.addParams({
siteName: $scope.site.name,
timezone: $scope.site.timezone,
currency: $scope.site.currency,
ecommerce: $scope.site.ecommerce,
excludedIps: $scope.site.excluded_ips.join(','),
excludedQueryParameters: $scope.site.excluded_parameters.join(','),
excludedUserAgents: $scope.site.excluded_user_agents.join(','),
keepURLFragments: $scope.site.keep_url_fragment,
siteSearch: $scope.site.sitesearch,
type: $scope.site.type,
searchKeywordParameters: sendSiteSearchKeywordParams ? $scope.site.sitesearch_keyword_parameters.join(',') : null,
searchCategoryParameters: sendSearchCategoryParameters ? $scope.site.sitesearch_category_parameters.join(',') : null,
urls: $scope.site.alias_urls,
excludeUnknownUrls: $scope.site.exclude_unknown_urls,
settings: flatSettings
}, 'POST');
ajaxHandler.redirectOnSuccess($scope.redirectParams);
ajaxHandler.setLoadingElement();
ajaxHandler.send(true);
};
var siteIsNew = function() {
return angular.isUndefined($scope.site.idsite);
};
var initNewSite = function() {
$scope.informSiteIsBeingEdited();
$scope.site.editMode = true;
$scope.site.name = "Name";
$scope.site.alias_urls = [
"http://siteUrl.com/",
"http://siteUrl2.com/"
];
$scope.site.exclude_unknown_urls = 0;
$scope.site.keep_url_fragment = "0";
$scope.site.excluded_ips = [];
$scope.site.excluded_parameters = [];
$scope.site.excluded_user_agents = [];
$scope.site.sitesearch_keyword_parameters = [];
$scope.site.sitesearch_category_parameters = [];
$scope.site.sitesearch = $scope.globalSettings.searchKeywordParametersGlobal.length ? "1" : "0";
$scope.site.timezone = $scope.globalSettings.defaultTimezone;
$scope.site.currency = $scope.globalSettings.defaultCurrency;
$scope.site.ecommerce = "0";
updateSiteWithSiteSearchConfig();
};
var initExistingSite = function() {
$scope.site.excluded_ips = sitesManagerApiHelper.commaDelimitedFieldToArray($scope.site.excluded_ips);
$scope.site.excluded_parameters = sitesManagerApiHelper.commaDelimitedFieldToArray($scope.site.excluded_parameters);
$scope.site.excluded_user_agents = sitesManagerApiHelper.commaDelimitedFieldToArray($scope.site.excluded_user_agents);
$scope.site.sitesearch_keyword_parameters = sitesManagerApiHelper.commaDelimitedFieldToArray($scope.site.sitesearch_keyword_parameters);
$scope.site.sitesearch_category_parameters = sitesManagerApiHelper.commaDelimitedFieldToArray($scope.site.sitesearch_category_parameters);
updateSiteWithSiteSearchConfig();
};
var updateSiteWithSiteSearchConfig = function() {
$scope.site.useDefaultSiteSearchParams =
$scope.globalSettings.searchKeywordParametersGlobal.length && !$scope.site.sitesearch_keyword_parameters.length;
};
var openDeleteDialog = function() {
$scope.site.removeDialog.title = translate('SitesManager_DeleteConfirm', '"' + $scope.site.name + '" (idSite = ' + $scope.site.idsite + ')');
$scope.site.removeDialog.show = true;
};
var deleteSite = function() {
var ajaxHandler = new ajaxHelper();
ajaxHandler.addParams({
idSite: $scope.site.idsite,
module: 'API',
format: 'json',
method: 'SitesManager.deleteSite'
}, 'GET');
ajaxHandler.redirectOnSuccess($scope.redirectParams);
ajaxHandler.setLoadingElement();
ajaxHandler.send(true);
};
init();
}
})();

View file

@ -0,0 +1,52 @@
/**
* Model for Sites Manager. Fetches only sites one has at least Admin permission.
*/
(function () {
angular.module('piwikApp').factory('sitesManagerTypeModel', sitesManagerTypeModel);
sitesManagerTypeModel.$inject = ['piwikApi'];
function sitesManagerTypeModel(piwikApi)
{
var typesPromise = null;
var model = {
typesById: {},
fetchTypeById: fetchTypeById,
fetchAvailableTypes: fetchAvailableTypes,
hasMultipleTypes: hasMultipleTypes
};
return model;
function hasMultipleTypes(typeId)
{
return fetchAvailableTypes().then(function (types) {
return types && types.length > 1;
});
}
function fetchTypeById(typeId)
{
return fetchAvailableTypes().then(function () {
return model.typesById[typeId];
});
}
function fetchAvailableTypes()
{
if (!typesPromise) {
typesPromise = piwikApi.fetch({method: 'API.getAvailableMeasurableTypes'}).then(function (types) {
angular.forEach(types, function (type) {
model.typesById[type.id] = type;
});
return types;
});
}
return typesPromise;
}
}
})();

View file

@ -0,0 +1,283 @@
/*!
* Piwik - free/libre analytics platform
*
* @link http://piwik.org
* @license http://www.gnu.org/licenses/gpl-3.0.html GPL v3 or later
*/
(function () {
angular.module('piwikApp').controller('SitesManagerController', SitesManagerController);
SitesManagerController.$inject = ['$scope', '$filter', 'coreAPI', 'sitesManagerAPI', 'piwikApi', 'sitesManagerAdminSitesModel', 'piwik', 'sitesManagerApiHelper', 'sitesManagerTypeModel'];
function SitesManagerController($scope, $filter, coreAPI, sitesManagerAPI, piwikApi, adminSites, piwik, sitesManagerApiHelper, sitesManagerTypeModel) {
var translate = $filter('translate');
var init = function () {
$scope.period = piwik.broadcast.getValueFromUrl('period');
$scope.date = piwik.broadcast.getValueFromUrl('date');
$scope.adminSites = adminSites;
$scope.hasSuperUserAccess = piwik.hasSuperUserAccess;
$scope.redirectParams = {showaddsite: false};
$scope.siteIsBeingEdited = false;
$scope.cacheBuster = piwik.cacheBuster;
$scope.totalNumberOfSites = '?';
initSelectLists();
initUtcTime();
initUserIP();
initCustomVariablesActivated();
initIsTimezoneSupportEnabled();
initGlobalParams();
initActions();
};
var initActions = function () {
$scope.cancelEditSite = cancelEditSite;
$scope.addSite = addSite;
$scope.addNewEntity = addNewEntity;
$scope.saveGlobalSettings = saveGlobalSettings;
$scope.informSiteIsBeingEdited = informSiteIsBeingEdited;
$scope.lookupCurrentEditSite = lookupCurrentEditSite;
$scope.closeAddMeasurableDialog = function () {
// I couldn't figure out another way to close that jquery dialog
var element = angular.element('[piwik-dialog="$parent.showAddSiteDialog"]');
if (element.parents('ui-dialog') && element.dialog('isOpen')) {
element.dialog('close');
}
}
};
var initAvailableTypes = function () {
return sitesManagerTypeModel.fetchAvailableTypes().then(function (types) {
$scope.availableTypes = types;
$scope.typeForNewEntity = 'website';
return types;
});
};
var informSiteIsBeingEdited = function() {
$scope.siteIsBeingEdited = true;
};
var initSelectLists = function() {
initSiteSearchSelectOptions();
initEcommerceSelectOptions();
initCurrencyList();
initTimezones();
};
var initGlobalParams = function() {
showLoading();
var availableTypesPromise = initAvailableTypes();
sitesManagerAPI.getGlobalSettings(function(globalSettings) {
$scope.globalSettings = globalSettings;
$scope.globalSettings.searchKeywordParametersGlobal = sitesManagerApiHelper.commaDelimitedFieldToArray($scope.globalSettings.searchKeywordParametersGlobal);
$scope.globalSettings.searchCategoryParametersGlobal = sitesManagerApiHelper.commaDelimitedFieldToArray($scope.globalSettings.searchCategoryParametersGlobal);
$scope.globalSettings.excludedIpsGlobal = sitesManagerApiHelper.commaDelimitedFieldToArray($scope.globalSettings.excludedIpsGlobal);
$scope.globalSettings.excludedQueryParametersGlobal = sitesManagerApiHelper.commaDelimitedFieldToArray($scope.globalSettings.excludedQueryParametersGlobal);
$scope.globalSettings.excludedUserAgentsGlobal = sitesManagerApiHelper.commaDelimitedFieldToArray($scope.globalSettings.excludedUserAgentsGlobal);
hideLoading();
initKeepURLFragmentsList();
adminSites.fetchLimitedSitesWithAdminAccess(function () {
availableTypesPromise.then(function () {
triggerAddSiteIfRequested();
});
});
sitesManagerAPI.getSitesIdWithAdminAccess(function (siteIds) {
if (siteIds && siteIds.length) {
$scope.totalNumberOfSites = siteIds.length;
}
});
});
};
var triggerAddSiteIfRequested = function() {
var search = String(window.location.search);
if(piwik.helper.getArrayFromQueryString(search).showaddsite == 1)
addNewEntity();
};
var initEcommerceSelectOptions = function() {
$scope.eCommerceptions = [
{key: '0', value: translate('SitesManager_NotAnEcommerceSite')},
{key: '1', value: translate('SitesManager_EnableEcommerce')}
];
};
var initUtcTime = function() {
var currentDate = new Date();
$scope.utcTime = new Date(
currentDate.getUTCFullYear(),
currentDate.getUTCMonth(),
currentDate.getUTCDate(),
currentDate.getUTCHours(),
currentDate.getUTCMinutes(),
currentDate.getUTCSeconds()
);
};
var initIsTimezoneSupportEnabled = function() {
sitesManagerAPI.isTimezoneSupportEnabled(function (timezoneSupportEnabled) {
$scope.timezoneSupportEnabled = timezoneSupportEnabled;
});
};
var initTimezones = function() {
sitesManagerAPI.getTimezonesList(
function (timezones) {
$scope.timezones = [];
angular.forEach(timezones, function(groupTimezones, timezoneGroup) {
angular.forEach(groupTimezones, function(label, code) {
$scope.timezones.push({
group: timezoneGroup,
code: code,
label: label
});
});
});
}
);
};
var initCustomVariablesActivated = function() {
coreAPI.isPluginActivated(
function (customVariablesActivated) {
$scope.customVariablesActivated = customVariablesActivated;
},
{pluginName: 'CustomVariables'}
);
};
var initUserIP = function() {
coreAPI.getIpFromHeader(function(ip) {
$scope.currentIpAddress = ip;
});
};
var initSiteSearchSelectOptions = function() {
$scope.siteSearchOptions = [
{key: '1', value: translate('SitesManager_EnableSiteSearch')},
{key: '0', value: translate('SitesManager_DisableSiteSearch')}
];
};
var initKeepURLFragmentsList = function() {
$scope.keepURLFragmentsOptions = {
0: ($scope.globalSettings.keepURLFragmentsGlobal ? translate('General_Yes') : translate('General_No')) + ' (' + translate('General_Default') + ')',
1: translate('General_Yes'),
2: translate('General_No')
};
};
var addNewEntity = function () {
sitesManagerTypeModel.hasMultipleTypes().then(function (hasMultipleTypes) {
if (hasMultipleTypes) {
$scope.showAddSiteDialog = true;
} else if ($scope.availableTypes.length === 1) {
var type = $scope.availableTypes[0].id;
addSite(type);
}
});
};
var addSite = function(type) {
if (!type) {
type = 'website'; // todo shall we really hard code this or trigger an exception or so?
}
$scope.adminSites.sites.unshift({type: type});
};
var saveGlobalSettings = function() {
var ajaxHandler = new ajaxHelper();
ajaxHandler.addParams({
module: 'SitesManager',
format: 'json',
action: 'setGlobalSettings'
}, 'GET');
ajaxHandler.addParams({
timezone: $scope.globalSettings.defaultTimezone,
currency: $scope.globalSettings.defaultCurrency,
excludedIps: $scope.globalSettings.excludedIpsGlobal.join(','),
excludedQueryParameters: $scope.globalSettings.excludedQueryParametersGlobal.join(','),
excludedUserAgents: $scope.globalSettings.excludedUserAgentsGlobal.join(','),
keepURLFragments: $scope.globalSettings.keepURLFragmentsGlobal ? 1 : 0,
enableSiteUserAgentExclude: $scope.globalSettings.siteSpecificUserAgentExcludeEnabled ? 1 : 0,
searchKeywordParameters: $scope.globalSettings.searchKeywordParametersGlobal.join(','),
searchCategoryParameters: $scope.globalSettings.searchCategoryParametersGlobal.join(',')
}, 'POST');
ajaxHandler.redirectOnSuccess($scope.redirectParams);
ajaxHandler.setLoadingElement();
ajaxHandler.send(true);
};
var cancelEditSite = function ($event) {
$event.stopPropagation();
piwik.helper.redirect($scope.redirectParams);
};
var lookupCurrentEditSite = function () {
var sitesInEditMode = $scope.adminSites.sites.filter(function(site) {
return site.editMode;
});
return sitesInEditMode[0];
};
var initCurrencyList = function () {
sitesManagerAPI.getCurrencyList(function (currencies) {
$scope.currencies = currencies;
});
};
var showLoading = function() {
$scope.loading = true;
};
var hideLoading = function() {
$scope.loading = false;
};
init();
}
})();