(NFC) Civi/Afform/Symbols.php - Docblock
[civicrm-core.git] / ext / afform / core / Civi / Afform / Symbols.php
CommitLineData
77dccccb
TO
1<?php
2namespace Civi\Afform;
3
b853b419
TO
4/**
5 * Class Symbols
6 * @package Civi\Afform
7 *
8 * This class repesents a list of key symbols used by an
9 * HTML document, such as element (tag) names, attribute
10 * names, and CSS class names.
11 */
77dccccb
TO
12class Symbols {
13
14 /**
15 * @var array
16 * Array(string $element => int $count).
17 */
18 public $elements = [];
19
20 /**
21 * @var array
22 * Array(string $class => int $count).
23 */
24 public $classes = [];
25
26 /**
27 * @var array
28 * Array(string $attr => int $count).
29 */
30 public $attributes = [];
31
32 /**
33 * @param string $html
34 * @return static
35 */
36 public static function scan($html) {
37 $symbols = new static();
38 $doc = new \DOMDocumentWrapper($html, 'text/html');
39 $symbols->scanNode($doc->root);
40 return $symbols;
41 }
42
43 protected function scanNode(\DOMNode $node) {
44 if ($node instanceof \DOMElement) {
45
46 self::increment($this->elements, $node->tagName);
47
48 foreach ($node->childNodes as $childNode) {
49 $this->scanNode($childNode);
50 }
51
52 foreach ($node->attributes as $attribute) {
53 $this->scanNode($attribute);
54 }
55 }
56
57 elseif ($node instanceof \DOMAttr) {
58 self::increment($this->attributes, $node->nodeName);
59
60 if ($node->nodeName === 'class') {
648f59bf 61 $classes = $this->parseClasses($node->nodeValue);
77dccccb
TO
62 foreach ($classes as $class) {
63 self::increment($this->classes, $class);
64 }
65 }
66 }
67 }
68
648f59bf
TO
69 /**
70 * @param string $expr
71 * Ex: 'crm-icon fa-mail'
72 * @return array
73 * Ex: ['crm-icon', 'fa-mail']
74 */
75 protected function parseClasses($expr) {
76 if ($expr === '' || $expr === NULL || $expr === FALSE) {
77 return [];
78 }
79 if (strpos($expr, '{{') === FALSE) {
80 return explode(' ', $expr);
81 }
82 if (preg_match_all(';([a-zA-Z\-_]+|\{\{.*\}\}) ;U', "$expr ", $m)) {
83 return $m[1];
84 }
85 error_log("Failed to parse CSS classes: $expr");
86 return [];
87 }
88
77dccccb
TO
89 private static function increment(&$arr, $key) {
90 if (!isset($arr[$key])) {
91 $arr[$key] = 0;
92 }
93 $arr[$key]++;
94 }
95
96}