Verzeichnisstruktur phpBB-3.3.15
- Veröffentlicht
- 28.08.2024
So funktioniert es
|
Auf das letzte Element klicken. Dies geht jeweils ein Schritt zurück |
Auf das Icon klicken, dies öffnet das Verzeichnis. Nochmal klicken schließt das Verzeichnis. |
|
(Beispiel Datei-Icons)
|
Auf das Icon klicken um den Quellcode anzuzeigen |
Renderer.php
001 <?php
002
003 /**
004 * @package s9e\TextFormatter
005 * @copyright Copyright (c) 2010-2022 The s9e authors
006 * @license http://www.opensource.org/licenses/mit-license.php The MIT License
007 */
008 namespace s9e\TextFormatter;
009
010 use DOMDocument;
011 use InvalidArgumentException;
012
013 abstract class Renderer
014 {
015 /**
016 * @var array Associative array of [paramName => paramValue]
017 */
018 protected $params = [];
019
020 /**
021 * @var string Saved locale
022 */
023 protected $savedLocale = '0';
024
025 /**
026 * Create a return a new DOMDocument loaded with given XML
027 *
028 * @param string $xml Source XML
029 * @return DOMDocument
030 */
031 protected function loadXML($xml)
032 {
033 $this->checkUnsupported($xml);
034
035 // Activate small nodes allocation and relax LibXML's hardcoded limits if applicable. Limits
036 // on tags can be set during configuration
037 $flags = (LIBXML_VERSION >= 20700) ? LIBXML_COMPACT | LIBXML_PARSEHUGE : 0;
038
039 $useErrors = libxml_use_internal_errors(true);
040 $dom = new DOMDocument;
041 $success = $dom->loadXML($xml, $flags);
042 libxml_use_internal_errors($useErrors);
043
044 if (!$success)
045 {
046 throw new InvalidArgumentException('Cannot load XML: ' . libxml_get_last_error()->message);
047 }
048
049 return $dom;
050 }
051
052 /**
053 * Render an intermediate representation
054 *
055 * @param string $xml Intermediate representation
056 * @return string Rendered result
057 */
058 public function render($xml)
059 {
060 if (substr($xml, 0, 3) === '<t>' && substr($xml, -4) === '</t>')
061 {
062 return $this->renderPlainText($xml);
063 }
064 else
065 {
066 return $this->renderRichText(preg_replace('(<[eis]>[^<]*</[eis]>)', '', $xml));
067 }
068 }
069
070 /**
071 * Render an intermediate representation of plain text
072 *
073 * @param string $xml Intermediate representation
074 * @return string Rendered result
075 */
076 protected function renderPlainText($xml)
077 {
078 // Remove the <t> and </t> tags
079 $html = substr($xml, 3, -4);
080
081 // Replace all <br/> with <br>
082 $html = str_replace('<br/>', '<br>', $html);
083
084 // Decode encoded characters from the Supplementary Multilingual Plane
085 $html = $this->decodeSMP($html);
086
087 return $html;
088 }
089
090 /**
091 * Render an intermediate representation of rich text
092 *
093 * @param string $xml Intermediate representation
094 * @return string Rendered result
095 */
096 abstract protected function renderRichText($xml);
097
098 /**
099 * Get the value of a parameter
100 *
101 * @param string $paramName
102 * @return string
103 */
104 public function getParameter($paramName)
105 {
106 return $this->params[$paramName] ?? '';
107 }
108
109 /**
110 * Get the values of all parameters
111 *
112 * @return array Associative array of parameter names and values
113 */
114 public function getParameters()
115 {
116 return $this->params;
117 }
118
119 /**
120 * Set the value of a parameter from the stylesheet
121 *
122 * @param string $paramName Parameter name
123 * @param mixed $paramValue Parameter's value
124 * @return void
125 */
126 public function setParameter($paramName, $paramValue)
127 {
128 $this->params[$paramName] = (string) $paramValue;
129 }
130
131 /**
132 * Set the values of several parameters from the stylesheet
133 *
134 * @param array $params Associative array of [parameter name => parameter value]
135 * @return void
136 */
137 public function setParameters(array $params)
138 {
139 foreach ($params as $paramName => $paramValue)
140 {
141 $this->setParameter($paramName, $paramValue);
142 }
143 }
144
145 /**
146 * Test for the presence of unsupported XML and throw an exception if found
147 *
148 * @param string $xml XML
149 * @return void
150 */
151 protected function checkUnsupported($xml)
152 {
153 if (preg_match('((?<=<)[!?])', $xml, $m))
154 {
155 $errors = [
156 '!' => 'DTDs, CDATA nodes and comments are not allowed',
157 '?' => 'Processing instructions are not allowed'
158 ];
159
160 throw new InvalidArgumentException($errors[$m[0]]);
161 }
162 }
163
164 /**
165 * Decode encoded characters from the Supplementary Multilingual Plane
166 *
167 * @param string $str Encoded string
168 * @return string Decoded string
169 */
170 protected function decodeSMP($str)
171 {
172 if (strpos($str, '&#') === false)
173 {
174 return $str;
175 }
176
177 return preg_replace_callback('(&#(?:x[0-9A-Fa-f]+|[0-9]+);)', __CLASS__ . '::decodeEntity', $str);
178 }
179
180 /**
181 * Decode a matched SGML entity
182 *
183 * @param string[] $m Captures from PCRE
184 * @return string Decoded entity
185 */
186 protected static function decodeEntity(array $m)
187 {
188 return htmlspecialchars(html_entity_decode($m[0], ENT_QUOTES, 'UTF-8'), ENT_COMPAT);
189 }
190
191 /**
192 * Restore the original locale
193 */
194 protected function restoreLocale(): void
195 {
196 if ($this->savedLocale !== 'C')
197 {
198 setlocale(LC_NUMERIC, $this->savedLocale);
199 }
200 }
201
202 /**
203 * Temporarily set the locale to C
204 */
205 protected function setLocale(): void
206 {
207 $this->savedLocale = setlocale(LC_NUMERIC, '0');
208 if ($this->savedLocale !== 'C')
209 {
210 setlocale(LC_NUMERIC, 'C');
211 }
212 }
213 }
214