From 99522056fee1c71ac0a83bec9d2691f74e619e0e Mon Sep 17 00:00:00 2001 From: mokaddem Date: Tue, 27 Jul 2021 13:39:56 +0200 Subject: [PATCH] chg: [instance:settings] Moved setting provider function at the top --- src/Model/Table/SettingsProviderTable.php | 291 +++++++++++----------- 1 file changed, 146 insertions(+), 145 deletions(-) diff --git a/src/Model/Table/SettingsProviderTable.php b/src/Model/Table/SettingsProviderTable.php index 8c97f77..cf2252f 100644 --- a/src/Model/Table/SettingsProviderTable.php +++ b/src/Model/Table/SettingsProviderTable.php @@ -22,154 +22,11 @@ class SettingsProviderTable extends AppTable $this->error_info = __('There are some optional tweaks that could be done to improve the looks of your Cerebrate instance.'); $this->settingValidator = new SettingValidator(); } - - /** - * 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)