Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
86.49% covered (warning)
86.49%
32 / 37
77.78% covered (warning)
77.78%
7 / 9
CRAP
0.00% covered (danger)
0.00%
0 / 1
Value
86.49% covered (warning)
86.49%
32 / 37
77.78% covered (warning)
77.78%
7 / 9
29.93
0.00% covered (danger)
0.00%
0 / 1
 __construct
100.00% covered (success)
100.00%
5 / 5
100.00% covered (success)
100.00%
1 / 1
1
 __get
80.00% covered (warning)
80.00%
4 / 5
0.00% covered (danger)
0.00%
0 / 1
3.07
 __toString
n/a
0 / 0
n/a
0 / 0
0
 isset
n/a
0 / 0
n/a
0 / 0
0
 json
n/a
0 / 0
n/a
0 / 0
0
 unwrap
n/a
0 / 0
n/a
0 / 0
0
 styleClass
100.00% covered (success)
100.00%
2 / 2
100.00% covered (success)
100.00%
1 / 1
3
 elementId
100.00% covered (success)
100.00%
2 / 2
100.00% covered (success)
100.00%
1 / 1
3
 value
100.00% covered (success)
100.00%
4 / 4
100.00% covered (success)
100.00%
1 / 1
4
 zxx
0.00% covered (danger)
0.00%
0 / 4
0.00% covered (danger)
0.00%
0 / 1
6
 meta
100.00% covered (success)
100.00%
6 / 6
100.00% covered (success)
100.00%
1 / 1
5
 effective
100.00% covered (success)
100.00%
8 / 8
100.00% covered (success)
100.00%
1 / 1
4
 filled
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
3
1<?php
2
3declare(strict_types=1);
4
5namespace Cosray\Value;
6
7use Cosray\Exception\NoSuchProperty;
8use Cosray\Field\Field;
9use Cosray\Field\Field as FieldBase;
10use Cosray\Field\Owner;
11use Cosray\Locale;
12
13abstract class Value
14{
15    public readonly string $fieldType;
16    protected readonly Locale $locale;
17    protected readonly Locale $defaultLocale;
18    protected readonly string $fieldName;
19    protected readonly array $data;
20
21    public function __construct(
22        protected readonly Owner $owner,
23        protected readonly Field $field,
24        protected readonly ValueContext $context,
25    ) {
26        $this->locale = $owner->locale();
27        $this->defaultLocale = $owner->defaultLocale();
28        $this->data = $context->data;
29        $this->fieldName = $context->fieldName;
30        $this->fieldType = $field->type;
31    }
32
33    public function __get(string $name): mixed
34    {
35        if (array_key_exists($name, $this->data)) {
36            return $this->data[$name];
37        }
38
39        if (array_key_exists($name, $this->data['meta'] ?? [])) {
40            return $this->meta($name);
41        }
42
43        throw new NoSuchProperty("The field '{$this->fieldName}' doesn't have the property '{$name}'");
44    }
45
46    abstract public function __toString(): string;
47
48    abstract public function isset(): bool;
49
50    abstract public function json(): mixed;
51
52    abstract public function unwrap(): mixed;
53
54    public function styleClass(): ?string
55    {
56        $value = $this->meta('class');
57
58        return is_string($value) && $value !== '' ? $value : null;
59    }
60
61    public function elementId(): ?string
62    {
63        $value = $this->meta('id');
64
65        return is_string($value) && $value !== '' ? $value : null;
66    }
67
68    protected function value(): mixed
69    {
70        $value = $this->data['value'] ?? [];
71
72        if (!is_array($value) && !isset($this->data['type'])) {
73            return $value;
74        }
75
76        return is_array($value) ? $this->effective($value) : null;
77    }
78
79    protected function zxx(): mixed
80    {
81        $value = $this->data['value'] ?? [];
82
83        if (!is_array($value)) {
84            return null;
85        }
86
87        return $value[FieldBase::NEUTRAL_LOCALE] ?? null;
88    }
89
90    protected function meta(string $key, mixed $default = null): mixed
91    {
92        $meta = $this->data['meta'][$key] ?? null;
93
94        if (!is_array($meta) && !isset($this->data['type']) && array_key_exists($key, $this->data)) {
95            return $this->data[$key];
96        }
97
98        if (!is_array($meta)) {
99            return $default;
100        }
101
102        return $this->effective($meta) ?? $default;
103    }
104
105    protected function effective(array $map): mixed
106    {
107        $locale = $this->locale;
108
109        while ($locale) {
110            if ($this->filled($map[$locale->id] ?? null)) {
111                return $map[$locale->id];
112            }
113
114            $locale = $locale->fallback();
115        }
116
117        if ($this->filled($map[FieldBase::NEUTRAL_LOCALE] ?? null)) {
118            return $map[FieldBase::NEUTRAL_LOCALE];
119        }
120
121        return null;
122    }
123
124    protected function filled(mixed $value): bool
125    {
126        return $value !== null && $value !== '' && $value !== [];
127    }
128}