The Matomo (formerly Piwik) platform differentiate between "System Settings", "User Settings" and "Measurable Settings":
User Settings can be configured by any logged in user and each user can configure the setting independently. The Matomo platform makes sure that settings are stored per user and that a user cannot see another user's configuration. A user will be able to change the settings on the "Personal Settings" page.
System Settings applies to all of your users. It can be configured only by a user who has super user access. System Settings will appear on the "General Settings" page.
Measurable Settings add new fields when creating or editing a website or another measurable such as a mobile app. The values for these settings can be changed by any user having admin access for a specific website and the settings are saved separately for each site. All fields shown in the websites manager are actually Measurable Settings and these can be used to create whole new types such as "Mobile Apps", "Cars", "Embedded device", etc.
All these classes extend the Settings class.
Matomo can create the Settings
class for you by using the console:
$ ./console generate:settings
The command will ask you to enter the name of your plugin and for the type of settings you want to create.
Depending on the chosen type it will create a file named UserSettings.php
, SystemSettings.php
or
MeasurableSettings.php
, for example plugins/MyPlugin/SystemSettings.php
. This created file contains some examples to
get you started. The creation and definition of settings works the same across the different types.
To see the settings in action go to Administration > General Settings in your Matomo installation.
Settings are added in the init()
method of the settings class. To do this, call the makeSetting()
and pass in the
internal name of the setting, the default value, which PHP type the setting should return and a callback to configure
the UI representation of the form field.
For example:
class SystemSettings extends \Piwik\Settings\Plugin\SystemSettings
{
/** @var Setting */
public $autoRefresh;
/** @var Setting */
public $refreshInterval;
protected function init()
{
$this->autoRefresh = $this->createAutoRefreshSetting();
$this->refreshInterval = $this->createRefreshIntervalSetting();
}
private function createAutoRefreshSetting()
{
return $this->makeSetting('autoRefresh', $default = false, FieldConfig::TYPE_BOOL, function (FieldConfig $field) {
$field->title = 'Auto refresh';
$field->uiControl = FieldConfig::UI_CONTROL_CHECKBOX;
$field->description = 'If enabled, the value will be automatically refreshed depending on the specified interval';
});
}
private function createRefreshIntervalSetting()
{
return $this->makeSetting('refreshInterval', $default = '3', FieldConfig::TYPE_INT, function (FieldConfig $field) {
$field->title = 'Refresh Interval';
$field->uiControl = FieldConfig::UI_CONTROL_TEXT;
$field->uiControlAttributes = array('size' => 3);
$field->inlineHelp = 'Enter a number which is >= 15';
$field->introduction = 'New group of settings';
$field->description = 'Defines how often the value should be updated';
$field->validate = function ($value, $setting) {
if ($value < 15) {
throw new \Exception('Value is invalid');
}
};
});
}
}
For a list of possible properties for each setting have a look at the Setting and FieldConfig API reference. See also the ExampleSettingsPlugin to see what else is possible.
You might be wondering why some properties are configured as parameters when making the setting and some properties in
the callback method. The reason for this is performance because we usually create all settings on each request.
Everything that is configured within the callback to configure the FieldConfig $field
is only needed when the setting
is going to be displayed in the UI. All other times the field config is irrelevant, and we save time by not executing
these actions. Especially since some settings might perform API requests to get a list of available values etc. within
this callback.
System settings cannot be only configured via the UI but also via the config/config.ini.php
file. For example for
the plugin MyPlugin
it is possible to configure the value for a setting refreshInterval
like this:
[MyPlugin]
refreshInterval = 15
As soon as a value in the config file is configured, it won't be possible to change the value for that setting anymore in the UI and the setting will not be even displayed.
For example a system setting can be only configured by a user with super user access by default. However, you can
customize this behaviour by using the setIsWritableByCurrentUser
method. For example, you can define to let only a user
named "MyRootUser" change the setting. All other users would not be able to see the value for that setting and neither
would they be able to change it.
$this->autoRefresh = $this->createAutoRefreshSetting();
$login = \Piwik\Piwik::getCurrentUserLogin();
$this->autoRefresh->setIsWritableByCurrentUser($login == 'MyRootUser');
Sometimes you might want to create a setting but not have it visible in the UI at all. This is for example useful if you
make the visibility of a setting dependent on another setting or you only want users to configure it via the
config/config.ini.php
. To make sure a setting cannot be changed via the UI call setIsWritableByCurrentUser(false)
.
$this->autoRefresh = $this->createAutoRefreshSetting();
$login = \Piwik\Piwik::getCurrentUserLogin();
$this->autoRefresh->setIsWritableByCurrentUser(false);
Sometimes you might have a bit more complicated form where a setting should be only visible when another setting
is configured in a certain way. Matomo can show or hide settings dynamically without reloading based on a certain
condition. Say we wanted to have the setting refreshInterval
only visible if autoRefresh
is enabled, then
we can do this as follows:
$this->makeSetting('refreshInterval', $default = '3', FieldConfig::TYPE_INT, function (FieldConfig $field) {
$field->condition = 'autoRefresh';
// instead it was also possible to write eg 'autoRefresh == 1' or 'autoRefresh == true'
// multiple conditions can be combined such as 'autoRefresh == 1 && anotherSetting == "foobar"'
});
You can access the value of a setting in a widget, in a controller, in a report or anywhere you want. To access the value create an instance of your settings class and get the value like below.
$settings = new \Piwik\Plugins\MyPlugin\SystemSettings();
$interval = $settings->refreshInterval->getValue()
$settings = new \Piwik\Plugins\MyPlugin\UserSettings();
$interval = $settings->refreshInterval->getValue()
$settings = new \Piwik\Plugins\MyPlugin\MeasurableSettings($idSite);
$interval = $settings->refreshInterval->getValue()