PDF rausgenommen
This commit is contained in:
@ -0,0 +1,40 @@
|
||||
/*!
|
||||
* 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('AnonymizeIpController', AnonymizeIpController);
|
||||
|
||||
AnonymizeIpController.$inject = ['piwikApi'];
|
||||
|
||||
function AnonymizeIpController(piwikApi) {
|
||||
// remember to keep controller very simple. Create a service/factory (model) if needed
|
||||
|
||||
var self = this;
|
||||
this.isLoading = false;
|
||||
|
||||
this.save = function () {
|
||||
this.isLoading = true;
|
||||
|
||||
piwikApi.post({module: 'API', method: 'PrivacyManager.setAnonymizeIpSettings'}, {
|
||||
anonymizeIPEnable: this.enabled ? '1' : '0',
|
||||
anonymizeUserId: this.anonymizeUserId ? '1' : '0',
|
||||
anonymizeOrderId: this.anonymizeOrderId ? '1' : '0',
|
||||
maskLength: this.maskLength,
|
||||
useAnonymizedIpForVisitEnrichment: parseInt(this.useAnonymizedIpForVisitEnrichment, 10) ? '1' : '0'
|
||||
}).then(function (success) {
|
||||
self.isLoading = false;
|
||||
|
||||
var UI = require('piwik/UI');
|
||||
var notification = new UI.Notification();
|
||||
notification.show(_pk_translate('CoreAdminHome_SettingsSaveSuccess'), {context: 'success', id:'privacyManagerSettings'});
|
||||
notification.scrollToNotification();
|
||||
|
||||
}, function () {
|
||||
self.isLoading = false;
|
||||
});
|
||||
};
|
||||
}
|
||||
})();
|
@ -0,0 +1,145 @@
|
||||
/*!
|
||||
* 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('AnonymizeLogDataController', AnonymizeLogDataController);
|
||||
|
||||
AnonymizeLogDataController.$inject = ["$scope", "piwikApi", "piwik", "$timeout"];
|
||||
|
||||
function AnonymizeLogDataController($scope, piwikApi, piwik, $timeout) {
|
||||
function sub(value)
|
||||
{
|
||||
if (value < 10) {
|
||||
return '0' + value;
|
||||
}
|
||||
return value;
|
||||
}
|
||||
|
||||
var self = this;
|
||||
var now = new Date();
|
||||
this.isLoading = false;
|
||||
this.isDeleting = false;
|
||||
this.anonymizeIp = false;
|
||||
this.anonymizeLocation = false;
|
||||
this.anonymizeUserId = false;
|
||||
this.site = {id: 'all', name: 'All Websites'};
|
||||
this.availableVisitColumns = [];
|
||||
this.availableActionColumns = [];
|
||||
this.selectedVisitColumns = [{column: ''}];
|
||||
this.selectedActionColumns = [{column: ''}];
|
||||
this.start_date = now.getFullYear() + '-' + sub(now.getMonth() + 1) + '-' + sub(now.getDay() + 1);
|
||||
this.end_date = this.start_date;
|
||||
|
||||
piwikApi.fetch({method: 'PrivacyManager.getAvailableVisitColumnsToAnonymize'}).then(function (columns) {
|
||||
self.availableVisitColumns = [];
|
||||
angular.forEach(columns, function (column) {
|
||||
self.availableVisitColumns.push({key: column.column_name, value: column.column_name});
|
||||
});
|
||||
});
|
||||
|
||||
piwikApi.fetch({method: 'PrivacyManager.getAvailableLinkVisitActionColumnsToAnonymize'}).then(function (columns) {
|
||||
self.availableActionColumns = [];
|
||||
|
||||
angular.forEach(columns, function (column) {
|
||||
self.availableActionColumns.push({key: column.column_name, value: column.column_name});
|
||||
});
|
||||
});
|
||||
|
||||
this.onVisitColumnChange = function () {
|
||||
var hasAll = true;
|
||||
angular.forEach(this.selectedVisitColumns, function (visitColumn) {
|
||||
if (!visitColumn || !visitColumn.column) {
|
||||
hasAll = false;
|
||||
}
|
||||
});
|
||||
if (hasAll) {
|
||||
this.addVisitColumn();
|
||||
}
|
||||
};
|
||||
|
||||
this.addVisitColumn = function () {
|
||||
this.selectedVisitColumns.push({column: ''});
|
||||
};
|
||||
|
||||
this.removeVisitColumn = function (index) {
|
||||
if (index > -1) {
|
||||
var lastIndex = this.selectedVisitColumns.length - 1;
|
||||
if (lastIndex === index) {
|
||||
this.selectedVisitColumns[index] = {column: ''};
|
||||
} else {
|
||||
this.selectedVisitColumns.splice(index, 1);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
this.onActionColumnChange = function () {
|
||||
var hasAll = true;
|
||||
angular.forEach(this.selectedActionColumns, function (actionColumn) {
|
||||
if (!actionColumn || !actionColumn.column) {
|
||||
hasAll = false;
|
||||
}
|
||||
});
|
||||
if (hasAll) {
|
||||
this.addActionColumn();
|
||||
}
|
||||
};
|
||||
|
||||
this.addActionColumn = function () {
|
||||
this.selectedActionColumns.push({column: ''});
|
||||
};
|
||||
|
||||
this.removeActionColumn = function (index) {
|
||||
if (index > -1) {
|
||||
var lastIndex = this.selectedActionColumns.length - 1;
|
||||
if (lastIndex === index) {
|
||||
this.selectedActionColumns[index] = {column: ''};
|
||||
} else {
|
||||
this.selectedActionColumns.splice(index, 1);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
this.scheduleAnonymization = function () {
|
||||
var date = this.start_date + ',' + this.end_date;
|
||||
if (this.start_date === this.end_date) {
|
||||
date = this.start_date;
|
||||
}
|
||||
|
||||
var params = {date: date};
|
||||
params.idSites = this.site.id;
|
||||
params.anonymizeIp = this.anonymizeIp ? '1' : '0';
|
||||
params.anonymizeLocation = this.anonymizeLocation ? '1' : '0';
|
||||
params.anonymizeUserId = this.anonymizeUserId ? '1' : '0';
|
||||
params.unsetVisitColumns = [];
|
||||
params.unsetLinkVisitActionColumns = [];
|
||||
angular.forEach(this.selectedVisitColumns, function (column) {
|
||||
if (column.column) {
|
||||
params.unsetVisitColumns.push(column.column);
|
||||
}
|
||||
});
|
||||
angular.forEach(this.selectedActionColumns, function (column) {
|
||||
if (column.column) {
|
||||
params.unsetLinkVisitActionColumns.push(column.column);
|
||||
}
|
||||
});
|
||||
|
||||
piwik.helper.modalConfirm('#confirmAnonymizeLogData', {yes: function () {
|
||||
piwikApi.post({method: 'PrivacyManager.anonymizeSomeRawData'}, params).then(function () {
|
||||
location.reload(true);
|
||||
});
|
||||
}});
|
||||
};
|
||||
|
||||
$timeout(function () {
|
||||
var options1 = piwik.getBaseDatePickerOptions(null);
|
||||
var options2 = piwik.getBaseDatePickerOptions(null);
|
||||
|
||||
$(".anonymizeStartDate").datepicker(options1);
|
||||
$(".anonymizeEndDate").datepicker(options2);
|
||||
});
|
||||
|
||||
}
|
||||
})();
|
@ -0,0 +1,142 @@
|
||||
<div class="anonymizeLogData">
|
||||
|
||||
<div class="form-group row">
|
||||
<div class="col s12 input-field">
|
||||
<div>
|
||||
<label for="anonymizeSite" class="siteSelectorLabel">Anonymize the data of this site(s)</label>
|
||||
<div piwik-siteselector
|
||||
class="sites_autocomplete"
|
||||
ng-model="anonymizeLogData.site"
|
||||
id="anonymizeSite"
|
||||
show-all-sites-item="true"
|
||||
switch-site-on-select="false"
|
||||
show-selected-site="true"></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="form-group row">
|
||||
<div class="col s6 input-field">
|
||||
<div>
|
||||
<label for="anonymizeStartDate" class="active">Anonymize all raw data starting from:</label>
|
||||
<input type="text" ng-model="anonymizeLogData.start_date"
|
||||
class="anonymizeStartDate"
|
||||
name="anonymizeStartDate">
|
||||
</div>
|
||||
</div>
|
||||
<div class="col s6 input-field">
|
||||
<div>
|
||||
<label for="anonymizeEndDate" class="active">Anonymize all raw data up to:</label>
|
||||
<input type="text" ng-model="anonymizeLogData.end_date"
|
||||
class="anonymizeEndDate"
|
||||
name="anonymizeEndDate">
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div piwik-field uicontrol="checkbox" name="anonymizeIp"
|
||||
title="Anonymize IP"
|
||||
ng-model="anonymizeLogData.anonymizeIp"
|
||||
introduction="Visit"
|
||||
inline-help="This action cannot be undone. If enabled, for all visits during this duration the IP will be anonymized by at least 2 bytes, for example '192.168.xxx.xxx'. If you have currently configured to anonymize by 3 bytes, then this setting will be respected and all IPs will be anonymized by 3 bytes.">
|
||||
</div>
|
||||
|
||||
<div piwik-field uicontrol="checkbox" name="anonymizeLocation"
|
||||
title="Anonymize Location"
|
||||
ng-model="anonymizeLogData.anonymizeLocation"
|
||||
inline-help="This action cannot be undone. Re-evaluates the location based on the anonymized IP (at least 2 bytes of the IP will be anonymized).">
|
||||
</div>
|
||||
|
||||
<div piwik-field uicontrol="checkbox" name="anonymizeTheUserId"
|
||||
title="Replace User ID with a pseudonym"
|
||||
ng-model="anonymizeLogData.anonymizeUserId"
|
||||
inline-help="When you enable this option, the User ID will be replaced by a pseudonym to avoid directly storing and displaying personally identifiable information such as an email address. In technical terms: given your User ID, Matomo will process the User ID pseudonym using a salted hash function.<br/><br/><em>Note: replacing with a pseudonym is not the same as anonymisation. In GDPR terms: the User ID pseudonym still counts as personal data. The original User ID could still be identified if certain additional information is available (which only Matomo and your data processor has access to).</em>">
|
||||
</div>
|
||||
|
||||
<div class="form-group row">
|
||||
<div class="col s12 m6">
|
||||
<div>
|
||||
<label for="visit_columns">Unset visit columns</label>
|
||||
|
||||
<div ng-repeat="(index, visitColumn) in anonymizeLogData.selectedVisitColumns"
|
||||
class="selectedVisitColumns selectedVisitColumns{{ index }} multiple valign-wrapper">
|
||||
|
||||
<div piwik-field uicontrol="select" name="visit_columns"
|
||||
class="innerFormField"
|
||||
full-width="true"
|
||||
ng-model="anonymizeLogData.selectedVisitColumns[index].column"
|
||||
ng-change="anonymizeLogData.onVisitColumnChange();"
|
||||
options="anonymizeLogData.availableVisitColumns">
|
||||
</div>
|
||||
|
||||
<span ng-click="anonymizeLogData.removeVisitColumn(index)"
|
||||
title="{{ 'General_Remove'|translate }}"
|
||||
ng-hide="(index + 1) == (anonymizeLogData.selectedVisitColumns|length)"
|
||||
class="icon-minus valign"></span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="col s12 m6">
|
||||
<div class="form-help">
|
||||
<span class="inline-help">
|
||||
This action cannot be undone. A list of database columns in scope visit that you want to unset.
|
||||
Each value for that column will be set to its default value. Please note that if the same
|
||||
column exists in scope 'conversion', then this column will be deleted as well
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="form-group row">
|
||||
<div class="col s12"><h3>Action</h3></div>
|
||||
</div>
|
||||
|
||||
<div class="form-group row">
|
||||
<div class="col s12 m6">
|
||||
<div>
|
||||
<label for="action_columns">Unset action columns</label>
|
||||
|
||||
<div ng-repeat="(index, actionColumn) in anonymizeLogData.selectedActionColumns"
|
||||
class="selectedActionColumns selectedActionColumns{{ index }} multiple valign-wrapper">
|
||||
|
||||
<div piwik-field uicontrol="select" name="action_columns"
|
||||
class="innerFormField"
|
||||
full-width="true"
|
||||
ng-model="anonymizeLogData.selectedActionColumns[index].column"
|
||||
ng-change="anonymizeLogData.onActionColumnChange();"
|
||||
options="anonymizeLogData.availableActionColumns">
|
||||
</div>
|
||||
|
||||
<span ng-click="anonymizeLogData.removeActionColumn(index)"
|
||||
title="{{ 'General_Remove'|translate }}"
|
||||
ng-hide="(index + 1) == (anonymizeLogData.selectedActionColumns|length)"
|
||||
class="icon-minus valign"></span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="col s12 m6">
|
||||
<div class="form-help">
|
||||
<span class="inline-help">
|
||||
This action cannot be undone. A list of database columns in scope action that you want to unset. Each value for that column will be set to its default value.
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<p><span class="icon-info"></span> This action may take a long time and will therefore not be executed right away. You will be able to follow the current state of the process below. The anonymization should typically start within one hour.</p>
|
||||
|
||||
<div piwik-save-button
|
||||
class="anonymizePastData"
|
||||
onconfirm="anonymizeLogData.scheduleAnonymization()"
|
||||
data-disabled="!anonymizeLogData.anonymizeIp && !anonymizeLogData.anonymizeLocation && !anonymizeLogData.selectedVisitColumns && !anonymizeLogData.selectedActionColumns"
|
||||
value="Anonymize past data for the selected site and time">
|
||||
</div>
|
||||
|
||||
<div class="ui-confirm" id="confirmAnonymizeLogData">
|
||||
<h2>Are you sure you want to anonymize the data for the selected website(s) and time range? This action cannot be undone, data may be deleted as requested, and this process may take a long time.</h2>
|
||||
<input role="yes" type="button" value="{{ 'General_Yes'|translate }}"/>
|
||||
<input role="no" type="button" value="{{ 'General_No'|translate }}"/>
|
||||
</div>
|
||||
</div>
|
@ -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
|
||||
*/
|
||||
|
||||
/**
|
||||
* Usage:
|
||||
* <div matomo-anonymize-log-data>
|
||||
*/
|
||||
(function () {
|
||||
angular.module('piwikApp').directive('matomoAnonymizeLogData', anonymizeLogData);
|
||||
|
||||
anonymizeLogData.$inject = ['piwik'];
|
||||
|
||||
function anonymizeLogData(piwik){
|
||||
return {
|
||||
restrict: 'A',
|
||||
scope: {},
|
||||
templateUrl: 'plugins/PrivacyManager/angularjs/anonymize-log-data/anonymize-log-data.directive.html?cb=' + piwik.cacheBuster,
|
||||
controller: 'AnonymizeLogDataController',
|
||||
controllerAs: 'anonymizeLogData',
|
||||
compile: function (element, attrs) {
|
||||
|
||||
}
|
||||
};
|
||||
}
|
||||
})();
|
@ -0,0 +1,17 @@
|
||||
.anonymizeLogData {
|
||||
.icon-minus {
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.innerFormField {
|
||||
margin-left: -0.75rem;
|
||||
.form-group.row {
|
||||
margin-top: 2px;
|
||||
margin-bottom: 2px;
|
||||
}
|
||||
}
|
||||
|
||||
.innerFormField {
|
||||
width: 100%;
|
||||
}
|
||||
}
|
@ -0,0 +1,54 @@
|
||||
/*!
|
||||
* 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('DeleteOldLogsController', DeleteOldLogsController);
|
||||
|
||||
DeleteOldLogsController.$inject = ['reportDeletionModel', 'piwikApi', '$timeout'];
|
||||
|
||||
function DeleteOldLogsController(reportDeletionModel, piwikApi, $timeout) {
|
||||
|
||||
var self = this;
|
||||
|
||||
this.isLoading = false;
|
||||
|
||||
function saveSettings()
|
||||
{
|
||||
var method = 'PrivacyManager.setDeleteLogsSettings';
|
||||
reportDeletionModel.savePurageDataSettings(self, method, self.getSettings());
|
||||
}
|
||||
|
||||
this.getSettings = function () {
|
||||
return {
|
||||
enableDeleteLogs: this.enabled ? '1' : '0',
|
||||
deleteLogsOlderThan: this.deleteOlderThan
|
||||
};
|
||||
}
|
||||
|
||||
this.reloadDbStats = function () {
|
||||
reportDeletionModel.updateSettings(this.getSettings());
|
||||
}
|
||||
|
||||
$timeout(function () {
|
||||
reportDeletionModel.initSettings(self.getSettings());
|
||||
});
|
||||
|
||||
this.save = function () {
|
||||
|
||||
if (this.enabled) {
|
||||
var confirmId = 'deleteLogsConfirm';
|
||||
if (reportDeletionModel.settings && '1' === reportDeletionModel.settings.enableDeleteReports) {
|
||||
confirmId = 'deleteBothConfirm';
|
||||
}
|
||||
$('#confirmDeleteSettings').find('>h2').hide();
|
||||
$("#" + confirmId).show();
|
||||
piwikHelper.modalConfirm('#confirmDeleteSettings', {yes: saveSettings});
|
||||
} else {
|
||||
saveSettings();
|
||||
}
|
||||
};
|
||||
}
|
||||
})();
|
@ -0,0 +1,66 @@
|
||||
/*!
|
||||
* 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('DeleteOldReportsController', DeleteOldReportsController);
|
||||
|
||||
DeleteOldReportsController.$inject = ['reportDeletionModel', 'piwikApi', '$timeout'];
|
||||
|
||||
function DeleteOldReportsController(reportDeletionModel, piwikApi, $timeout) {
|
||||
// remember to keep controller very simple. Create a service/factory (model) if needed
|
||||
|
||||
var self = this;
|
||||
this.isLoading = false;
|
||||
|
||||
function getInt(value)
|
||||
{
|
||||
return value ? '1' : '0';
|
||||
}
|
||||
|
||||
function saveSettings()
|
||||
{
|
||||
var method = 'PrivacyManager.setDeleteReportsSettings';
|
||||
reportDeletionModel.savePurageDataSettings(self, method, self.getSettings());
|
||||
}
|
||||
|
||||
this.getSettings = function () {
|
||||
return {
|
||||
enableDeleteReports: this.enabled ? '1' : '0',
|
||||
deleteReportsOlderThan: this.deleteOlderThan,
|
||||
keepBasic: getInt(this.keepBasic),
|
||||
keepDay: getInt(this.keepDataForDay),
|
||||
keepWeek: getInt(this.keepDataForWeek),
|
||||
keepMonth: getInt(this.keepDataForMonth),
|
||||
keepYear: getInt(this.keepDataForYear),
|
||||
keepRange: getInt(this.keepDataForRange),
|
||||
keepSegments: getInt(this.keepDataForSegments),
|
||||
};
|
||||
}
|
||||
|
||||
this.reloadDbStats = function () {
|
||||
reportDeletionModel.updateSettings(this.getSettings());
|
||||
}
|
||||
|
||||
$timeout(function () {
|
||||
reportDeletionModel.initSettings(self.getSettings());
|
||||
});
|
||||
|
||||
this.save = function () {
|
||||
|
||||
if (this.enabled) {
|
||||
var confirmId = 'deleteReportsConfirm';
|
||||
if (reportDeletionModel.settings && '1' === reportDeletionModel.settings.enableDeleteLogs) {
|
||||
confirmId = 'deleteBothConfirm';
|
||||
}
|
||||
$('#confirmDeleteSettings').find('>h2').hide();
|
||||
$("#" + confirmId).show();
|
||||
piwikHelper.modalConfirm('#confirmDeleteSettings', {yes: saveSettings});
|
||||
} else {
|
||||
saveSettings();
|
||||
}
|
||||
};
|
||||
}
|
||||
})();
|
@ -0,0 +1,40 @@
|
||||
/*!
|
||||
* 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('DoNotTrackPreferenceController', DoNotTrackPreferenceController);
|
||||
|
||||
DoNotTrackPreferenceController.$inject = ['piwikApi'];
|
||||
|
||||
function DoNotTrackPreferenceController(piwikApi) {
|
||||
// remember to keep controller very simple. Create a service/factory (model) if needed
|
||||
|
||||
var self = this;
|
||||
this.isLoading = false;
|
||||
|
||||
this.save = function () {
|
||||
this.isLoading = true;
|
||||
|
||||
var action = 'deactivateDoNotTrack';
|
||||
if (this.enabled === '1') {
|
||||
action = 'activateDoNotTrack';
|
||||
}
|
||||
|
||||
piwikApi.post({module: 'API', method: 'PrivacyManager.' + action}).then(function (success) {
|
||||
|
||||
self.isLoading = false;
|
||||
|
||||
var UI = require('piwik/UI');
|
||||
var notification = new UI.Notification();
|
||||
notification.show(_pk_translate('CoreAdminHome_SettingsSaveSuccess'), {context: 'success', id:'privacyManagerSettings'});
|
||||
notification.scrollToNotification();
|
||||
|
||||
}, function () {
|
||||
self.isLoading = false;
|
||||
});
|
||||
};
|
||||
}
|
||||
})();
|
@ -0,0 +1,159 @@
|
||||
/*!
|
||||
* 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('ManageGdprController', ManageGdprController);
|
||||
|
||||
ManageGdprController.$inject = ["$scope", "piwikApi", "piwik", "$timeout"];
|
||||
|
||||
function ManageGdprController($scope, piwikApi, piwik, $timeout) {
|
||||
|
||||
var self = this;
|
||||
this.isLoading = false;
|
||||
this.isDeleting = false;
|
||||
this.site = {id: 'all', name: 'All Websites'};
|
||||
this.segment_filter = 'userId==';
|
||||
this.dataSubjects = [];
|
||||
this.toggleAll = true;
|
||||
this.hasSearched = false
|
||||
|
||||
var sitesPromise = piwikApi.fetch({method: 'SitesManager.getSitesIdWithAdminAccess', filter_limit: '-1'});
|
||||
|
||||
this.linkTo = function (action){
|
||||
var currentUrl = window.location.pathname + window.location.search;
|
||||
var newUrl = piwik.broadcast.updateParamValue('module=PrivacyManager', currentUrl);
|
||||
newUrl = piwik.broadcast.updateParamValue('action=' + action, newUrl);
|
||||
return newUrl;
|
||||
}
|
||||
|
||||
function showSuccessNotification(message)
|
||||
{
|
||||
var UI = require('piwik/UI');
|
||||
var notification = new UI.Notification();
|
||||
notification.show(message, {context: 'success', id: 'manageGdpr'});
|
||||
|
||||
$timeout(function () {
|
||||
notification.scrollToNotification();
|
||||
}, 200);
|
||||
}
|
||||
|
||||
this.toggleActivateAll = function () {
|
||||
var toggleAll = this.toggleAll;
|
||||
angular.forEach(this.dataSubjects, function (dataSubject) {
|
||||
dataSubject.dataSubjectActive = toggleAll;
|
||||
});
|
||||
};
|
||||
|
||||
this.hasActiveDataSubjects = function()
|
||||
{
|
||||
return !!this.getActivatedDataSubjects().length;
|
||||
};
|
||||
|
||||
this.getActivatedDataSubjects = function () {
|
||||
var visitsToDelete = [];
|
||||
|
||||
angular.forEach(this.dataSubjects, function (visit) {
|
||||
if (visit.dataSubjectActive) {
|
||||
visitsToDelete.push({idsite: visit.idSite, idvisit: visit.idVisit});
|
||||
}
|
||||
});
|
||||
return visitsToDelete;
|
||||
}
|
||||
|
||||
this.showProfile = function (visitorId, idSite) {
|
||||
require('piwik/UI').VisitorProfileControl.showPopover(visitorId, idSite);
|
||||
};
|
||||
|
||||
this.exportDataSubject = function () {
|
||||
var visitsToDelete = this.getActivatedDataSubjects();
|
||||
piwikApi.post({
|
||||
module: 'API',
|
||||
method: 'PrivacyManager.exportDataSubjects',
|
||||
format: 'json',
|
||||
filter_limit: -1,
|
||||
}, {visits: visitsToDelete}).then(function (visits) {
|
||||
showSuccessNotification('Visits were successfully exported');
|
||||
piwik.helper.sendContentAsDownload('exported_data_subjects.json', JSON.stringify(visits));
|
||||
});
|
||||
};
|
||||
|
||||
this.deleteDataSubject = function () {
|
||||
piwik.helper.modalConfirm('#confirmDeleteDataSubject', {yes: function () {
|
||||
self.isDeleting = true;
|
||||
var visitsToDelete = self.getActivatedDataSubjects();
|
||||
|
||||
piwikApi.post({
|
||||
module: 'API',
|
||||
method: 'PrivacyManager.deleteDataSubjects',
|
||||
filter_limit: -1,
|
||||
}, {visits: visitsToDelete}).then(function (visits) {
|
||||
self.dataSubjects = [];
|
||||
self.isDeleting = false;
|
||||
showSuccessNotification('Visits were successfully deleted');
|
||||
self.findDataSubjects();
|
||||
}, function () {
|
||||
self.isDeleting = false;
|
||||
});
|
||||
}});
|
||||
};
|
||||
|
||||
this.addFilter = function (segment, value) {
|
||||
this.segment_filter += ',' + segment + '==' + value;
|
||||
this.findDataSubjects();
|
||||
};
|
||||
|
||||
this.findDataSubjects = function () {
|
||||
this.dataSubjects = [];
|
||||
this.isLoading = true;
|
||||
this.toggleAll = true;
|
||||
|
||||
function addDatePadding(number)
|
||||
{
|
||||
if (number < 10) {
|
||||
return '0' + number;
|
||||
}
|
||||
return number;
|
||||
}
|
||||
|
||||
var now = new Date();
|
||||
var dateString = (now.getFullYear() + 2) + '-' + addDatePadding(now.getMonth() + 1) + '-' + addDatePadding(now.getDay());
|
||||
// we are adding two years to make sure to also capture some requests in the future as we fetch data across
|
||||
// different sites and different timezone and want to avoid missing any possible requests
|
||||
|
||||
sitesPromise.then(function (idsites) {
|
||||
|
||||
var siteIds = self.site.id;
|
||||
if (siteIds === 'all' && !piwik.hasSuperUserAccess) {
|
||||
// when superuser, we speed the request up a little and simply use 'all'
|
||||
siteIds = idsites;
|
||||
if (angular.isArray(idsites)) {
|
||||
siteIds = idsites.join(',');
|
||||
}
|
||||
}
|
||||
|
||||
piwikApi.fetch({
|
||||
idSite: siteIds,
|
||||
period: 'range',
|
||||
date: '1998-01-01,today',
|
||||
module: 'API',
|
||||
method: 'Live.getLastVisitsDetails',
|
||||
segment: self.segment_filter,
|
||||
filter_limit: 401,
|
||||
doNotFetchActions: 1
|
||||
}).then(function (visits) {
|
||||
self.hasSearched = true;
|
||||
angular.forEach(visits, function (visit) {
|
||||
visit.dataSubjectActive = true;
|
||||
});
|
||||
self.dataSubjects = visits;
|
||||
self.isLoading = false;
|
||||
}, function () {
|
||||
self.isLoading = false;
|
||||
});
|
||||
});
|
||||
};
|
||||
}
|
||||
})();
|
@ -0,0 +1,139 @@
|
||||
<div class="manageGdpr">
|
||||
<div piwik-content-block content-title="GDPR Tools">
|
||||
<div class="intro">
|
||||
<p>
|
||||
This page has been designed in order for you to exercise data subject rights.
|
||||
<br /><br />
|
||||
Here you can exercise the rights of your users with our GDPR-friendly procedures:
|
||||
<br />
|
||||
</p>
|
||||
<ol>
|
||||
<li>the right of access to all of their data (and the right to data portability),</li>
|
||||
<li>the right to erase some or all of their data (and the right to rectification).</li>
|
||||
</ol>
|
||||
<p><br />In case you do not know what GDPR is, please refer to the <a ng-href="{{ manageGdpr.linkTo('gdprOverview') }}">GDPR overview</a>.</p>
|
||||
</div>
|
||||
<h3>Search for a data subject</h3>
|
||||
|
||||
<div class="form-group row">
|
||||
<div class="col s12 input-field">
|
||||
<div>
|
||||
<label for="gdprsite" class="siteSelectorLabel">Select a website</label>
|
||||
<div piwik-siteselector
|
||||
class="sites_autocomplete"
|
||||
ng-model="manageGdpr.site"
|
||||
id="gdprsite"
|
||||
show-all-sites-item="true"
|
||||
switch-site-on-select="false"
|
||||
show-selected-site="true"></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="form-group row segmentFilterGroup">
|
||||
<div class="col s12">
|
||||
<div>
|
||||
<label style="margin: 8px 0;display: inline-block;">Find data subjects by</label>
|
||||
<div piwik-segment-generator
|
||||
visit-segments-only="1"
|
||||
idsite="manageGdpr.site.id"
|
||||
ng-model="manageGdpr.segment_filter"></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div piwik-save-button
|
||||
class="findDataSubjects"
|
||||
onconfirm="manageGdpr.findDataSubjects()"
|
||||
data-disabled="!manageGdpr.segment_filter"
|
||||
value="Find matching data subjects"
|
||||
saving="manageGdpr.isLoading">
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div ng-show="!manageGdpr.dataSubjects.length && manageGdpr.hasSearched">
|
||||
<h2>No data subjects found</h2>
|
||||
</div>
|
||||
<div ng-show="manageGdpr.dataSubjects.length">
|
||||
|
||||
<h2>Matching data subjects</h2>
|
||||
<p>These visits match the selected criteria.
|
||||
In case you are exporting the data to exercise the right of access, please make sure the selected visits are actually performed by the data subject you want to export the data for.
|
||||
<br />
|
||||
<br />
|
||||
When deleting data to exercise the right of erasure keep in mind that any data that will be deleted for this data subject might still be included in previously generated reports.
|
||||
As many reports are aggregated this is in most cases not a problem unless you have for example URLs, Page Titles, Custom Variables or Custom Dimensions that include personal data. In this case
|
||||
you may want to consider to <a href="https://matomo.org/faq/how-to/faq_155/" target="_blank" rel="noreferrer noopener">invalidate reports</a> after deleting these visits.
|
||||
<br /><br />
|
||||
Please also note that any data will be only deleted from the Matomo database but not from your webserver logs. Also note that if you re-import any historical data, for example from logs, that any previously deleted data may be imported again.
|
||||
|
||||
<br /><br />
|
||||
The found results include all visits without any time restriction and include today.
|
||||
</p>
|
||||
<table piwik-content-table>
|
||||
<thead>
|
||||
<tr>
|
||||
<th class="checkInclude">
|
||||
<div piwik-field uicontrol="checkbox" name="activateAll"
|
||||
ng-model="manageGdpr.toggleAll"
|
||||
ng-change="manageGdpr.toggleActivateAll()"
|
||||
full-width="true">
|
||||
</div>
|
||||
</th><th>Site</th>
|
||||
<th>Visit ID</th>
|
||||
<th>Visitor ID</th>
|
||||
<th>Visitor IP</th>
|
||||
<th>User ID</th>
|
||||
<th>Info</th>
|
||||
<th>Action</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr ng-show="(manageGdpr.dataSubjects|length) > 400">
|
||||
<td colspan="8">More than 400 results were found and the result was truncated to the first 400 visits.</td>
|
||||
</tr>
|
||||
<tr ng-repeat="(index, dataSubject) in manageGdpr.dataSubjects" title="Last action: {{ dataSubject.lastActionDateTime }}">
|
||||
<td class="checkInclude">
|
||||
<div piwik-field uicontrol="checkbox" name="subject{{dataSubject.idVisit}}"
|
||||
ng-model="manageGdpr.dataSubjects[index].dataSubjectActive"
|
||||
full-width="true">
|
||||
</div>
|
||||
</td>
|
||||
<td class="site" title="(ID {{dataSubject.idSite}})">{{ dataSubject.siteName }}</td>
|
||||
<td class="visitId">{{ dataSubject.idVisit }}</td>
|
||||
<td class="visitorId"><a ng-click="manageGdpr.addFilter('visitorId', dataSubject.visitorId)" title="Click to add this visitorID to the search">{{ dataSubject.visitorId }}</a></td>
|
||||
<td class="visitorIp"><a ng-click="manageGdpr.addFilter('visitIp', dataSubject.visitIp)" title="Click to add this visitorIP to the search">{{ dataSubject.visitIp }}</a></td>
|
||||
<td class="userId"><a ng-click="manageGdpr.addFilter('userId', dataSubject.userId)" title="Click to add this userID to the search">{{ dataSubject.userId }}</a></td>
|
||||
<td>
|
||||
<span title="{{ dataSubject.deviceType }} {{ dataSubject.deviceModel }}"><img height="16" ng-src="{{ dataSubject.deviceTypeIcon }}"></span>
|
||||
<span title="{{ dataSubject.operatingSystem }}"><img height="16" ng-src="{{ dataSubject.operatingSystemIcon }}"></span>
|
||||
<span title="{{ dataSubject.browser }} {{ dataSubject.browserFamilyDescription }}"><img height="16" ng-src="{{ dataSubject.browserIcon }}"></span>
|
||||
<span title="{{ dataSubject.country }} {{ dataSubject.region }}"><img height="16" ng-src="{{ dataSubject.countryFlag }}"></span>
|
||||
</td>
|
||||
<td><a class="visitorLogTooltip" title="View visitor profile" ng-click="manageGdpr.showProfile(dataSubject.visitorId, dataSubject.idSite)">
|
||||
<img src="plugins/Live/images/visitorProfileLaunch.png"> <span>View visitor profile</span>
|
||||
</a></td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
<div piwik-save-button
|
||||
class="exportDataSubjects"
|
||||
onconfirm="manageGdpr.exportDataSubject()"
|
||||
data-disabled="!manageGdpr.hasActiveDataSubjects()"
|
||||
value="Export selected visits">
|
||||
</div>
|
||||
<div piwik-save-button
|
||||
class="deleteDataSubjects"
|
||||
onconfirm="manageGdpr.deleteDataSubject()"
|
||||
data-disabled="!manageGdpr.hasActiveDataSubjects() || manageGdpr.isDeleting"
|
||||
value="Delete selected visits">
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="ui-confirm" id="confirmDeleteDataSubject">
|
||||
<h2>Are you sure you want to delete the selected visits? This action cannot be undone. </h2>
|
||||
<input role="yes" type="button" value="{{ 'General_Yes'|translate }}"/>
|
||||
<input role="no" type="button" value="{{ 'General_No'|translate }}"/>
|
||||
</div>
|
||||
</div>
|
@ -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
|
||||
*/
|
||||
|
||||
/**
|
||||
* Usage:
|
||||
* <div matomo-manage-gdpr>
|
||||
*/
|
||||
(function () {
|
||||
angular.module('piwikApp').directive('matomoManageGdpr', matomoManageGdpr);
|
||||
|
||||
matomoManageGdpr.$inject = ['piwik'];
|
||||
|
||||
function matomoManageGdpr(piwik){
|
||||
return {
|
||||
restrict: 'A',
|
||||
scope: {},
|
||||
templateUrl: 'plugins/PrivacyManager/angularjs/manage-gdpr/managegdpr.directive.html?cb=' + piwik.cacheBuster,
|
||||
controller: 'ManageGdprController',
|
||||
controllerAs: 'manageGdpr',
|
||||
compile: function (element, attrs) {
|
||||
|
||||
}
|
||||
};
|
||||
}
|
||||
})();
|
@ -0,0 +1,16 @@
|
||||
.manageGdpr {
|
||||
td.checkInclude {
|
||||
width: 80px;
|
||||
.form-group.row {
|
||||
margin-top: 0;
|
||||
}
|
||||
}
|
||||
|
||||
td.site {
|
||||
width: 180px;
|
||||
}
|
||||
}
|
||||
|
||||
.deleteDataSubjects .btn {
|
||||
background-color: @color-red-piwik;
|
||||
}
|
@ -0,0 +1,62 @@
|
||||
/*!
|
||||
* 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('OptOutCustomizerController', OptOutCustomizerController);
|
||||
|
||||
OptOutCustomizerController.$inject = ["$scope"];
|
||||
|
||||
function OptOutCustomizerController($scope) {
|
||||
var vm = this;
|
||||
vm.piwikurl = $scope.piwikurl;
|
||||
vm.language = $scope.language;
|
||||
vm.fontSizeUnit = 'px';
|
||||
vm.fontSizeWithUnit = '';
|
||||
vm.backgroundColor = '';
|
||||
vm.fontColor = '';
|
||||
vm.fontSize = '';
|
||||
vm.fontFamily = '';
|
||||
vm.updateFontSize = function () {
|
||||
if (vm.fontSize) {
|
||||
vm.fontSizeWithUnit = vm.fontSize + vm.fontSizeUnit;
|
||||
} else {
|
||||
vm.fontSizeWithUnit = "";
|
||||
}
|
||||
this.onUpdate();
|
||||
};
|
||||
vm.onUpdate = function () {
|
||||
if (vm.piwikurl) {
|
||||
if (vm.backgroundColor === '' && vm.fontColor !== '' && vm.nearlyWhite(vm.fontColor.substr(1))) {
|
||||
$('#previewIframe').addClass('withBg');
|
||||
} else {
|
||||
$('#previewIframe').removeClass('withBg');
|
||||
}
|
||||
var value = vm.piwikurl + "index.php?module=CoreAdminHome&action=optOut&language=" + vm.language + "&backgroundColor=" + vm.backgroundColor.substr(1) + "&fontColor=" + vm.fontColor.substr(1) + "&fontSize=" + vm.fontSizeWithUnit + "&fontFamily=" + encodeURIComponent(vm.fontFamily);
|
||||
var isAnimationAlreadyRunning = $('.optOutCustomizer pre').queue('fx').length > 0;
|
||||
if (value !== vm.iframeUrl && !isAnimationAlreadyRunning) {
|
||||
$('.optOutCustomizer pre').effect("highlight", {}, 1500);
|
||||
}
|
||||
vm.iframeUrl = value;
|
||||
|
||||
} else {
|
||||
vm.iframeUrl = "";
|
||||
};
|
||||
}
|
||||
vm.nearlyWhite = function (hex) {
|
||||
var bigint = parseInt(hex, 16);
|
||||
var r = (bigint >> 16) & 255;
|
||||
var g = (bigint >> 8) & 255;
|
||||
var b = bigint & 255;
|
||||
|
||||
return (r >= 225 && g >= 225 && b >= 225);
|
||||
}
|
||||
vm.onUpdate();
|
||||
|
||||
$scope.$watch('piwikurl', function (val, oldVal) {
|
||||
vm.onUpdate();
|
||||
});
|
||||
}
|
||||
})();
|
@ -0,0 +1,52 @@
|
||||
<div class="optOutCustomizer">
|
||||
<p>
|
||||
{{ 'CoreAdminHome_OptOutExplanation'|translate }}
|
||||
<span ng-bind-html="'General_ReadThisToLearnMore'|translate:'<a rel=\'noreferrer noopener\' target=\'_blank\' href=\'https://matomo.org/faq/how-to/faq_25918/\'>':'</a>'"></span>
|
||||
</p>
|
||||
|
||||
<h3>Customize the Opt-out iframe</h3>
|
||||
<div>
|
||||
<p>
|
||||
<span>
|
||||
Font Color:
|
||||
<input type="color" ng-model="optOutCustomizer.fontColor" ng-change="optOutCustomizer.onUpdate()">
|
||||
</span>
|
||||
|
||||
<span>
|
||||
Background Color:
|
||||
<input type="color" ng-model="optOutCustomizer.backgroundColor" ng-change="optOutCustomizer.onUpdate()">
|
||||
</span>
|
||||
|
||||
<span>
|
||||
Font Size:
|
||||
<input id=FontSizeInput type="number" min="1" max="100" ng-model="optOutCustomizer.fontSize" ng-change="optOutCustomizer.updateFontSize()">
|
||||
</span>
|
||||
|
||||
<span>
|
||||
<select class="browser-default" ng-model="optOutCustomizer.fontSizeUnit" ng-change="optOutCustomizer.updateFontSize()">
|
||||
<option value="px">px</option>
|
||||
<option value="pt">pt</option>
|
||||
<option value="em">em</option>
|
||||
<option value="rem">rem</option>
|
||||
<option value="%">%</option>
|
||||
</select>
|
||||
</span>
|
||||
|
||||
<span>
|
||||
Font Family:
|
||||
<input id=FontFamilyInput type="text" ng-model="optOutCustomizer.fontFamily" ng-change="optOutCustomizer.onUpdate()">
|
||||
</span>
|
||||
|
||||
</p>
|
||||
</div>
|
||||
</p>
|
||||
<h3>HTML code to embed on your website</h3>
|
||||
<pre piwik-select-on-focus><iframe
|
||||
style="border: 0; height: 200px; width: 600px;"
|
||||
src="{{ optOutCustomizer.iframeUrl }}"
|
||||
></iframe></pre>
|
||||
<p ng-bind-html="'CoreAdminHome_OptOutExplanationIntro'|translate:'<a href=\'' + optOutCustomizer.iframeUrl + '\' rel=\'noreferrer noopener\' target=\'_blank\'>':'</a>'">
|
||||
</p>
|
||||
<h3>Preview of the Opt-out as it will appear on your website</h3>
|
||||
<iframe id="previewIframe" ng-src="{{ optOutCustomizer.iframeUrl }}" style="border: 1px solid #333; height: 200px; width: 600px;" />
|
||||
</div>
|
@ -0,0 +1,45 @@
|
||||
/*!
|
||||
* Piwik - free/libre analytics platform
|
||||
*
|
||||
* @link http://piwik.org
|
||||
* @license http://www.gnu.org/licenses/gpl-3.0.html GPL v3 or later
|
||||
*/
|
||||
|
||||
/**
|
||||
* Usage:
|
||||
* <div piwik-opt-out-customizer>
|
||||
*/
|
||||
(function () {
|
||||
angular.module('piwikApp').directive('piwikOptOutCustomizer', piwikOptOutCustomizer);
|
||||
|
||||
piwikOptOutCustomizer.$inject = ['piwik'];
|
||||
|
||||
function piwikOptOutCustomizer(piwik){
|
||||
var defaults = {
|
||||
// showAllSitesItem: 'true'
|
||||
};
|
||||
|
||||
return {
|
||||
restrict: 'A',
|
||||
scope: {
|
||||
language: '@',
|
||||
piwikurl: '@'
|
||||
},
|
||||
templateUrl: 'plugins/PrivacyManager/angularjs/opt-out-customizer/opt-out-customizer.directive.html?cb=' + piwik.cacheBuster,
|
||||
controller: 'OptOutCustomizerController',
|
||||
controllerAs: 'optOutCustomizer',
|
||||
compile: function (element, attrs) {
|
||||
|
||||
for (var index in defaults) {
|
||||
if (defaults.hasOwnProperty(index) && attrs[index] === undefined) {
|
||||
attrs[index] = defaults[index];
|
||||
}
|
||||
}
|
||||
|
||||
return function (scope, element, attrs) {
|
||||
|
||||
};
|
||||
}
|
||||
};
|
||||
}
|
||||
})();
|
@ -0,0 +1,30 @@
|
||||
.optOutCustomizer {
|
||||
|
||||
#FontSizeInput {
|
||||
width: 100px;
|
||||
}
|
||||
|
||||
#FontFamilyInput {
|
||||
width: 180px;
|
||||
}
|
||||
|
||||
input, select{
|
||||
margin-right: 30px;
|
||||
}
|
||||
|
||||
select{
|
||||
width:60px;
|
||||
display: inline-block;
|
||||
}
|
||||
|
||||
p span{
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
iframe{
|
||||
width: 100%;
|
||||
&.withBg{
|
||||
background-color: #4d4d4d;
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,111 @@
|
||||
/*!
|
||||
* 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.service').factory('reportDeletionModel', reportDeletionModel);
|
||||
|
||||
reportDeletionModel.$inject = ['piwik', 'piwikApi'];
|
||||
|
||||
function reportDeletionModel (piwik, piwikApi) {
|
||||
|
||||
var currentRequest;
|
||||
var isFirstLoad = true;
|
||||
|
||||
var model = {
|
||||
settings: {},
|
||||
showEstimate: false,
|
||||
loadingEstimation: false,
|
||||
estimation: '',
|
||||
isModified: false,
|
||||
isEitherDeleteSectionEnabled: isEitherDeleteSectionEnabled,
|
||||
reloadDbStats: reloadDbStats,
|
||||
savePurageDataSettings: savePurageDataSettings,
|
||||
updateSettings: updateSettings,
|
||||
initSettings: initSettings
|
||||
};
|
||||
|
||||
return model;
|
||||
|
||||
function updateSettings(settings)
|
||||
{
|
||||
initSettings(settings);
|
||||
model.isModified = true;
|
||||
}
|
||||
|
||||
function initSettings(settings)
|
||||
{
|
||||
model.settings = angular.merge({}, model.settings, settings);
|
||||
model.reloadDbStats();
|
||||
}
|
||||
|
||||
function savePurageDataSettings(controller, apiMethod, settings)
|
||||
{
|
||||
controller.isLoading = true;
|
||||
model.isModified = false;
|
||||
|
||||
return piwikApi.post({
|
||||
module: 'API', method: apiMethod
|
||||
}, settings).then(function () {
|
||||
controller.isLoading = false;
|
||||
|
||||
var UI = require('piwik/UI');
|
||||
var notification = new UI.Notification();
|
||||
notification.show(_pk_translate('CoreAdminHome_SettingsSaveSuccess'), {context: 'success', id:'privacyManagerSettings'});
|
||||
notification.scrollToNotification();
|
||||
}, function () {
|
||||
controller.isLoading = false;
|
||||
});
|
||||
}
|
||||
|
||||
function isEitherDeleteSectionEnabled() {
|
||||
return ('1' === model.settings.enableDeleteLogs || '1' === model.settings.enableDeleteReports);
|
||||
}
|
||||
|
||||
function isManualEstimationLinkShowing()
|
||||
{
|
||||
return $('#getPurgeEstimateLink').length > 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {boolean} [forceEstimate] (defaults to false)
|
||||
*/
|
||||
function reloadDbStats(forceEstimate) {
|
||||
if (currentRequest) {
|
||||
currentRequest.abort();
|
||||
}
|
||||
|
||||
// if the manual estimate link is showing, abort unless forcing
|
||||
if (forceEstimate !== true
|
||||
&& (!isEitherDeleteSectionEnabled() || isManualEstimationLinkShowing())) {
|
||||
return;
|
||||
}
|
||||
|
||||
model.loadingEstimation = true;
|
||||
model.estimation = '';
|
||||
model.showEstimate = false;
|
||||
|
||||
var formData = model.settings;
|
||||
|
||||
if (forceEstimate === true) {
|
||||
formData['forceEstimate'] = 1;
|
||||
}
|
||||
|
||||
currentRequest = piwikApi.post({
|
||||
module: 'PrivacyManager',
|
||||
action: 'getDatabaseSize',
|
||||
format: 'html'
|
||||
}, formData).then(function (data) {
|
||||
currentRequest = undefined;
|
||||
model.estimation = data;
|
||||
model.showEstimate = true;
|
||||
model.loadingEstimation = false;
|
||||
}, function () {
|
||||
model.loadingEstimation = true;
|
||||
});
|
||||
}
|
||||
|
||||
}
|
||||
})();
|
@ -0,0 +1,65 @@
|
||||
/*!
|
||||
* 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('ScheduleReportDeletionController', ScheduleReportDeletionController);
|
||||
|
||||
ScheduleReportDeletionController.$inject = ['reportDeletionModel', 'piwikApi', '$timeout'];
|
||||
|
||||
function ScheduleReportDeletionController(reportDeletionModel, piwikApi, $timeout) {
|
||||
|
||||
var self = this;
|
||||
this.isLoading = false;
|
||||
this.dataWasPurged = false;
|
||||
this.showPurgeNowLink = true;
|
||||
this.model = reportDeletionModel;
|
||||
|
||||
this.save = function () {
|
||||
var method = 'PrivacyManager.setScheduleReportDeletionSettings';
|
||||
self.model.savePurageDataSettings(this, method, {
|
||||
deleteLowestInterval: this.deleteLowestInterval
|
||||
});
|
||||
};
|
||||
|
||||
this.executeDataPurgeNow = function () {
|
||||
|
||||
if (reportDeletionModel.isModified) {
|
||||
piwikHelper.modalConfirm('#saveSettingsBeforePurge', {yes: function () {}});
|
||||
return;
|
||||
}
|
||||
|
||||
// ask user if they really want to delete their old data
|
||||
piwikHelper.modalConfirm('#confirmPurgeNow', {
|
||||
yes: function () {
|
||||
self.loadingDataPurge = true;
|
||||
self.showPurgeNowLink = false;
|
||||
|
||||
// execute a data purge
|
||||
piwikApi.withTokenInUrl();
|
||||
var ajaxRequest = piwikApi.fetch({
|
||||
module: 'PrivacyManager',
|
||||
action: 'executeDataPurge',
|
||||
format: 'html'
|
||||
}).then(function () {
|
||||
self.loadingDataPurge = false;
|
||||
// force reload
|
||||
reportDeletionModel.reloadDbStats();
|
||||
|
||||
self.dataWasPurged = true;
|
||||
|
||||
$timeout(function () {
|
||||
self.dataWasPurged = false;
|
||||
self.showPurgeNowLink = true;
|
||||
}, 2000);
|
||||
}, function () {
|
||||
self.loadingDataPurge = false;
|
||||
});
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
}
|
||||
})();
|
Reference in New Issue
Block a user