Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
66.67% covered (warning)
66.67%
14 / 21
16.67% covered (danger)
16.67%
1 / 6
CRAP
0.00% covered (danger)
0.00%
0 / 1
Schema
66.67% covered (warning)
66.67%
14 / 21
16.67% covered (danger)
16.67%
1 / 6
15.48
0.00% covered (danger)
0.00%
0 / 1
 __construct
100.00% covered (success)
100.00%
2 / 2
100.00% covered (success)
100.00%
1 / 1
1
 __get
40.00% covered (danger)
40.00%
2 / 5
0.00% covered (danger)
0.00%
0 / 1
2.86
 __isset
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
6
 get
66.67% covered (warning)
66.67%
2 / 3
0.00% covered (danger)
0.00%
0 / 1
2.15
 properties
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 resolveAttributes
88.89% covered (warning)
88.89%
8 / 9
0.00% covered (danger)
0.00%
0 / 1
3.01
1<?php
2
3declare(strict_types=1);
4
5namespace Cosray\Collection;
6
7use Cosray\Collection\Schema\Registry;
8use Cosray\Exception\NoSuchProperty;
9use ReflectionClass;
10
11class Schema
12{
13    /** @var array<string, mixed> */
14    private array $properties;
15
16    /**
17     * @param class-string $class
18     */
19    public function __construct(
20        private readonly string $class,
21        private readonly Registry $registry,
22    ) {
23        $resolved = $this->resolveAttributes();
24        $this->properties = $this->registry->resolveDefaults($this->class, $resolved);
25    }
26
27    public function __get(string $key): mixed
28    {
29        if (!array_key_exists($key, $this->properties)) {
30            throw new NoSuchProperty(
31                "The collection schema '{$this->class}' doesn't have the property '{$key}'",
32            );
33        }
34
35        return $this->properties[$key];
36    }
37
38    public function __isset(string $key): bool
39    {
40        return array_key_exists($key, $this->properties) && $this->properties[$key] !== null;
41    }
42
43    public function get(string $key, mixed $default = null): mixed
44    {
45        if (array_key_exists($key, $this->properties)) {
46            return $this->properties[$key];
47        }
48
49        return $default;
50    }
51
52    /** @return array<string, mixed> */
53    public function properties(): array
54    {
55        return $this->properties;
56    }
57
58    /** @return array<string, mixed> */
59    private function resolveAttributes(): array
60    {
61        $resolved = [];
62        $reflection = new ReflectionClass($this->class);
63
64        foreach ($reflection->getAttributes() as $attribute) {
65            $instance = $attribute->newInstance();
66            $handler = $this->registry->getHandler($instance);
67
68            if ($handler === null) {
69                continue;
70            }
71
72            $resolved = array_merge($resolved, $handler->resolve($instance, $this->class));
73        }
74
75        return $resolved;
76    }
77}