From a00ef2c87f3e66a2c240007a99063e318d4b75c1 Mon Sep 17 00:00:00 2001 From: ignace nyamagana butera Date: Mon, 13 Nov 2023 07:35:05 +0100 Subject: [PATCH] Improve Serializer internal codebase --- docs/9.0/reader/record-mapping.md | 2 +- src/Serializer.php | 41 ++++++++++++++----------------- src/SerializerTest.php | 2 +- 3 files changed, 20 insertions(+), 25 deletions(-) diff --git a/docs/9.0/reader/record-mapping.md b/docs/9.0/reader/record-mapping.md index e659046f..e5317537 100644 --- a/docs/9.0/reader/record-mapping.md +++ b/docs/9.0/reader/record-mapping.md @@ -340,7 +340,7 @@ To allow your object to cast the cell value to your liking it needs to implement To do so, you must define a `toVariable` method that will return the correct value once converted.

Of note The class constructor method must take the property type value as -one of its argument with the name $propertyTyoe. This means you can not use the +one of its argument with the name $propertyType. This means you can not use the propertyType as a possible key of the associative array given to castArguments

```php diff --git a/src/Serializer.php b/src/Serializer.php index b774d4b1..13d5cc34 100644 --- a/src/Serializer.php +++ b/src/Serializer.php @@ -157,45 +157,24 @@ private function findPropertySetters(array $propertyNames): array $propertySetters = []; foreach ($this->class->getProperties(ReflectionProperty::IS_PUBLIC) as $property) { if ($property->isStatic()) { - //the property can not be cast yet - //as casting may be set using the Cell attribute continue; } $attribute = $property->getAttributes(Cell::class, ReflectionAttribute::IS_INSTANCEOF); if ([] !== $attribute) { - //the property can not be cast yet - //as casting will be set using the Cell attribute continue; } - $propertyName = $property->getName(); /** @var int|false $offset */ - $offset = array_search($propertyName, $propertyNames, true); + $offset = array_search($property->getName(), $propertyNames, true); if (false === $offset) { - //the property is not in the record header - //we can not throw as it may be set via a - //setter method using the Cell attribute continue; } - $type = $property->getType(); - if (null === $type) { - throw new MappingFailed('The property `'.$propertyName.'` must be typed.'); - } - - $cast = $this->resolveTypeCasting($type); - if (null === $cast) { - throw new MappingFailed('No valid type casting for `'.$type.'` was found for property `'.$propertyName.'`.'); - } - - $propertySetters[] = new PropertySetter($property, $offset, $cast); + $propertySetters[] = $this->autoDiscoverPropertySetter($property, $offset); } $propertySetters = [...$propertySetters, ...$this->findPropertySettersByCellAttribute($propertyNames)]; - - //if converters is empty it means the Serializer - //was unable to detect properties to assign if ([] === $propertySetters) { throw new MappingFailed('No properties or method setters were found eligible on the class `'.$this->class->getName().'` to be used for type casting.'); } @@ -203,6 +182,22 @@ private function findPropertySetters(array $propertyNames): array return $propertySetters; } + private function autoDiscoverPropertySetter(ReflectionProperty $property, int $offset): PropertySetter + { + $propertyName = $property->getName(); + $type = $property->getType(); + if (null === $type) { + throw new MappingFailed('The property `'.$propertyName.'` must be typed.'); + } + + $cast = $this->resolveTypeCasting($type); + if (null === $cast) { + throw new MappingFailed('No valid type casting for `'.$type.' $'.$propertyName.'`.'); + } + + return new PropertySetter($property, $offset, $cast); + } + /** * @param array $propertyNames * diff --git a/src/SerializerTest.php b/src/SerializerTest.php index 67f1ba2c..f9921591 100644 --- a/src/SerializerTest.php +++ b/src/SerializerTest.php @@ -157,7 +157,7 @@ public function testItWillThrowBecauseTheObjectDoesNotHaveTypedProperties(): voi public function testItWillFailForLackOfTypeCasting(): void { $this->expectException(MappingFailed::class); - $this->expectExceptionMessage('No valid type casting for `SplFileObject` was found for property `observedOn`'); + $this->expectExceptionMessage('No valid type casting for `SplFileObject $observedOn`.'); new Serializer(InvaliDWeatherWithRecordAttributeAndUnknownCasting::class, ['temperature', 'place', 'observedOn']); }