<?php /** * League.Csv (https://csv.thephpleague.com) * * (c) Ignace Nyamagana Butera <nyamsprod@gmail.com> * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. */ declare(strict_types=1); namespace League\Csv\Serializer; use Attribute; use ReflectionAttribute; use ReflectionClass; use ReflectionException; use ReflectionMethod; use ValueError; #[Attribute(Attribute::TARGET_CLASS)] final class MapRecord { public function __construct( /** @var array<string> $afterMapping */ public readonly array $afterMapping = [], public readonly ?bool $convertEmptyStringToNull = null, public readonly bool $trimFieldValueBeforeCasting = false, ) { foreach ($this->afterMapping as $method) { is_string($method) || throw new ValueError('The method names must be string.'); } } /** * @return array<ReflectionMethod> */ public function afterMappingMethods(ReflectionClass $class): array { $methods = []; foreach ($this->afterMapping as $method) { try { $accessor = $class->getMethod($method); } catch (ReflectionException $exception) { throw new MappingFailed('The method `'.$method.'` is not defined on the `'.$class->getName().'` class.', 0, $exception); } 0 === $accessor->getNumberOfRequiredParameters() || throw new MappingFailed('The method `'.$class->getName().'::'.$accessor->getName().'` has too many required parameters.'); $methods[] = $accessor; } return $methods; } /** * @throws MappingFailed */ public static function tryFrom(ReflectionClass $class): ?self { $attributes = $class->getAttributes(self::class, ReflectionAttribute::IS_INSTANCEOF); $nbAttributes = count($attributes); return match ($nbAttributes) { 0 => null, 1 => $attributes[0]->newInstance(), default => throw new MappingFailed('Using more than one `'.self::class.'` attribute on a class property or method is not supported.'), }; } }