Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
100.00% covered (success)
100.00%
33 / 33
100.00% covered (success)
100.00%
4 / 4
CRAP
100.00% covered (success)
100.00%
1 / 1
Index
100.00% covered (success)
100.00%
33 / 33
100.00% covered (success)
100.00%
4 / 4
8
100.00% covered (success)
100.00%
1 / 1
 add
100.00% covered (success)
100.00%
5 / 5
100.00% covered (success)
100.00%
1 / 1
3
 resolve
100.00% covered (success)
100.00%
5 / 5
100.00% covered (success)
100.00%
1 / 1
3
 all
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 withDefaults
100.00% covered (success)
100.00%
22 / 22
100.00% covered (success)
100.00%
1 / 1
1
1<?php
2
3declare(strict_types=1);
4
5namespace Cosray\Field;
6
7use Cosray\Exception\RuntimeException;
8
9/**
10 * Registry of available field types and their string aliases.
11 *
12 * Canonical field type references use the FQCN; aliases are
13 * legacy-import sugar consumed by content normalization.
14 */
15final class Index
16{
17    /** @var array<class-string<Field>, true> */
18    private array $types = [];
19
20    /** @var array<string, class-string<Field>> */
21    private array $aliases = [];
22
23    /** @param class-string<Field> $class */
24    public function add(string $class, string ...$aliases): void
25    {
26        if (!is_subclass_of($class, Field::class)) {
27            throw new RuntimeException('Field types must extend ' . Field::class);
28        }
29
30        $this->types[$class] = true;
31
32        foreach ($aliases as $alias) {
33            $this->aliases[$alias] = $class;
34        }
35    }
36
37    /** @return class-string<Field>|null */
38    public function resolve(string $type): ?string
39    {
40        if (isset($this->aliases[$type])) {
41            return $this->aliases[$type];
42        }
43
44        if (is_subclass_of($type, Field::class)) {
45            return $type;
46        }
47
48        return null;
49    }
50
51    /** @return list<class-string<Field>> */
52    public function all(): array
53    {
54        return array_keys($this->types);
55    }
56
57    public static function withDefaults(): self
58    {
59        $index = new self();
60        $index->add(Blocks::class, 'blocks', 'grid');
61        $index->add(Checkbox::class, 'checkbox');
62        $index->add(Code::class, 'code');
63        $index->add(Date::class, 'date');
64        $index->add(DateTime::class, 'datetime');
65        $index->add(Decimal::class, 'decimal');
66        $index->add(Entries::class, 'entries', 'matrix');
67        $index->add(File::class, 'file');
68        $index->add(Iframe::class, 'iframe');
69        $index->add(Image::class, 'image', 'picture');
70        $index->add(Number::class, 'number');
71        $index->add(Option::class, 'option');
72        $index->add(Radio::class, 'radio');
73        $index->add(Reference::class, 'reference');
74        $index->add(RichText::class, 'richtext', 'html');
75        $index->add(Text::class, 'text');
76        $index->add(Textarea::class, 'textarea');
77        $index->add(Time::class, 'time');
78        $index->add(Video::class, 'video');
79        $index->add(Youtube::class, 'youtube');
80
81        return $index;
82    }
83}