Completed
Push — master ( 65c705...b5cfd6 )
by P.R.
07:19
created

HtmlElement::addClasses()   A

Complexity

Conditions 4
Paths 6

Size

Total Lines 17
Code Lines 7

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 8
CRAP Score 4

Importance

Changes 0
Metric Value
cc 4
eloc 7
nc 6
nop 1
dl 0
loc 17
ccs 8
cts 8
cp 1
crap 4
rs 10
c 0
b 0
f 0
1
<?php
2
declare(strict_types=1);
3
4
namespace Plaisio\Helper;
5
6
use SetBased\Exception\LogicException;
7
8
/**
9
 * Parent class for HTML elements.
10
 *
11
 * This class should be used for generation "heavy" HTML elements only. For light weight elements use methods of
12
 * {@link \Plaisio\Helper\Html}.
13
 *
14
 * #### Global Attributes
15
 * This class defines methods for getting attributes and setting
16
 * [global attributes](http://www.w3schools.com/tags/ref_standardattributes.asp) only.
17
 *
18
 * Unless stated otherwise setting an attribute to null, false, or '' will unset the attribute.
19
 *
20
 * #### Event Attributes
21
 * This class does not define methods for setting event attributes. Events handlers must be set with JavaScript.
22
 */
23
class HtmlElement
24
{
25
  //--------------------------------------------------------------------------------------------------------------------
26
  /**
27
   * The attributes of this HTML element.
28
   *
29
   * @var array
30
   *
31
   * @since 1.0.0
32
   * @api
33
   */
34
  protected array $attributes = [];
35
36
  //--------------------------------------------------------------------------------------------------------------------
37
  /**
38
   * Adds a class to the list of classes.
39
   *
40
   * @param string|null $class The class.
41
   *
42
   * @return $this
43
   *
44
   * @since 1.0.0
45
   * @api
46
   */
47 7
  public function addClass(?string $class): self
48
  {
49 7
    if ($class===null || $class==='')
50
    {
51 2
      return $this;
52
    }
53
54 5
    if (empty($this->attributes['class']))
55
    {
56 3
      $this->attributes['class'] = [];
57
    }
58 3
    elseif (is_string($this->attributes['class']))
59
    {
60 1
      $this->attributes['class'] = explode(' ', $this->attributes['class']);
61
    }
62
63 5
    $this->attributes['class'][] = $class;
64
65 5
    return $this;
66
  }
67
68
  //--------------------------------------------------------------------------------------------------------------------
69
  /**
70
   * Adds classes to the list of classes.
71
   *
72
   * @param array $classes The classes.
73
   *
74
   * @return $this
75
   *
76
   * @since 1.5.0
77
   * @api
78
   */
79 4
  public function addClasses(array $classes): self
80
  {
81 4
    if (empty($this->attributes['class']))
82
    {
83 3
      $this->attributes['class'] = [];
84
    }
85 2
    elseif (is_string($this->attributes['class']))
86
    {
87 1
      $this->attributes['class'] = explode(' ', $this->attributes['class']);
88
    }
89
90 4
    foreach ($classes as $class)
91
    {
92 4
      $this->attributes['class'][] = $class;
93
    }
94
95 4
    return $this;
96
  }
97
98
  //--------------------------------------------------------------------------------------------------------------------
99
  /**
100
   * Returns the value of an attribute.
101
   *
102
   * @param string $attributeName The name of the attribute.
103
   *
104
   * @return mixed
105
   *
106
   * @since 1.0.0
107
   * @api
108
   */
109 4
  public function getAttribute(string $attributeName)
110
  {
111 4
    return $this->attributes[$attributeName] ?? null;
112
  }
113
114
  //--------------------------------------------------------------------------------------------------------------------
115
  /**
116
   * Returns the mandatory attribute [id](http://www.w3schools.com/tags/att_global_id.asp) of this element. If the id
117
   * attribute was not set prior calling this method the id attribute will set with a automatically generate value.
118
   *
119
   * @return string
120
   *
121
   * @since 1.4.0
122
   * @api
123
   */
124 1
  public function getId(): string
125
  {
126 1
    $this->attributes['id'] ??= Html::getAutoId();
127
128 1
    return $this->attributes['id'];
129
  }
130
131
  //--------------------------------------------------------------------------------------------------------------------
132
  /**
133
   * Removes a class from the list of classes.
134
   *
135
   * @param string|null $class The class to be removed.
136
   *
137
   * @return $this
138
   *
139
   * @since 1.0.0
140
   * @api
141
   */
142 5
  public function removeClass(?string $class): self
143
  {
144
    // If class is empty or no classes are set return immediately.
145 5
    if ($class===null || $class==='' || !isset($this->attributes['class'])) return $this;
146
147 3
    $this->attributes['class'] = array_unique($this->attributes['class']);
148 3
    $key                       = array_search($class, $this->attributes['class']);
149 3
    if ($key!==false)
150
    {
151 3
      unset($this->attributes['class'][$key]);
152
    }
153
154 3
    return $this;
155
  }
156
157
  //--------------------------------------------------------------------------------------------------------------------
158
  /**
159
   * Sets the attribute [accesskey](http://www.w3schools.com/tags/att_global_accesskey.asp).
160
   *
161
   * @param string|null $value The attribute value.
162
   *
163
   * @return $this
164
   *
165
   * @api
166
   * @since 1.0.0
167
   */
168 1
  public function setAttrAccessKey(?string $value): self
169
  {
170 1
    $this->attributes['accesskey'] = $value;
171
172 1
    return $this;
173
  }
174
175
  //--------------------------------------------------------------------------------------------------------------------
176
  /**
177
   * Sets a [aria](http://w3c.github.io/html/infrastructure.html#element-attrdef-aria-aria) attribute.
178
   *
179
   * @param string      $name  The name of the attribute (without 'aria-').
180
   * @param string|null $value The attribute value.
181
   *
182
   * @return $this
183
   *
184
   * @since 1.3.0
185
   * @api
186
   */
187 1
  public function setAttrAria(string $name, ?string $value): self
188
  {
189 1
    $this->attributes['aria-'.$name] = $value;
190
191 1
    return $this;
192
  }
193
194
  //--------------------------------------------------------------------------------------------------------------------
195
  /**
196
   * Sets the attribute [class](https://www.w3schools.com/tags/att_global_class.asp).
197
   *
198
   * @param string|null $value The class or classes. Any value set by {@link addClass} will be overwritten.
199
   *
200
   * @return $this
201
   *
202
   * @since 1.4.0
203
   * @api
204
   */
205 4
  public function setAttrClass(?string $value): self
206
  {
207 4
    if ($value===null || $value==='')
208
    {
209 1
      unset($this->attributes['class']);
210
    }
211
    else
212
    {
213 4
      $this->attributes['class'] = [$value];
214
    }
215
216 4
    return $this;
217
  }
218
219
  //--------------------------------------------------------------------------------------------------------------------
220
  /**
221
   * Sets the attribute [contenteditable](http://www.w3schools.com/tags/att_global_contenteditable.asp).
222
   * <ul>
223
   * <li> Any value that evaluates to true will set the attribute to 'true'.
224
   * <li> Any value that evaluates to false will set the attribute to 'false'.
225
   * <li> Null will unset the attribute.
226
   * </ul>
227
   *
228
   * @param mixed $value The attribute value.
229
   *
230
   * @return $this
231
   *
232
   * @since 1.0.0
233
   * @api
234
   */
235 1
  public function setAttrContentEditable(?string $value): self
236
  {
237 1
    $this->attributes['contenteditable'] = $value;
238
239 1
    return $this;
240
  }
241
242
  //--------------------------------------------------------------------------------------------------------------------
243
  /**
244
   * Sets the attribute [contextmenu](http://www.w3schools.com/tags/att_global_contextmenu.asp).
245
   *
246
   * @param string|null $value The attribute value.
247
   *
248
   * @return $this
249
   *
250
   * @since 1.0.0
251
   * @api
252
   */
253 1
  public function setAttrContextMenu(?string $value): self
254
  {
255 1
    $this->attributes['contextmenu'] = $value;
256
257 1
    return $this;
258
  }
259
260
  //--------------------------------------------------------------------------------------------------------------------
261
  /**
262
   * Sets a [data](http://www.w3schools.com/tags/att_global_data.asp) attribute.
263
   *
264
   * @param string      $name  The name of the attribute (without 'data-').
265
   * @param string|null $value The attribute value.
266
   *
267
   * @return $this
268
   *
269
   * @since 1.0.0
270
   * @api
271
   */
272 1
  public function setAttrData(string $name, ?string $value): self
273
  {
274 1
    $this->attributes['data-'.$name] = $value;
275
276 1
    return $this;
277
  }
278
279
  //--------------------------------------------------------------------------------------------------------------------
280
  /**
281
   * Sets the attribute [dir](http://www.w3schools.com/tags/att_global_dir.asp). Possible values:
282
   * <ul>
283
   * <li> ltr
284
   * <li> rtl
285
   * <li> auto
286
   * </ul>
287
   *
288
   * @param string|null $value The attribute value.
289
   *
290
   * @return $this
291
   *
292
   * @since 1.0.0
293
   * @api
294
   */
295 1
  public function setAttrDir(?string $value): self
296
  {
297 1
    $this->attributes['dir'] = $value;
298
299 1
    return $this;
300
  }
301
302
  //--------------------------------------------------------------------------------------------------------------------
303
  /**
304
   * Sets the attribute [draggable](http://www.w3schools.com/tags/att_global_draggable.asp). Possible values:
305
   * <ul>
306
   * <li> true
307
   * <li> false
308
   * <li> auto
309
   * </ul>
310
   *
311
   * @param string|null $value The attribute value.
312
   *
313
   * @return $this
314
   *
315
   * @since 1.0.0
316
   * @api
317
   */
318 1
  public function setAttrDraggable(?string $value): self
319
  {
320 1
    $this->attributes['draggable'] = $value;
321
322 1
    return $this;
323
  }
324
325
  //--------------------------------------------------------------------------------------------------------------------
326
  /**
327
   * Sets the attribute [dropzone](http://www.w3schools.com/tags/att_global_dropzone.asp).
328
   *
329
   * @param string|null $value The attribute value.
330
   *
331
   * @return $this
332
   *
333
   * @since 1.0.0
334
   * @api
335
   */
336 1
  public function setAttrDropZone(?string $value): self
337
  {
338 1
    $this->attributes['dropzone'] = $value;
339
340 1
    return $this;
341
  }
342
343
  //--------------------------------------------------------------------------------------------------------------------
344
  /**
345
   * Sets the attribute [hidden](http://www.w3schools.com/tags/att_global_hidden.asp).
346
   * This is a boolean attribute. Any none [empty](http://php.net/manual/function.empty.php) value will set the
347
   * attribute to 'hidden'. Any other value will unset the attribute.
348
   *
349
   * @param mixed $value The attribute value.
350
   *
351
   * @return $this
352
   *
353
   * @since 1.0.0
354
   * @api
355
   */
356 1
  public function setAttrHidden(?string $value): self
357
  {
358 1
    $this->attributes['hidden'] = $value;
359
360 1
    return $this;
361
  }
362
363
  //--------------------------------------------------------------------------------------------------------------------
364
  /**
365
   * Sets the attribute [id](http://www.w3schools.com/tags/att_global_id.asp).
366
   *
367
   * @param string|null $value The attribute value.
368
   *
369
   * @return $this
370
   *
371
   * @since 1.0.0
372
   * @api
373
   */
374 2
  public function setAttrId(?string $value): self
375
  {
376 2
    $this->attributes['id'] = $value;
377
378 2
    return $this;
379
  }
380
381
  //--------------------------------------------------------------------------------------------------------------------
382
  /**
383
   * Sets the attribute [lang](http://www.w3schools.com/tags/att_global_lang.asp).
384
   *
385
   * @param string|null $value The attribute value.
386
   *
387
   * @return $this
388
   *
389
   * @since 1.0.0
390
   * @api
391
   */
392 1
  public function setAttrLang(?string $value): self
393
  {
394 1
    $this->attributes['lang'] = $value;
395
396 1
    return $this;
397
  }
398
399
  //--------------------------------------------------------------------------------------------------------------------
400
  /**
401
   * Sets the attribute [role](http://w3c.github.io/html/infrastructure.html#element-attrdef-aria-role).
402
   *
403
   * @param string|null $value The attribute value.
404
   *
405
   * @return $this
406
   *
407
   * @since 1.3.0
408
   * @api
409
   */
410 1
  public function setAttrRole(?string $value): self
411
  {
412 1
    $this->attributes['role'] = $value;
413
414 1
    return $this;
415
  }
416
417
  //--------------------------------------------------------------------------------------------------------------------
418
  /**
419
   * Sets the attribute [spellcheck](http://www.w3schools.com/tags/att_global_spellcheck.asp).
420
   * <ul>
421
   * <li> Any value that evaluates to true will set the attribute to 'true'.
422
   * <li> Any value that evaluates to false will set the attribute to 'false'.
423
   * <li> Null will unset the attribute.
424
   * <ul>
425
   *
426
   * @param string|null $value The attribute value.
427
   *
428
   * @return $this
429
   *
430
   * @since 1.0.0
431
   * @api
432
   */
433 1
  public function setAttrSpellCheck(?string $value): self
434
  {
435 1
    $this->attributes['spellcheck'] = $value;
436
437 1
    return $this;
438
  }
439
440
  //--------------------------------------------------------------------------------------------------------------------
441
  /**
442
   * Sets the attribute [style](http://www.w3schools.com/tags/att_global_style.asp)
443
   *
444
   * @param string|null $value The attribute value.
445
   *
446
   * @return $this
447
   *
448
   * @since 1.0.0
449
   * @api
450
   */
451 1
  public function setAttrStyle(?string $value): self
452
  {
453 1
    $this->attributes['style'] = $value;
454
455 1
    return $this;
456
  }
457
458
  //--------------------------------------------------------------------------------------------------------------------
459
  /**
460
   * Sets the attribute [tabindex](http://www.w3schools.com/tags/att_global_tabindex.asp).
461
   *
462
   * @param int|null $value The attribute value.
463
   *
464
   * @return $this
465
   *
466
   * @since 1.0.0
467
   * @api
468
   */
469 1
  public function setAttrTabIndex(?int $value): self
470
  {
471 1
    $this->attributes['tabindex'] = $value;
472
473 1
    return $this;
474
  }
475
476
  //--------------------------------------------------------------------------------------------------------------------
477
  /**
478
   * Sets the attribute [title](http://www.w3schools.com/tags/att_global_title.asp).
479
   *
480
   * @param string|null $value The attribute value.
481
   *
482
   * @return $this
483
   *
484
   * @since 1.0.0
485
   * @api
486
   */
487 1
  public function setAttrTitle(?string $value): self
488
  {
489 1
    $this->attributes['title'] = $value;
490
491 1
    return $this;
492
  }
493
494
  //--------------------------------------------------------------------------------------------------------------------
495
  /**
496
   * Sets the attribute [translate](http://www.w3schools.com/tags/att_global_translate.asp).
497
   * <ul>
498
   * <li> Any value that evaluates to true will set the attribute to 'yes'.
499
   * <li> Any value that evaluates to false will set the attribute to 'no'.
500
   * <li> Null will unset the attribute.
501
   * </ul>
502
   *
503
   * @param mixed $value The attribute value.
504
   *
505
   * @return $this
506
   *
507
   * @since 1.0.0
508
   * @api
509
   */
510 1
  public function setAttrTranslate(?string $value): self
511
  {
512 1
    $this->attributes['translate'] = $value;
513
514 1
    return $this;
515
  }
516
517
  //--------------------------------------------------------------------------------------------------------------------
518
  /**
519
   * Sets a fake attribute. A fake attribute has a name that starts with an underscore. Fake attributes will not be
520
   * included in the generated HTML code.
521
   *
522
   * @param string $name  The name of the fake attribute.
523
   * @param mixed  $value The value of the fake attribute.
524
   *
525
   * @return $this
526
   *
527
   * @since 1.0.0
528
   * @api
529
   */
530 2
  public function setFakeAttribute(string $name, $value): self
531
  {
532 2
    if (strpos($name, '_')!==0)
533
    {
534 1
      throw new LogicException("Attribute '%s' is not a valid fake attribute.", $name);
535
    }
536
537 1
    $this->attributes[$name] = $value;
538
539 1
    return $this;
540
  }
541
542
  //--------------------------------------------------------------------------------------------------------------------
543
  /**
544
   * Removes all classes for the list of classes.
545
   *
546
   * @return $this
547
   *
548
   * @since 1.0.0
549
   * @api
550
   */
551 1
  public function unsetClass(): self
552
  {
553 1
    unset($this->attributes['class']);
554
555 1
    return $this;
556
  }
557
558
  //--------------------------------------------------------------------------------------------------------------------
559
}
560
561
//----------------------------------------------------------------------------------------------------------------------
562