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.
Auf den Verzeichnisnamen klicken, dies zeigt nur das Verzeichnis mit Inhalt an

(Beispiel Datei-Icons)

Auf das Icon klicken um den Quellcode anzuzeigen

TraitUsageGenerator.php

Zuletzt modifiziert: 02.04.2025, 15:03 - Dateigröße: 12.16 KiB


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