diff --git a/src/Control/RSS/RSSFeed_Entry.php b/src/Control/RSS/RSSFeed_Entry.php index 1ebaae7e7de..810f2589649 100644 --- a/src/Control/RSS/RSSFeed_Entry.php +++ b/src/Control/RSS/RSSFeed_Entry.php @@ -47,7 +47,7 @@ class RSSFeed_Entry extends ModelData */ public function __construct($entry, $titleField, $descriptionField, $authorField) { - $this->failover = $entry; + $this->setFailover($entry); $this->titleField = $titleField; $this->descriptionField = $descriptionField; $this->authorField = $authorField; @@ -58,9 +58,9 @@ public function __construct($entry, $titleField, $descriptionField, $authorField /** * Get the description of this entry * - * @return DBField Returns the description of the entry. + * @return DBField|null Returns the description of the entry. */ - public function Title() + public function getTitle() { return $this->rssField($this->titleField); } @@ -68,9 +68,9 @@ public function Title() /** * Get the description of this entry * - * @return DBField Returns the description of the entry. + * @return DBField|null Returns the description of the entry. */ - public function Description() + public function getDescription() { $description = $this->rssField($this->descriptionField); @@ -85,9 +85,9 @@ public function Description() /** * Get the author of this entry * - * @return DBField Returns the author of the entry. + * @return DBField|null Returns the author of the entry. */ - public function Author() + public function getAuthor() { return $this->rssField($this->authorField); } @@ -96,7 +96,7 @@ public function Author() * Return the safely casted field * * @param string $fieldName Name of field - * @return DBField + * @return DBField|null */ public function rssField($fieldName) { diff --git a/src/Core/CustomMethods.php b/src/Core/CustomMethods.php index 97f84f07d64..e6edc573894 100644 --- a/src/Core/CustomMethods.php +++ b/src/Core/CustomMethods.php @@ -36,6 +36,8 @@ trait CustomMethods */ protected static $built_in_methods = []; + protected array $extraMethodsForInstance = []; + /** * Attempts to locate and call a method dynamically added to a class at runtime if a default cannot be located * @@ -175,7 +177,7 @@ protected function getExtraMethodConfig($method) $this->defineMethods(); } - return self::class::$extra_methods[$lowerClass][strtolower($method)] ?? null; + return $this->extraMethodsForInstance[strtolower($method)] ?? self::class::$extra_methods[$lowerClass][strtolower($method)] ?? null; } /** @@ -190,6 +192,9 @@ public function allMethodNames($custom = false) // Query extra methods $lowerClass = strtolower(static::class); + if ($custom && !empty($this->extraMethodsForInstance)) { + $methods = array_merge($this->extraMethodsForInstance, $methods); + } if ($custom && isset(self::class::$extra_methods[$lowerClass])) { $methods = array_merge(self::class::$extra_methods[$lowerClass], $methods); } @@ -256,7 +261,7 @@ protected function findMethodsFrom($object) * @param string|int $index an index to use if the property is an array * @throws InvalidArgumentException */ - protected function addMethodsFrom($property, $index = null) + protected function addMethodsFrom($property, $index = null, bool $static = true) { $class = static::class; $object = ($index !== null) ? $this->{$property}[$index] : $this->$property; @@ -280,10 +285,18 @@ protected function addMethodsFrom($property, $index = null) // Merge with extra_methods $lowerClass = strtolower($class); - if (isset(self::class::$extra_methods[$lowerClass])) { - self::class::$extra_methods[$lowerClass] = array_merge(self::class::$extra_methods[$lowerClass], $newMethods); + if ($static) { + if (isset(self::class::$extra_methods[$lowerClass])) { + self::class::$extra_methods[$lowerClass] = array_merge(self::class::$extra_methods[$lowerClass], $newMethods); + } else { + self::class::$extra_methods[$lowerClass] = $newMethods; + } } else { - self::class::$extra_methods[$lowerClass] = $newMethods; + if (!empty($this->extraMethodsForInstance)) { + $this->extraMethodsForInstance = array_merge($this->extraMethodsForInstance, $newMethods); + } else { + $this->extraMethodsForInstance = $newMethods; + } } } @@ -293,7 +306,7 @@ protected function addMethodsFrom($property, $index = null) * @param string $property the property name * @param string|int $index an index to use if the property is an array */ - protected function removeMethodsFrom($property, $index = null) + protected function removeMethodsFrom($property, $index = null, bool $static = true) { $extension = ($index !== null) ? $this->{$property}[$index] : $this->$property; $class = static::class; @@ -310,12 +323,22 @@ protected function removeMethodsFrom($property, $index = null) } $methods = $this->findMethodsFrom($extension); - // Unset by key - self::class::$extra_methods[$lowerClass] = array_diff_key(self::class::$extra_methods[$lowerClass], $methods); + if ($static) { + // Unset by key + self::class::$extra_methods[$lowerClass] = array_diff_key(self::class::$extra_methods[$lowerClass], $methods); - // Clear empty list - if (empty(self::class::$extra_methods[$lowerClass])) { - unset(self::class::$extra_methods[$lowerClass]); + // Clear empty list + if (empty(self::class::$extra_methods[$lowerClass])) { + unset(self::class::$extra_methods[$lowerClass]); + } + } else { + // Unset by key + $this->extraMethodsForInstance = array_diff_key($this->extraMethodsForInstance, $methods); + + // Clear empty list + if (empty($this->extraMethodsForInstance)) { + unset($this->extraMethodsForInstance); + } } } diff --git a/src/Dev/Backtrace.php b/src/Dev/Backtrace.php index 62d402efc51..9aa7b85ad81 100644 --- a/src/Dev/Backtrace.php +++ b/src/Dev/Backtrace.php @@ -149,11 +149,11 @@ public static function full_func_name($item, $showArgs = false, $argCharLimit = if ($showArgs && isset($item['args'])) { $args = []; foreach ($item['args'] as $arg) { - if (!is_object($arg) || method_exists($arg, '__toString')) { + if (is_object($arg)) { + $args[] = get_class($arg); + } else { $sarg = is_array($arg) ? 'Array' : strval($arg); $args[] = (strlen($sarg ?? '') > $argCharLimit) ? substr($sarg, 0, $argCharLimit) . '...' : $sarg; - } else { - $args[] = get_class($arg); } } diff --git a/src/Forms/CheckboxSetField.php b/src/Forms/CheckboxSetField.php index 6f11db35799..6386564f187 100644 --- a/src/Forms/CheckboxSetField.php +++ b/src/Forms/CheckboxSetField.php @@ -46,13 +46,13 @@ class CheckboxSetField extends MultiSelectField * @param array $properties * @return DBHTMLText */ - public function Field($properties = []) + public function renderField($properties = []) { $properties = array_merge($properties, [ 'Options' => $this->getOptions() ]); - return FormField::Field($properties); + return FormField::renderField($properties); } /** diff --git a/src/Forms/ConfirmedPasswordField.php b/src/Forms/ConfirmedPasswordField.php index fa61dc91a38..d990a28fa9b 100644 --- a/src/Forms/ConfirmedPasswordField.php +++ b/src/Forms/ConfirmedPasswordField.php @@ -195,7 +195,7 @@ public function setTitle($title) * * @return string */ - public function Field($properties = []) + public function renderField($properties = []) { // Build inner content $fieldContent = ''; @@ -209,7 +209,7 @@ public function Field($properties = []) } } - $fieldContent .= $field->FieldHolder(['AttributesHTML' => $this->getAttributesHTMLForChild($field)]); + $fieldContent .= $field->renderFieldHolder(['AttributesHTML' => $this->getAttributesHTMLForChild($field)]); } if (!$this->showOnClick) { diff --git a/src/Forms/CurrencyField_Disabled.php b/src/Forms/CurrencyField_Disabled.php index 4b26a7065d0..c5963b479a9 100644 --- a/src/Forms/CurrencyField_Disabled.php +++ b/src/Forms/CurrencyField_Disabled.php @@ -19,7 +19,7 @@ class CurrencyField_Disabled extends CurrencyField * @param array $properties * @return string */ - public function Field($properties = []) + public function renderField($properties = []) { if ($this->value) { $val = Convert::raw2xml($this->value); diff --git a/src/Forms/CurrencyField_Readonly.php b/src/Forms/CurrencyField_Readonly.php index d9bb4037fcf..28280f18ed7 100644 --- a/src/Forms/CurrencyField_Readonly.php +++ b/src/Forms/CurrencyField_Readonly.php @@ -17,7 +17,7 @@ class CurrencyField_Readonly extends ReadonlyField * @param array $properties * @return string */ - public function Field($properties = []) + public function renderField($properties = []) { $currencySymbol = DBCurrency::config()->get('currency_symbol'); if ($this->value) { diff --git a/src/Forms/DatalessField.php b/src/Forms/DatalessField.php index 0bddbc657a1..21d7a0fd1b4 100644 --- a/src/Forms/DatalessField.php +++ b/src/Forms/DatalessField.php @@ -42,9 +42,9 @@ public function getAttributes() * @param array $properties * @return DBHTMLText */ - public function FieldHolder($properties = []) + public function renderFieldHolder($properties = []) { - return $this->Field($properties); + return $this->renderField($properties); } /** @@ -54,9 +54,9 @@ public function FieldHolder($properties = []) * @param array $properties * @return DBHTMLText */ - public function SmallFieldHolder($properties = []) + public function renderSmallFieldHolder($properties = []) { - return $this->Field($properties); + return $this->renderField($properties); } /** diff --git a/src/Forms/DateField_Disabled.php b/src/Forms/DateField_Disabled.php index 6bdc64f882e..113ae0bb219 100644 --- a/src/Forms/DateField_Disabled.php +++ b/src/Forms/DateField_Disabled.php @@ -14,7 +14,7 @@ class DateField_Disabled extends DateField protected $disabled = true; - public function Field($properties = []) + public function renderField($properties = []) { // Default display value $displayValue = '(' . _t('SilverStripe\\Forms\\DateField.NOTSET', 'not set') . ')'; diff --git a/src/Forms/DropdownField.php b/src/Forms/DropdownField.php index ed5da300034..2dfba72b8c3 100644 --- a/src/Forms/DropdownField.php +++ b/src/Forms/DropdownField.php @@ -68,7 +68,7 @@ * DropdownField::create( * 'Country', * 'Country', - * singleton(MyObject::class)->dbObject('Country')->enumValues() + * singleton(MyObject::class)->dbObject('Country')?->enumValues() * ); * * @@ -128,7 +128,7 @@ public function getHasEmptyDefault() * @param array $properties * @return string */ - public function Field($properties = []) + public function renderField($properties = []) { $options = []; @@ -141,6 +141,6 @@ public function Field($properties = []) 'Options' => new ArrayList($options) ]); - return parent::Field($properties); + return parent::renderField($properties); } } diff --git a/src/Forms/FieldGroup.php b/src/Forms/FieldGroup.php index 9a0d6c67588..1a14021a78c 100644 --- a/src/Forms/FieldGroup.php +++ b/src/Forms/FieldGroup.php @@ -9,8 +9,8 @@ * Lets you include a nested group of fields inside a template. * This control gives you more flexibility over form layout. * - * Note: the child fields within a field group aren't rendered using FieldHolder(). Instead, - * SmallFieldHolder() is called, which just prefixes $Field with a