Completed
Push — master ( f7065a...90f0b9 )
by Denis
01:25
created

AbstractElement::getClassName()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 4
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 2
eloc 2
nc 2
nop 1
dl 0
loc 4
rs 10
c 0
b 0
f 0
1
<?php
2
3
namespace Ngtfkx\Laradeck\FormBuilder\Elements;
4
5
6
use Illuminate\Support\Collection;
7
use Ngtfkx\Laradeck\FormBuilder\Layouts\AbstractLayout;
8
use Ngtfkx\Laradeck\FormBuilder\Render;
9
10
abstract class AbstractElement
11
{
12
    /**
13
     * @var Collection|iterable $classes Коллекция классом элемента
14
     */
15
    public $classes;
16
17
    /**
18
     * @var Collection|iterable $attributes Коллекция дополнительных атрибутов элемента
19
     */
20
    public $attributes;
21
22
    /**
23
     * @var Collection|iterable $styles Коллекция inline-стилей элемента
24
     */
25
    public $styles;
26
27
    /**
28
     * @var string $value Значение элемента
29
     */
30
    public $value;
31
32
    /**
33
     * @var string $tag Тег элемента
34
     */
35
    protected $tag;
36
37
    /**
38
     * @var Collection|iterable $parts Набор атрибутов для генерации html-кода элементов
39
     */
40
    public $parts;
41
42
    /**
43
     * @var string $label
44
     */
45
    public $label;
46
47
    /**
48
     * @var string $help
49
     */
50
    public $help;
51
52
    /**
53
     * @var AbstractLayout
54
     */
55
    public $layout;
56
57
    public $onlyTagRender = false;
58
59
    /**
60
     * @return void
61
     */
62
    abstract public function tag();
63
64
    public function __construct()
65
    {
66
        $this->classes = new Collection();
67
68
        $this->attributes = new Collection();
69
70
        $this->styles = new Collection();
71
72
        $this->parts = new Collection();
73
74
        $this->tag();
75
    }
76
77
    public function layout(?AbstractLayout $layout): self
78
    {
79
        $this->layout = $layout;
80
81
        return $this;
82
    }
83
84
    /**
85
     * Сеттер значения лейбла для элемента
86
     *
87
     * @param string|null $value
88
     * @return AbstractElement
89
     */
90
    public function label(?string $value): self
91
    {
92
        $this->label = $value;
93
94
        return $this;
95
    }
96
97
    /**
98
     * Сеттер значения подсказки для элемента
99
     *
100
     * @param string|null $value
101
     * @return AbstractElement
102
     */
103
    public function help(?string $value): self
104
    {
105
        $this->help = $value;
106
107
        return $this;
108
    }
109
110
    /**
111
     * Сеттер значения элемента
112
     *
113
     * @param string|null $value
114
     * @return AbstractElement
115
     */
116
    public function value(?string $value): self
117
    {
118
        $this->value = $value;
119
120
        return $this;
121
    }
122
123
    /**
124
     * Сеттер атрибута id элемента
125
     *
126
     * @param string|null $value
127
     * @return AbstractElement
128
     */
129
    public function id(?string $value): self
130
    {
131
        $this->attr('id', $value);
132
133
        return $this;
134
    }
135
136
    /**
137
     * Сеттер атрибута name элемента
138
     *
139
     * @param string|null $value
140
     * @return AbstractElement
141
     */
142
    public function name(?string $value): self
143
    {
144
        $this->attr('name', $value);
145
146
        return $this;
147
    }
148
149
    /**
150
     * Добавить элементу один или несколько классов
151
     *
152
     * @param array ...$classes
153
     * @return AbstractElement
154
     */
155
    public function class(...$classes): self
0 ignored issues
show
Coding Style introduced by
Possible parse error: non-abstract method defined as abstract
Loading history...
Coding Style introduced by
It is generally advisable to only define one property per statement.

Only declaring a single property per statement allows you to later on add doc comments more easily.

It is also recommended by PSR2, so it is a common style that many people expect.

Loading history...
156
    {
157
        $this->classes($classes);
0 ignored issues
show
Documentation introduced by
$classes is of type array<integer,array>, but the function expects a object<Ngtfkx\Laradeck\F...lder\Elements\iterable>.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
158
159
        return $this;
0 ignored issues
show
Coding Style introduced by
The visibility should be declared for property $this.

The PSR-2 coding standard requires that all properties in a class have their visibility explicitly declared. If you declare a property using

class A {
    var $property;
}

the property is implicitly global.

To learn more about the PSR-2, please see the PHP-FIG site on the PSR-2.

Loading history...
160
    }
161
162
    /**
163
     *  Добавить элементу один или несколько классов из массива
164
     *
165
     * @param iterable $classes
166
     * @return AbstractElement
167
     */
168
    public function classes(iterable $classes): self
169
    {
170
        foreach ($classes as $class) {
171
            if (!$this->classes->contains($class)) {
172
                $this->classes->push($class);
173
            }
174
        }
175
176
        return $this;
177
    }
178
179
    /**
180
     * Добавить к элементу один или несколько inline-стилей
181
     *
182
     * @param string $key
183
     * @param string|null $value
184
     * @return AbstractElement
185
     */
186
    public function style(string $key, string $value = null): self
187
    {
188
        if (empty($value)) {
189
            $pos = strpos($key, ':', 2);
190
            if ($pos !== false) {
191
                $parts = explode(':', strrev($key));
192
                $key = strrev($parts[1]);
193
                $value = strrev($parts[0]);
194
            }
195
        }
196
197
        if ($key && $value) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $value of type null|string is loosely compared to true; this is ambiguous if the string can be empty. You might want to explicitly use !== null instead.

In PHP, under loose comparison (like ==, or !=, or switch conditions), values of different types might be equal.

For string values, the empty string '' is a special case, in particular the following results might be unexpected:

''   == false // true
''   == null  // true
'ab' == false // false
'ab' == null  // false

// It is often better to use strict comparison
'' === false // false
'' === null  // false
Loading history...
198
            $this->styles->put($key, $value);
199
        }
200
201
        return $this;
202
    }
203
204
    /**
205
     * Добавить к элементу один или несколько inline-стилей из массива
206
     *
207
     * @param iterable $styles
208
     * @return AbstractElement
209
     */
210
    public function styles(iterable $styles): self
211
    {
212
        foreach ($styles as $key => $value) {
213
            $this->styles->put($key, $value);
214
        }
215
216
        return $this;
217
    }
218
219
    /**
220
     * Добавить аттрибут к элементу
221
     *
222
     * @param string $key
223
     * @param string|null $value
224
     * @return AbstractElement
225
     */
226
    public function attr(string $key, $value = null): self
227
    {
228
        $this->attributes->put($key, $value);
229
230
        return $this;
231
    }
232
233
    /**
234
     * Добавить один или несколько атрибутов из массива к элементу
235
     *
236
     * @param iterable $attributes
237
     * @return AbstractElement
238
     */
239
    public function attrs(iterable $attributes): self
240
    {
241
        foreach ($attributes as $key => $value) {
242
            if ($key === 'class') {
243
                $this->class($value);
244
            } else if ($key === 'style') {
245
                $this->style($value);
246
            } else {
247
                $this->attributes->put($key, $value);
248
            }
249
        }
250
251
        return $this;
252
    }
253
254
    /**
255
     * Очистить классы элемента
256
     *
257
     * @return AbstractElement
258
     */
259
    public function clearClasses(): self
260
    {
261
        $this->classes = new Collection();
262
263
        return $this;
264
    }
265
266
    /**
267
     * Очистить классы стили
268
     *
269
     * @return AbstractElement
270
     */
271
    public function clearStyles(): self
272
    {
273
        $this->styles = new Collection();
274
275
        return $this;
276
    }
277
278
    /**
279
     * Очистить классы атрибуты
280
     *
281
     * @return AbstractElement
282
     */
283
    public function clearAttributes(): self
284
    {
285
        $this->attributes = new Collection();
286
287
        return $this;
288
    }
289
290
    public function getTagHtml()
291
    {
292
        return '<' . $this->tag . '**attributes**>';
293
    }
294
295
    public function beforeToParts(): void
296
    {
297
        $this->addAttr('value');
298
299
        if (is_null($this->layout) === false && $this->layout->getElementClasses() && !in_array($this->getClassName(), $this->layout->skipElementClasses)) {
300
            $this->class($this->layout->getElementClasses());
301
        }
302
    }
303
304
    public function afterToParts(): void
305
    {
306
        if($this->parts->has('id') === false) {
307
            $this->parts->put('id', str_random(20));
308
        }
309
    }
310
311
    public function getClassName($strToLower = false): string
312
    {
313
        return $strToLower ? class_basename($this) : strtolower(class_basename($this));
314
    }
315
316
    /**
317
     * Преобразовать в строку для вывода в HTML
318
     *
319
     * @return string
320
     */
321
    public function __toString(): string
322
    {
323
        return new Render($this);
324
    }
325
326
    protected function addAttr(...$names): self
327
    {
328
        foreach ($names as $name) {
329
            if (!empty($this->$name)) {
330
                $this->parts[$name] = $this->$name;
331
            }
332
        }
333
334
        return $this;
335
    }
336
337
    protected function addAttrAs(...$names): self
338
    {
339
        foreach ($names as $name) {
340
            if (!empty($this->$name)) {
341
                $this->parts[$name] = $name;
342
            }
343
        }
344
345
        return $this;
346
    }
347
}