From b407f26e024c9f3d10fc9c0ea14fe2649c01e1e2 Mon Sep 17 00:00:00 2001 From: Luke Towers Date: Thu, 10 Sep 2020 12:12:46 -0600 Subject: [PATCH] Add support for \Path\To\Class::staticMethodName for defining field options. Related: https://github.com/octobercms/library/commit/95d0b61a298d0933dd2117967481e00b416029c4 --- modules/backend/lang/en/lang.php | 1 + modules/backend/widgets/Form.php | 17 +++++++++++++++++ 2 files changed, 18 insertions(+) diff --git a/modules/backend/lang/en/lang.php b/modules/backend/lang/en/lang.php index 368664c63..230e744a4 100644 --- a/modules/backend/lang/en/lang.php +++ b/modules/backend/lang/en/lang.php @@ -9,6 +9,7 @@ return [ 'invalid_type' => 'Invalid field type used :type.', 'options_method_invalid_model' => "The attribute ':field' does not resolve to a valid model. Try specifying the options method for model class :model explicitly.", 'options_method_not_exists' => "The model class :model must define a method :method() returning options for the ':field' form field.", + 'options_static_method_invalid_value' => "The static method ':method()' on :class did not return a valid options array.", 'colors_method_not_exists' => "The model class :model must define a method :method() returning html color HEX codes for the ':field' form field.", ], 'widget' => [ diff --git a/modules/backend/widgets/Form.php b/modules/backend/widgets/Form.php index 5b79a6c75..c2acbb2a3 100644 --- a/modules/backend/widgets/Form.php +++ b/modules/backend/widgets/Form.php @@ -1283,6 +1283,7 @@ class Form extends WidgetBase { /* * Advanced usage, supplied options are callable + * [\Path\To\Class, methodName] */ if (is_array($fieldOptions) && is_callable($fieldOptions)) { $fieldOptions = call_user_func($fieldOptions, $this, $field); @@ -1328,6 +1329,22 @@ class Form extends WidgetBase * Field options are an explicit method reference */ elseif (is_string($fieldOptions)) { + // \Path\To\Class::staticMethodOptions + if (str_contains($fieldOptions, '::')) { + $options = explode('::', $fieldOptions); + if (count($options) === 2 && class_exists($options[0]) && method_exists($options[0], $options[1])) { + $result = $options[0]::{$options[1]}(); + if (!is_array($result)) { + throw new ApplicationException(Lang::get('backend::lang.field.options_static_method_invalid_value', [ + 'class' => $options[0], + 'method' => $options[1] + ])); + } + return $result; + } + } + + // $model->{$fieldOptions}() if (!$this->objectMethodExists($this->model, $fieldOptions)) { throw new ApplicationException(Lang::get('backend::lang.field.options_method_not_exists', [ 'model' => get_class($this->model),