[ Index ]

PHP Cross Reference of phpBB-3.3.14-deutsch

title

Body

[close]

/vendor/zendframework/zend-code/src/Generator/ -> TraitUsageGenerator.php (source)

   1  <?php
   2  /**
   3   * Zend Framework (http://framework.zend.com/)
   4   *
   5   * @link      http://github.com/zendframework/zf2 for the canonical source repository
   6   * @copyright Copyright (c) 2005-2016 Zend Technologies USA Inc. (http://www.zend.com)
   7   * @license   http://framework.zend.com/license/new-bsd New BSD License
   8   */
   9  
  10  namespace Zend\Code\Generator;
  11  
  12  use Reflection;
  13  use ReflectionMethod;
  14  
  15  use function array_key_exists;
  16  use function array_search;
  17  use function array_values;
  18  use function count;
  19  use function current;
  20  use function explode;
  21  use function implode;
  22  use function in_array;
  23  use function is_array;
  24  use function is_string;
  25  use function sprintf;
  26  use function strpos;
  27  
  28  class TraitUsageGenerator extends AbstractGenerator implements TraitUsageInterface
  29  {
  30      /**
  31       * @var ClassGenerator
  32       */
  33      protected $classGenerator;
  34  
  35      /**
  36       * @var array Array of trait names
  37       */
  38      protected $traits = [];
  39  
  40      /**
  41       * @var array Array of trait aliases
  42       */
  43      protected $traitAliases = [];
  44  
  45      /**
  46       * @var array Array of trait overrides
  47       */
  48      protected $traitOverrides = [];
  49  
  50      /**
  51       * @var array Array of string names
  52       */
  53      protected $uses = [];
  54  
  55      public function __construct(ClassGenerator $classGenerator)
  56      {
  57          $this->classGenerator = $classGenerator;
  58      }
  59  
  60      /**
  61       * @inheritDoc
  62       */
  63      public function addUse($use, $useAlias = null)
  64      {
  65          $this->removeUse($use);
  66  
  67          if (! empty($useAlias)) {
  68              $use .= ' as ' . $useAlias;
  69          }
  70  
  71          $this->uses[$use] = $use;
  72          return $this;
  73      }
  74  
  75      /**
  76       * @inheritDoc
  77       */
  78      public function getUses()
  79      {
  80          return array_values($this->uses);
  81      }
  82  
  83      /**
  84       * @param string $use
  85       * @return bool
  86       */
  87      public function hasUse($use)
  88      {
  89          foreach ($this->uses as $key => $value) {
  90              $parts = explode(' ', $value);
  91              if ($parts[0] === $use) {
  92                  return true;
  93              }
  94          }
  95  
  96          return false;
  97      }
  98  
  99      /**
 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  }


Generated: Mon Nov 25 19:05:08 2024 Cross-referenced by PHPXref 0.7.1