diff --git a/src/Illuminate/Queue/Attributes/WithoutRelations.php b/src/Illuminate/Queue/Attributes/WithoutRelations.php index 3c70f2ac7545..072733c28d15 100644 --- a/src/Illuminate/Queue/Attributes/WithoutRelations.php +++ b/src/Illuminate/Queue/Attributes/WithoutRelations.php @@ -4,7 +4,7 @@ use Attribute; -#[Attribute(Attribute::TARGET_PROPERTY)] +#[Attribute(Attribute::TARGET_CLASS | Attribute::TARGET_PROPERTY)] class WithoutRelations { // diff --git a/src/Illuminate/Queue/SerializesModels.php b/src/Illuminate/Queue/SerializesModels.php index fdca57cb042e..db17b98755af 100644 --- a/src/Illuminate/Queue/SerializesModels.php +++ b/src/Illuminate/Queue/SerializesModels.php @@ -19,9 +19,13 @@ public function __serialize() { $values = []; - $properties = (new ReflectionClass($this))->getProperties(); + $reflectionClass = new ReflectionClass($this); - $class = get_class($this); + [$class, $properties, $classLevelWithoutRelations] = [ + get_class($this), + $reflectionClass->getProperties(), + ! empty($reflectionClass->getAttributes(WithoutRelations::class)), + ]; foreach ($properties as $property) { if ($property->isStatic()) { @@ -48,7 +52,8 @@ public function __serialize() $values[$name] = $this->getSerializedPropertyValue( $value, - empty($property->getAttributes(WithoutRelations::class)) + ! $classLevelWithoutRelations && + empty($property->getAttributes(WithoutRelations::class)) ); } diff --git a/tests/Integration/Queue/ModelSerializationTest.php b/tests/Integration/Queue/ModelSerializationTest.php index 2469f65cb938..254aff380e23 100644 --- a/tests/Integration/Queue/ModelSerializationTest.php +++ b/tests/Integration/Queue/ModelSerializationTest.php @@ -332,6 +332,26 @@ public function test_it_respects_without_relations_attribute() ); } + public function test_it_respects_without_relations_attribute_applied_to_class() + { + $user = User::create([ + 'email' => 'taylor@laravel.com', + ])->load(['roles']); + + $serialized = serialize(new ModelSerializationAttributeTargetsClassTestClass($user, new DataValueObject('hello'))); + + $this->assertSame( + 'O:83:"Illuminate\Tests\Integration\Queue\ModelSerializationAttributeTargetsClassTestClass":2:{s:4:"user";O:45:"Illuminate\Contracts\Database\ModelIdentifier":5:{s:5:"class";s:39:"Illuminate\Tests\Integration\Queue\User";s:2:"id";i:1;s:9:"relations";a:0:{}s:10:"connection";s:7:"testing";s:15:"collectionClass";N;}s:5:"value";O:50:"Illuminate\Tests\Integration\Queue\DataValueObject":1:{s:5:"value";s:5:"hello";}}', + $serialized + ); + + /** @var ModelSerializationAttributeTargetsClassTestClass $unserialized */ + $unserialized = unserialize($serialized); + + $this->assertFalse($unserialized->user->relationLoaded('roles')); + $this->assertEquals('hello', $unserialized->value->value); + } + public function test_serialization_types_empty_custom_eloquent_collection() { $class = new ModelSerializationTypedCustomCollectionTestClass( @@ -526,6 +546,16 @@ public function __construct(User $user) } } +#[WithoutRelations] +class ModelSerializationAttributeTargetsClassTestClass +{ + use SerializesModels; + + public function __construct(public User $user, public DataValueObject $value) + { + } +} + class ModelRelationSerializationTestClass { use SerializesModels; @@ -549,3 +579,10 @@ public function __construct($users) $this->users = $users; } } + +class DataValueObject +{ + public function __construct(public $value = 1) + { + } +}