Verzeichnisstruktur phpBB-3.2.0
- Veröffentlicht
- 06.01.2017
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 |
Configurator.php
001 <?php
002
003 /*
004 * @package s9e\TextFormatter
005 * @copyright Copyright (c) 2010-2016 The s9e Authors
006 * @license http://www.opensource.org/licenses/mit-license.php The MIT License
007 */
008 namespace s9e\TextFormatter\Plugins\Preg;
009 use DOMAttr;
010 use DOMText;
011 use DOMXPath;
012 use Exception;
013 use InvalidArgumentException;
014 use s9e\TextFormatter\Configurator\Helpers\RegexpParser;
015 use s9e\TextFormatter\Configurator\Helpers\TemplateHelper;
016 use s9e\TextFormatter\Configurator\Items\Regexp;
017 use s9e\TextFormatter\Configurator\Items\Tag;
018 use s9e\TextFormatter\Configurator\JavaScript\RegexpConvertor;
019 use s9e\TextFormatter\Plugins\ConfiguratorBase;
020 class Configurator extends ConfiguratorBase
021 {
022 public $captures;
023 protected $collection = array();
024 protected $delimiter;
025 protected $modifiers;
026 protected $references;
027 protected $referencesRegexp = '((?<!\\\\)(?:\\\\\\\\)*\\K(?:[$\\\\]\\d+|\\$\\{\\d+\\}))S';
028 public function asConfig()
029 {
030 if (!\count($this->collection))
031 return;
032 $pregs = array();
033 foreach ($this->collection as $_ca164be8)
034 {
035 list($tagName, $regexp, $passthroughIdx) = $_ca164be8;
036 $captures = RegexpParser::getCaptureNames($regexp);
037 $pregs[] = array($tagName, new Regexp($regexp, \true), $passthroughIdx, $captures);
038 }
039 return array('generics' => $pregs);
040 }
041 public function getJSHints()
042 {
043 $hasPassthrough = \false;
044 foreach ($this->collection as $_ca164be8)
045 {
046 list($tagName, $regexp, $passthroughIdx) = $_ca164be8;
047 if ($passthroughIdx)
048 {
049 $hasPassthrough = \true;
050 break;
051 }
052 }
053 return array('PREG_HAS_PASSTHROUGH' => $hasPassthrough);
054 }
055 public function match($regexp, $tagName)
056 {
057 $passthrough = 0;
058 $this->parseRegexp($regexp);
059 foreach ($this->captures as $i => $capture)
060 {
061 if (!$this->isCatchAll($capture['expr']))
062 continue;
063 $passthrough = $i;
064 }
065 $this->collection[] = array($tagName, $regexp, $passthrough);
066 }
067 public function replace($regexp, $template, $tagName = \null)
068 {
069 if (!isset($tagName))
070 $tagName = 'PREG_' . \strtoupper(\dechex(\crc32($regexp)));
071 $this->parseRegexp($regexp);
072 $this->parseTemplate($template);
073 $passthrough = $this->getPassthroughCapture();
074 if ($passthrough)
075 $this->captures[$passthrough]['passthrough'] = \true;
076 $regexp = $this->fixUnnamedCaptures($regexp);
077 $template = $this->convertTemplate($template, $passthrough);
078 $this->collection[] = array($tagName, $regexp, $passthrough);
079 return $this->createTag($tagName, $template);
080 }
081 protected function addAttribute(Tag $tag, $attrName)
082 {
083 $isUrl = \false;
084 $exprs = array();
085 foreach ($this->captures as $key => $capture)
086 {
087 if ($capture['name'] !== $attrName)
088 continue;
089 $exprs[] = $capture['expr'];
090 if (isset($this->references['asUrl'][$key]))
091 $isUrl = \true;
092 }
093 $exprs = \array_unique($exprs);
094 $regexp = $this->delimiter . '^';
095 $regexp .= (\count($exprs) === 1) ? $exprs[0] : '(?:' . \implode('|', $exprs) . ')';
096 $regexp .= '$' . $this->delimiter . 'D' . $this->modifiers;
097 $attribute = $tag->attributes->add($attrName);
098 $filter = $this->configurator->attributeFilters['#regexp'];
099 $filter->setRegexp($regexp);
100 $attribute->filterChain[] = $filter;
101 if ($isUrl)
102 {
103 $filter = $this->configurator->attributeFilters['#url'];
104 $attribute->filterChain[] = $filter;
105 }
106 }
107 protected function convertTemplate($template, $passthrough)
108 {
109 $_this = $this;
110 $template = TemplateHelper::replaceTokens(
111 $template,
112 $this->referencesRegexp,
113 function ($m, $node) use ($passthrough, $_this)
114 {
115 $key = (int) \trim($m[0], '\\${}');
116 if ($key === 0)
117 return array('expression', '.');
118 if ($key === $passthrough && $node instanceof DOMText)
119 return array('passthrough');
120 if (isset($_this->captures[$key]['name']))
121 return array('expression', '@' . $_this->captures[$key]['name']);
122 return array('literal', '');
123 }
124 );
125 $template = TemplateHelper::replaceTokens(
126 $template,
127 '(\\\\+[0-9${\\\\])',
128 function ($m)
129 {
130 return array('literal', \stripslashes($m[0]));
131 }
132 );
133 return $template;
134 }
135 protected function createTag($tagName, $template)
136 {
137 $tag = new Tag;
138 foreach ($this->captures as $key => $capture)
139 {
140 if (!isset($capture['name']))
141 continue;
142 $attrName = $capture['name'];
143 if (isset($tag->attributes[$attrName]))
144 continue;
145 $this->addAttribute($tag, $attrName);
146 }
147 $tag->template = $template;
148 $this->configurator->templateNormalizer->normalizeTag($tag);
149 $this->configurator->templateChecker->checkTag($tag);
150 return $this->configurator->tags->add($tagName, $tag);
151 }
152 protected function fixUnnamedCaptures($regexp)
153 {
154 $keys = array();
155 foreach ($this->references['anywhere'] as $key)
156 {
157 $capture = $this->captures[$key];
158 if (!$key || isset($capture['name']))
159 continue;
160 if (isset($this->references['asUrl'][$key]) || !isset($capture['passthrough']))
161 $keys[] = $key;
162 }
163 \rsort($keys);
164 foreach ($keys as $key)
165 {
166 $name = '_' . $key;
167 $pos = $this->captures[$key]['pos'];
168 $regexp = \substr_replace($regexp, "?'" . $name . "'", 2 + $pos, 0);
169 $this->captures[$key]['name'] = $name;
170 }
171 return $regexp;
172 }
173 protected function getPassthroughCapture()
174 {
175 $passthrough = 0;
176 foreach ($this->references['inText'] as $key)
177 {
178 if (!$this->isCatchAll($this->captures[$key]['expr']))
179 continue;
180 if ($passthrough)
181 {
182 $passthrough = 0;
183 break;
184 }
185 $passthrough = (int) $key;
186 }
187 return $passthrough;
188 }
189 protected function getRegexpInfo($regexp)
190 {
191 $valid = \false;
192 try
193 {
194 $valid = @\preg_match_all($regexp, '', $m);
195 }
196 catch (Exception $e)
197 {
198 }
199 if ($valid === \false)
200 throw new InvalidArgumentException('Invalid regexp');
201 return RegexpParser::parse($regexp);
202 }
203 protected function isCatchAll($expr)
204 {
205 return (bool) \preg_match('(^\\.[*+]\\??$)D', $expr);
206 }
207 protected function parseRegexp($regexp)
208 {
209 $this->captures = array(array('name' => \null, 'expr' => \null));
210 $regexpInfo = $this->getRegexpInfo($regexp);
211 $this->delimiter = $regexpInfo['delimiter'];
212 $this->modifiers = \str_replace('D', '', $regexpInfo['modifiers']);
213 foreach ($regexpInfo['tokens'] as $token)
214 {
215 if ($token['type'] !== 'capturingSubpatternStart')
216 continue;
217 $this->captures[] = array(
218 'pos' => $token['pos'],
219 'name' => (isset($token['name'])) ? $token['name'] : \null,
220 'expr' => $token['content']
221 );
222 }
223 }
224 protected function parseTemplate($template)
225 {
226 $this->references = array(
227 'anywhere' => array(),
228 'asUrl' => array(),
229 'inText' => array()
230 );
231 \preg_match_all($this->referencesRegexp, $template, $matches);
232 foreach ($matches[0] as $match)
233 {
234 $key = \trim($match, '\\${}');
235 $this->references['anywhere'][$key] = $key;
236 }
237 $dom = TemplateHelper::loadTemplate($template);
238 $xpath = new DOMXPath($dom);
239 foreach ($xpath->query('//text()') as $node)
240 {
241 \preg_match_all($this->referencesRegexp, $node->textContent, $matches);
242 foreach ($matches[0] as $match)
243 {
244 $key = \trim($match, '\\${}');
245 $this->references['inText'][$key] = $key;
246 }
247 }
248 foreach (TemplateHelper::getURLNodes($dom) as $node)
249 if ($node instanceof DOMAttr
250 && \preg_match('(^(?:[$\\\\]\\d+|\\$\\{\\d+\\}))', \trim($node->value), $m))
251 {
252 $key = \trim($m[0], '\\${}');
253 $this->references['asUrl'][$key] = $key;
254 }
255 $this->removeUnknownReferences();
256 }
257 protected function removeUnknownReferences()
258 {
259 foreach ($this->references as &$references)
260 $references = \array_intersect_key($references, $this->captures);
261 }
262 }