diff --git a/modules/cms/classes/Theme.php b/modules/cms/classes/Theme.php index e6ae6c64f..c7b9f525f 100644 --- a/modules/cms/classes/Theme.php +++ b/modules/cms/classes/Theme.php @@ -312,7 +312,77 @@ class Theme return $this->configCache = []; } - return $this->configCache = Yaml::parseFile($path); + $config = Yaml::parseFile($path); + + /** + * @event cms.theme.extendFormConfig + * Extend basic theme configuration supplied by the theme by returning an array. + * + * Note if planning on extending form fields, use the `cms.theme.extendFormConfig` + * event instead. + * + * Example usage: + * + * Event::listen('cms.theme.extendConfig', function ($themeCode, $config) { + * $config['name'] = 'October Theme'; + * $config['description'] = 'Another great theme from October CMS'; + * return $config; + * }); + * + */ + if ($results = Event::fire('cms.theme.extendConfig', [$this->getDirName(), $config])) { + foreach ($results as $result) { + if (!is_array($result)) { + continue; + } + $config = array_merge($config, $result); + } + } + + return $this->configCache = $config; + } + + /** + * Themes have a dedicated `form` option that provide form fields + * for customization, this is an immutable accessor for that and + * also an solid anchor point for extension. + * @return array + */ + public function getFormConfig() + { + $config = $this->getConfigArray('form'); + + /** + * @event cms.theme.extendFormConfig + * Extend form field configuration supplied by the theme by returning an array. + * + * Note if you are planning on using `assetVar` to inject CSS variables from a + * plugin registration file, make sure the plugin has elevated permissions. + * + * Example usage: + * + * Event::listen('cms.theme.extendFormConfig', function ($themeCode, $config) { + * array_set($config, 'tabs.fields.header_color', [ + * 'label' => 'Header Colour', + * 'type' => 'colorpicker', + * 'availableColors' => [#34495e, #708598, #3498db], + * 'assetVar' => 'header-bg', + * 'tab' => 'Global' + * ]); + * return $config; + * }); + * + */ + if ($results = Event::fire('cms.theme.extendFormConfig', [$this->getDirName(), $config])) { + foreach ($results as $result) { + if (!is_array($result)) { + continue; + } + $config = array_merge($config, $result); + } + } + + return $config; } /** diff --git a/modules/cms/controllers/ThemeOptions.php b/modules/cms/controllers/ThemeOptions.php index 6f44476ad..dd4a332a6 100644 --- a/modules/cms/controllers/ThemeOptions.php +++ b/modules/cms/controllers/ThemeOptions.php @@ -86,7 +86,7 @@ class ThemeOptions extends Controller { $model = $form->model; $theme = $this->findThemeObject($model->theme); - $config = $theme->getConfigArray('form'); + $config = $theme->getFormConfig(); if ($fields = array_get($config, 'fields')) { $form->addFields($fields); diff --git a/modules/cms/models/ThemeData.php b/modules/cms/models/ThemeData.php index 69194d310..60da81270 100644 --- a/modules/cms/models/ThemeData.php +++ b/modules/cms/models/ThemeData.php @@ -52,6 +52,10 @@ class ThemeData extends Model */ protected static $instances = []; + /** + * Before saving the model, strip dynamic attributes applied from config. + * @return void + */ public function beforeSave() { /* @@ -64,6 +68,10 @@ class ThemeData extends Model $this->setRawAttributes(array_only($this->getAttributes(), $staticAttributes)); } + /** + * Clear asset cache after saving to ensure `assetVar` form fields take + * immediate effect. + */ public function afterSave() { try { @@ -95,6 +103,11 @@ class ThemeData extends Model return self::$instances[$dirName] = $themeData; } + /** + * After fetching the model, intiialize model relationships based + * on form field definitions. + * @return void + */ public function afterFetch() { $data = (array) $this->data + $this->getDefaultValues(); @@ -122,6 +135,10 @@ class ThemeData extends Model $this->setRawAttributes((array) $this->getAttributes() + $data, true); } + /** + * Before model is validated, set the default values. + * @return void + */ public function beforeValidate() { if (!$this->exists) { @@ -149,6 +166,7 @@ class ThemeData extends Model /** * Gets default values for this model based on form field definitions. + * @return array */ public function getDefaultValues() { @@ -175,7 +193,7 @@ class ThemeData extends Model throw new Exception(Lang::get('Unable to find theme with name :name', $this->theme)); } - $config = $theme->getConfigArray('form'); + $config = $theme->getFormConfig(); return array_get($config, 'fields', []) + array_get($config, 'tabs.fields', []) +