diff --git a/src/Illuminate/Database/Eloquent/Concerns/HasAttributes.php b/src/Illuminate/Database/Eloquent/Concerns/HasAttributes.php index 5225cc01207f..d536d1fd0970 100644 --- a/src/Illuminate/Database/Eloquent/Concerns/HasAttributes.php +++ b/src/Illuminate/Database/Eloquent/Concerns/HasAttributes.php @@ -2145,25 +2145,27 @@ public function hasAppended($attribute) */ public function getMutatedAttributes() { - $class = static::class; - - if (! isset(static::$mutatorCache[$class])) { - static::cacheMutatedAttributes($class); + if (! isset(static::$mutatorCache[static::class])) { + static::cacheMutatedAttributes($this); } - return static::$mutatorCache[$class]; + return static::$mutatorCache[static::class]; } /** * Extract and cache all the mutated attributes of a class. * - * @param string $class + * @param object|string $classOrInstance * @return void */ - public static function cacheMutatedAttributes($class) + public static function cacheMutatedAttributes($classOrInstance) { + $reflection = new ReflectionClass($classOrInstance); + + $class = $reflection->getName(); + static::$getAttributeMutatorCache[$class] = - collect($attributeMutatorMethods = static::getAttributeMarkedMutatorMethods($class)) + collect($attributeMutatorMethods = static::getAttributeMarkedMutatorMethods($classOrInstance)) ->mapWithKeys(function ($match) { return [lcfirst(static::$snakeAttributes ? Str::snake($match) : $match) => true]; })->all(); diff --git a/tests/Database/DatabaseConcernsHasAttributesTest.php b/tests/Database/DatabaseConcernsHasAttributesTest.php new file mode 100644 index 000000000000..2e2159c4c102 --- /dev/null +++ b/tests/Database/DatabaseConcernsHasAttributesTest.php @@ -0,0 +1,42 @@ +getMutatedAttributes(); + $this->assertEquals(['some_attribute'], $attributes); + } + + public function testWithConstructorArguments() + { + $instance = new HasAttributesWithConstructorArguments(null); + $attributes = $instance->getMutatedAttributes(); + $this->assertEquals(['some_attribute'], $attributes); + } +} + +class HasAttributesWithoutConstructor +{ + use HasAttributes; + + public function someAttribute(): Attribute + { + return new Attribute(function () { + }); + } +} + +class HasAttributesWithConstructorArguments extends HasAttributesWithoutConstructor +{ + public function __construct($someValue) + { + } +}