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

      (Beispiel Datei-Icons)

Auf das Icon klicken um den Quellcode anzuzeigen

FileGenerator.php

Zuletzt modifiziert: 09.10.2024, 12:57 - Dateigröße: 15.38 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-2015 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 Zend\Code\Reflection\Exception as ReflectionException;
 013  use Zend\Code\Reflection\FileReflection;
 014   
 015  class FileGenerator extends AbstractGenerator
 016  {
 017      /**
 018       * @var string
 019       */
 020      protected $filename = null;
 021   
 022      /**
 023       * @var DocBlockGenerator
 024       */
 025      protected $docBlock = null;
 026   
 027      /**
 028       * @var array
 029       */
 030      protected $requiredFiles = array();
 031   
 032      /**
 033       * @var string
 034       */
 035      protected $namespace = null;
 036   
 037      /**
 038       * @var array
 039       */
 040      protected $uses = array();
 041   
 042      /**
 043       * @var array
 044       */
 045      protected $classes = array();
 046   
 047      /**
 048       * @var string
 049       */
 050      protected $body = null;
 051   
 052      /**
 053       * Passes $options to {@link setOptions()}.
 054       *
 055       * @param  array|\Traversable $options
 056       */
 057      public function __construct($options = null)
 058      {
 059          if (null !== $options) {
 060              $this->setOptions($options);
 061          }
 062      }
 063   
 064      /**
 065       * Use this if you intend on generating code generation objects based on the same file.
 066       * This will keep previous changes to the file in tact during the same PHP process
 067       *
 068       * @param  string $filePath
 069       * @param  bool $includeIfNotAlreadyIncluded
 070       * @throws ReflectionException\InvalidArgumentException If file does not exists
 071       * @throws ReflectionException\RuntimeException If file exists but is not included or required
 072       * @return FileGenerator
 073       */
 074      public static function fromReflectedFileName($filePath, $includeIfNotAlreadyIncluded = true)
 075      {
 076          $fileReflector = new FileReflection($filePath, $includeIfNotAlreadyIncluded);
 077          $codeGenerator = static::fromReflection($fileReflector);
 078   
 079          return $codeGenerator;
 080      }
 081   
 082      /**
 083       * @param  FileReflection $fileReflection
 084       * @return FileGenerator
 085       */
 086      public static function fromReflection(FileReflection $fileReflection)
 087      {
 088          $file = new static();
 089   
 090          $file->setSourceContent($fileReflection->getContents());
 091          $file->setSourceDirty(false);
 092   
 093          $uses = $fileReflection->getUses();
 094   
 095          foreach ($fileReflection->getClasses() as $class) {
 096              $phpClass = ClassGenerator::fromReflection($class);
 097              $phpClass->setContainingFileGenerator($file);
 098   
 099              foreach ($uses as $fileUse) {
 100                  $phpClass->addUse($fileUse['use'], $fileUse['as']);
 101              }
 102   
 103              $file->setClass($phpClass);
 104          }
 105   
 106          $namespace = $fileReflection->getNamespace();
 107   
 108          if ($namespace != '') {
 109              $file->setNamespace($namespace);
 110          }
 111   
 112          if ($uses) {
 113              $file->setUses($uses);
 114          }
 115   
 116          if (($fileReflection->getDocComment() != '')) {
 117              $docBlock = $fileReflection->getDocBlock();
 118              $file->setDocBlock(DocBlockGenerator::fromReflection($docBlock));
 119          }
 120   
 121          return $file;
 122      }
 123   
 124      /**
 125       * @param  array $values
 126       * @return FileGenerator
 127       */
 128      public static function fromArray(array $values)
 129      {
 130          $fileGenerator = new static;
 131          foreach ($values as $name => $value) {
 132              switch (strtolower(str_replace(array('.', '-', '_'), '', $name))) {
 133                  case 'filename':
 134                      $fileGenerator->setFilename($value);
 135                      continue;
 136                  case 'class':
 137                      $fileGenerator->setClass(($value instanceof ClassGenerator) ? $value : ClassGenerator::fromArray($value));
 138                      continue;
 139                  case 'requiredfiles':
 140                      $fileGenerator->setRequiredFiles($value);
 141                      continue;
 142                  default:
 143                      if (property_exists($fileGenerator, $name)) {
 144                          $fileGenerator->{$name} = $value;
 145                      } elseif (method_exists($fileGenerator, 'set' . $name)) {
 146                          $fileGenerator->{'set' . $name}($value);
 147                      }
 148              }
 149          }
 150   
 151          return $fileGenerator;
 152      }
 153   
 154      /**
 155       * @param  DocBlockGenerator|array|string $docBlock
 156       * @throws Exception\InvalidArgumentException
 157       * @return FileGenerator
 158       */
 159      public function setDocBlock($docBlock)
 160      {
 161          if (is_string($docBlock)) {
 162              $docBlock = array('shortDescription' => $docBlock);
 163          }
 164   
 165          if (is_array($docBlock)) {
 166              $docBlock = new DocBlockGenerator($docBlock);
 167          } elseif (!$docBlock instanceof DocBlockGenerator) {
 168              throw new Exception\InvalidArgumentException(sprintf(
 169                  '%s is expecting either a string, array or an instance of %s\DocBlockGenerator',
 170                  __METHOD__,
 171                  __NAMESPACE__
 172              ));
 173          }
 174   
 175          $this->docBlock = $docBlock;
 176          return $this;
 177      }
 178   
 179      /**
 180       * @return DocBlockGenerator
 181       */
 182      public function getDocBlock()
 183      {
 184          return $this->docBlock;
 185      }
 186   
 187      /**
 188       * @param  array $requiredFiles
 189       * @return FileGenerator
 190       */
 191      public function setRequiredFiles(array $requiredFiles)
 192      {
 193          $this->requiredFiles = $requiredFiles;
 194          return $this;
 195      }
 196   
 197      /**
 198       * @return array
 199       */
 200      public function getRequiredFiles()
 201      {
 202          return $this->requiredFiles;
 203      }
 204   
 205      /**
 206       * @return string
 207       */
 208      public function getNamespace()
 209      {
 210          return $this->namespace;
 211      }
 212   
 213      /**
 214       * @param  string $namespace
 215       * @return FileGenerator
 216       */
 217      public function setNamespace($namespace)
 218      {
 219          $this->namespace = (string) $namespace;
 220          return $this;
 221      }
 222   
 223      /**
 224       * Returns an array with the first element the use statement, second is the as part.
 225       * If $withResolvedAs is set to true, there will be a third element that is the
 226       * "resolved" as statement, as the second part is not required in use statements
 227       *
 228       * @param  bool $withResolvedAs
 229       * @return array
 230       */
 231      public function getUses($withResolvedAs = false)
 232      {
 233          $uses = $this->uses;
 234          if ($withResolvedAs) {
 235              for ($useIndex = 0, $count = count($uses); $useIndex < $count; $useIndex++) {
 236                  if ($uses[$useIndex][1] == '') {
 237                      if (($lastSeparator = strrpos($uses[$useIndex][0], '\\')) !== false) {
 238                          $uses[$useIndex][2] = substr($uses[$useIndex][0], $lastSeparator + 1);
 239                      } else {
 240                          $uses[$useIndex][2] = $uses[$useIndex][0];
 241                      }
 242                  } else {
 243                      $uses[$useIndex][2] = $uses[$useIndex][1];
 244                  }
 245              }
 246          }
 247   
 248          return $uses;
 249      }
 250   
 251      /**
 252       * @param  array $uses
 253       * @return FileGenerator
 254       */
 255      public function setUses(array $uses)
 256      {
 257          foreach ($uses as $use) {
 258              $use = (array) $use;
 259              if (array_key_exists('use', $use) && array_key_exists('as', $use)) {
 260                  $import = $use['use'];
 261                  $alias  = $use['as'];
 262              } elseif (count($use) == 2) {
 263                  list($import, $alias) = $use;
 264              } else {
 265                  $import = current($use);
 266                  $alias  = null;
 267              }
 268              $this->setUse($import, $alias);
 269          }
 270          return $this;
 271      }
 272   
 273      /**
 274       * @param  string $use
 275       * @param  null|string $as
 276       * @return FileGenerator
 277       */
 278      public function setUse($use, $as = null)
 279      {
 280          if (!in_array(array($use, $as), $this->uses)) {
 281              $this->uses[] = array($use, $as);
 282          }
 283          return $this;
 284      }
 285   
 286      /**
 287       * @param  array $classes
 288       * @return FileGenerator
 289       */
 290      public function setClasses(array $classes)
 291      {
 292          foreach ($classes as $class) {
 293              $this->setClass($class);
 294          }
 295   
 296          return $this;
 297      }
 298   
 299      /**
 300       * @param  string $name
 301       * @return ClassGenerator
 302       */
 303      public function getClass($name = null)
 304      {
 305          if ($name === null) {
 306              reset($this->classes);
 307   
 308              return current($this->classes);
 309          }
 310   
 311          return $this->classes[(string) $name];
 312      }
 313   
 314      /**
 315       * @param  array|string|ClassGenerator $class
 316       * @throws Exception\InvalidArgumentException
 317       * @return FileGenerator
 318       */
 319      public function setClass($class)
 320      {
 321          if (is_array($class)) {
 322              $class = ClassGenerator::fromArray($class);
 323          } elseif (is_string($class)) {
 324              $class = new ClassGenerator($class);
 325          } elseif (!$class instanceof ClassGenerator) {
 326              throw new Exception\InvalidArgumentException(sprintf(
 327                  '%s is expecting either a string, array or an instance of %s\ClassGenerator',
 328                  __METHOD__,
 329                  __NAMESPACE__
 330              ));
 331          }
 332   
 333          // @todo check for dup here
 334          $className                 = $class->getName();
 335          $this->classes[$className] = $class;
 336   
 337          return $this;
 338      }
 339   
 340      /**
 341       * @param  string $filename
 342       * @return FileGenerator
 343       */
 344      public function setFilename($filename)
 345      {
 346          $this->filename = (string) $filename;
 347          return $this;
 348      }
 349   
 350      /**
 351       * @return string
 352       */
 353      public function getFilename()
 354      {
 355          return $this->filename;
 356      }
 357   
 358      /**
 359       * @return ClassGenerator[]
 360       */
 361      public function getClasses()
 362      {
 363          return $this->classes;
 364      }
 365   
 366      /**
 367       * @param  string $body
 368       * @return FileGenerator
 369       */
 370      public function setBody($body)
 371      {
 372          $this->body = (string) $body;
 373          return $this;
 374      }
 375   
 376      /**
 377       * @return string
 378       */
 379      public function getBody()
 380      {
 381          return $this->body;
 382      }
 383   
 384      /**
 385       * @return bool
 386       */
 387      public function isSourceDirty()
 388      {
 389          $docBlock = $this->getDocBlock();
 390          if ($docBlock && $docBlock->isSourceDirty()) {
 391              return true;
 392          }
 393   
 394          foreach ($this->classes as $class) {
 395              if ($class->isSourceDirty()) {
 396                  return true;
 397              }
 398          }
 399   
 400          return parent::isSourceDirty();
 401      }
 402   
 403      /**
 404       * @return string
 405       */
 406      public function generate()
 407      {
 408          if ($this->isSourceDirty() === false) {
 409              return $this->sourceContent;
 410          }
 411   
 412          $output = '';
 413   
 414          // @note body gets populated when FileGenerator created
 415          // from a file.  @see fromReflection and may also be set
 416          // via FileGenerator::setBody
 417          $body = $this->getBody();
 418   
 419          // start with the body (if there), or open tag
 420          if (preg_match('#(?:\s*)<\?php#', $body) == false) {
 421              $output = '<?php' . self::LINE_FEED;
 422          }
 423   
 424          // if there are markers, put the body into the output
 425          if (preg_match('#/\* Zend_Code_Generator_Php_File-(.*?)Marker:#m', $body)) {
 426              $tokens = token_get_all($body);
 427              foreach ($tokens as $token) {
 428                  if (is_array($token) && in_array($token[0], array(T_OPEN_TAG, T_COMMENT, T_DOC_COMMENT, T_WHITESPACE))
 429                  ) {
 430                      $output .= $token[1];
 431                  }
 432              }
 433              $body = '';
 434          }
 435   
 436          // Add file DocBlock, if any
 437          if (null !== ($docBlock = $this->getDocBlock())) {
 438              $docBlock->setIndentation('');
 439   
 440              if (preg_match('#/\* Zend_Code_Generator_FileGenerator-DocBlockMarker \*/#m', $output)) {
 441                  $output = preg_replace('#/\* Zend_Code_Generator_FileGenerator-DocBlockMarker \*/#m', $docBlock->generate(), $output, 1);
 442              } else {
 443                  $output .= $docBlock->generate() . self::LINE_FEED;
 444              }
 445          }
 446   
 447          // newline
 448          $output .= self::LINE_FEED;
 449   
 450          // namespace, if any
 451          $namespace = $this->getNamespace();
 452          if ($namespace) {
 453              $namespace = sprintf('namespace %s;%s', $namespace, str_repeat(self::LINE_FEED, 2));
 454              if (preg_match('#/\* Zend_Code_Generator_FileGenerator-NamespaceMarker \*/#m', $output)) {
 455                  $output = preg_replace(
 456                      '#/\* Zend_Code_Generator_FileGenerator-NamespaceMarker \*/#m',
 457                      $namespace,
 458                      $output,
 459                      1
 460                  );
 461              } else {
 462                  $output .= $namespace;
 463              }
 464          }
 465   
 466          // process required files
 467          // @todo marker replacement for required files
 468          $requiredFiles = $this->getRequiredFiles();
 469          if (!empty($requiredFiles)) {
 470              foreach ($requiredFiles as $requiredFile) {
 471                  $output .= 'require_once \'' . $requiredFile . '\';' . self::LINE_FEED;
 472              }
 473   
 474              $output .= self::LINE_FEED;
 475          }
 476   
 477          $classes = $this->getClasses();
 478          $classUses = array();
 479          //build uses array
 480          foreach ($classes as $class) {
 481              //check for duplicate use statements
 482              $uses = $class->getUses();
 483              if (!empty($uses) && is_array($uses)) {
 484                  $classUses = array_merge($classUses, $uses);
 485              }
 486          }
 487   
 488          // process import statements
 489          $uses = $this->getUses();
 490          if (!empty($uses)) {
 491              $useOutput = '';
 492   
 493              foreach ($uses as $use) {
 494                  list($import, $alias) = $use;
 495                  if (null === $alias) {
 496                      $tempOutput = sprintf('%s', $import);
 497                  } else {
 498                      $tempOutput = sprintf('%s as %s', $import, $alias);
 499                  }
 500   
 501                  //don't duplicate use statements
 502                  if (!in_array($tempOutput, $classUses)) {
 503                      $useOutput .= "use ". $tempOutput .";";
 504                      $useOutput .= self::LINE_FEED;
 505                  }
 506              }
 507              $useOutput .= self::LINE_FEED;
 508   
 509              if (preg_match('#/\* Zend_Code_Generator_FileGenerator-UseMarker \*/#m', $output)) {
 510                  $output = preg_replace(
 511                      '#/\* Zend_Code_Generator_FileGenerator-UseMarker \*/#m',
 512                      $useOutput,
 513                      $output,
 514                      1
 515                  );
 516              } else {
 517                  $output .= $useOutput;
 518              }
 519          }
 520   
 521          // process classes
 522          if (!empty($classes)) {
 523              foreach ($classes as $class) {
 524                  $regex = str_replace('&', $class->getName(), '/\* Zend_Code_Generator_Php_File-ClassMarker: \{[A-Za-z0-9\\\]+?&\} \*/');
 525                  if (preg_match('#' . $regex . '#m', $output)) {
 526                      $output = preg_replace('#' . $regex . '#', $class->generate(), $output, 1);
 527                  } else {
 528                      if ($namespace) {
 529                          $class->setNamespaceName(null);
 530                      }
 531                      $output .= $class->generate() . self::LINE_FEED;
 532                  }
 533              }
 534          }
 535   
 536          if (!empty($body)) {
 537              // add an extra space between classes and
 538              if (!empty($classes)) {
 539                  $output .= self::LINE_FEED;
 540              }
 541   
 542              $output .= $body;
 543          }
 544   
 545          return $output;
 546      }
 547   
 548      /**
 549       * @return FileGenerator
 550       * @throws Exception\RuntimeException
 551       */
 552      public function write()
 553      {
 554          if ($this->filename == '' || !is_writable(dirname($this->filename))) {
 555              throw new Exception\RuntimeException('This code generator object is not writable.');
 556          }
 557          file_put_contents($this->filename, $this->generate());
 558   
 559          return $this;
 560      }
 561  }
 562