‪TYPO3CMS  10.4
SimpleParser.php
Go to the documentation of this file.
1 <?php
2 
3 declare(strict_types=1);
4 
5 /*
6  * This file is part of the TYPO3 CMS project.
7  *
8  * It is free software; you can redistribute it and/or modify it under
9  * the terms of the GNU General Public License, either version 2
10  * of the License, or any later version.
11  *
12  * For the full copyright and license information, please read the
13  * LICENSE.txt file that was distributed with this source code.
14  *
15  * The TYPO3 project - inspiring people to share!
16  */
17 
18 namespace ‪TYPO3\CMS\Core\Html;
19 
32 {
36  protected ‪$attribute;
37 
41  protected ‪$nodes = [];
42 
47 
51  protected ‪$currentData = '';
52 
53  public static function ‪fromString(string $string): self
54  {
55  return new self($string);
56  }
57 
58  public function ‪__construct(string $string)
59  {
60  $this->‪process($string);
61  }
62 
67  public function ‪getNodes(int ...$types): array
68  {
69  if (empty($types)) {
70  return ‪$this->nodes;
71  }
72  ‪$nodes = array_filter(
73  $this->nodes,
74  function (SimpleNode $node) use ($types): bool {
75  return in_array(
76  $node->getType(),
77  $types,
78  true
79  );
80  }
81  );
82  // reindex nodes
83  return array_values(‪$nodes);
84  }
85 
90  public function ‪getFirstNode(int $type = null): ?SimpleNode
91  {
92  foreach ($this->nodes as $node) {
93  if ($type === null || $type === $node->getType()) {
94  return $node;
95  }
96  }
97  return null;
98  }
99 
104  public function ‪getLastNode(int $type = null): ?SimpleNode
105  {
106  foreach (array_reverse($this->nodes) as $node) {
107  if ($type === null || $type === $node->getType()) {
108  return $node;
109  }
110  }
111  return null;
112  }
113 
119  protected function ‪process(string $string): void
120  {
121  $skip = 0;
122  $characters = str_split($string, 1);
123  foreach ($characters as $i => $character) {
124  // skip tokens that already haven been processed
125  if ($skip > 0 && $skip-- > 0) {
126  continue;
127  }
128  // CDATA start
129  if ($character === '<'
130  && $this->‪isType(‪SimpleNode::TYPE_TEXT) && substr($string, $i, 9) === '<![CDATA['
131  ) {
133  $this->‪append('<![CDATA[');
134  $skip = 8;
135  // comment start
136  } elseif ($character === '<'
137  && $this->‪isType(‪SimpleNode::TYPE_TEXT) && substr($string, $i, 4) === '<!--'
138  ) {
140  $this->‪append('<!--');
141  $skip = 3;
142  // element start
143  } elseif ($character === '<'
145  && preg_match('#^</?[a-z]#i', substr($string, $i, 3))
146  ) {
148  $this->‪append($character);
149  // CDATA end
150  } elseif ($character === ']'
151  && $this->‪isType(‪SimpleNode::TYPE_CDATA) && substr($string, $i, 3) === ']]>'
152  ) {
153  $this->‪append(']]>');
155  $skip = 2;
156  // comment end
157  } elseif ($character === '-'
158  && $this->‪isType(‪SimpleNode::TYPE_COMMENT) && substr($string, $i, 3) === '-->'
159  ) {
160  $this->‪append('-->');
162  $skip = 2;
163  // element end
164  } elseif ($character === '>'
166  ) {
167  $this->‪append($character);
169  // element attribute start
170  } elseif (($character === '"' || $character === "'")
172  ) {
173  $this->attribute = $character;
174  $this->‪append($character);
175  // element attribute end
176  } elseif (($character === '"' || $character === "'")
177  && $this->‪isType(‪SimpleNode::TYPE_ELEMENT) && $this->attribute === $character
178  ) {
179  $this->‪append($character);
180  $this->attribute = null;
181  // anything else (put to current type)
182  } else {
183  $this->‪append($character);
184  }
185  }
186  $this->‪finish();
187  }
188 
194  protected function ‪next(int $nextType): void
195  {
196  if ($this->currentData !== '') {
197  $this->nodes[] = ‪SimpleNode::fromString(
198  $this->currentType,
199  count($this->nodes),
200  $this->currentData
201  );
202  }
203  $this->currentType = $nextType;
204  $this->currentData = '';
205  }
206 
212  protected function ‪finish(): void
213  {
214  if ($this->currentData === '') {
215  return;
216  }
217  if ($this->‪isType(‪SimpleNode::TYPE_TEXT)) {
218  $this->nodes[] = ‪SimpleNode::fromString(
219  $this->currentType,
220  count($this->nodes),
221  $this->currentData
222  );
223  }
224  // either unfinished element or comment
225  // (ignored on purpose)
226  }
227 
228  protected function ‪append(string $string): void
229  {
230  $this->currentData .= $string;
231  }
232 
233  protected function ‪isType(int $type): bool
234  {
235  return $this->currentType === $type;
236  }
237 
238  protected function ‪inAttribute(): bool
239  {
240  return $this->attribute !== null;
241  }
242 }
‪TYPO3\CMS\Core\Html
Definition: DefaultSanitizerBuilder.php:15
‪TYPO3\CMS\Core\Html\SimpleParser\$attribute
‪string null $attribute
Definition: SimpleParser.php:35
‪TYPO3\CMS\Core\Html\SimpleParser\append
‪append(string $string)
Definition: SimpleParser.php:224
‪TYPO3\CMS\Core\Html\SimpleNode\getType
‪int getType()
Definition: SimpleNode.php:63
‪TYPO3\CMS\Core\Html\SimpleParser
Definition: SimpleParser.php:32
‪TYPO3\CMS\Core\Html\SimpleParser\getFirstNode
‪SimpleNode null getFirstNode(int $type=null)
Definition: SimpleParser.php:86
‪TYPO3\CMS\Core\Html\SimpleParser\inAttribute
‪inAttribute()
Definition: SimpleParser.php:234
‪TYPO3\CMS\Core\Html\SimpleParser\process
‪process(string $string)
Definition: SimpleParser.php:115
‪TYPO3\CMS\Core\Html\SimpleNode\TYPE_ELEMENT
‪const TYPE_ELEMENT
Definition: SimpleNode.php:26
‪TYPO3\CMS\Core\Html\SimpleNode\fromString
‪static fromString(int $type, int $index, string $string)
Definition: SimpleNode.php:43
‪TYPO3\CMS\Core\Html\SimpleParser\$nodes
‪SimpleNode[] $nodes
Definition: SimpleParser.php:39
‪TYPO3\CMS\Core\Html\SimpleParser\isType
‪isType(int $type)
Definition: SimpleParser.php:229
‪TYPO3\CMS\Core\Html\SimpleNode\TYPE_TEXT
‪const TYPE_TEXT
Definition: SimpleNode.php:27
‪TYPO3\CMS\Core\Html\SimpleNode\TYPE_COMMENT
‪const TYPE_COMMENT
Definition: SimpleNode.php:29
‪TYPO3\CMS\Core\Html\SimpleParser\$currentData
‪string $currentData
Definition: SimpleParser.php:47
‪TYPO3\CMS\Core\Html\SimpleParser\finish
‪finish()
Definition: SimpleParser.php:208
‪TYPO3\CMS\Core\Html\SimpleParser\getLastNode
‪SimpleNode null getLastNode(int $type=null)
Definition: SimpleParser.php:100
‪TYPO3\CMS\Core\Html\SimpleParser\next
‪next(int $nextType)
Definition: SimpleParser.php:190
‪TYPO3\CMS\Core\Html\SimpleNode\TYPE_CDATA
‪const TYPE_CDATA
Definition: SimpleNode.php:28
‪TYPO3\CMS\Core\Html\SimpleParser\fromString
‪static fromString(string $string)
Definition: SimpleParser.php:49
‪TYPO3\CMS\Core\Html\SimpleParser\getNodes
‪SimpleNode[] getNodes(int ... $types)
Definition: SimpleParser.php:63
‪TYPO3\CMS\Core\Html\SimpleNode
Definition: SimpleNode.php:24
‪TYPO3\CMS\Core\Html\SimpleParser\$currentType
‪int $currentType
Definition: SimpleParser.php:43
‪TYPO3\CMS\Core\Html\SimpleParser\__construct
‪__construct(string $string)
Definition: SimpleParser.php:54