Author: Derick Rethans (derickr)
Date: 2025-01-28T10:43:23Z
Commit:
https://github.com/php/web-analytics/commit/295337bed842de426a08483bdd6779fc7ea8adb0
Raw diff:
https://github.com/php/web-analytics/commit/295337bed842de426a08483bdd6779fc7ea8adb0.diff
Upgrade Matomo to 5.2.2
Changed paths:
M www/core/Updates/5.2.0-b6.php
M www/plugins/API/API.php
M www/plugins/CoreAdminHome/OptOutManager.php
M www/plugins/CorePluginsAdmin/SettingsMetadata.php
M www/plugins/CorePluginsAdmin/vue/dist/CorePluginsAdmin.umd.js
M www/plugins/CorePluginsAdmin/vue/dist/CorePluginsAdmin.umd.min.js
M www/plugins/CorePluginsAdmin/vue/src/PluginSettings/PluginSettings.vue
M www/plugins/Monolog/Formatter/LineMessageFormatter.php
M www/plugins/Overlay/templates/startOverlaySession.twig
M www/plugins/UsersManager/API.php
M www/vendor/composer/InstalledVersions.php
Diff:
diff --git a/www/core/Updates/5.2.0-b6.php b/www/core/Updates/5.2.0-b6.php
index c2b8dba..4394792 100644
--- a/www/core/Updates/5.2.0-b6.php
+++ b/www/core/Updates/5.2.0-b6.php
@@ -31,17 +31,17 @@ public function __construct(MigrationFactory $factory)
public function getMigrations(Updater $updater)
{
- $startOfCurrentYear = Date::now()->toString('Y') . '-01-01';
+ $startOfCurrentMonth = Date::now()->toString('Y-m') . '-01';
$commandToExecute = sprintf(
'./console core:invalidate-report-data --dates=%s,today
--plugin=Actions.Actions_hits',
- $startOfCurrentYear
+ $startOfCurrentMonth
);
$migrations = [
- new CustomMigration(function () use ($startOfCurrentYear) {
+ new CustomMigration(function () use ($startOfCurrentMonth) {
$invalidator = StaticContainer::get(ArchiveInvalidator::class);
- $invalidator->scheduleReArchiving('all', 'Actions',
'Actions_hits', Date::factory($startOfCurrentYear));
+ $invalidator->scheduleReArchiving('all', 'Actions',
'Actions_hits', Date::factory($startOfCurrentMonth));
}, $commandToExecute)
];
diff --git a/www/plugins/API/API.php b/www/plugins/API/API.php
index b2f4ec4..f8c7ada 100644
--- a/www/plugins/API/API.php
+++ b/www/plugins/API/API.php
@@ -525,7 +525,7 @@ public function getBulkRequest($urls)
$params += $queryParameters;
- if (!empty($params['method']) && $params['method'] ===
'API.getBulkRequest') {
+ if (!empty($params['method']) && is_string($params['method']) &&
trim($params['method']) === 'API.getBulkRequest') {
continue;
}
diff --git a/www/plugins/CoreAdminHome/OptOutManager.php
b/www/plugins/CoreAdminHome/OptOutManager.php
index 72154f7..81c1a4f 100644
--- a/www/plugins/CoreAdminHome/OptOutManager.php
+++ b/www/plugins/CoreAdminHome/OptOutManager.php
@@ -18,6 +18,7 @@
use Piwik\Request;
use Piwik\Tracker\IgnoreCookie;
use Piwik\Url;
+use Piwik\UrlHelper;
use Piwik\View;
/*
@@ -205,6 +206,20 @@ public function getOptOutJSEmbedCode(
bool $applyStyling,
bool $showIntro
): string {
+ $parsedUrl = parse_url($matomoUrl);
+
+ if (
+ (!empty($matomoUrl) && false === $parsedUrl)
+ || (!empty($parsedUrl['scheme']) &&
!in_array(strtolower($parsedUrl['scheme']), ['http', 'https']))
+ || (empty($parsedUrl['host']) ||
!Url::isValidHost($parsedUrl['host']))
+ ) {
+ throw new \Piwik\Exception\Exception('The provided URL is
invalid.');
+ }
+
+ // We put together the url based on the parsed parameters manually to
ensure it might not include unexpected values
+ // for protocol less urls starting with //, we need to prepend the
double slash again
+ $matomoUrl = (strpos($matomoUrl, '//') === 0 ? '//' : '') .
UrlHelper::getParseUrlReverse($parsedUrl);
+
return '<div id="matomo-opt-out"></div>
<script src="' . rtrim($matomoUrl, '/') .
'/index.php?module=CoreAdminHome&action=optOutJS&divId=matomo-opt-out&language='
. $language . ($applyStyling ? '&backgroundColor=' . $backgroundColor .
'&fontColor=' . $fontColor . '&fontSize=' . $fontSize . '&fontFamily=' .
$fontFamily : '') . '&showIntro=' . ($showIntro ? '1' : '0') . '"></script>';
}
diff --git a/www/plugins/CorePluginsAdmin/SettingsMetadata.php
b/www/plugins/CorePluginsAdmin/SettingsMetadata.php
index 96907b7..6afe240 100644
--- a/www/plugins/CorePluginsAdmin/SettingsMetadata.php
+++ b/www/plugins/CorePluginsAdmin/SettingsMetadata.php
@@ -20,6 +20,8 @@ class SettingsMetadata
{
public const PASSWORD_PLACEHOLDER = '******';
+ public const EMPTY_ARRAY = '__empty__';
+
/**
* @param Settings[] $settingsInstances
* @param array $settingValues array('pluginName' => array('settingName'
=> 'settingValue'))
@@ -34,6 +36,11 @@ public function setPluginSettings($settingsInstances,
$settingValues)
$fieldConfig = $setting->configureField();
+ // empty arrays are sent as __empty__ value, so we need to
convert it here back to an array
+ if ($setting->getType() === FieldConfig::TYPE_ARRAY &&
$value === self::EMPTY_ARRAY) {
+ $value = [];
+ }
+
if (
isset($value) && (
$fieldConfig->uiControl !==
FieldConfig::UI_CONTROL_PASSWORD ||
diff --git a/www/plugins/CorePluginsAdmin/vue/dist/CorePluginsAdmin.umd.js
b/www/plugins/CorePluginsAdmin/vue/dist/CorePluginsAdmin.umd.js
index de81481..8a5a535 100644
--- a/www/plugins/CorePluginsAdmin/vue/dist/CorePluginsAdmin.umd.js
+++ b/www/plugins/CorePluginsAdmin/vue/dist/CorePluginsAdmin.umd.js
@@ -17267,34 +17267,34 @@ var UI_CONTROLS_TO_TYPE = {
Fieldvue_type_script_lang_ts.render = Fieldvue_type_template_id_5f883444_render
/* harmony default export */ var Field = (Fieldvue_type_script_lang_ts);
-// CONCATENATED MODULE:
./node_modules/@vue/cli-plugin-babel/node_modules/cache-loader/dist/cjs.js??ref--12-0!./node_modules/@vue/cli-plugin-babel/node_modules/thread-loader/dist/cjs.js!./node_modules/babel-loader/lib!./node_modules/@vue/cli-service/node_modules/vue-loader-v16/dist/templateLoader.js??ref--6!./node_modules/@vue/cli-service/node_modules/cache-loader/dist/cjs.js??ref--0-0!./node_modules/@vue/cli-service/node_modules/vue-loader-v16/dist??ref--0-1!./plugins/CorePluginsAdmin/vue/src/PluginSettings/PluginSettings.vue?vue&type=template&id=919e3cb4
+// CONCATENATED MODULE:
./node_modules/@vue/cli-plugin-babel/node_modules/cache-loader/dist/cjs.js??ref--12-0!./node_modules/@vue/cli-plugin-babel/node_modules/thread-loader/dist/cjs.js!./node_modules/babel-loader/lib!./node_modules/@vue/cli-service/node_modules/vue-loader-v16/dist/templateLoader.js??ref--6!./node_modules/@vue/cli-service/node_modules/cache-loader/dist/cjs.js??ref--0-0!./node_modules/@vue/cli-service/node_modules/vue-loader-v16/dist??ref--0-1!./plugins/CorePluginsAdmin/vue/src/PluginSettings/PluginSettings.vue?vue&type=template&id=601e4fc6
-var PluginSettingsvue_type_template_id_919e3cb4_hoisted_1 = {
+var PluginSettingsvue_type_template_id_601e4fc6_hoisted_1 = {
class: "pluginSettings",
ref: "root"
};
-var PluginSettingsvue_type_template_id_919e3cb4_hoisted_2 = ["id"];
-var PluginSettingsvue_type_template_id_919e3cb4_hoisted_3 = {
+var PluginSettingsvue_type_template_id_601e4fc6_hoisted_2 = ["id"];
+var PluginSettingsvue_type_template_id_601e4fc6_hoisted_3 = {
class: "card-content"
};
-var PluginSettingsvue_type_template_id_919e3cb4_hoisted_4 = ["id"];
-var PluginSettingsvue_type_template_id_919e3cb4_hoisted_5 = ["onClick",
"disabled", "value"];
-function PluginSettingsvue_type_template_id_919e3cb4_render(_ctx, _cache,
$props, $setup, $data, $options) {
+var PluginSettingsvue_type_template_id_601e4fc6_hoisted_4 = ["id"];
+var PluginSettingsvue_type_template_id_601e4fc6_hoisted_5 = ["onClick",
"disabled", "value"];
+function PluginSettingsvue_type_template_id_601e4fc6_render(_ctx, _cache,
$props, $setup, $data, $options) {
var _component_GroupedSettings =
Object(external_commonjs_vue_commonjs2_vue_root_Vue_["resolveComponent"])("GroupedSettings");
var _component_ActivityIndicator =
Object(external_commonjs_vue_commonjs2_vue_root_Vue_["resolveComponent"])("ActivityIndicator");
var _component_PasswordConfirmation =
Object(external_commonjs_vue_commonjs2_vue_root_Vue_["resolveComponent"])("PasswordConfirmation");
- return Object(external_commonjs_vue_commonjs2_vue_root_Vue_["openBlock"])(),
Object(external_commonjs_vue_commonjs2_vue_root_Vue_["createElementBlock"])("div",
PluginSettingsvue_type_template_id_919e3cb4_hoisted_1,
[(Object(external_commonjs_vue_commonjs2_vue_root_Vue_["openBlock"])(true),
Object(external_commonjs_vue_commonjs2_vue_root_Vue_["createElementBlock"])(external_commonjs_vue_commonjs2_vue_root_Vue_["Fragment"],
null,
Object(external_commonjs_vue_commonjs2_vue_root_Vue_["renderList"])(_ctx.settingsPerPlugin,
function (settings) {
+ return Object(external_commonjs_vue_commonjs2_vue_root_Vue_["openBlock"])(),
Object(external_commonjs_vue_commonjs2_vue_root_Vue_["createElementBlock"])("div",
PluginSettingsvue_type_template_id_601e4fc6_hoisted_1,
[(Object(external_commonjs_vue_commonjs2_vue_root_Vue_["openBlock"])(true),
Object(external_commonjs_vue_commonjs2_vue_root_Vue_["createElementBlock"])(external_commonjs_vue_commonjs2_vue_root_Vue_["Fragment"],
null,
Object(external_commonjs_vue_commonjs2_vue_root_Vue_["renderList"])(_ctx.settingsPerPlugin,
function (settings) {
return
Object(external_commonjs_vue_commonjs2_vue_root_Vue_["openBlock"])(),
Object(external_commonjs_vue_commonjs2_vue_root_Vue_["createElementBlock"])("div",
{
class: "card",
id: "".concat(settings.pluginName, "PluginSettings"),
key: "".concat(settings.pluginName, "PluginSettings")
- },
[Object(external_commonjs_vue_commonjs2_vue_root_Vue_["createElementVNode"])("div",
PluginSettingsvue_type_template_id_919e3cb4_hoisted_3,
[Object(external_commonjs_vue_commonjs2_vue_root_Vue_["createElementVNode"])("h2",
{
+ },
[Object(external_commonjs_vue_commonjs2_vue_root_Vue_["createElementVNode"])("div",
PluginSettingsvue_type_template_id_601e4fc6_hoisted_3,
[Object(external_commonjs_vue_commonjs2_vue_root_Vue_["createElementVNode"])("h2",
{
class: "card-title",
id: settings.pluginName
- },
Object(external_commonjs_vue_commonjs2_vue_root_Vue_["toDisplayString"])(settings.title),
9, PluginSettingsvue_type_template_id_919e3cb4_hoisted_4),
Object(external_commonjs_vue_commonjs2_vue_root_Vue_["createVNode"])(_component_GroupedSettings,
{
+ },
Object(external_commonjs_vue_commonjs2_vue_root_Vue_["toDisplayString"])(settings.title),
9, PluginSettingsvue_type_template_id_601e4fc6_hoisted_4),
Object(external_commonjs_vue_commonjs2_vue_root_Vue_["createVNode"])(_component_GroupedSettings,
{
"group-name": settings.pluginName,
settings: settings.settings,
"all-setting-values": _ctx.settingValues,
@@ -17309,9 +17309,9 @@ function
PluginSettingsvue_type_template_id_919e3cb4_render(_ctx, _cache, $props
disabled: _ctx.isLoading,
class: "pluginsSettingsSubmit btn",
value: _ctx.translate('General_Save')
- }, null, 8, PluginSettingsvue_type_template_id_919e3cb4_hoisted_5),
Object(external_commonjs_vue_commonjs2_vue_root_Vue_["createVNode"])(_component_ActivityIndicator,
{
+ }, null, 8, PluginSettingsvue_type_template_id_601e4fc6_hoisted_5),
Object(external_commonjs_vue_commonjs2_vue_root_Vue_["createVNode"])(_component_ActivityIndicator,
{
loading: _ctx.isLoading || _ctx.isSaving[settings.pluginName]
- }, null, 8, ["loading"])])], 8,
PluginSettingsvue_type_template_id_919e3cb4_hoisted_2);
+ }, null, 8, ["loading"])])], 8,
PluginSettingsvue_type_template_id_601e4fc6_hoisted_2);
}), 128)),
Object(external_commonjs_vue_commonjs2_vue_root_Vue_["createVNode"])(_component_PasswordConfirmation,
{
modelValue: _ctx.showPasswordConfirmModal,
"onUpdate:modelValue": _cache[0] || (_cache[0] = function ($event) {
@@ -17320,7 +17320,7 @@ function
PluginSettingsvue_type_template_id_919e3cb4_render(_ctx, _cache, $props
onConfirmed: _ctx.confirmPassword
}, null, 8, ["modelValue", "onConfirmed"])], 512);
}
-// CONCATENATED MODULE:
./plugins/CorePluginsAdmin/vue/src/PluginSettings/PluginSettings.vue?vue&type=template&id=919e3cb4
+// CONCATENATED MODULE:
./plugins/CorePluginsAdmin/vue/src/PluginSettings/PluginSettings.vue?vue&type=template&id=601e4fc6
// CONCATENATED MODULE:
./node_modules/@vue/cli-plugin-babel/node_modules/cache-loader/dist/cjs.js??ref--12-0!./node_modules/@vue/cli-plugin-babel/node_modules/thread-loader/dist/cjs.js!./node_modules/babel-loader/lib!./node_modules/@vue/cli-service/node_modules/vue-loader-v16/dist/templateLoader.js??ref--6!./node_modules/@vue/cli-service/node_modules/cache-loader/dist/cjs.js??ref--0-0!./node_modules/@vue/cli-service/node_modules/vue-loader-v16/dist??ref--0-1!./plugins/CorePluginsAdmin/vue/src/GroupedSettings/GroupedSettings.vue?vue&type=template&id=566a93cc
@@ -17807,6 +17807,10 @@ var PluginSettingsvue_type_script_lang_ts_window =
window,
postValue = '1';
}
+ if (Array.isArray(postValue) && postValue.length === 0) {
+ postValue = '__empty__';
+ }
+
values[pluginName].push({
name: settingName,
value: postValue
@@ -17822,7 +17826,7 @@ var PluginSettingsvue_type_script_lang_ts_window =
window,
-PluginSettingsvue_type_script_lang_ts.render =
PluginSettingsvue_type_template_id_919e3cb4_render
+PluginSettingsvue_type_script_lang_ts.render =
PluginSettingsvue_type_template_id_601e4fc6_render
/* harmony default export */ var PluginSettings =
(PluginSettingsvue_type_script_lang_ts);
// CONCATENATED MODULE:
./plugins/CorePluginsAdmin/vue/src/Plugins/PluginFilter.ts
diff --git a/www/plugins/CorePluginsAdmin/vue/dist/CorePluginsAdmin.umd.min.js
b/www/plugins/CorePluginsAdmin/vue/dist/CorePluginsAdmin.umd.min.js
index 67cd177..e0380c6 100644
--- a/www/plugins/CorePluginsAdmin/vue/dist/CorePluginsAdmin.umd.min.js
+++ b/www/plugins/CorePluginsAdmin/vue/dist/CorePluginsAdmin.umd.min.js
@@ -4,7 +4,7 @@
*
* @link https://matomo.org
* @license https://www.gnu.org/licenses/gpl-3.0.html GPL v3 or later
- */function Xs(e,t){if(!e)return[];var n=[];return
Object.entries(e).forEach((function(e){var
r=Ws(e,2),o=r[0],i=r[1];if(i&&"object"===zs(i)&&"undefined"!==typeof
i.key)n.push(i);else{var a=o;"integer"===t&&"string"===typeof
o&&(a=parseInt(a,10)),n.push({key:a,value:i})}})),n}function Qs(e){return
Qs="function"===typeof Symbol&&"symbol"===typeof
Symbol.iterator?function(e){return typeof e}:function(e){return
e&&"function"===typeof
Symbol&&e.constructor===Symbol&&e!==Symbol.prototype?"symbol":typeof
e},Qs(e)}var
el=["password","url","search","email"],tl=["textarea","checkbox","text"],nl={checkbox:"FieldCheckbox","expandable-select":"FieldExpandableSelect","field-array":"FieldFieldArray",file:"FieldFile",hidden:"FieldHidden",multiselect:"FieldSelect",multituple:"FieldMultituple",number:"FieldNumber",radio:"FieldRadio",select:"FieldSelect",site:"FieldSite",text:"FieldText",textarea:"FieldTextarea"},rl={FieldSelect:ms,FieldCheckboxArray:Xs,FieldRadio:Xs,FieldExpandableSelect:oa},ol=Object(Oi["defineComponent"])({props:{modelValue:null,modelModifiers:Object,formField:{type:Object,required:!0}},emits:["update:modelValue"],components:{FieldCheckbox:Mi,FieldCheckboxArray:zi,FieldExpandableSelect:aa,FieldFieldArray:ua,FieldFile:ya,FieldHidden:wa,FieldMultituple:Ca,FieldNumber:Pa,FieldRadio:Fa,FieldSelect:bs,FieldSite:ws,FieldText:Cs,FieldTextArray:Ps,FieldTextarea:Fs,FieldTextareaArray:Rs},setup:function(e){var
t=Object(Oi["ref"])(null),n=function(e){var n;e&&t.value&&"function"!==typeof
e.render&&(n="string"===typeof
e?0===e.indexOf("#")?window.$(e):window.vueSanitize(e):e,window.$(t.value).html("").append(n))};return
Object(Oi["watch"])((function(){return
e.formField.inlineHelp}),n),Object(Oi["onMounted"])((function(){n(e.formField.inlineHelp)})),{inlineHelp:t}},computed:{inlineHelpComponent:function(){var
e=this.formField,t=e.inlineHelp;if(t&&"function"===typeof t.render)return
e.inlineHelp},inlineHelpBind:function(){return
this.inlineHelpComponent?this.formField.inlineHelpBind:void
0},childComponent:function(){var e=this.formField;if(e.component){var
t=e.component;if(e.component.plugin){var
n=e.component,r=n.plugin,o=n.name;if(!r||!o)throw new Error("Invalid component
property given to FormField directive, must be {plugin: '...',name:
'...'}");t=Object(Ci["useExternalPluginComponent"])(r,o)}return
Object(Oi["markRaw"])(t)}var
i=e.uiControl,a=nl[i];return-1!==el.indexOf(i)&&(a="FieldText"),"array"===this.formField.type&&-1!==tl.indexOf(i)&&(a="".concat(a,"Array")),a},extraChildComponentParams:function(){return"multiselect"===this.formField.uiControl?{multiple:!0}:{}},showFormHelp:function(){return
this.formField.description||this.formField.inlineHelp||this.showDefaultValue||this.hasInlineHelpSlot},showDefaultValue:function(){return
this.defaultValuePretty&&"checkbox"!==this.formField.uiControl&&"radio"!==this.formField.uiControl},processedModelValue:function(){var
e=this.formField;if("boolean"===e.type){var
t=this.modelValue&&this.modelValue>0&&"0"!==this.modelValue;if("checkbox"===e.uiControl)return
t;if("radio"===e.uiControl)return t?"1":"0"}return
this.modelValue},defaultValue:function(){var
e=this.formField.defaultValue;return
Array.isArray(e)?e.join(","):e},availableOptions:function(){var
e=this.childComponent;if("string"!==typeof e)return null;var
t=this.formField;return
t.availableValues&&rl[e]?rl[e](t.availableValues,t.type,t.uiControlAttributes):null},defaultValuePretty:function(){var
e=this.formField,t=e.defaultValue,n=this.availableOptions;if("string"===typeof
t&&t){var
r=null;try{r=JSON.parse(t)}catch(i){}if(null!==r&&"object"===Qs(r))return""}if(!Array.isArray(n))return
Array.isArray(t)?"":t?"".concat(t):"";var o=[];return
Array.isArray(t)||(t=[t]),(n||[]).forEach((function(e){"undefined"!==typeof
e.value&&-1!==t.indexOf(e.key)&&o.push(e.value)})),o.join(",
")},defaultValuePrettyTruncated:function(){return
this.defaultValuePretty.substring(0,50)},hasInlineHelpSlot:function(){var
e,t;if(!this.$slots["inline-help"])return!1;var
n=this.$slots["inline-help"]();return!(null===n||void
0===n||null===(e=n[0])||void 0===e||null===(t=e.children)||void
0===t||!t.length)}},methods:{onChange:function(e){this.$emit("update:modelValue",e)}}});ol.render=Ei;var
il=ol;function al(e,t,n,r,o,i){var
a=Object(Oi["resolveComponent"])("FormField");return
Object(Oi["openBlock"])(),Object(Oi["createBlock"])(a,{"form-field":e.field,"model-value":e.modelValue,"onUpdate:modelValue":t[0]||(t[0]=function(t){return
e.onChange(t)}),"model-modifiers":e.modelModifiers},{"inline-help":Object(Oi["withCtx"])((function(){return[Object(Oi["renderSlot"])(e.$slots,"inline-help")]})),_:3},8,["form-field","model-value","model-modifiers"])}var
sl={multiselect:"array",checkbox:"boolean",site:"object",number:"integer"},ll=Object(Oi["defineComponent"])({props:{modelValue:null,modelModifiers:Object,uicontrol:String,name:String,defaultValue:null,options:[Object,Array],description:String,introduction:String,title:String,inlineHelp:[String,Object],inlineHelpBind:Object,disabled:Boolean,uiControlAttributes:{type:Object,default:function(){return{}}},uiControlOptions:{type:Object,default:function(){return{}}},autocomplete:String,varType:String,autofocus:Boolean,tabindex:Number,fullWidth:Boolean,maxlength:Number,required:Boolean,placeholder:String,rows:Number,min:Number,max:Number,component:null},emits:["update:modelValue"],components:{FormField:il},computed:{type:function(){if(this.varType)return
this.varType;var e=this.uicontrol;return
e&&sl[e]?sl[e]:"string"},field:function(){return{uiControl:this.uicontrol,type:this.type,name:this.name,defaultValue:this.defaultValue,availableValues:this.options,description:this.description,introduction:this.introduction,inlineHelp:this.inlineHelp,inlineHelpBind:this.inlineHelpBind,title:this.title,component:this.component,uiControlAttributes:Object.assign(Object.assign({},this.uiControlAttributes),{},{disabled:this.disabled,autocomplete:this.autocomplete,tabindex:this.tabindex,autofocus:this.autofocus,rows:this.rows,required:this.required,maxlength:this.maxlength,placeholder:this.placeholder,min:this.min,max:this.max}),fullWidth:this.fullWidth,uiControlOptions:this.uiControlOptions}}},methods:{onChange:function(e){this.$emit("update:modelValue",e)}}});ll.render=al;var
cl=ll,ul={class:"pluginSettings",ref:"root"},pl=["id"],dl={class:"card-content"},fl=["id"],ml=["onClick","disabled","value"];function
hl(e,t,n,r,o,i){var
a=Object(Oi["resolveComponent"])("GroupedSettings"),s=Object(Oi["resolveComponent"])("ActivityIndicator"),l=Object(Oi["resolveComponent"])("PasswordConfirmation");return
Object(Oi["openBlock"])(),Object(Oi["createElementBlock"])("div",ul,[(Object(Oi["openBlock"])(!0),Object(Oi["createElementBlock"])(Oi["Fragment"],null,Object(Oi["renderList"])(e.settingsPerPlugin,(function(t){return
Object(Oi["openBlock"])(),Object(Oi["createElementBlock"])("div",{class:"card",id:"".concat(t.pluginName,"PluginSettings"),key:"".concat(t.pluginName,"PluginSettings")},[Object(Oi["createElementVNode"])("div",dl,[Object(Oi["createElementVNode"])("h2",{class:"card-title",id:t.pluginName},Object(Oi["toDisplayString"])(t.title),9,fl),Object(Oi["createVNode"])(a,{"group-name":t.pluginName,settings:t.settings,"all-setting-values":e.settingValues,onChange:function(n){return
e.settingValues["".concat(t.pluginName,".").concat(n.name)]=n.value}},null,8,["group-name","settings","all-setting-values","onChange"]),Object(Oi["createElementVNode"])("input",{type:"button",onClick:function(n){return
e.saveSetting(t.pluginName)},disabled:e.isLoading,class:"pluginsSettingsSubmit
btn",value:e.translate("General_Save")},null,8,ml),Object(Oi["createVNode"])(s,{loading:e.isLoading||e.isSaving[t.pluginName]},null,8,["loading"])])],8,pl)})),128)),Object(Oi["createVNode"])(l,{modelValue:e.showPasswordConfirmModal,"onUpdate:modelValue":t[0]||(t[0]=function(t){return
e.showPasswordConfirmModal=t}),onConfirmed:e.confirmPassword},null,8,["modelValue","onConfirmed"])],512)}function
gl(e,t,n,r,o,i){var a=Object(Oi["resolveComponent"])("GroupedSetting");return
Object(Oi["openBlock"])(!0),Object(Oi["createElementBlock"])(Oi["Fragment"],null,Object(Oi["renderList"])(e.settings,(function(t){return
Object(Oi["openBlock"])(),Object(Oi["createElementBlock"])("div",{key:"".concat(e.groupPrefix).concat(t.name)},[Object(Oi["createVNode"])(a,{"model-value":e.allSettingValues["".concat(e.groupPrefix).concat(t.name)],"onUpdate:modelValue":function(n){return
e.$emit("change",{name:t.name,value:n})},setting:t,"condition-values":e.settingValues},null,8,["model-value","onUpdate:modelValue","setting","condition-values"])])})),128)}function
bl(e,t,n,r,o,i){var a=Object(Oi["resolveComponent"])("FormField");return
Object(Oi["withDirectives"])((Object(Oi["openBlock"])(),Object(Oi["createElementBlock"])("div",null,[Object(Oi["createVNode"])(a,{"model-value":e.modelValue,"onUpdate:modelValue":t[0]||(t[0]=function(t){return
e.changeValue(t)}),"form-field":e.setting},null,8,["model-value","form-field"])],512)),[[Oi["vShow"],e.showField]])}var
yl=Object(Oi["defineComponent"])({props:{setting:{type:Object,required:!0},modelValue:null,conditionValues:{type:Object,required:!0}},components:{FormField:il},emits:["update:modelValue"],computed:{showField:function(){var
e=this.setting.condition;if(!e)return!0;e=e.replace(/&&/g," and
"),e=e.replace(/\|\|/g," or "),e=e.replace(/!/g," not ");try{return
vi.evaluate(e,this.conditionValues)}catch(t){return console.log("failed to
parse setting condition '".concat(e,"':
").concat(t.message)),console.log(this.conditionValues),!1}}},methods:{changeValue:function(e){this.$emit("update:modelValue",e)}}});yl.render=bl;var
vl=yl;function Ol(e,t){return kl(e)||xl(e,t)||wl(e,t)||jl()}function
jl(){throw new TypeError("Invalid attempt to destructure non-iterable
instance.\nIn order to be iterable, non-array objects must have a
[Symbol.iterator]() method.")}function wl(e,t){if(e){if("string"===typeof
e)return Nl(e,t);var
n=Object.prototype.toString.call(e).slice(8,-1);return"Object"===n&&e.constructor&&(n=e.constructor.name),"Map"===n||"Set"===n?Array.from(e):"Arguments"===n||/^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)?Nl(e,t):void
0}}function Nl(e,t){(null==t||t>e.length)&&(t=e.length);for(var n=0,r=new
Array(t);n<t;n++)r[n]=e[n];return r}function xl(e,t){var
n=null==e?null:"undefined"!==typeof
Symbol&&e[Symbol.iterator]||e["@@iterator"];if(null!=n){var
r,o,i=[],a=!0,s=!1;try{for(n=n.call(e);!(a=(r=n.next()).done);a=!0)if(i.push(r.value),t&&i.length===t)break}catch(l){s=!0,o=l}finally{try{a||null==n["return"]||n["return"]()}finally{if(s)throw
o}}return i}}function kl(e){if(Array.isArray(e))return e}var
El=Object(Oi["defineComponent"])({props:{groupName:String,settings:{type:Array,required:!0},allSettingValues:{type:Object,required:!0}},emits:["change"],components:{GroupedSetting:vl},computed:{settingValues:function(){var
e=this,t=Object.entries(this.allSettingValues).filter((function(t){var
n=Ol(t,1),r=n[0];if(e.groupName){var
o=r.split("."),i=Ol(o,1),a=i[0];if(a!==e.groupName)return!1}return!0})).map((function(t){var
n=Ol(t,2),r=n[0],o=n[1];return e.groupName?[r.split(".")[1],o]:[r,o]}));return
Object.fromEntries(t)},groupPrefix:function(){return
this.groupName?"".concat(this.groupName,"."):""}}});El.render=gl;var
Cl=El,Sl={class:"confirm-password-modal
modal",ref:"root"},Al={class:"modal-content"},Vl={class:"modal-text"},Tl={ref:"content"},Pl={key:0},Ml={key:1},Bl={key:2},Dl={class:"modal-footer"},$l=["disabled"];function
Fl(e,t,n,r,o,i){var a=Object(Oi["resolveComponent"])("Field");return
Object(Oi["openBlock"])(),Object(Oi["createElementBlock"])("div",Sl,[Object(Oi["createElementVNode"])("div",Al,[Object(Oi["createElementVNode"])("div",Vl,[Object(Oi["createElementVNode"])("div",Tl,[Object(Oi["renderSlot"])(e.$slots,"default")],512),e.requiresPasswordConfirmation||e.slotHasContent?Object(Oi["createCommentVNode"])("",!0):(Object(Oi["openBlock"])(),Object(Oi["createElementBlock"])("h2",Pl,Object(Oi["toDisplayString"])(e.translate("UsersManager_ConfirmThisChange")),1)),e.requiresPasswordConfirmation&&!e.slotHasContent?(Object(Oi["openBlock"])(),Object(Oi["createElementBlock"])("h2",Ml,Object(Oi["toDisplayString"])(e.translate("UsersManager_ConfirmWithPassword")),1)):Object(Oi["createCommentVNode"])("",!0),e.requiresPasswordConfirmation&&e.slotHasContent?(Object(Oi["openBlock"])(),Object(Oi["createElementBlock"])("div",Bl,Object(Oi["toDisplayString"])(e.translate("UsersManager_ConfirmWithPassword")),1)):Object(Oi["createCommentVNode"])("",!0)]),Object(Oi["withDirectives"])(Object(Oi["createElementVNode"])("div",null,[Object(Oi["createVNode"])(a,{modelValue:e.passwordConfirmation,"onUpdate:modelValue":t[0]||(t[0]=function(t){return
e.passwordConfirmation=t}),uicontrol:"password",disabled:e.requiresPasswordConfirmation?void
0:"disabled",name:"currentUserPassword",autocomplete:"off","full-width":!0,title:e.translate("UsersManager_YourCurrentPassword")},null,8,["modelValue","disabled","title"])],512),[[Oi["vShow"],e.requiresPasswordConfirmation]])]),Object(Oi["createElementVNode"])("div",Dl,[Object(Oi["createElementVNode"])("a",{href:"",class:"modal-action
modal-close
btn",disabled:e.requiresPasswordConfirmation&&!e.passwordConfirmation?"disabled":void
0,onClick:t[1]||(t[1]=function(t){return
e.onClickConfirm(t)})},Object(Oi["toDisplayString"])(e.translate("General_Confirm")),9,$l),Object(Oi["createElementVNode"])("a",{href:"",class:"modal-action
modal-close modal-no btn-flat",onClick:t[2]||(t[2]=function(t){return
e.onClickCancel(t)})},Object(Oi["toDisplayString"])(e.translate("General_Cancel")),1)])],512)}var
_l=window,Il=_l.$,Ll=Object(Oi["defineComponent"])({props:{modelValue:{type:Boolean,required:!0}},data:function(){return{passwordConfirmation:"",slotHasContent:!0}},emits:["confirmed","aborted","update:modelValue"],components:{Field:cl},activated:function(){this.$emit("update:modelValue",!1)},methods:{onClickConfirm:function(e){e.preventDefault(),this.$emit("confirmed",this.passwordConfirmation),this.passwordConfirmation=""},onClickCancel:function(e){e.preventDefault(),this.$emit("aborted"),this.passwordConfirmation=""},showPasswordConfirmModal:function(){var
e=this;this.slotHasContent=!this.$refs.content.matches(":empty");var
t=this.$refs.root,n=Il(t),r=function(t){var
r=t.keyCode?t.keyCode:t.which;13===r&&(n.modal("close"),e.$emit("confirmed",e.passwordConfirmation),e.passwordConfirmation="")};n.modal({dismissible:!1,onOpenEnd:function(){var
e=".modal.open
#currentUserPassword";Il(e).focus(),Il(e).off("keypress").keypress(r)},onCloseEnd:function(){e.$emit("update:modelValue",!1)}}).modal("open")}},computed:{requiresPasswordConfirmation:function(){return!!Ci["Matomo"].requiresPasswordConfirmation}},watch:{modelValue:function(e){e&&this.showPasswordConfirmModal()}}});Ll.render=Fl;var
Ul=Ll;function Hl(e,t){return Jl(e)||Wl(e,t)||Rl(e,t)||ql()}function
ql(){throw new TypeError("Invalid attempt to destructure non-iterable
instance.\nIn order to be iterable, non-array objects must have a
[Symbol.iterator]() method.")}function Rl(e,t){if(e){if("string"===typeof
e)return zl(e,t);var
n=Object.prototype.toString.call(e).slice(8,-1);return"Object"===n&&e.constructor&&(n=e.constructor.name),"Map"===n||"Set"===n?Array.from(e):"Arguments"===n||/^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)?zl(e,t):void
0}}function zl(e,t){(null==t||t>e.length)&&(t=e.length);for(var n=0,r=new
Array(t);n<t;n++)r[n]=e[n];return r}function Wl(e,t){var
n=null==e?null:"undefined"!==typeof
Symbol&&e[Symbol.iterator]||e["@@iterator"];if(null!=n){var
r,o,i=[],a=!0,s=!1;try{for(n=n.call(e);!(a=(r=n.next()).done);a=!0)if(i.push(r.value),t&&i.length===t)break}catch(l){s=!0,o=l}finally{try{a||null==n["return"]||n["return"]()}finally{if(s)throw
o}}return i}}function Jl(e){if(Array.isArray(e))return e}var
Gl=window,Kl=Gl.$,Yl=Object(Oi["defineComponent"])({props:{mode:String},components:{PasswordConfirmation:Ul,ActivityIndicator:Ci["ActivityIndicator"],GroupedSettings:Cl},data:function(){return{isLoading:!0,isSaving:{},showPasswordConfirmModal:!1,settingsToSave:null,settingsPerPlugin:[],settingValues:{}}},created:function(){var
e=this;Ci["AjaxHelper"].fetch({method:this.apiMethod}).then((function(t){e.isLoading=!1,e.settingsPerPlugin=t,t.forEach((function(t){t.settings.forEach((function(n){e.settingValues["".concat(t.pluginName,".").concat(n.name)]=n.value}))})),Object(Ci["scrollToAnchorInUrl"])(),e.addSectionsToTableOfContents()})).catch((function(){e.isLoading=!1}))},computed:{apiMethod:function(){return"admin"===this.mode?"CorePluginsAdmin.getSystemSettings":"CorePluginsAdmin.getUserSettings"},saveApiMethod:function(){return"admin"===this.mode?"CorePluginsAdmin.setSystemSettings":"CorePluginsAdmin.setUserSettings"}},methods:{addSectionsToTableOfContents:function(){var
e=Kl("#generalSettingsTOC");if(e.length){var
t=this.settingsPerPlugin;t.forEach((function(t){var
n=t.pluginName,r=t.settings;n&&("CoreAdminHome"===n&&r?r.filter((function(e){return
e.introduction})).forEach((function(t){e.append('<a
href="#/'.concat(n,'PluginSettings">').concat(t.introduction,"</a>
"))})):e.append('<a href="#/'.concat(n,'">').concat(n.replace(/([A-Z])/g,"
$1").trim(),"</a>
")))}))}},confirmPassword:function(e){this.showPasswordConfirmModal=!1,this.save(this.settingsToSave,e)},saveSetting:function(e){"admin"===this.mode?(this.settingsToSave=e,this.showPasswordConfirmModal=!0):this.save(e)},save:function(e,t){var
n=this,r=this.saveApiMethod;this.isSaving[e]=!0;var
o=this.getValuesForPlugin(e);Ci["AjaxHelper"].post({method:r},{settingValues:o,passwordConfirmation:t}).then((function(){n.isSaving[e]=!1;var
t=Ci["NotificationsStore"].show({message:Object(Ci["translate"])("CoreAdminHome_PluginSettingsSaveSuccess"),id:"generalSettings",context:"success",type:"transient"});Ci["NotificationsStore"].scrollToNotification(t)})).catch((function(){n.isSaving[e]=!1})),this.settingsToSave=null},getValuesForPlugin:function(e){var
t={};return
t[e]||(t[e]=[]),Object.entries(this.settingValues).forEach((function(n){var
r=Hl(n,2),o=r[0],i=r[1],a=o.split("."),s=Hl(a,2),l=s[0],c=s[1];if(l===e){var
u=i;!1===u?u="0":!0===u&&(u="1"),t[l].push({name:c,value:u})}})),t}}});Yl.render=hl;var
Zl=Yl,Xl=window,Ql=Xl.$;
+ */function Xs(e,t){if(!e)return[];var n=[];return
Object.entries(e).forEach((function(e){var
r=Ws(e,2),o=r[0],i=r[1];if(i&&"object"===zs(i)&&"undefined"!==typeof
i.key)n.push(i);else{var a=o;"integer"===t&&"string"===typeof
o&&(a=parseInt(a,10)),n.push({key:a,value:i})}})),n}function Qs(e){return
Qs="function"===typeof Symbol&&"symbol"===typeof
Symbol.iterator?function(e){return typeof e}:function(e){return
e&&"function"===typeof
Symbol&&e.constructor===Symbol&&e!==Symbol.prototype?"symbol":typeof
e},Qs(e)}var
el=["password","url","search","email"],tl=["textarea","checkbox","text"],nl={checkbox:"FieldCheckbox","expandable-select":"FieldExpandableSelect","field-array":"FieldFieldArray",file:"FieldFile",hidden:"FieldHidden",multiselect:"FieldSelect",multituple:"FieldMultituple",number:"FieldNumber",radio:"FieldRadio",select:"FieldSelect",site:"FieldSite",text:"FieldText",textarea:"FieldTextarea"},rl={FieldSelect:ms,FieldCheckboxArray:Xs,FieldRadio:Xs,FieldExpandableSelect:oa},ol=Object(Oi["defineComponent"])({props:{modelValue:null,modelModifiers:Object,formField:{type:Object,required:!0}},emits:["update:modelValue"],components:{FieldCheckbox:Mi,FieldCheckboxArray:zi,FieldExpandableSelect:aa,FieldFieldArray:ua,FieldFile:ya,FieldHidden:wa,FieldMultituple:Ca,FieldNumber:Pa,FieldRadio:Fa,FieldSelect:bs,FieldSite:ws,FieldText:Cs,FieldTextArray:Ps,FieldTextarea:Fs,FieldTextareaArray:Rs},setup:function(e){var
t=Object(Oi["ref"])(null),n=function(e){var n;e&&t.value&&"function"!==typeof
e.render&&(n="string"===typeof
e?0===e.indexOf("#")?window.$(e):window.vueSanitize(e):e,window.$(t.value).html("").append(n))};return
Object(Oi["watch"])((function(){return
e.formField.inlineHelp}),n),Object(Oi["onMounted"])((function(){n(e.formField.inlineHelp)})),{inlineHelp:t}},computed:{inlineHelpComponent:function(){var
e=this.formField,t=e.inlineHelp;if(t&&"function"===typeof t.render)return
e.inlineHelp},inlineHelpBind:function(){return
this.inlineHelpComponent?this.formField.inlineHelpBind:void
0},childComponent:function(){var e=this.formField;if(e.component){var
t=e.component;if(e.component.plugin){var
n=e.component,r=n.plugin,o=n.name;if(!r||!o)throw new Error("Invalid component
property given to FormField directive, must be {plugin: '...',name:
'...'}");t=Object(Ci["useExternalPluginComponent"])(r,o)}return
Object(Oi["markRaw"])(t)}var
i=e.uiControl,a=nl[i];return-1!==el.indexOf(i)&&(a="FieldText"),"array"===this.formField.type&&-1!==tl.indexOf(i)&&(a="".concat(a,"Array")),a},extraChildComponentParams:function(){return"multiselect"===this.formField.uiControl?{multiple:!0}:{}},showFormHelp:function(){return
this.formField.description||this.formField.inlineHelp||this.showDefaultValue||this.hasInlineHelpSlot},showDefaultValue:function(){return
this.defaultValuePretty&&"checkbox"!==this.formField.uiControl&&"radio"!==this.formField.uiControl},processedModelValue:function(){var
e=this.formField;if("boolean"===e.type){var
t=this.modelValue&&this.modelValue>0&&"0"!==this.modelValue;if("checkbox"===e.uiControl)return
t;if("radio"===e.uiControl)return t?"1":"0"}return
this.modelValue},defaultValue:function(){var
e=this.formField.defaultValue;return
Array.isArray(e)?e.join(","):e},availableOptions:function(){var
e=this.childComponent;if("string"!==typeof e)return null;var
t=this.formField;return
t.availableValues&&rl[e]?rl[e](t.availableValues,t.type,t.uiControlAttributes):null},defaultValuePretty:function(){var
e=this.formField,t=e.defaultValue,n=this.availableOptions;if("string"===typeof
t&&t){var
r=null;try{r=JSON.parse(t)}catch(i){}if(null!==r&&"object"===Qs(r))return""}if(!Array.isArray(n))return
Array.isArray(t)?"":t?"".concat(t):"";var o=[];return
Array.isArray(t)||(t=[t]),(n||[]).forEach((function(e){"undefined"!==typeof
e.value&&-1!==t.indexOf(e.key)&&o.push(e.value)})),o.join(",
")},defaultValuePrettyTruncated:function(){return
this.defaultValuePretty.substring(0,50)},hasInlineHelpSlot:function(){var
e,t;if(!this.$slots["inline-help"])return!1;var
n=this.$slots["inline-help"]();return!(null===n||void
0===n||null===(e=n[0])||void 0===e||null===(t=e.children)||void
0===t||!t.length)}},methods:{onChange:function(e){this.$emit("update:modelValue",e)}}});ol.render=Ei;var
il=ol;function al(e,t,n,r,o,i){var
a=Object(Oi["resolveComponent"])("FormField");return
Object(Oi["openBlock"])(),Object(Oi["createBlock"])(a,{"form-field":e.field,"model-value":e.modelValue,"onUpdate:modelValue":t[0]||(t[0]=function(t){return
e.onChange(t)}),"model-modifiers":e.modelModifiers},{"inline-help":Object(Oi["withCtx"])((function(){return[Object(Oi["renderSlot"])(e.$slots,"inline-help")]})),_:3},8,["form-field","model-value","model-modifiers"])}var
sl={multiselect:"array",checkbox:"boolean",site:"object",number:"integer"},ll=Object(Oi["defineComponent"])({props:{modelValue:null,modelModifiers:Object,uicontrol:String,name:String,defaultValue:null,options:[Object,Array],description:String,introduction:String,title:String,inlineHelp:[String,Object],inlineHelpBind:Object,disabled:Boolean,uiControlAttributes:{type:Object,default:function(){return{}}},uiControlOptions:{type:Object,default:function(){return{}}},autocomplete:String,varType:String,autofocus:Boolean,tabindex:Number,fullWidth:Boolean,maxlength:Number,required:Boolean,placeholder:String,rows:Number,min:Number,max:Number,component:null},emits:["update:modelValue"],components:{FormField:il},computed:{type:function(){if(this.varType)return
this.varType;var e=this.uicontrol;return
e&&sl[e]?sl[e]:"string"},field:function(){return{uiControl:this.uicontrol,type:this.type,name:this.name,defaultValue:this.defaultValue,availableValues:this.options,description:this.description,introduction:this.introduction,inlineHelp:this.inlineHelp,inlineHelpBind:this.inlineHelpBind,title:this.title,component:this.component,uiControlAttributes:Object.assign(Object.assign({},this.uiControlAttributes),{},{disabled:this.disabled,autocomplete:this.autocomplete,tabindex:this.tabindex,autofocus:this.autofocus,rows:this.rows,required:this.required,maxlength:this.maxlength,placeholder:this.placeholder,min:this.min,max:this.max}),fullWidth:this.fullWidth,uiControlOptions:this.uiControlOptions}}},methods:{onChange:function(e){this.$emit("update:modelValue",e)}}});ll.render=al;var
cl=ll,ul={class:"pluginSettings",ref:"root"},pl=["id"],dl={class:"card-content"},fl=["id"],ml=["onClick","disabled","value"];function
hl(e,t,n,r,o,i){var
a=Object(Oi["resolveComponent"])("GroupedSettings"),s=Object(Oi["resolveComponent"])("ActivityIndicator"),l=Object(Oi["resolveComponent"])("PasswordConfirmation");return
Object(Oi["openBlock"])(),Object(Oi["createElementBlock"])("div",ul,[(Object(Oi["openBlock"])(!0),Object(Oi["createElementBlock"])(Oi["Fragment"],null,Object(Oi["renderList"])(e.settingsPerPlugin,(function(t){return
Object(Oi["openBlock"])(),Object(Oi["createElementBlock"])("div",{class:"card",id:"".concat(t.pluginName,"PluginSettings"),key:"".concat(t.pluginName,"PluginSettings")},[Object(Oi["createElementVNode"])("div",dl,[Object(Oi["createElementVNode"])("h2",{class:"card-title",id:t.pluginName},Object(Oi["toDisplayString"])(t.title),9,fl),Object(Oi["createVNode"])(a,{"group-name":t.pluginName,settings:t.settings,"all-setting-values":e.settingValues,onChange:function(n){return
e.settingValues["".concat(t.pluginName,".").concat(n.name)]=n.value}},null,8,["group-name","settings","all-setting-values","onChange"]),Object(Oi["createElementVNode"])("input",{type:"button",onClick:function(n){return
e.saveSetting(t.pluginName)},disabled:e.isLoading,class:"pluginsSettingsSubmit
btn",value:e.translate("General_Save")},null,8,ml),Object(Oi["createVNode"])(s,{loading:e.isLoading||e.isSaving[t.pluginName]},null,8,["loading"])])],8,pl)})),128)),Object(Oi["createVNode"])(l,{modelValue:e.showPasswordConfirmModal,"onUpdate:modelValue":t[0]||(t[0]=function(t){return
e.showPasswordConfirmModal=t}),onConfirmed:e.confirmPassword},null,8,["modelValue","onConfirmed"])],512)}function
gl(e,t,n,r,o,i){var a=Object(Oi["resolveComponent"])("GroupedSetting");return
Object(Oi["openBlock"])(!0),Object(Oi["createElementBlock"])(Oi["Fragment"],null,Object(Oi["renderList"])(e.settings,(function(t){return
Object(Oi["openBlock"])(),Object(Oi["createElementBlock"])("div",{key:"".concat(e.groupPrefix).concat(t.name)},[Object(Oi["createVNode"])(a,{"model-value":e.allSettingValues["".concat(e.groupPrefix).concat(t.name)],"onUpdate:modelValue":function(n){return
e.$emit("change",{name:t.name,value:n})},setting:t,"condition-values":e.settingValues},null,8,["model-value","onUpdate:modelValue","setting","condition-values"])])})),128)}function
bl(e,t,n,r,o,i){var a=Object(Oi["resolveComponent"])("FormField");return
Object(Oi["withDirectives"])((Object(Oi["openBlock"])(),Object(Oi["createElementBlock"])("div",null,[Object(Oi["createVNode"])(a,{"model-value":e.modelValue,"onUpdate:modelValue":t[0]||(t[0]=function(t){return
e.changeValue(t)}),"form-field":e.setting},null,8,["model-value","form-field"])],512)),[[Oi["vShow"],e.showField]])}var
yl=Object(Oi["defineComponent"])({props:{setting:{type:Object,required:!0},modelValue:null,conditionValues:{type:Object,required:!0}},components:{FormField:il},emits:["update:modelValue"],computed:{showField:function(){var
e=this.setting.condition;if(!e)return!0;e=e.replace(/&&/g," and
"),e=e.replace(/\|\|/g," or "),e=e.replace(/!/g," not ");try{return
vi.evaluate(e,this.conditionValues)}catch(t){return console.log("failed to
parse setting condition '".concat(e,"':
").concat(t.message)),console.log(this.conditionValues),!1}}},methods:{changeValue:function(e){this.$emit("update:modelValue",e)}}});yl.render=bl;var
vl=yl;function Ol(e,t){return kl(e)||xl(e,t)||wl(e,t)||jl()}function
jl(){throw new TypeError("Invalid attempt to destructure non-iterable
instance.\nIn order to be iterable, non-array objects must have a
[Symbol.iterator]() method.")}function wl(e,t){if(e){if("string"===typeof
e)return Nl(e,t);var
n=Object.prototype.toString.call(e).slice(8,-1);return"Object"===n&&e.constructor&&(n=e.constructor.name),"Map"===n||"Set"===n?Array.from(e):"Arguments"===n||/^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)?Nl(e,t):void
0}}function Nl(e,t){(null==t||t>e.length)&&(t=e.length);for(var n=0,r=new
Array(t);n<t;n++)r[n]=e[n];return r}function xl(e,t){var
n=null==e?null:"undefined"!==typeof
Symbol&&e[Symbol.iterator]||e["@@iterator"];if(null!=n){var
r,o,i=[],a=!0,s=!1;try{for(n=n.call(e);!(a=(r=n.next()).done);a=!0)if(i.push(r.value),t&&i.length===t)break}catch(l){s=!0,o=l}finally{try{a||null==n["return"]||n["return"]()}finally{if(s)throw
o}}return i}}function kl(e){if(Array.isArray(e))return e}var
El=Object(Oi["defineComponent"])({props:{groupName:String,settings:{type:Array,required:!0},allSettingValues:{type:Object,required:!0}},emits:["change"],components:{GroupedSetting:vl},computed:{settingValues:function(){var
e=this,t=Object.entries(this.allSettingValues).filter((function(t){var
n=Ol(t,1),r=n[0];if(e.groupName){var
o=r.split("."),i=Ol(o,1),a=i[0];if(a!==e.groupName)return!1}return!0})).map((function(t){var
n=Ol(t,2),r=n[0],o=n[1];return e.groupName?[r.split(".")[1],o]:[r,o]}));return
Object.fromEntries(t)},groupPrefix:function(){return
this.groupName?"".concat(this.groupName,"."):""}}});El.render=gl;var
Cl=El,Sl={class:"confirm-password-modal
modal",ref:"root"},Al={class:"modal-content"},Vl={class:"modal-text"},Tl={ref:"content"},Pl={key:0},Ml={key:1},Bl={key:2},Dl={class:"modal-footer"},$l=["disabled"];function
Fl(e,t,n,r,o,i){var a=Object(Oi["resolveComponent"])("Field");return
Object(Oi["openBlock"])(),Object(Oi["createElementBlock"])("div",Sl,[Object(Oi["createElementVNode"])("div",Al,[Object(Oi["createElementVNode"])("div",Vl,[Object(Oi["createElementVNode"])("div",Tl,[Object(Oi["renderSlot"])(e.$slots,"default")],512),e.requiresPasswordConfirmation||e.slotHasContent?Object(Oi["createCommentVNode"])("",!0):(Object(Oi["openBlock"])(),Object(Oi["createElementBlock"])("h2",Pl,Object(Oi["toDisplayString"])(e.translate("UsersManager_ConfirmThisChange")),1)),e.requiresPasswordConfirmation&&!e.slotHasContent?(Object(Oi["openBlock"])(),Object(Oi["createElementBlock"])("h2",Ml,Object(Oi["toDisplayString"])(e.translate("UsersManager_ConfirmWithPassword")),1)):Object(Oi["createCommentVNode"])("",!0),e.requiresPasswordConfirmation&&e.slotHasContent?(Object(Oi["openBlock"])(),Object(Oi["createElementBlock"])("div",Bl,Object(Oi["toDisplayString"])(e.translate("UsersManager_ConfirmWithPassword")),1)):Object(Oi["createCommentVNode"])("",!0)]),Object(Oi["withDirectives"])(Object(Oi["createElementVNode"])("div",null,[Object(Oi["createVNode"])(a,{modelValue:e.passwordConfirmation,"onUpdate:modelValue":t[0]||(t[0]=function(t){return
e.passwordConfirmation=t}),uicontrol:"password",disabled:e.requiresPasswordConfirmation?void
0:"disabled",name:"currentUserPassword",autocomplete:"off","full-width":!0,title:e.translate("UsersManager_YourCurrentPassword")},null,8,["modelValue","disabled","title"])],512),[[Oi["vShow"],e.requiresPasswordConfirmation]])]),Object(Oi["createElementVNode"])("div",Dl,[Object(Oi["createElementVNode"])("a",{href:"",class:"modal-action
modal-close
btn",disabled:e.requiresPasswordConfirmation&&!e.passwordConfirmation?"disabled":void
0,onClick:t[1]||(t[1]=function(t){return
e.onClickConfirm(t)})},Object(Oi["toDisplayString"])(e.translate("General_Confirm")),9,$l),Object(Oi["createElementVNode"])("a",{href:"",class:"modal-action
modal-close modal-no btn-flat",onClick:t[2]||(t[2]=function(t){return
e.onClickCancel(t)})},Object(Oi["toDisplayString"])(e.translate("General_Cancel")),1)])],512)}var
_l=window,Il=_l.$,Ll=Object(Oi["defineComponent"])({props:{modelValue:{type:Boolean,required:!0}},data:function(){return{passwordConfirmation:"",slotHasContent:!0}},emits:["confirmed","aborted","update:modelValue"],components:{Field:cl},activated:function(){this.$emit("update:modelValue",!1)},methods:{onClickConfirm:function(e){e.preventDefault(),this.$emit("confirmed",this.passwordConfirmation),this.passwordConfirmation=""},onClickCancel:function(e){e.preventDefault(),this.$emit("aborted"),this.passwordConfirmation=""},showPasswordConfirmModal:function(){var
e=this;this.slotHasContent=!this.$refs.content.matches(":empty");var
t=this.$refs.root,n=Il(t),r=function(t){var
r=t.keyCode?t.keyCode:t.which;13===r&&(n.modal("close"),e.$emit("confirmed",e.passwordConfirmation),e.passwordConfirmation="")};n.modal({dismissible:!1,onOpenEnd:function(){var
e=".modal.open
#currentUserPassword";Il(e).focus(),Il(e).off("keypress").keypress(r)},onCloseEnd:function(){e.$emit("update:modelValue",!1)}}).modal("open")}},computed:{requiresPasswordConfirmation:function(){return!!Ci["Matomo"].requiresPasswordConfirmation}},watch:{modelValue:function(e){e&&this.showPasswordConfirmModal()}}});Ll.render=Fl;var
Ul=Ll;function Hl(e,t){return Jl(e)||Wl(e,t)||Rl(e,t)||ql()}function
ql(){throw new TypeError("Invalid attempt to destructure non-iterable
instance.\nIn order to be iterable, non-array objects must have a
[Symbol.iterator]() method.")}function Rl(e,t){if(e){if("string"===typeof
e)return zl(e,t);var
n=Object.prototype.toString.call(e).slice(8,-1);return"Object"===n&&e.constructor&&(n=e.constructor.name),"Map"===n||"Set"===n?Array.from(e):"Arguments"===n||/^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)?zl(e,t):void
0}}function zl(e,t){(null==t||t>e.length)&&(t=e.length);for(var n=0,r=new
Array(t);n<t;n++)r[n]=e[n];return r}function Wl(e,t){var
n=null==e?null:"undefined"!==typeof
Symbol&&e[Symbol.iterator]||e["@@iterator"];if(null!=n){var
r,o,i=[],a=!0,s=!1;try{for(n=n.call(e);!(a=(r=n.next()).done);a=!0)if(i.push(r.value),t&&i.length===t)break}catch(l){s=!0,o=l}finally{try{a||null==n["return"]||n["return"]()}finally{if(s)throw
o}}return i}}function Jl(e){if(Array.isArray(e))return e}var
Gl=window,Kl=Gl.$,Yl=Object(Oi["defineComponent"])({props:{mode:String},components:{PasswordConfirmation:Ul,ActivityIndicator:Ci["ActivityIndicator"],GroupedSettings:Cl},data:function(){return{isLoading:!0,isSaving:{},showPasswordConfirmModal:!1,settingsToSave:null,settingsPerPlugin:[],settingValues:{}}},created:function(){var
e=this;Ci["AjaxHelper"].fetch({method:this.apiMethod}).then((function(t){e.isLoading=!1,e.settingsPerPlugin=t,t.forEach((function(t){t.settings.forEach((function(n){e.settingValues["".concat(t.pluginName,".").concat(n.name)]=n.value}))})),Object(Ci["scrollToAnchorInUrl"])(),e.addSectionsToTableOfContents()})).catch((function(){e.isLoading=!1}))},computed:{apiMethod:function(){return"admin"===this.mode?"CorePluginsAdmin.getSystemSettings":"CorePluginsAdmin.getUserSettings"},saveApiMethod:function(){return"admin"===this.mode?"CorePluginsAdmin.setSystemSettings":"CorePluginsAdmin.setUserSettings"}},methods:{addSectionsToTableOfContents:function(){var
e=Kl("#generalSettingsTOC");if(e.length){var
t=this.settingsPerPlugin;t.forEach((function(t){var
n=t.pluginName,r=t.settings;n&&("CoreAdminHome"===n&&r?r.filter((function(e){return
e.introduction})).forEach((function(t){e.append('<a
href="#/'.concat(n,'PluginSettings">').concat(t.introduction,"</a>
"))})):e.append('<a href="#/'.concat(n,'">').concat(n.replace(/([A-Z])/g,"
$1").trim(),"</a>
")))}))}},confirmPassword:function(e){this.showPasswordConfirmModal=!1,this.save(this.settingsToSave,e)},saveSetting:function(e){"admin"===this.mode?(this.settingsToSave=e,this.showPasswordConfirmModal=!0):this.save(e)},save:function(e,t){var
n=this,r=this.saveApiMethod;this.isSaving[e]=!0;var
o=this.getValuesForPlugin(e);Ci["AjaxHelper"].post({method:r},{settingValues:o,passwordConfirmation:t}).then((function(){n.isSaving[e]=!1;var
t=Ci["NotificationsStore"].show({message:Object(Ci["translate"])("CoreAdminHome_PluginSettingsSaveSuccess"),id:"generalSettings",context:"success",type:"transient"});Ci["NotificationsStore"].scrollToNotification(t)})).catch((function(){n.isSaving[e]=!1})),this.settingsToSave=null},getValuesForPlugin:function(e){var
t={};return
t[e]||(t[e]=[]),Object.entries(this.settingValues).forEach((function(n){var
r=Hl(n,2),o=r[0],i=r[1],a=o.split("."),s=Hl(a,2),l=s[0],c=s[1];if(l===e){var
u=i;!1===u?u="0":!0===u&&(u="1"),Array.isArray(u)&&0===u.length&&(u="__empty__"),t[l].push({name:c,value:u})}})),t}}});Yl.render=hl;var
Zl=Yl,Xl=window,Ql=Xl.$;
/*!
* Matomo - free/libre analytics platform
*
diff --git
a/www/plugins/CorePluginsAdmin/vue/src/PluginSettings/PluginSettings.vue
b/www/plugins/CorePluginsAdmin/vue/src/PluginSettings/PluginSettings.vue
index 0e47b71..914f68c 100644
--- a/www/plugins/CorePluginsAdmin/vue/src/PluginSettings/PluginSettings.vue
+++ b/www/plugins/CorePluginsAdmin/vue/src/PluginSettings/PluginSettings.vue
@@ -199,6 +199,10 @@ export default defineComponent({
postValue = '1';
}
+ if (Array.isArray(postValue) && postValue.length === 0) {
+ postValue = '__empty__';
+ }
+
values[pluginName].push({
name: settingName,
value: postValue,
diff --git a/www/plugins/Monolog/Formatter/LineMessageFormatter.php
b/www/plugins/Monolog/Formatter/LineMessageFormatter.php
index 6639b56..0468820 100644
--- a/www/plugins/Monolog/Formatter/LineMessageFormatter.php
+++ b/www/plugins/Monolog/Formatter/LineMessageFormatter.php
@@ -53,6 +53,8 @@ public function format(array $record)
$total = '';
foreach ($messages as $message) {
+ // escape control characters
+ $message = addcslashes($message, "\x00..\x09\x0B..\x1F\x7F");
$message = $this->prefixMessageWithRequestId($record, $message);
$total .= $this->formatMessage($class, $message, $date, $record);
}
diff --git a/www/plugins/Overlay/templates/startOverlaySession.twig
b/www/plugins/Overlay/templates/startOverlaySession.twig
index 7e8b4d5..ce1cfb3 100644
--- a/www/plugins/Overlay/templates/startOverlaySession.twig
+++ b/www/plugins/Overlay/templates/startOverlaySession.twig
@@ -16,22 +16,24 @@
parser.href = urlToRedirect;
var hostToRedirect = parser.hostname;
- var knownUrls = {{ knownUrls|raw }};
- for (var i = 0; i < knownUrls.length; i++) {
- parser.href = knownUrls[i];
- var testHost = parser.hostname;
- if (hostToRedirect === testHost && testHost) {
- match = true;
- if (navigator.appName == "Microsoft Internet Explorer") {
- // internet explorer loses the referrer if we use
window.location.href=X
- var referLink = document.createElement("a");
- referLink.href = handleProtocol(urlToRedirect);
- document.body.appendChild(referLink);
- referLink.click();
- } else {
- window.location.href = handleProtocol(urlToRedirect);
+ if (parser.protocol === 'http:' || parser.protocol === 'https:') {
+ var knownUrls = {{ knownUrls|raw }};
+ for (var i = 0; i < knownUrls.length; i++) {
+ parser.href = knownUrls[i];
+ var testHost = parser.hostname;
+ if (hostToRedirect === testHost && testHost) {
+ match = true;
+ if (navigator.appName == "Microsoft Internet Explorer") {
+ // internet explorer loses the referrer if we use
window.location.href=X
+ var referLink = document.createElement("a");
+ referLink.href = handleProtocol(urlToRedirect);
+ document.body.appendChild(referLink);
+ referLink.click();
+ } else {
+ window.location.href = handleProtocol(urlToRedirect);
+ }
+ break;
}
- break;
}
}
diff --git a/www/plugins/UsersManager/API.php b/www/plugins/UsersManager/API.php
index 999604f..ae16801 100644
--- a/www/plugins/UsersManager/API.php
+++ b/www/plugins/UsersManager/API.php
@@ -16,6 +16,8 @@
use Piwik\Access\RolesProvider;
use Piwik\Auth\Password;
use Piwik\Common;
+use Piwik\Concurrency\Lock;
+use Piwik\Concurrency\LockBackend;
use Piwik\Config;
use Piwik\Container\StaticContainer;
use Piwik\Date;
@@ -825,33 +827,35 @@ public function inviteUser($userLogin, $email,
$initialIdSite = null, $expiryInD
*/
public function setSuperUserAccess($userLogin, $hasSuperUserAccess,
$passwordConfirmation = null)
{
- Piwik::checkUserHasSuperUserAccess();
- $this->checkUserIsNotAnonymous($userLogin);
- UsersManager::dieIfUsersAdminIsDisabled();
-
- $requirePasswordConfirmation =
self::$SET_SUPERUSER_ACCESS_REQUIRE_PASSWORD_CONFIRMATION;
- self::$SET_SUPERUSER_ACCESS_REQUIRE_PASSWORD_CONFIRMATION = true;
-
- $isCliMode = Common::isPhpCliMode() && !(defined('PIWIK_TEST_MODE') &&
PIWIK_TEST_MODE);
- if (
- !$isCliMode
- && $requirePasswordConfirmation
- ) {
- $this->confirmCurrentUserPassword($passwordConfirmation);
- }
- $this->checkUserExists($userLogin);
+ $this->executeConcurrencySafe($userLogin, function () use ($userLogin,
$hasSuperUserAccess, $passwordConfirmation) {
+ Piwik::checkUserHasSuperUserAccess();
+ $this->checkUserIsNotAnonymous($userLogin);
+ UsersManager::dieIfUsersAdminIsDisabled();
+
+ $requirePasswordConfirmation =
self::$SET_SUPERUSER_ACCESS_REQUIRE_PASSWORD_CONFIRMATION;
+ self::$SET_SUPERUSER_ACCESS_REQUIRE_PASSWORD_CONFIRMATION = true;
+
+ $isCliMode = Common::isPhpCliMode() &&
!(defined('PIWIK_TEST_MODE') && PIWIK_TEST_MODE);
+ if (
+ !$isCliMode
+ && $requirePasswordConfirmation
+ ) {
+ $this->confirmCurrentUserPassword($passwordConfirmation);
+ }
+ $this->checkUserExists($userLogin);
- if (!$hasSuperUserAccess &&
$this->isUserTheOnlyUserHavingSuperUserAccess($userLogin)) {
- $message =
Piwik::translate("UsersManager_ExceptionRemoveSuperUserAccessOnlySuperUser",
$userLogin)
- . " "
- .
Piwik::translate("UsersManager_ExceptionYouMustGrantSuperUserAccessFirst");
- throw new Exception($message);
- }
+ if (!$hasSuperUserAccess &&
$this->isUserTheOnlyUserHavingSuperUserAccess($userLogin)) {
+ $message =
Piwik::translate("UsersManager_ExceptionRemoveSuperUserAccessOnlySuperUser",
$userLogin)
+ . " "
+ .
Piwik::translate("UsersManager_ExceptionYouMustGrantSuperUserAccessFirst");
+ throw new Exception($message);
+ }
- $this->model->deleteUserAccess($userLogin);
- $this->model->setSuperUserAccess($userLogin, $hasSuperUserAccess);
+ $this->model->deleteUserAccess($userLogin);
+ $this->model->setSuperUserAccess($userLogin, $hasSuperUserAccess);
- Cache::deleteTrackerCache();
+ Cache::deleteTrackerCache();
+ });
}
/**
@@ -1152,46 +1156,50 @@ public function setUserAccess($userLogin, $access,
$idSites, $passwordConfirmati
}
$this->checkUserExist($userLogin);
- $this->checkUsersHasNotSuperUserAccess($userLogin);
- $this->model->deleteUserAccess($userLogin, $idSites);
+ $this->executeConcurrencySafe($userLogin, function () use ($userLogin,
$access, $idSites, $roles, $capabilities) {
+ $idSites = $this->getIdSitesCheckAdminAccess($idSites);
+ $this->checkUsersHasNotSuperUserAccess($userLogin);
- if ($access === 'noaccess') {
- // if the access is noaccess then we don't save it as this is the
default value
- // when no access are specified
- Piwik::postEvent('UsersManager.removeSiteAccess', [$userLogin,
$idSites]);
- } else {
- $role = array_shift($roles);
- $this->model->addUserAccess($userLogin, $role, $idSites);
- }
+ $this->model->deleteUserAccess($userLogin, $idSites);
- if (!empty($capabilities)) {
- $this->addCapabilities($userLogin, $capabilities, $idSites);
- }
+ if ($access === 'noaccess') {
+ // if the access is noaccess then we don't save it as this is
the default value
+ // when no access are specified
+ Piwik::postEvent('UsersManager.removeSiteAccess', [$userLogin,
$idSites]);
+ } else {
+ $role = array_shift($roles);
+ $this->model->addUserAccess($userLogin, $role, $idSites);
+ }
- // Send notification to all super users if anonymous access is set for
a site
- if ($userLogin === 'anonymous' && $access === 'view') {
- $container = StaticContainer::getContainer();
+ if (!empty($capabilities)) {
+ $this->addCapabilitesToUser($userLogin, $capabilities,
$idSites);
+ }
- $siteNames = [];
+ // Send notification to all super users if anonymous access is set
for a site
+ if ($userLogin === 'anonymous' && $access === 'view') {
+ $container = StaticContainer::getContainer();
- foreach ($idSites as $idSite) {
- $siteNames[] = Site::getNameFor($idSite);
- }
+ $siteNames = [];
- $superUsers = Piwik::getAllSuperUserAccessEmailAddresses();
- foreach ($superUsers as $login => $email) {
- $email = $container->make(AnonymousAccessEnabledEmail::class,
array(
- 'login' => $login,
- 'emailAddress' => $email,
- 'siteName' => implode(', ', $siteNames)
- ));
- $email->safeSend();
+ foreach ($idSites as $idSite) {
+ $siteNames[] = Site::getNameFor($idSite);
+ }
+
+ $superUsers = Piwik::getAllSuperUserAccessEmailAddresses();
+ foreach ($superUsers as $login => $email) {
+ $email =
$container->make(AnonymousAccessEnabledEmail::class, array(
+ 'login' => $login,
+ 'emailAddress' => $email,
+ 'siteName' => implode(', ', $siteNames)
+ ));
+ $email->safeSend();
+ }
}
- }
- // we reload the access list which doesn't yet take in consideration
this new user access
- $this->reloadPermissions();
+ // we reload the access list which doesn't yet take in
consideration this new user access
+ $this->reloadPermissions();
+ });
}
/**
@@ -1208,28 +1216,40 @@ public function setUserAccess($userLogin, $access,
$idSites, $passwordConfirmati
*/
public function addCapabilities($userLogin, $capabilities, $idSites)
{
- $idSites = $this->getIdSitesCheckAdminAccess($idSites);
+ $this->executeConcurrencySafe($userLogin, function () use ($userLogin,
$capabilities, $idSites) {
+ $idSites = $this->getIdSitesCheckAdminAccess($idSites);
- if ($userLogin == 'anonymous') {
- throw new
Exception(Piwik::translate("UsersManager_ExceptionAnonymousNoCapabilities"));
- }
+ if ($userLogin == 'anonymous') {
+ throw new
Exception(Piwik::translate("UsersManager_ExceptionAnonymousNoCapabilities"));
+ }
- $this->checkUserExists($userLogin);
- $this->checkUsersHasNotSuperUserAccess([$userLogin]);
+ $this->checkUserExists($userLogin);
+ $this->checkUsersHasNotSuperUserAccess([$userLogin]);
- if (!is_array($capabilities)) {
- $capabilities = [$capabilities];
- }
+ if (!is_array($capabilities)) {
+ $capabilities = [$capabilities];
+ }
- foreach ($capabilities as $entry) {
- $this->capabilityProvider->checkValidCapability($entry);
- }
+ foreach ($capabilities as $entry) {
+ $this->capabilityProvider->checkValidCapability($entry);
+ }
+
+ $this->addCapabilitesToUser($userLogin, $capabilities, $idSites);
+ // we reload the access list which doesn't yet take in
consideration this new user access
+ $this->reloadPermissions();
+ });
+ }
+
+ private function addCapabilitesToUser(string $userLogin, array
$capabilities, $idSites)
+ {
[$sitesIdWithRole, $sitesIdWithCapability] =
$this->getRolesAndCapabilitiesForLogin($userLogin);
foreach ($idSites as $idSite) {
if (!array_key_exists($idSite, $sitesIdWithRole)) {
- throw new
Exception(Piwik::translate('UsersManager_ExceptionNoCapabilitiesWithoutRole',
[$userLogin, $idSite]));
+ throw new Exception(
+
Piwik::translate('UsersManager_ExceptionNoCapabilitiesWithoutRole',
[$userLogin, $idSite])
+ );
}
}
@@ -1252,9 +1272,6 @@ public function addCapabilities($userLogin,
$capabilities, $idSites)
}
}
}
-
- // we reload the access list which doesn't yet take in consideration
this new user access
- $this->reloadPermissions();
}
private function getRolesAndCapabilitiesForLogin($userLogin)
@@ -1290,24 +1307,26 @@ private function
getRolesAndCapabilitiesForLogin($userLogin)
*/
public function removeCapabilities($userLogin, $capabilities, $idSites)
{
- $idSites = $this->getIdSitesCheckAdminAccess($idSites);
+ $this->executeConcurrencySafe($userLogin, function () use ($userLogin,
$capabilities, $idSites) {
+ $idSites = $this->getIdSitesCheckAdminAccess($idSites);
- $this->checkUserExists($userLogin);
+ $this->checkUserExists($userLogin);
- if (!is_array($capabilities)) {
- $capabilities = [$capabilities];
- }
+ if (!is_array($capabilities)) {
+ $capabilities = [$capabilities];
+ }
- foreach ($capabilities as $capability) {
- $this->capabilityProvider->checkValidCapability($capability);
- }
+ foreach ($capabilities as $capability) {
+ $this->capabilityProvider->checkValidCapability($capability);
+ }
- foreach ($capabilities as $capability) {
- $this->model->removeUserAccess($userLogin, $capability, $idSites);
- }
+ foreach ($capabilities as $capability) {
+ $this->model->removeUserAccess($userLogin, $capability,
$idSites);
+ }
- // we reload the access list which doesn't yet take in consideration
this removed capability
- $this->reloadPermissions();
+ // we reload the access list which doesn't yet take in
consideration this removed capability
+ $this->reloadPermissions();
+ });
}
private function reloadPermissions()
@@ -1318,6 +1337,9 @@ private function reloadPermissions()
private function getIdSitesCheckAdminAccess($idSites)
{
+ // reload access to ensure we're not working with cached entries that
might have been changed in between
+ Access::getInstance()->reloadAccess();
+
if ($idSites === 'all') {
// in case idSites is all we grant access to all the websites on
which the current connected user has an 'admin' access
$idSites =
\Piwik\Plugins\SitesManager\API::getInstance()->getSitesIdWithAdminAccess();
@@ -1658,4 +1680,10 @@ public function generateInviteLink($userLogin,
$expiryInDays = 7, $passwordConfi
'token' => $token,
]);
}
+
+ private function executeConcurrencySafe(string $userLogin, callable
$callback = null)
+ {
+ $lock = new Lock(StaticContainer::get(LockBackend::class),
'UsersManager.changePermissions');
+ $lock->execute($userLogin, $callback);
+ }
}
diff --git a/www/vendor/composer/InstalledVersions.php
b/www/vendor/composer/InstalledVersions.php
index 07b32ed..6d29bff 100644
--- a/www/vendor/composer/InstalledVersions.php
+++ b/www/vendor/composer/InstalledVersions.php
@@ -32,6 +32,11 @@ class InstalledVersions
*/
private static $installed;
+ /**
+ * @var bool
+ */
+ private static $installedIsLocalDir;
+
/**
* @var bool|null
*/
@@ -309,6 +314,12 @@ public static function reload($data)
{
self::$installed = $data;
self::$installedByVendor = array();
+
+ // when using reload, we disable the duplicate protection to ensure
that self::$installed data is
+ // always returned, but we cannot know whether it comes from the
installed.php in __DIR__ or not,
+ // so we have to assume it does not, and that may result in duplicate
data being returned when listing
+ // all installed packages for example
+ self::$installedIsLocalDir = false;
}
/**
@@ -325,7 +336,9 @@ private static function getInstalled()
$copiedLocalDir = false;
if (self::$canGetVendors) {
+ $selfDir = strtr(__DIR__, '\\', '/');
foreach (ClassLoader::getRegisteredLoaders() as $vendorDir =>
$loader) {
+ $vendorDir = strtr($vendorDir, '\\', '/');
if (isset(self::$installedByVendor[$vendorDir])) {
$installed[] = self::$installedByVendor[$vendorDir];
} elseif (is_file($vendorDir.'/composer/installed.php')) {
@@ -333,11 +346,14 @@ private static function getInstalled()
$required = require $vendorDir.'/composer/installed.php';
self::$installedByVendor[$vendorDir] = $required;
$installed[] = $required;
- if (strtr($vendorDir.'/composer', '\\', '/') ===
strtr(__DIR__, '\\', '/')) {
+ if (self::$installed === null && $vendorDir.'/composer'
=== $selfDir) {
self::$installed = $required;
- $copiedLocalDir = true;
+ self::$installedIsLocalDir = true;
}
}
+ if (self::$installedIsLocalDir && $vendorDir.'/composer' ===
$selfDir) {
+ $copiedLocalDir = true;
+ }
}
}