Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
90.91% covered (success)
90.91%
40 / 44
60.00% covered (warning)
60.00%
3 / 5
CRAP
0.00% covered (danger)
0.00%
0 / 1
File
90.91% covered (success)
90.91%
40 / 44
60.00% covered (warning)
60.00%
3 / 5
14.15
0.00% covered (danger)
0.00%
0 / 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%
29 / 29
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 Celemas\Sire\Extra;
8use Celemas\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    /** @return list<TranslateMode> */
20    protected function supportedTranslateModes(): array
21    {
22        return [TranslateMode::Symmetric, TranslateMode::Asymmetric];
23    }
24
25    public function value(): Value\File|Value\Files
26    {
27        if ($this->allowsMultipleItems()) {
28            if ($this->isAsymmetricallyTranslated()) {
29                return new Value\TranslatedFiles($this->owner, $this, $this->valueContext);
30            }
31
32            return new Value\Files($this->owner, $this, $this->valueContext);
33        }
34
35        if ($this->isAsymmetricallyTranslated()) {
36            return new Value\TranslatedFile($this->owner, $this, $this->valueContext);
37        }
38
39        return new Value\File($this->owner, $this, $this->valueContext);
40    }
41
42    public function structure(mixed $value = null): array
43    {
44        if ($this->isAsymmetricallyTranslated()) {
45            return $this->getTranslatableFileStructure('file', $value);
46        }
47
48        return $this->getFileStructure('file', $value);
49    }
50
51    public function shape(): Shape
52    {
53        $limitValidators = $this->limitValidators();
54        $shape = Shapes::create();
55        $this->addType($shape);
56        $fileShape = $this->fileListShape();
57
58        if ($this->isAsymmetricallyTranslated()) {
59            $i18nShape = Shapes::create();
60            $locales = $this->owner->locales();
61            $defaultLocale = $locales->getDefault()->id;
62
63            foreach ($locales as $locale) {
64                $localeValidators = $limitValidators;
65                $localeField = $i18nShape
66                    ->add($locale->id, $fileShape)
67                    ->prepare(Prepare::nullAsEmpty(...));
68
69                if ($this->isRequired() && $locale->id === $defaultLocale) {
70                    $localeValidators[] = 'required';
71                } else {
72                    $localeField->optional()->nullable();
73                }
74
75                $localeField->rules(...$localeValidators);
76            }
77
78            $value = $shape
79                ->add('value', $i18nShape)
80                ->rules(...$this->validators)
81                ->prepare(Prepare::nullAsEmpty(...));
82        } else {
83            $value = $shape
84                ->add('value', $this->zxxShape($fileShape, $limitValidators))
85                ->rules(...$this->validators)
86                ->prepare(Prepare::nullAsEmpty(...));
87        }
88
89        if (!$this->isRequired()) {
90            $value->optional()->nullable();
91        }
92
93        $this->addMeta($shape);
94
95        return $shape;
96    }
97
98    protected function fileListShape(): Shape
99    {
100        $fileShape = Shapes::list();
101        $fileShape->add('file', 'string')->rules('required');
102        $fileShape->add('meta', Shapes::create()->extra(Extra::Allow))->optional()->nullable();
103
104        return $fileShape;
105    }
106}