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 |
TraitUsageGenerator.php
001 <?php
002 /**
003 * Zend Framework (http://framework.zend.com/)
004 *
005 * @link http://github.com/zendframework/zf2 for the canonical source repository
006 * @copyright Copyright (c) 2005-2016 Zend Technologies USA Inc. (http://www.zend.com)
007 * @license http://framework.zend.com/license/new-bsd New BSD License
008 */
009
010 namespace Zend\Code\Generator;
011
012 use Reflection;
013 use ReflectionMethod;
014
015 use function array_key_exists;
016 use function array_search;
017 use function array_values;
018 use function count;
019 use function current;
020 use function explode;
021 use function implode;
022 use function in_array;
023 use function is_array;
024 use function is_string;
025 use function sprintf;
026 use function strpos;
027
028 class TraitUsageGenerator extends AbstractGenerator implements TraitUsageInterface
029 {
030 /**
031 * @var ClassGenerator
032 */
033 protected $classGenerator;
034
035 /**
036 * @var array Array of trait names
037 */
038 protected $traits = [];
039
040 /**
041 * @var array Array of trait aliases
042 */
043 protected $traitAliases = [];
044
045 /**
046 * @var array Array of trait overrides
047 */
048 protected $traitOverrides = [];
049
050 /**
051 * @var array Array of string names
052 */
053 protected $uses = [];
054
055 public function __construct(ClassGenerator $classGenerator)
056 {
057 $this->classGenerator = $classGenerator;
058 }
059
060 /**
061 * @inheritDoc
062 */
063 public function addUse($use, $useAlias = null)
064 {
065 $this->removeUse($use);
066
067 if (! empty($useAlias)) {
068 $use .= ' as ' . $useAlias;
069 }
070
071 $this->uses[$use] = $use;
072 return $this;
073 }
074
075 /**
076 * @inheritDoc
077 */
078 public function getUses()
079 {
080 return array_values($this->uses);
081 }
082
083 /**
084 * @param string $use
085 * @return bool
086 */
087 public function hasUse($use)
088 {
089 foreach ($this->uses as $key => $value) {
090 $parts = explode(' ', $value);
091 if ($parts[0] === $use) {
092 return true;
093 }
094 }
095
096 return false;
097 }
098
099 /**
100 * @param string $use
101 * @return bool
102 */
103 public function hasUseAlias($use)
104 {
105 foreach ($this->uses as $key => $value) {
106 $parts = explode(' as ', $value);
107 if ($parts[0] === $use && count($parts) == 2) {
108 return true;
109 }
110 }
111
112 return false;
113 }
114
115 /**
116 * Returns the alias of the provided FQCN
117 *
118 * @param string $use
119 * @return string|null
120 */
121 public function getUseAlias(string $use): ?string
122 {
123 foreach ($this->uses as $key => $value) {
124 $parts = explode(' as ', $key);
125 if ($parts[0] === $use && count($parts) == 2) {
126 return $parts[1];
127 }
128 }
129 return null;
130 }
131
132 /**
133 * Returns true if the alias is defined in the use list
134 *
135 * @param string $alias
136 * @return bool
137 */
138 public function isUseAlias(string $alias): bool
139 {
140 foreach ($this->uses as $key => $value) {
141 $parts = explode(' as ', $key);
142 if (count($parts) === 2 && $parts[1] === $alias) {
143 return true;
144 }
145 }
146 return false;
147 }
148
149 /**
150 * @param string $use
151 * @return TraitUsageGenerator
152 */
153 public function removeUse($use)
154 {
155 foreach ($this->uses as $key => $value) {
156 $parts = explode(' ', $value);
157 if ($parts[0] === $use) {
158 unset($this->uses[$value]);
159 }
160 }
161
162 return $this;
163 }
164
165 /**
166 * @param string $use
167 * @return TraitUsageGenerator
168 */
169 public function removeUseAlias($use)
170 {
171 foreach ($this->uses as $key => $value) {
172 $parts = explode(' as ', $value);
173 if ($parts[0] === $use && count($parts) == 2) {
174 unset($this->uses[$value]);
175 }
176 }
177
178 return $this;
179 }
180
181 /**
182 * @inheritDoc
183 */
184 public function addTrait($trait)
185 {
186 $traitName = $trait;
187 if (is_array($trait)) {
188 if (! array_key_exists('traitName', $trait)) {
189 throw new Exception\InvalidArgumentException('Missing required value for traitName');
190 }
191 $traitName = $trait['traitName'];
192
193 if (array_key_exists('aliases', $trait)) {
194 foreach ($trait['aliases'] as $alias) {
195 $this->addAlias($alias);
196 }
197 }
198
199 if (array_key_exists('insteadof', $trait)) {
200 foreach ($trait['insteadof'] as $insteadof) {
201 $this->addTraitOverride($insteadof);
202 }
203 }
204 }
205
206 if (! $this->hasTrait($traitName)) {
207 $this->traits[] = $traitName;
208 }
209
210 return $this;
211 }
212
213 /**
214 * @inheritDoc
215 */
216 public function addTraits(array $traits)
217 {
218 foreach ($traits as $trait) {
219 $this->addTrait($trait);
220 }
221
222 return $this;
223 }
224
225 /**
226 * @inheritDoc
227 */
228 public function hasTrait($traitName)
229 {
230 return in_array($traitName, $this->traits);
231 }
232
233 /**
234 * @inheritDoc
235 */
236 public function getTraits()
237 {
238 return $this->traits;
239 }
240
241 /**
242 * @inheritDoc
243 */
244 public function removeTrait($traitName)
245 {
246 $key = array_search($traitName, $this->traits);
247 if (false !== $key) {
248 unset($this->traits[$key]);
249 }
250
251 return $this;
252 }
253
254 /**
255 * @inheritDoc
256 */
257 public function addTraitAlias($method, $alias, $visibility = null)
258 {
259 $traitAndMethod = $method;
260 if (is_array($method)) {
261 if (! array_key_exists('traitName', $method)) {
262 throw new Exception\InvalidArgumentException('Missing required argument "traitName" for $method');
263 }
264
265 if (! array_key_exists('method', $method)) {
266 throw new Exception\InvalidArgumentException('Missing required argument "method" for $method');
267 }
268
269 $traitAndMethod = $method['traitName'] . '::' . $method['method'];
270 }
271
272 // Validations
273 if (false === strpos($traitAndMethod, '::')) {
274 throw new Exception\InvalidArgumentException(
275 'Invalid Format: $method must be in the format of trait::method'
276 );
277 }
278 if (! is_string($alias)) {
279 throw new Exception\InvalidArgumentException('Invalid Alias: $alias must be a string or array.');
280 }
281 if ($this->classGenerator->hasMethod($alias)) {
282 throw new Exception\InvalidArgumentException('Invalid Alias: Method name already exists on this class.');
283 }
284 if (null !== $visibility
285 && $visibility !== ReflectionMethod::IS_PUBLIC
286 && $visibility !== ReflectionMethod::IS_PRIVATE
287 && $visibility !== ReflectionMethod::IS_PROTECTED
288 ) {
289 throw new Exception\InvalidArgumentException(
290 'Invalid Type: $visibility must of ReflectionMethod::IS_PUBLIC,'
291 . ' ReflectionMethod::IS_PRIVATE or ReflectionMethod::IS_PROTECTED'
292 );
293 }
294
295 list($trait, $method) = explode('::', $traitAndMethod);
296 if (! $this->hasTrait($trait)) {
297 throw new Exception\InvalidArgumentException('Invalid trait: Trait does not exists on this class');
298 }
299
300 $this->traitAliases[$traitAndMethod] = [
301 'alias' => $alias,
302 'visibility' => $visibility,
303 ];
304
305 return $this;
306 }
307
308 /**
309 * @inheritDoc
310 */
311 public function getTraitAliases()
312 {
313 return $this->traitAliases;
314 }
315
316 /**
317 * @inheritDoc
318 */
319 public function addTraitOverride($method, $traitsToReplace)
320 {
321 if (false === is_array($traitsToReplace)) {
322 $traitsToReplace = [$traitsToReplace];
323 }
324
325 $traitAndMethod = $method;
326 if (is_array($method)) {
327 if (! array_key_exists('traitName', $method)) {
328 throw new Exception\InvalidArgumentException('Missing required argument "traitName" for $method');
329 }
330
331 if (! array_key_exists('method', $method)) {
332 throw new Exception\InvalidArgumentException('Missing required argument "method" for $method');
333 }
334
335 $traitAndMethod = (string) $method['traitName'] . '::' . (string) $method['method'];
336 }
337
338 // Validations
339 if (false === strpos($traitAndMethod, '::')) {
340 throw new Exception\InvalidArgumentException(
341 'Invalid Format: $method must be in the format of trait::method'
342 );
343 }
344
345 list($trait, $method) = explode('::', $traitAndMethod);
346 if (! $this->hasTrait($trait)) {
347 throw new Exception\InvalidArgumentException('Invalid trait: Trait does not exists on this class');
348 }
349
350 if (! array_key_exists($traitAndMethod, $this->traitOverrides)) {
351 $this->traitOverrides[$traitAndMethod] = [];
352 }
353
354 foreach ($traitsToReplace as $traitToReplace) {
355 if (! is_string($traitToReplace)) {
356 throw new Exception\InvalidArgumentException(
357 'Invalid Argument: $traitToReplace must be a string or array of strings'
358 );
359 }
360
361 if (! in_array($traitToReplace, $this->traitOverrides[$traitAndMethod])) {
362 $this->traitOverrides[$traitAndMethod][] = $traitToReplace;
363 }
364 }
365
366 return $this;
367 }
368
369 /**
370 * @inheritDoc
371 */
372 public function removeTraitOverride($method, $overridesToRemove = null)
373 {
374 if (! array_key_exists($method, $this->traitOverrides)) {
375 return $this;
376 }
377
378 if (null === $overridesToRemove) {
379 unset($this->traitOverrides[$method]);
380 return $this;
381 }
382
383 $overridesToRemove = ! is_array($overridesToRemove)
384 ? [$overridesToRemove]
385 : $overridesToRemove;
386 foreach ($overridesToRemove as $traitToRemove) {
387 $key = array_search($traitToRemove, $this->traitOverrides[$method]);
388 if (false !== $key) {
389 unset($this->traitOverrides[$method][$key]);
390 }
391 }
392 return $this;
393 }
394
395 /**
396 * @inheritDoc
397 */
398 public function getTraitOverrides()
399 {
400 return $this->traitOverrides;
401 }
402
403 /**
404 * @inheritDoc
405 */
406 public function generate()
407 {
408 $output = '';
409 $indent = $this->getIndentation();
410 $traits = $this->getTraits();
411
412 if (empty($traits)) {
413 return $output;
414 }
415
416 $output .= $indent . 'use ' . implode(', ', $traits);
417
418 $aliases = $this->getTraitAliases();
419 $overrides = $this->getTraitOverrides();
420 if (empty($aliases) && empty($overrides)) {
421 $output .= ';' . self::LINE_FEED . self::LINE_FEED;
422 return $output;
423 }
424
425 $output .= ' {' . self::LINE_FEED;
426 foreach ($aliases as $method => $alias) {
427 $visibility = null !== $alias['visibility']
428 ? current(Reflection::getModifierNames($alias['visibility'])) . ' '
429 : '';
430
431 // validation check
432 if ($this->classGenerator->hasMethod($alias['alias'])) {
433 throw new Exception\RuntimeException(sprintf(
434 'Generation Error: Aliased method %s already exists on this class',
435 $alias['alias']
436 ));
437 }
438
439 $output .=
440 $indent
441 . $indent
442 . $method
443 . ' as '
444 . $visibility
445 . $alias['alias']
446 . ';'
447 . self::LINE_FEED;
448 }
449
450 foreach ($overrides as $method => $insteadofTraits) {
451 foreach ($insteadofTraits as $insteadofTrait) {
452 $output .=
453 $indent
454 . $indent
455 . $method
456 . ' insteadof '
457 . $insteadofTrait
458 . ';'
459 . self::LINE_FEED;
460 }
461 }
462
463 $output .= self::LINE_FEED . $indent . '}' . self::LINE_FEED . self::LINE_FEED;
464
465 return $output;
466 }
467 }
468