[ Index ] |
PHP Cross Reference of phpBB-3.2.11-deutsch |
[Summary view] [Print] [Text view]
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-2015 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 Zend\Code\Reflection\Exception as ReflectionException; 13 use Zend\Code\Reflection\FileReflection; 14 15 class FileGenerator extends AbstractGenerator 16 { 17 /** 18 * @var string 19 */ 20 protected $filename = null; 21 22 /** 23 * @var DocBlockGenerator 24 */ 25 protected $docBlock = null; 26 27 /** 28 * @var array 29 */ 30 protected $requiredFiles = array(); 31 32 /** 33 * @var string 34 */ 35 protected $namespace = null; 36 37 /** 38 * @var array 39 */ 40 protected $uses = array(); 41 42 /** 43 * @var array 44 */ 45 protected $classes = array(); 46 47 /** 48 * @var string 49 */ 50 protected $body = null; 51 52 /** 53 * Passes $options to {@link setOptions()}. 54 * 55 * @param array|\Traversable $options 56 */ 57 public function __construct($options = null) 58 { 59 if (null !== $options) { 60 $this->setOptions($options); 61 } 62 } 63 64 /** 65 * Use this if you intend on generating code generation objects based on the same file. 66 * This will keep previous changes to the file in tact during the same PHP process 67 * 68 * @param string $filePath 69 * @param bool $includeIfNotAlreadyIncluded 70 * @throws ReflectionException\InvalidArgumentException If file does not exists 71 * @throws ReflectionException\RuntimeException If file exists but is not included or required 72 * @return FileGenerator 73 */ 74 public static function fromReflectedFileName($filePath, $includeIfNotAlreadyIncluded = true) 75 { 76 $fileReflector = new FileReflection($filePath, $includeIfNotAlreadyIncluded); 77 $codeGenerator = static::fromReflection($fileReflector); 78 79 return $codeGenerator; 80 } 81 82 /** 83 * @param FileReflection $fileReflection 84 * @return FileGenerator 85 */ 86 public static function fromReflection(FileReflection $fileReflection) 87 { 88 $file = new static(); 89 90 $file->setSourceContent($fileReflection->getContents()); 91 $file->setSourceDirty(false); 92 93 $uses = $fileReflection->getUses(); 94 95 foreach ($fileReflection->getClasses() as $class) { 96 $phpClass = ClassGenerator::fromReflection($class); 97 $phpClass->setContainingFileGenerator($file); 98 99 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 }
title
Description
Body
title
Description
Body
title
Description
Body
title
Body
Generated: Wed Nov 11 20:33:01 2020 | Cross-referenced by PHPXref 0.7.1 |