/application/libraries/Zend/CodeGenerator/Php/File.php
PHP | 465 lines | 372 code | 26 blank | 67 comment | 18 complexity | 2e82f6888831da4312ad9c92c1a7ff1f MD5 | raw file
- <?php
- /**
- * Zend Framework
- *
- * LICENSE
- *
- * This source file is subject to the new BSD license that is bundled
- * with this package in the file LICENSE.txt.
- * It is also available through the world-wide-web at this URL:
- * http://framework.zend.com/license/new-bsd
- * If you did not receive a copy of the license and are unable to
- * obtain it through the world-wide-web, please send an email
- * to license@zend.com so we can send you a copy immediately.
- *
- * @category Zend
- * @package Zend_CodeGenerator
- * @subpackage PHP
- * @copyright Copyright (c) 2005-2009 Zend Technologies USA Inc. (http://www.zend.com)
- * @license http://framework.zend.com/license/new-bsd New BSD License
- * @version $Id: File.php 16971 2009-07-22 18:05:45Z mikaelkael $
- */
- /**
- * @see Zend_CodeGenerator_Php_Abstract
- */
- // require_once 'Zend/CodeGenerator/Php/Abstract.php';
- /**
- * @see Zend_CodeGenerator_Php_Class
- */
- // require_once 'Zend/CodeGenerator/Php/Class.php';
- /**
- * @category Zend
- * @package Zend_CodeGenerator
- * @copyright Copyright (c) 2005-2009 Zend Technologies USA Inc. (http://www.zend.com)
- * @license http://framework.zend.com/license/new-bsd New BSD License
- */
- class Zend_CodeGenerator_Php_File extends Zend_CodeGenerator_Php_Abstract
- {
-
- /**
- * @var array Array of Zend_CodeGenerator_Php_File
- */
- protected static $_fileCodeGenerators = array();
-
- /**#@+
- * @var string
- */
- protected static $_markerDocblock = '/* Zend_CodeGenerator_Php_File-DocblockMarker */';
- protected static $_markerRequire = '/* Zend_CodeGenerator_Php_File-RequireMarker: {?} */';
- protected static $_markerClass = '/* Zend_CodeGenerator_Php_File-ClassMarker: {?} */';
- /**#@-*/
-
- /**
- * @var string
- */
- protected $_filename = null;
-
- /**
- * @var Zend_CodeGenerator_Php_Docblock
- */
- protected $_docblock = null;
-
- /**
- * @var array
- */
- protected $_requiredFiles = array();
-
- /**
- * @var array
- */
- protected $_classes = array();
-
- /**
- * @var string
- */
- protected $_body = null;
- public static function registerFileCodeGenerator(Zend_CodeGenerator_Php_File $fileCodeGenerator, $fileName = null)
- {
- if ($fileName == null) {
- $fileName = $fileCodeGenerator->getFilename();
- }
-
- if ($fileName == '') {
- // require_once 'Zend/CodeGenerator/Php/Exception.php';
- throw new Zend_CodeGenerator_Php_Exception('FileName does not exist.');
- }
-
- // cannot use realpath since the file might not exist, but we do need to have the index
- // in the same DIRECTORY_SEPARATOR that realpath would use:
- $fileName = str_replace(array('\\', '/'), DIRECTORY_SEPARATOR, $fileName);
-
- self::$_fileCodeGenerators[$fileName] = $fileCodeGenerator;
-
- }
-
- /**
- * fromReflectedFilePath() - use this if you intend on generating code generation objects based on the same file.
- * This will keep previous changes to the file in tact during the same PHP process
- *
- * @param string $filePath
- * @param bool $usePreviousCodeGeneratorIfItExists
- * @param bool $includeIfNotAlreadyIncluded
- * @return Zend_CodeGenerator_Php_File
- */
- public static function fromReflectedFileName($filePath, $usePreviousCodeGeneratorIfItExists = true, $includeIfNotAlreadyIncluded = true)
- {
- $realpath = realpath($filePath);
-
- if ($realpath === false) {
- if ( ($realpath = Zend_Reflection_file::findRealpathInIncludePath($filePath)) === false) {
- // require_once 'Zend/CodeGenerator/Php/Exception.php';
- throw new Zend_CodeGenerator_Php_Exception('No file for ' . $realpath . ' was found.');
- }
- }
-
- if ($usePreviousCodeGeneratorIfItExists && isset(self::$_fileCodeGenerators[$realpath])) {
- return self::$_fileCodeGenerators[$realpath];
- }
-
- if ($includeIfNotAlreadyIncluded && !in_array($realpath, get_included_files())) {
- include $realpath;
- }
-
- $codeGenerator = self::fromReflection(($fileReflector = new Zend_Reflection_File($realpath)));
-
- if (!isset(self::$_fileCodeGenerators[$fileReflector->getFileName()])) {
- self::$_fileCodeGenerators[$fileReflector->getFileName()] = $codeGenerator;
- }
-
- return $codeGenerator;
- }
-
- /**
- * fromReflection()
- *
- * @param Zend_Reflection_File $reflectionFile
- * @return Zend_CodeGenerator_Php_File
- */
- public static function fromReflection(Zend_Reflection_File $reflectionFile)
- {
- $file = new self();
-
- $file->setSourceContent($reflectionFile->getContents());
- $file->setSourceDirty(false);
-
- $body = $reflectionFile->getContents();
-
- // @todo this whole area needs to be reworked with respect to how body lines are processed
- foreach ($reflectionFile->getClasses() as $class) {
- $file->setClass(Zend_CodeGenerator_Php_Class::fromReflection($class));
- $classStartLine = $class->getStartLine(true);
- $classEndLine = $class->getEndLine();
-
- $bodyLines = explode("\n", $body);
- $bodyReturn = array();
- for ($lineNum = 1; $lineNum <= count($bodyLines); $lineNum++) {
- if ($lineNum == $classStartLine) {
- $bodyReturn[] = str_replace('?', $class->getName(), self::$_markerClass); //'/* Zend_CodeGenerator_Php_File-ClassMarker: {' . $class->getName() . '} */';
- $lineNum = $classEndLine;
- } else {
- $bodyReturn[] = $bodyLines[$lineNum - 1]; // adjust for index -> line conversion
- }
- }
- $body = implode("\n", $bodyReturn);
- unset($bodyLines, $bodyReturn, $classStartLine, $classEndLine);
- }
-
- if (($reflectionFile->getDocComment() != '')) {
- $docblock = $reflectionFile->getDocblock();
- $file->setDocblock(Zend_CodeGenerator_Php_Docblock::fromReflection($docblock));
-
- $bodyLines = explode("\n", $body);
- $bodyReturn = array();
- for ($lineNum = 1; $lineNum <= count($bodyLines); $lineNum++) {
- if ($lineNum == $docblock->getStartLine()) {
- $bodyReturn[] = str_replace('?', $class->getName(), self::$_markerDocblock); //'/* Zend_CodeGenerator_Php_File-ClassMarker: {' . $class->getName() . '} */';
- $lineNum = $docblock->getEndLine();
- } else {
- $bodyReturn[] = $bodyLines[$lineNum - 1]; // adjust for index -> line conversion
- }
- }
- $body = implode("\n", $bodyReturn);
- unset($bodyLines, $bodyReturn, $classStartLine, $classEndLine);
- }
-
- $file->setBody($body);
-
- return $file;
- }
-
- /**
- * setDocblock() Set the docblock
- *
- * @param Zend_CodeGenerator_Php_Docblock|array|string $docblock
- * @return Zend_CodeGenerator_Php_File
- */
- public function setDocblock($docblock)
- {
- if (is_string($docblock)) {
- $docblock = array('shortDescription' => $docblock);
- }
-
- if (is_array($docblock)) {
- $docblock = new Zend_CodeGenerator_Php_Docblock($docblock);
- } elseif (!$docblock instanceof Zend_CodeGenerator_Php_Docblock) {
- // require_once 'Zend/CodeGenerator/Php/Exception.php';
- throw new Zend_CodeGenerator_Php_Exception('setDocblock() is expecting either a string, array or an instance of Zend_CodeGenerator_Php_Docblock');
- }
-
- $this->_docblock = $docblock;
- return $this;
- }
-
- /**
- * Get docblock
- *
- * @return Zend_CodeGenerator_Php_Docblock
- */
- public function getDocblock()
- {
- return $this->_docblock;
- }
- /**
- * setRequiredFiles
- *
- * @param array $requiredFiles
- * @return Zend_CodeGenerator_Php_File
- */
- public function setRequiredFiles($requiredFiles)
- {
- $this->_requiredFiles = $requiredFiles;
- return $this;
- }
-
- /**
- * getRequiredFiles()
- *
- * @return array
- */
- public function getRequiredFiles()
- {
- return $this->_requiredFiles;
- }
- /**
- * setClasses()
- *
- * @param array $classes
- * @return Zend_CodeGenerator_Php_File
- */
- public function setClasses(Array $classes)
- {
- foreach ($classes as $class) {
- $this->setClass($class);
- }
- return $this;
- }
-
- /**
- * getClass()
- *
- * @param string $name
- * @return Zend_CodeGenerator_Php_Class
- */
- public function getClass($name = null)
- {
- if ($name == null) {
- reset($this->_classes);
- return current($this->_classes);
- }
-
- return $this->_classes[$name];
- }
-
- /**
- * setClass()
- *
- * @param Zend_CodeGenerator_Php_Class|array $class
- * @return Zend_CodeGenerator_Php_File
- */
- public function setClass($class)
- {
- if (is_array($class)) {
- $class = new Zend_CodeGenerator_Php_Class($class);
- $className = $class->getName();
- } elseif ($class instanceof Zend_CodeGenerator_Php_Class) {
- $className = $class->getName();
- } else {
- // require_once 'Zend/CodeGenerator/Php/Exception.php';
- throw new Zend_CodeGenerator_Php_Exception('Expecting either an array or an instance of Zend_CodeGenerator_Php_Class');
- }
-
- // @todo check for dup here
-
- $this->_classes[$className] = $class;
- return $this;
- }
-
- /**
- * setFilename()
- *
- * @param string $filename
- * @return Zend_CodeGenerator_Php_File
- */
- public function setFilename($filename)
- {
- $this->_filename = $filename;
- return $this;
- }
-
- /**
- * getFilename()
- *
- * @return string
- */
- public function getFilename()
- {
- return $this->_filename;
- }
-
- /**
- * getClasses()
- *
- * @return array Array of Zend_CodeGenerator_Php_Class
- */
- public function getClasses()
- {
- return $this->_classes;
- }
- /**
- * setBody()
- *
- * @param string $body
- * @return Zend_CodeGenerator_Php_File
- */
- public function setBody($body)
- {
- $this->_body = $body;
- return $this;
- }
-
- /**
- * getBody()
- *
- * @return string
- */
- public function getBody()
- {
- return $this->_body;
- }
-
- /**
- * isSourceDirty()
- *
- * @return bool
- */
- public function isSourceDirty()
- {
- if (($docblock = $this->getDocblock()) && $docblock->isSourceDirty()) {
- return true;
- }
-
- foreach ($this->_classes as $class) {
- if ($class->isSourceDirty()) {
- return true;
- }
- }
-
- return parent::isSourceDirty();
- }
-
- /**
- * generate()
- *
- * @return string
- */
- public function generate()
- {
- if ($this->isSourceDirty() === false) {
- return $this->_sourceContent;
- }
-
- $output = '';
-
- // start with the body (if there), or open tag
- if (preg_match('#(?:\s*)<\?php#', $this->getBody()) == false) {
- $output = '<?php' . self::LINE_FEED;
- }
-
- // if there are markers, put the body into the output
- $body = $this->getBody();
- if (preg_match('#/\* Zend_CodeGenerator_Php_File-(.*?)Marker:#', $body)) {
- $output .= $body;
- $body = '';
- }
-
- // Add file docblock, if any
- if (null !== ($docblock = $this->getDocblock())) {
- $docblock->setIndentation('');
- $regex = preg_quote(self::$_markerDocblock, '#');
- if (preg_match('#'.$regex.'#', $output)) {
- $output = preg_replace('#'.$regex.'#', $docblock->generate(), $output, 1);
- } else {
- $output .= $docblock->generate() . self::LINE_FEED;
- }
- }
-
- // newline
- $output .= self::LINE_FEED;
-
- // process required files
- // @todo marker replacement for required files
- $requiredFiles = $this->getRequiredFiles();
- if (!empty($requiredFiles)) {
- foreach ($requiredFiles as $requiredFile) {
- $output .= '// require_once \'' . $requiredFile . '\';' . self::LINE_FEED;
- }
-
- $output .= self::LINE_FEED;
- }
-
- // process classes
- $classes = $this->getClasses();
- if (!empty($classes)) {
- foreach ($classes as $class) {
- $regex = str_replace('?', $class->getName(), self::$_markerClass);
- $regex = preg_quote($regex, '#');
- if (preg_match('#'.$regex.'#', $output)) {
- $output = preg_replace('#'.$regex.'#', $class->generate(), $output, 1);
- } else {
- $output .= $class->generate() . self::LINE_FEED;
- }
- }
-
- }
- if (!empty($body)) {
- // add an extra space betwee clsses and
- if (!empty($classes)) {
- $output .= self::LINE_FEED;
- }
-
- $output .= $body;
- }
- return $output;
- }
-
- public function write()
- {
- if ($this->_filename == '' || !is_writable(dirname($this->_filename))) {
- // require_once 'Zend/CodeGenerator/Php/Exception.php';
- throw new Zend_CodeGenerator_Php_Exception('This code generator object is not writable.');
- }
- file_put_contents($this->_filename, $this->generate());
- return $this;
- }
-
- }