chg: [instance:settings] Moved setting provider function at the top
parent
6a89e65a37
commit
99522056fe
|
@ -24,152 +24,9 @@ class SettingsProviderTable extends AppTable
|
|||
}
|
||||
|
||||
/**
|
||||
* getSettingsConfiguration Return the setting configuration and merge existing settings into it if provided
|
||||
*
|
||||
* @param null|array $settings - Settings to be merged in the provided setting configuration
|
||||
* @return array
|
||||
*/
|
||||
public function getSettingsConfiguration($settings = null) {
|
||||
$settingConf = $this->settingsConfiguration;
|
||||
if (!is_null($settings)) {
|
||||
$settingConf = $this->mergeSettingsIntoSettingConfiguration($settingConf, $settings);
|
||||
}
|
||||
return $settingConf;
|
||||
}
|
||||
|
||||
/**
|
||||
* mergeSettingsIntoSettingConfiguration Inject the provided settings into the configuration while performing depencency and validation checks
|
||||
*
|
||||
* @param array $settingConf the setting configuration to have the setting injected into
|
||||
* @param array $settings the settings
|
||||
* @return void
|
||||
*/
|
||||
private function mergeSettingsIntoSettingConfiguration(array $settingConf, array $settings, string $path=''): array
|
||||
{
|
||||
foreach ($settingConf as $key => $value) {
|
||||
if ($this->isLeaf($value)) {
|
||||
if (isset($settings[$key])) {
|
||||
$settingConf[$key]['value'] = $settings[$key];
|
||||
}
|
||||
$settingConf[$key] = $this->evaluateLeaf($settingConf[$key], $settingConf);
|
||||
$settingConf[$key]['setting-path'] = $path;
|
||||
$settingConf[$key]['true-name'] = $key;
|
||||
} else {
|
||||
$currentPath = empty($path) ? $key : sprintf('%s.%s', $path, $key);
|
||||
$settingConf[$key] = $this->mergeSettingsIntoSettingConfiguration($value, $settings, $currentPath);
|
||||
}
|
||||
}
|
||||
return $settingConf;
|
||||
}
|
||||
|
||||
public function flattenSettingsConfiguration(array $settingsProvider, $flattenedSettings=[]): array
|
||||
{
|
||||
foreach ($settingsProvider as $key => $value) {
|
||||
if ($this->isLeaf($value)) {
|
||||
$flattenedSettings[$key] = $value;
|
||||
} else {
|
||||
$flattenedSettings = $this->flattenSettingsConfiguration($value, $flattenedSettings);
|
||||
}
|
||||
}
|
||||
return $flattenedSettings;
|
||||
}
|
||||
|
||||
/**
|
||||
* getNoticesFromSettingsConfiguration Summarize the validation errors
|
||||
*
|
||||
* @param array $settingsProvider the setting configuration having setting value assigned
|
||||
* @return void
|
||||
*/
|
||||
public function getNoticesFromSettingsConfiguration(array $settingsProvider): array
|
||||
{
|
||||
$notices = [];
|
||||
foreach ($settingsProvider as $key => $value) {
|
||||
if ($this->isLeaf($value)) {
|
||||
if (!empty($value['error'])) {
|
||||
if (empty($notices[$value['severity']])) {
|
||||
$notices[$value['severity']] = [];
|
||||
}
|
||||
$notices[$value['severity']][] = $key;
|
||||
}
|
||||
} else {
|
||||
$notices = array_merge_recursive($notices, $this->getNoticesFromSettingsConfiguration($value));
|
||||
}
|
||||
}
|
||||
return $notices;
|
||||
}
|
||||
|
||||
private function isLeaf($setting)
|
||||
{
|
||||
return !empty($setting['name']) && !empty($setting['type']);
|
||||
}
|
||||
|
||||
private function evaluateLeaf($setting, $settingSection)
|
||||
{
|
||||
$skipValidation = false;
|
||||
if ($setting['type'] == 'select') {
|
||||
if (!empty($setting['options']) && is_callable($setting['options'])) {
|
||||
$setting['options'] = $setting['options']($this);
|
||||
}
|
||||
}
|
||||
if (isset($setting['dependsOn'])) {
|
||||
$parentSetting = null;
|
||||
foreach ($settingSection as $settingSectionName => $settingSectionConfig) {
|
||||
if ($settingSectionName == $setting['dependsOn']) {
|
||||
$parentSetting = $settingSectionConfig;
|
||||
}
|
||||
}
|
||||
if (!is_null($parentSetting)) {
|
||||
$parentSetting = $this->evaluateLeaf($parentSetting, $settingSection);
|
||||
$skipValidation = $parentSetting['error'] === true || empty($parentSetting['value']);
|
||||
}
|
||||
}
|
||||
if (!$skipValidation) {
|
||||
$validationResult = true;
|
||||
if (!isset($setting['value'])) {
|
||||
$validationResult = $this->settingValidator->testEmptyBecomesDefault(null, $setting);
|
||||
} else if (isset($setting['test'])) {
|
||||
$setting['value'] = $setting['value'] ?? '';
|
||||
$validationResult = $this->evaluateFunctionForSetting($setting['test'], $setting);
|
||||
}
|
||||
if ($validationResult !== true) {
|
||||
$setting['severity'] = $setting['severity'] ?? 'warning';
|
||||
if (!in_array($setting['severity'], $this->severities)) {
|
||||
$setting['severity'] = 'warning';
|
||||
}
|
||||
$setting['errorMessage'] = $validationResult;
|
||||
}
|
||||
$setting['error'] = $validationResult !== true ? true : false;
|
||||
}
|
||||
return $setting;
|
||||
}
|
||||
|
||||
/**
|
||||
* evaluateFunctionForSetting - evaluate the provided function. If function could not be evaluated, its result is defaulted to true
|
||||
*
|
||||
* @param mixed $fun
|
||||
* @param array $setting
|
||||
* @return mixed
|
||||
*/
|
||||
public function evaluateFunctionForSetting($fun, $setting)
|
||||
{
|
||||
$functionResult = true;
|
||||
if (is_callable($fun)) { // Validate with anonymous function
|
||||
$functionResult = $fun($setting['value'], $setting, new Validator());
|
||||
} else if (method_exists($this->settingValidator, $fun)) { // Validate with function defined in settingValidator class
|
||||
$functionResult = $this->settingValidator->{$fun}($setting['value'], $setting);
|
||||
} else {
|
||||
$validator = new Validator();
|
||||
if (method_exists($validator, $fun)) { // Validate with cake's validator function
|
||||
$validator->{$fun};
|
||||
$functionResult = $validator->validate($setting['value']);
|
||||
}
|
||||
}
|
||||
return $functionResult;
|
||||
}
|
||||
|
||||
/**
|
||||
* Support up to 3 level:
|
||||
* Supports up to 3 levels:
|
||||
* Application -> Network -> Proxy -> Proxy.URL
|
||||
* page -> [group] -> [panel] -> setting
|
||||
*
|
||||
* - Leave errorMessage empty to let the validator generate the error message
|
||||
* - Default severity level is `info` if a `default` value is provided otherwise it becomes `critical`
|
||||
|
@ -322,6 +179,150 @@ class SettingsProviderTable extends AppTable
|
|||
],
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* getSettingsConfiguration Return the setting configuration and merge existing settings into it if provided
|
||||
*
|
||||
* @param null|array $settings - Settings to be merged in the provided setting configuration
|
||||
* @return array
|
||||
*/
|
||||
public function getSettingsConfiguration($settings = null) {
|
||||
$settingConf = $this->settingsConfiguration;
|
||||
if (!is_null($settings)) {
|
||||
$settingConf = $this->mergeSettingsIntoSettingConfiguration($settingConf, $settings);
|
||||
}
|
||||
return $settingConf;
|
||||
}
|
||||
|
||||
/**
|
||||
* mergeSettingsIntoSettingConfiguration Inject the provided settings into the configuration while performing depencency and validation checks
|
||||
*
|
||||
* @param array $settingConf the setting configuration to have the setting injected into
|
||||
* @param array $settings the settings
|
||||
* @return void
|
||||
*/
|
||||
private function mergeSettingsIntoSettingConfiguration(array $settingConf, array $settings, string $path=''): array
|
||||
{
|
||||
foreach ($settingConf as $key => $value) {
|
||||
if ($this->isLeaf($value)) {
|
||||
if (isset($settings[$key])) {
|
||||
$settingConf[$key]['value'] = $settings[$key];
|
||||
}
|
||||
$settingConf[$key] = $this->evaluateLeaf($settingConf[$key], $settingConf);
|
||||
$settingConf[$key]['setting-path'] = $path;
|
||||
$settingConf[$key]['true-name'] = $key;
|
||||
} else {
|
||||
$currentPath = empty($path) ? $key : sprintf('%s.%s', $path, $key);
|
||||
$settingConf[$key] = $this->mergeSettingsIntoSettingConfiguration($value, $settings, $currentPath);
|
||||
}
|
||||
}
|
||||
return $settingConf;
|
||||
}
|
||||
|
||||
public function flattenSettingsConfiguration(array $settingsProvider, $flattenedSettings=[]): array
|
||||
{
|
||||
foreach ($settingsProvider as $key => $value) {
|
||||
if ($this->isLeaf($value)) {
|
||||
$flattenedSettings[$key] = $value;
|
||||
} else {
|
||||
$flattenedSettings = $this->flattenSettingsConfiguration($value, $flattenedSettings);
|
||||
}
|
||||
}
|
||||
return $flattenedSettings;
|
||||
}
|
||||
|
||||
/**
|
||||
* getNoticesFromSettingsConfiguration Summarize the validation errors
|
||||
*
|
||||
* @param array $settingsProvider the setting configuration having setting value assigned
|
||||
* @return void
|
||||
*/
|
||||
public function getNoticesFromSettingsConfiguration(array $settingsProvider): array
|
||||
{
|
||||
$notices = [];
|
||||
foreach ($settingsProvider as $key => $value) {
|
||||
if ($this->isLeaf($value)) {
|
||||
if (!empty($value['error'])) {
|
||||
if (empty($notices[$value['severity']])) {
|
||||
$notices[$value['severity']] = [];
|
||||
}
|
||||
$notices[$value['severity']][] = $key;
|
||||
}
|
||||
} else {
|
||||
$notices = array_merge_recursive($notices, $this->getNoticesFromSettingsConfiguration($value));
|
||||
}
|
||||
}
|
||||
return $notices;
|
||||
}
|
||||
|
||||
private function isLeaf($setting)
|
||||
{
|
||||
return !empty($setting['name']) && !empty($setting['type']);
|
||||
}
|
||||
|
||||
private function evaluateLeaf($setting, $settingSection)
|
||||
{
|
||||
$skipValidation = false;
|
||||
if ($setting['type'] == 'select') {
|
||||
if (!empty($setting['options']) && is_callable($setting['options'])) {
|
||||
$setting['options'] = $setting['options']($this);
|
||||
}
|
||||
}
|
||||
if (isset($setting['dependsOn'])) {
|
||||
$parentSetting = null;
|
||||
foreach ($settingSection as $settingSectionName => $settingSectionConfig) {
|
||||
if ($settingSectionName == $setting['dependsOn']) {
|
||||
$parentSetting = $settingSectionConfig;
|
||||
}
|
||||
}
|
||||
if (!is_null($parentSetting)) {
|
||||
$parentSetting = $this->evaluateLeaf($parentSetting, $settingSection);
|
||||
$skipValidation = $parentSetting['error'] === true || empty($parentSetting['value']);
|
||||
}
|
||||
}
|
||||
if (!$skipValidation) {
|
||||
$validationResult = true;
|
||||
if (!isset($setting['value'])) {
|
||||
$validationResult = $this->settingValidator->testEmptyBecomesDefault(null, $setting);
|
||||
} else if (isset($setting['test'])) {
|
||||
$setting['value'] = $setting['value'] ?? '';
|
||||
$validationResult = $this->evaluateFunctionForSetting($setting['test'], $setting);
|
||||
}
|
||||
if ($validationResult !== true) {
|
||||
$setting['severity'] = $setting['severity'] ?? 'warning';
|
||||
if (!in_array($setting['severity'], $this->severities)) {
|
||||
$setting['severity'] = 'warning';
|
||||
}
|
||||
$setting['errorMessage'] = $validationResult;
|
||||
}
|
||||
$setting['error'] = $validationResult !== true ? true : false;
|
||||
}
|
||||
return $setting;
|
||||
}
|
||||
|
||||
/**
|
||||
* evaluateFunctionForSetting - evaluate the provided function. If function could not be evaluated, its result is defaulted to true
|
||||
*
|
||||
* @param mixed $fun
|
||||
* @param array $setting
|
||||
* @return mixed
|
||||
*/
|
||||
public function evaluateFunctionForSetting($fun, $setting)
|
||||
{
|
||||
$functionResult = true;
|
||||
if (is_callable($fun)) { // Validate with anonymous function
|
||||
$functionResult = $fun($setting['value'], $setting, new Validator());
|
||||
} else if (method_exists($this->settingValidator, $fun)) { // Validate with function defined in settingValidator class
|
||||
$functionResult = $this->settingValidator->{$fun}($setting['value'], $setting);
|
||||
} else {
|
||||
$validator = new Validator();
|
||||
if (method_exists($validator, $fun)) { // Validate with cake's validator function
|
||||
$validator->{$fun};
|
||||
$functionResult = $validator->validate($setting['value']);
|
||||
}
|
||||
}
|
||||
return $functionResult;
|
||||
}
|
||||
}
|
||||
|
||||
function testValidator($value, $validator)
|
||||
|
|
Loading…
Reference in New Issue