Issues (35)

src/Traits/Fill.php (6 issues)

1
<?php
2
3
declare(strict_types=1);
4
5
namespace Enjoys\Forms\Traits;
6
7
use Closure;
8
use Enjoys\Forms\AttributeFactory;
9
use Enjoys\Forms\Element;
10
use Enjoys\Forms\FillHandler;
11
use Enjoys\Forms\Interfaces\AttributeInterface;
12
use Enjoys\Forms\Interfaces\Fillable;
13
use InvalidArgumentException;
14
15
use function ucfirst;
16
17
trait Fill
18
{
19
    /**
20
     * @var array<array-key, Element&Fillable>
0 ignored issues
show
Documentation Bug introduced by
The doc comment array<array-key, Element&Fillable> at position 2 could not be parsed: Unknown type name 'array-key' at position 2 in array<array-key, Element&Fillable>.
Loading history...
21
     */
22
    private array $elements = [];
23
    private string $parentName = '';
24
    /**
25
     * @var mixed
26
     */
27
    private mixed $defaultValue = '';
28
29 72
    public function setParentName(string $parentName): void
30
    {
31 72
        $this->parentName = $parentName;
32
    }
33
34 11
    public function getParentName(): string
35
    {
36 11
        return $this->parentName;
37
    }
38
39
    /**
40
     * @since 3.4.1 Можно использовать замыкания для заполнения. Анонимная функция должна возвращать массив.
41
     * @since 3.4.0 Возвращен порядок установки value из индексированных массивов, т.к. неудобно,
42
     * По умолчанию теперь не надо добавлять пробел в ключи массива, чтобы value был числом,
43
     * но добавлен флаг $useTitleAsValue, если он установлен в true, то все будет работать как в версии 2.4.0
44
     * @since 2.4.0 Изменен принцип установки value и id из индексированных массивов
45
     * т.е. [1,2] значения будут 1 и 2 соответственно, а не 0 и 1 как раньше.
46
     * Чтобы использовать число в качестве value отличное от title, необходимо
47
     * в массиве конкретно указать значение key. Например, ["40 " => test] (обратите внимание на пробел).
48
     * Из-за того что php преобразует строки, содержащие целое число к int, приходится добавлять
49
     * пробел либо в начало, либо в конец ключа. В итоге пробелы в начале и в конце удаляются автоматически.
50
     */
51 69
    public function fill(array|Closure $data, bool $useTitleAsValue = false): static
52
    {
53 69
        if ($data instanceof Closure) {
0 ignored issues
show
$data is never a sub-type of Closure.
Loading history...
54
            /** @var mixed $data */
55 2
            $data = $data();
56
        }
57
58 69
        if (!is_array($data)) {
0 ignored issues
show
The condition is_array($data) is always true.
Loading history...
59 1
            throw new InvalidArgumentException('Fill data must be array or closure returned array');
60
        }
61
62
        /** @var scalar|array $title */
63 68
        foreach ($data as $value => $title) {
64 68
            $fillHandler = new FillHandler($value, $title, $useTitleAsValue);
65
66
            /** @var class-string<Fillable&Element> $class */
67 68
            $class = '\Enjoys\Forms\Elements\\' . ucfirst($this->getType());
0 ignored issues
show
It seems like getType() must be provided by classes using this trait. How about adding it as abstract method to this trait? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

67
            $class = '\Enjoys\Forms\Elements\\' . ucfirst($this->/** @scrutinizer ignore-call */ getType());
Loading history...
68
69 68
            $element = new $class($fillHandler->getValue(), $fillHandler->getLabel(), false);
70
71 68
            $element->setAttributes(AttributeFactory::createFromArray($fillHandler->getAttributes()), 'fill');
72
73 68
            $fillCollection = $element->getAttributeCollection('fill');
74
75
            /** @var AttributeInterface $attribute */
76 68
            foreach ($fillCollection as $attribute) {
77 28
                $element->setAttribute($attribute);
78
            }
79
80 68
            $this->addElement($element);
81
        }
82 68
        return $this;
83
    }
84
85
    /**
86
     * @psalm-return array<array-key, Element&Fillable>
87
     */
88 75
    public function getElements(): array
89
    {
90 75
        return $this->elements;
91
    }
92
93
    /**
94
     * @return mixed
95
     */
96 73
    public function getDefaultValue(): mixed
97
    {
98 73
        return $this->defaultValue;
99
    }
100
101
102 57
    public function setDefaultValue(mixed $defaultValue): void
103
    {
104 57
        $this->defaultValue = $defaultValue;
105
    }
106
107
108
    /**
109
     * @param Fillable&Element $element
110
     */
111 72
    public function addElement(Fillable $element): static
112
    {
113 72
        $element->setParentName($this->getName());
0 ignored issues
show
It seems like getName() must be provided by classes using this trait. How about adding it as abstract method to this trait? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

113
        $element->setParentName($this->/** @scrutinizer ignore-call */ getName());
Loading history...
114 72
        $element->setDefault($this->getDefaultValue());
0 ignored issues
show
The method setDefault() does not exist on Enjoys\Forms\Interfaces\Fillable. Since it exists in all sub-types, consider adding an abstract or default implementation to Enjoys\Forms\Interfaces\Fillable. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

114
        $element->/** @scrutinizer ignore-call */ 
115
                  setDefault($this->getDefaultValue());
Loading history...
115 72
        $this->elements[] = $element;
116 72
        return $this;
117
    }
118
119
    /**
120
     * @param array<Fillable&Element> $elements
121
     */
122 3
    public function addElements(array $elements): static
123
    {
124 3
        foreach ($elements as $element) {
125 3
            $this->addElement($element);
126
        }
127 3
        return $this;
128
    }
129
}
130