282c4c71493c765ae35ece3bf43b0229aaacda9e
[GitHub/WoltLab/WCF.git] /
1 <?php
2
3 declare(strict_types=1);
4
5 namespace CuyZ\Valinor\Mapper\Object\Factory;
6
7 use CuyZ\Valinor\Definition\ClassDefinition;
8 use CuyZ\Valinor\Definition\FunctionObject;
9 use CuyZ\Valinor\Definition\Repository\FunctionDefinitionRepository;
10 use CuyZ\Valinor\Mapper\Object\DateTimeFormatConstructor;
11 use CuyZ\Valinor\Mapper\Object\FunctionObjectBuilder;
12 use CuyZ\Valinor\Mapper\Object\NativeConstructorObjectBuilder;
13 use CuyZ\Valinor\Mapper\Object\ObjectBuilder;
14 use CuyZ\Valinor\Type\ClassType;
15 use DateTime;
16 use DateTimeImmutable;
17
18 use function array_filter;
19 use function count;
20
21 /** @internal */
22 final class DateTimeObjectBuilderFactory implements ObjectBuilderFactory
23 {
24 public function __construct(
25 private ObjectBuilderFactory $delegate,
26 private FunctionDefinitionRepository $functionDefinitionRepository
27 ) {
28 }
29
30 public function for(ClassDefinition $class): array
31 {
32 $className = $class->name();
33
34 $builders = $this->delegate->for($class);
35
36 if ($className !== DateTime::class && $className !== DateTimeImmutable::class) {
37 return $builders;
38 }
39
40 // Remove `DateTime` & `DateTimeImmutable` native constructors
41 $builders = array_filter($builders, fn (ObjectBuilder $builder) => ! $builder instanceof NativeConstructorObjectBuilder);
42
43 $useDefaultBuilder = true;
44
45 foreach ($builders as $builder) {
46 if (count($builder->describeArguments()) === 1) {
47 $useDefaultBuilder = false;
48 // @infection-ignore-all
49 break;
50 }
51 }
52
53 if ($useDefaultBuilder) {
54 // @infection-ignore-all / Ignore memoization
55 $builders[] = $this->defaultBuilder($class->type());
56 }
57
58 return $builders;
59 }
60
61 private function defaultBuilder(ClassType $type): FunctionObjectBuilder
62 {
63 $constructor = new DateTimeFormatConstructor(DATE_ATOM, 'U');
64 $function = new FunctionObject($this->functionDefinitionRepository->for($constructor), $constructor);
65
66 return new FunctionObjectBuilder($function, $type);
67 }
68 }