‪TYPO3CMS  ‪main
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  static 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 
89  public function ‪getFirstNode(int $type = null): ?‪SimpleNode
90  {
91  foreach ($this->nodes as $node) {
92  if ($type === null || $type === $node->getType()) {
93  return $node;
94  }
95  }
96  return null;
97  }
98 
102  public function ‪getLastNode(int $type = null): ?‪SimpleNode
103  {
104  foreach (array_reverse($this->nodes) as $node) {
105  if ($type === null || $type === $node->getType()) {
106  return $node;
107  }
108  }
109  return null;
110  }
111 
115  protected function ‪process(string $string): void
116  {
117  $skip = 0;
118  $characters = str_split($string, 1);
119  foreach ($characters as $i => $character) {
120  // skip tokens that already haven been processed
121  if ($skip > 0 && $skip-- > 0) {
122  continue;
123  }
124  // CDATA start
125  if ($character === '<'
126  && $this->‪isType(‪SimpleNode::TYPE_TEXT) && substr($string, $i, 9) === '<![CDATA['
127  ) {
129  $this->‪append('<![CDATA[');
130  $skip = 8;
131  // comment start
132  } elseif ($character === '<'
133  && $this->‪isType(‪SimpleNode::TYPE_TEXT) && substr($string, $i, 4) === '<!--'
134  ) {
136  $this->‪append('<!--');
137  $skip = 3;
138  // element start
139  } elseif ($character === '<'
141  && preg_match('#^</?[a-z]#i', substr($string, $i, 3))
142  ) {
144  $this->‪append($character);
145  // CDATA end
146  } elseif ($character === ']'
147  && $this->‪isType(‪SimpleNode::TYPE_CDATA) && substr($string, $i, 3) === ']]>'
148  ) {
149  $this->‪append(']]>');
151  $skip = 2;
152  // comment end
153  } elseif ($character === '-'
154  && $this->‪isType(‪SimpleNode::TYPE_COMMENT) && substr($string, $i, 3) === '-->'
155  ) {
156  $this->‪append('-->');
158  $skip = 2;
159  // element end
160  } elseif ($character === '>'
162  ) {
163  $this->‪append($character);
165  // element attribute start
166  } elseif (($character === '"' || $character === "'")
168  ) {
169  $this->attribute = $character;
170  $this->‪append($character);
171  // element attribute end
172  } elseif (($character === '"' || $character === "'")
173  && $this->‪isType(‪SimpleNode::TYPE_ELEMENT) && $this->attribute === $character
174  ) {
175  $this->‪append($character);
176  $this->attribute = null;
177  // anything else (put to current type)
178  } else {
179  $this->‪append($character);
180  }
181  }
182  $this->‪finish();
183  }
184 
188  protected function ‪next(int $nextType): void
189  {
190  if ($this->currentData !== '') {
191  $this->nodes[] = ‪SimpleNode::fromString(
192  $this->currentType,
193  count($this->nodes),
194  $this->currentData
195  );
196  }
197  $this->currentType = $nextType;
198  $this->currentData = '';
199  }
200 
206  protected function ‪finish(): void
207  {
208  if ($this->currentData === '') {
209  return;
210  }
211  if ($this->‪isType(‪SimpleNode::TYPE_TEXT)) {
212  $this->nodes[] = ‪SimpleNode::fromString(
213  $this->currentType,
214  count($this->nodes),
215  $this->currentData
216  );
217  }
218  // either unfinished element or comment
219  // (ignored on purpose)
220  }
221 
222  protected function ‪append(string $string): void
223  {
224  $this->currentData .= $string;
225  }
226 
227  protected function ‪isType(int $type): bool
228  {
229  return $this->currentType === $type;
230  }
231 
232  protected function ‪inAttribute(): bool
233  {
234  return $this->attribute !== null;
235  }
236 }
‪TYPO3\CMS\Core\Html
Definition: DefaultSanitizerBuilder.php:18
‪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:218
‪TYPO3\CMS\Core\Html\SimpleParser
Definition: SimpleParser.php:32
‪TYPO3\CMS\Core\Html\SimpleNode\getType
‪getType()
Definition: SimpleNode.php:60
‪TYPO3\CMS\Core\Html\SimpleParser\inAttribute
‪inAttribute()
Definition: SimpleParser.php:228
‪TYPO3\CMS\Core\Html\SimpleParser\process
‪process(string $string)
Definition: SimpleParser.php:111
‪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:223
‪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:202
‪TYPO3\CMS\Core\Html\SimpleParser\next
‪next(int $nextType)
Definition: SimpleParser.php:184
‪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\getFirstNode
‪getFirstNode(int $type=null)
Definition: SimpleParser.php:85
‪TYPO3\CMS\Core\Html\SimpleParser\getLastNode
‪getLastNode(int $type=null)
Definition: SimpleParser.php:98
‪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