Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
91.30% covered (success)
91.30%
42 / 46
66.67% covered (warning)
66.67%
4 / 6
CRAP
0.00% covered (danger)
0.00%
0 / 1
File
91.30% covered (success)
91.30%
42 / 46
66.67% covered (warning)
66.67%
4 / 6
15.15
0.00% covered (danger)
0.00%
0 / 1
 control
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 supportedTranslateModes
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 value
100.00% covered (success)
100.00%
7 / 7
100.00% covered (success)
100.00%
1 / 1
4
 structure
0.00% covered (danger)
0.00%
0 / 3
0.00% covered (danger)
0.00%
0 / 1
6
 shape
100.00% covered (success)
100.00%
30 / 30
100.00% covered (success)
100.00%
1 / 1
6
 fileListShape
100.00% covered (success)
100.00%
4 / 4
100.00% covered (success)
100.00%
1 / 1
1
1<?php
2
3declare(strict_types=1);
4
5namespace Cosray\Field;
6
7use Celema\Sire\Extra;
8use Celema\Sire\Shape;
9use Cosray\Schema\TranslateMode;
10use Cosray\Validation\Prepare;
11use Cosray\Validation\Shapes;
12use Cosray\Value;
13
14class File extends Field implements Capability\Limitable, Capability\Translatable
15{
16    use Capability\IsLimitable;
17    use Capability\IsTranslatable;
18
19    public function control(): Control
20    {
21        return Control::file();
22    }
23
24    /** @return list<TranslateMode> */
25    protected function supportedTranslateModes(): array
26    {
27        return [TranslateMode::Symmetric, TranslateMode::Asymmetric];
28    }
29
30    public function value(): Value\File|Value\Files
31    {
32        if ($this->allowsMultipleItems()) {
33            if ($this->isAsymmetricallyTranslated()) {
34                return new Value\TranslatedFiles($this->owner, $this, $this->valueContext);
35            }
36
37            return new Value\Files($this->owner, $this, $this->valueContext);
38        }
39
40        if ($this->isAsymmetricallyTranslated()) {
41            return new Value\TranslatedFile($this->owner, $this, $this->valueContext);
42        }
43
44        return new Value\File($this->owner, $this, $this->valueContext);
45    }
46
47    public function structure(mixed $value = null): array
48    {
49        if ($this->isAsymmetricallyTranslated()) {
50            return $this->getTranslatableFileStructure('file', $value);
51        }
52
53        return $this->getFileStructure('file', $value);
54    }
55
56    public function shape(): Shape
57    {
58        $limitValidators = $this->limitValidators();
59        $shape = Shapes::create();
60        $this->addType($shape);
61        $fileShape = $this->fileListShape();
62
63        if ($this->isAsymmetricallyTranslated()) {
64            $i18nShape = Shapes::create();
65            $locales = $this->owner->locales();
66            $defaultLocale = $locales->getDefault()->id;
67
68            foreach ($locales as $locale) {
69                $localeValidators = $limitValidators;
70                $localeField = $i18nShape
71                    ->add($locale->id, $fileShape)
72                    ->label($this->valueLabel($locale))
73                    ->prepare(Prepare::nullAsEmpty(...));
74
75                if ($this->isRequired() && $locale->id === $defaultLocale) {
76                    $localeValidators[] = 'required';
77                } else {
78                    $localeField->optional()->nullable();
79                }
80
81                $localeField->rules(...$localeValidators);
82            }
83
84            $value = $shape
85                ->add('value', $i18nShape)
86                ->rules(...$this->validators)
87                ->prepare(Prepare::nullAsEmpty(...));
88        } else {
89            $value = $shape
90                ->add('value', $this->zxxShape($fileShape, $limitValidators))
91                ->rules(...$this->validators)
92                ->prepare(Prepare::nullAsEmpty(...));
93        }
94
95        if (!$this->isRequired()) {
96            $value->optional()->nullable();
97        }
98
99        $this->addMeta($shape);
100
101        return $shape;
102    }
103
104    protected function fileListShape(): Shape
105    {
106        $fileShape = Shapes::list();
107        $fileShape->add('uid', 'string')->rules('required');
108        $fileShape->add('meta', Shapes::create()->extra(Extra::Allow))->optional()->nullable();
109
110        return $fileShape;
111    }
112}