Пример #1
0
 /**
  * @covers phpDocumentor\Event\Dispatcher::setInstance
  * @covers phpDocumentor\Event\Dispatcher::getInstance
  */
 public function testInstancesCanBeOverridden()
 {
     $fixture = Dispatcher::getInstance('mine');
     $this->assertSame($fixture, Dispatcher::getInstance('mine'));
     $newObject = m::mock('phpDocumentor\\Event\\Dispatcher');
     Dispatcher::setInstance('mine', $newObject);
     $this->assertSame($newObject, Dispatcher::getInstance('mine'));
 }
 /**
  * Export this tag to the given DocBlock.
  *
  * This method also invokes the 'reflection.docblock.tag.export' which can
  * be used to augment the data. This is useful for plugins so that they
  * can provide custom tags.
  *
  * @param \DOMElement   $parent  Element to augment.
  * @param Tag           $tag     The tag to export.
  * @param BaseReflector $element Element to log from.
  *
  * @return void
  */
 public function export(\DOMElement $parent, $tag, $element)
 {
     $child = new \DOMElement('tag');
     $parent->appendChild($child);
     $child->setAttribute('line', $parent->getAttribute('line'));
     if (class_exists('phpDocumentor\\Event\\Dispatcher')) {
         \phpDocumentor\Event\Dispatcher::getInstance()->dispatch('reflection.docblock.tag.export', \phpDocumentor\Reflection\Event\ExportDocBlockTagEvent::createInstance($element)->setObject($tag)->setXml($child));
     }
 }
Пример #3
0
 /**
  * This method combines the structure.xml and the given target template
  * and creates a static html page at the artifact location.
  *
  * @param \DOMDocument                        $structure      XML source.
  * @param \phpDocumentor\Transformer\Transformation $transformation Transformation.
  *
  * @throws \Exception
  *
  * @return void
  */
 public function transform(\DOMDocument $structure, \phpDocumentor\Transformer\Transformation $transformation)
 {
     if (!class_exists('XSLTProcessor')) {
         throw new \phpDocumentor\Plugin\Core\Exception('The XSL writer was unable to find your XSLTProcessor; ' . 'please check if you have installed the PHP XSL extension');
     }
     $artifact = $transformation->getTransformer()->getTarget() . DIRECTORY_SEPARATOR . $transformation->getArtifact();
     $xsl = new \DOMDocument();
     $xsl->load($transformation->getSourceAsPath());
     $proc = new \XSLTProcessor();
     $proc->importStyleSheet($xsl);
     if (empty($structure->documentElement)) {
         throw new \phpDocumentor\Plugin\Core\Exception('Specified DOMDocument lacks documentElement, cannot transform');
     }
     $proc->setParameter('', 'title', $structure->documentElement->getAttribute('title'));
     $proc->setParameter('', 'root', str_repeat('../', substr_count($transformation->getArtifact(), '/')));
     $proc->setParameter('', 'search_template', $transformation->getParameter('search', 'none'));
     $proc->setParameter('', 'version', \phpDocumentor\Application::VERSION);
     $proc->setParameter('', 'generated_datetime', date('r'));
     // check parameters for variables and add them when found
     $this->setProcessorParameters($transformation, $proc);
     // if a query is given, then apply a transformation to the artifact
     // location by replacing ($<var>} with the sluggified node-value of the
     // search result
     if ($transformation->getQuery() !== '') {
         $xpath = new \DOMXPath($transformation->getTransformer()->getSource());
         /** @var \DOMNodeList $qry */
         $qry = $xpath->query($transformation->getQuery());
         $count = $qry->length;
         foreach ($qry as $key => $element) {
             \phpDocumentor\Event\Dispatcher::getInstance()->dispatch('transformer.writer.xsl.pre', \phpDocumentor\Transformer\Event\PreXslWriterEvent::createInstance($this)->setElement($element)->setProgress(array($key + 1, $count)));
             $proc->setParameter('', $element->nodeName, $element->nodeValue);
             $file_name = $transformation->getTransformer()->generateFilename($element->nodeValue);
             $filename = str_replace('{$' . $element->nodeName . '}', $file_name, $artifact);
             $this->log('Processing the file: ' . $element->nodeValue . ' as ' . $filename);
             if (!file_exists(dirname($filename))) {
                 mkdir(dirname($filename), 0755, true);
             }
             $proc->transformToURI($structure, $this->getXsltUriFromFilename($filename));
         }
     } else {
         if (substr($transformation->getArtifact(), 0, 1) == '$') {
             // not a file, it must become a variable!
             $variable_name = substr($transformation->getArtifact(), 1);
             $this->xsl_variables[$variable_name] = $proc->transformToXml($structure);
         } else {
             if (!file_exists(dirname($artifact))) {
                 mkdir(dirname($artifact), 0755, true);
             }
             $proc->transformToURI($structure, $this->getXsltUriFromFilename($artifact));
         }
     }
 }
Пример #4
0
 /**
  * Returns the parsed DocBlock.
  *
  * @return \phpDocumentor\Reflection\DocBlock|null
  */
 public function getDocBlock()
 {
     $doc_block = null;
     $comment = $this->constant->getDocComment();
     if ($comment) {
         try {
             $doc_block = new \phpDocumentor\Reflection\DocBlock((string) $comment, $this->getNamespace(), $this->getNamespaceAliases());
             $doc_block->line_number = $comment->getLine();
         } catch (\Exception $e) {
             $this->log($e->getMessage(), 2);
         }
     }
     \phpDocumentor\Event\Dispatcher::getInstance()->dispatch('reflection.docblock-extraction.post', \phpDocumentor\Reflection\Event\PostDocBlockExtractionEvent::createInstance($this)->setDocblock($doc_block));
     return $doc_block;
 }
Пример #5
0
 public function beforeTraverse(array $nodes)
 {
     $node = null;
     $key = 0;
     foreach ($nodes as $k => $n) {
         if (!$n instanceof \PHPParser_Node_Stmt_InlineHTML) {
             $node = $n;
             $key = $k;
             break;
         }
     }
     if ($node) {
         $comments = (array) $node->getAttribute('comments');
         // remove non-DocBlock comments
         $comments = array_values(array_filter($comments, function ($comment) {
             return $comment instanceof \PHPParser_Comment_Doc;
         }));
         if (!empty($comments)) {
             $docblock = new \phpDocumentor\Reflection\DocBlock((string) $comments[0]);
             // the first DocBlock in a file documents the file if
             // * it precedes another DocBlock or
             // * it contains a @package tag and doesn't precede a class
             //   declaration or
             // * it precedes a non-documentable element (thus no include,
             //   require, class, function, define, const)
             if (count($comments) > 1 || !$node instanceof \PHPParser_Node_Stmt_Class && !$node instanceof \PHPParser_Node_Stmt_Interface && $docblock->hasTag('package') || !$this->isNodeDocumentable($node)) {
                 $docblock->line_number = $comments[0]->getLine();
                 $this->doc_block = $docblock;
                 // remove the file level DocBlock from the node's comments
                 $comments = array_slice($comments, 1);
             }
         }
         // always update the comments attribute so that standard comments
         // do not stop DocBlock from being attached to an element
         $node->setAttribute('comments', $comments);
         $nodes[$key] = $node;
     }
     \phpDocumentor\Event\Dispatcher::getInstance()->dispatch('reflection.docblock-extraction.post', \phpDocumentor\Reflection\Event\PostDocBlockExtractionEvent::createInstance($this)->setDocblock($this->doc_block));
     return $nodes;
 }
Пример #6
0
 protected function thenDispatcherShouldReceiveLoggingEvents()
 {
     $this->dispatcherMock->shouldReceive('dispatch')->atLeast(1)->with('system.log', m::type('phpDocumentor\\Event\\LogEvent'));
 }
Пример #7
0
 /**
  * Applies the given transformation to the provided project.
  *
  * This method will attempt to find an appropriate writer for the given transformation and invoke that with the
  * transformation and project so that an artifact can be generated that matches the intended transformation.
  *
  * In addition this method will emit the following events:
  *
  * - transformer.transformation.pre, before the project has been transformed with this transformation.
  * - transformer.transformation.post, after the project has been transformed with this transformation
  *
  * @param Transformation $transformation
  * @param ProjectDescriptor $project
  *
  * @uses Dispatcher to emit the events surrounding a transformation.
  *
  * @return void
  */
 private function applyTransformationToProject(Transformation $transformation, ProjectDescriptor $project)
 {
     $this->log(sprintf('  Writer %s %s on %s', $transformation->getWriter(), $transformation->getQuery() ? ' using query "' . $transformation->getQuery() . '"' : '', $transformation->getArtifact()));
     $preTransformationEvent = PreTransformationEvent::createInstance($this)->setTransformation($transformation);
     Dispatcher::getInstance()->dispatch(self::EVENT_PRE_TRANSFORMATION, $preTransformationEvent);
     $writer = $this->writers[$transformation->getWriter()];
     $writer->transform($project, $transformation);
     $postTransformationEvent = PostTransformationEvent::createInstance($this);
     Dispatcher::getInstance()->dispatch(self::EVENT_POST_TRANSFORMATION, $postTransformationEvent);
 }
Пример #8
0
 /**
  * Extracts a parsed DocBlock from an object.
  *
  * @param object $node Any object with a "getDocComment()" method.
  *
  * @return DocBlock|null
  */
 protected function extractDocBlock($node)
 {
     $doc_block = null;
     $comment = $node->getDocComment();
     if ($comment) {
         try {
             $doc_block = new DocBlock((string) $comment, $this->context, new Location($comment->getLine()));
         } catch (Exception $e) {
             $this->log($e->getMessage(), LogLevel::CRITICAL);
         }
     }
     if (class_exists('phpDocumentor\\Event\\Dispatcher')) {
         Dispatcher::getInstance()->dispatch('reflection.docblock-extraction.post', PostDocBlockExtractionEvent::createInstance($this)->setDocblock($doc_block));
     }
     return $doc_block;
 }
Пример #9
0
 /**
  * Dispatches a logging request to log a debug message.
  *
  * @param string $message The message to log.
  *
  * @return void
  */
 public function debug($message)
 {
     Dispatcher::getInstance()->dispatch('system.debug', DebugEvent::createInstance($this)->setMessage($message));
 }
Пример #10
0
 /**
  * Registers services on the given app.
  *
  * @param Application $app An Application instance.
  *
  * @throws Exception\MissingDependencyException if the application does not have a descriptor.builder service.
  * @throws Exception\MissingDependencyException if the application does not have a serializer service.
  */
 public function register(Application $app)
 {
     if (!isset($app['descriptor.builder'])) {
         throw new Exception\MissingDependencyException('The builder object that is used to construct the ProjectDescriptor is missing');
     }
     if (!isset($app['serializer'])) {
         throw new Exception\MissingDependencyException('The serializer object that is used to read the template configuration with is missing');
     }
     // parameters
     $app['linker.substitutions'] = array('phpDocumentor\\Descriptor\\ProjectDescriptor' => array('files'), 'phpDocumentor\\Descriptor\\FileDescriptor' => array('tags', 'classes', 'interfaces', 'traits', 'functions', 'constants'), 'phpDocumentor\\Descriptor\\ClassDescriptor' => array('tags', 'parent', 'interfaces', 'constants', 'properties', 'methods', 'usedTraits'), 'phpDocumentor\\Descriptor\\InterfaceDescriptor' => array('tags', 'parent', 'constants', 'methods'), 'phpDocumentor\\Descriptor\\TraitDescriptor' => array('tags', 'properties', 'methods', 'usedTraits'), 'phpDocumentor\\Descriptor\\FunctionDescriptor' => array('tags', 'arguments'), 'phpDocumentor\\Descriptor\\MethodDescriptor' => array('tags', 'arguments'), 'phpDocumentor\\Descriptor\\ArgumentDescriptor' => array('types'), 'phpDocumentor\\Descriptor\\PropertyDescriptor' => array('tags', 'types'), 'phpDocumentor\\Descriptor\\ConstantDescriptor' => array('tags', 'types'), 'phpDocumentor\\Descriptor\\Tag\\ParamDescriptor' => array('types'), 'phpDocumentor\\Descriptor\\Tag\\ReturnDescriptor' => array('types'), 'phpDocumentor\\Descriptor\\Tag\\SeeDescriptor' => array('reference'), 'phpDocumentor\\Descriptor\\Type\\CollectionDescriptor' => array('baseType', 'types', 'keyTypes'));
     // services
     $app['compiler'] = $app->share(function ($container) {
         $compiler = new Compiler();
         $compiler->insert(new ElementsIndexBuilder(), ElementsIndexBuilder::COMPILER_PRIORITY);
         $compiler->insert(new MarkerFromTagsExtractor(), MarkerFromTagsExtractor::COMPILER_PRIORITY);
         $compiler->insert(new ExampleTagsEnricher($container['parser.example.finder']), ExampleTagsEnricher::COMPILER_PRIORITY);
         $compiler->insert(new PackageTreeBuilder(), PackageTreeBuilder::COMPILER_PRIORITY);
         $compiler->insert(new NamespaceTreeBuilder(), NamespaceTreeBuilder::COMPILER_PRIORITY);
         $compiler->insert(new ResolveInlineLinkAndSeeTags($container['transformer.routing.queue']), ResolveInlineLinkAndSeeTags::COMPILER_PRIORITY);
         $compiler->insert($container['linker'], Linker::COMPILER_PRIORITY);
         $compiler->insert($container['transformer'], Transformer::COMPILER_PRIORITY);
         $compiler->insert(new Debug($container['monolog'], $container['descriptor.analyzer']), Debug::COMPILER_PRIORITY);
         return $compiler;
     });
     $app['linker'] = $app->share(function ($app) {
         return new Linker($app['linker.substitutions']);
     });
     $app['transformer.behaviour.collection'] = $app->share(function () {
         return new Behaviour\Collection();
     });
     $app['transformer.routing.standard'] = $app->share(function ($container) {
         /** @var ProjectDescriptorBuilder $projectDescriptorBuilder */
         $projectDescriptorBuilder = $container['descriptor.builder'];
         return new Router\StandardRouter($projectDescriptorBuilder);
     });
     $app['transformer.routing.external'] = $app->share(function ($container) {
         return new Router\ExternalRouter($container['config']);
     });
     $app['transformer.routing.queue'] = $app->share(function ($container) {
         $queue = new Router\Queue();
         // TODO: load from app configuration instead of hardcoded
         $queue->insert($container['transformer.routing.external'], 10500);
         $queue->insert($container['transformer.routing.standard'], 10000);
         return $queue;
     });
     $app['transformer.writer.collection'] = $app->share(function ($container) {
         return new Writer\Collection($container['transformer.routing.queue']);
     });
     $this->provideTemplatingSystem($app);
     $app['transformer'] = $app->share(function ($container) {
         $transformer = new Transformer($container['transformer.template.collection'], $container['transformer.writer.collection']);
         /** @var Behaviour\Collection $behaviourCollection */
         $behaviourCollection = $container['transformer.behaviour.collection'];
         Dispatcher::getInstance()->addListener(Transformer::EVENT_PRE_TRANSFORM, function (PreTransformEvent $event) use($behaviourCollection) {
             $behaviourCollection->process($event->getProject());
         });
         return $transformer;
     });
     $app->command(new TransformCommand($app['descriptor.builder'], $app['transformer'], $app['compiler']));
     $app->command(new ListCommand($app['transformer.template.factory']));
 }
Пример #11
0
 /**
  * Iterates through the given files feeds them to the builder.
  *
  * @param ProjectDescriptorBuilder $builder
  * @param Collection               $files          A files container to parse.
  *
  * @api
  *
  * @throws Exception if no files were found.
  *
  * @return bool|string
  */
 public function parse(ProjectDescriptorBuilder $builder, Collection $files)
 {
     $timer = microtime(true);
     $paths = $this->getFilenames($files);
     $this->log('  Project root is:  ' . $files->getProjectRoot());
     $this->log('  Ignore paths are: ' . implode(', ', $files->getIgnorePatterns()->getArrayCopy()));
     if ($builder->getProjectDescriptor()->getSettings()->isModified()) {
         $this->setForced(true);
         $this->log('One of the project\'s settings have changed, forcing a complete rebuild');
     }
     foreach ($paths as $filename) {
         if (class_exists('phpDocumentor\\Event\\Dispatcher')) {
             Dispatcher::getInstance()->dispatch('parser.file.pre', PreFileEvent::createInstance($this)->setFile($filename));
         }
         $this->log('Starting to parse file: ' . $filename);
         $memory = memory_get_usage();
         try {
             $file = new FileReflector($filename, $this->doValidation(), $this->getEncoding());
             $file->setDefaultPackageName($this->getDefaultPackageName());
             $file->setMarkers($this->getMarkers());
             $file->setFilename($this->getRelativeFilename($filename));
             // if the hash is unchanged; continue to the next file
             $cachedFiles = $builder->getProjectDescriptor()->getFiles();
             $hash = $cachedFiles->get($file->getFilename()) ? $cachedFiles->get($file->getFilename())->getHash() : null;
             if ($hash === $file->getHash() && !$this->isForced()) {
                 $this->log('>> Skipped file ' . $file->getFilename() . ' as no modifications were detected');
                 continue;
             }
             $file->process();
             $builder->buildFileUsingSourceData($file);
             $fileDescriptor = $builder->getProjectDescriptor()->getFiles()->get($file->getFilename());
             $errors = $fileDescriptor->getAllErrors();
             foreach ($errors as $error) {
                 $this->log($error->getCode(), $error->getSeverity(), $error->getContext());
             }
         } catch (Exception $e) {
             $this->log('  Unable to parse file "' . $filename . '", an error was detected: ' . $e->getMessage(), LogLevel::ALERT);
         }
         $memoryDelta = memory_get_usage() - $memory;
         $this->log('>> Memory after processing of file: ' . number_format(memory_get_usage() / 1024 / 1024, 2) . ' megabytes (' . ($memoryDelta > -0 ? '+' : '') . number_format($memoryDelta / 1024) . ' kilobytes)', LogLevel::DEBUG);
     }
     $this->log('Elapsed time to parse all files: ' . round(microtime(true) - $timer, 2) . 's');
     $this->log('Peak memory usage: ' . round(memory_get_peak_usage() / 1024 / 1024, 2) . 'M');
     return $builder->getProjectDescriptor();
 }
Пример #12
0
 /**
  * Iterates through the given files and builds the structure.xml file.
  *
  * @param Collection $files          A files container
  *     to parse.
  * @param bool       $include_source whether to include the source in the
  *     generated output..
  *
  * @api
  *
  * @throws Exception if no files were found.
  *
  * @return bool|string
  */
 public function parseFiles(Collection $files, $include_source = false)
 {
     $timer = microtime(true);
     $this->exporter = new \phpDocumentor\Parser\Exporter\Xml\Xml($this);
     $this->exporter->initialize();
     $paths = $files->getFilenames();
     $this->log('Starting to process ' . count($paths) . ' files');
     $this->log('  Project root is:  ' . $files->getProjectRoot());
     $this->log('  Ignore paths are: ' . implode(', ', $files->getIgnorePatterns()->getArrayCopy()));
     if (count($paths) < 1) {
         throw new Exception('No files were found', Exception::NO_FILES_FOUND);
     }
     $file_count = count($paths);
     foreach ($paths as $key => $file) {
         Dispatcher::getInstance()->dispatch('parser.file.pre', PreFileEvent::createInstance($this)->setFile($file));
         $this->parseFile($file, $include_source);
     }
     $this->exporter->finalize();
     $this->log('--');
     $this->log('Elapsed time to parse all files: ' . round(microtime(true) - $timer, 2) . 's');
     $this->log('Peak memory usage: ' . round(memory_get_peak_usage() / 1024 / 1024, 2) . 'M');
     return $this->exporter->getContents();
 }
Пример #13
0
 /**
  * Dispatches a logging request to log a debug message.
  *
  * @param string $message The message to log.
  *
  * @return void
  */
 public function debug($message)
 {
     \phpDocumentor\Event\Dispatcher::getInstance()->dispatch('system.debug', \phpDocumentor\Event\DebugEvent::createInstance($this)->setMessage($message));
 }
Пример #14
0
 public function beforeTraverse(array $nodes)
 {
     $node = null;
     $key = 0;
     foreach ($nodes as $k => $n) {
         if (!$n instanceof InlineHTML) {
             $node = $n;
             $key = $k;
             break;
         }
     }
     if ($node) {
         $comments = (array) $node->getAttribute('comments');
         // remove non-DocBlock comments
         $comments = array_values(array_filter($comments, function ($comment) {
             return $comment instanceof Doc;
         }));
         if (!empty($comments)) {
             try {
                 $docblock = new DocBlock((string) $comments[0], null, new Location($comments[0]->getLine()));
                 // the first DocBlock in a file documents the file if
                 // * it precedes another DocBlock or
                 // * it contains a @package tag and doesn't precede a class
                 //   declaration or
                 // * it precedes a non-documentable element (thus no include,
                 //   require, class, function, define, const)
                 if (count($comments) > 1 || !$node instanceof Class_ && !$node instanceof Interface_ && $docblock->hasTag('package') || !$this->isNodeDocumentable($node)) {
                     $this->doc_block = $docblock;
                     // remove the file level DocBlock from the node's comments
                     array_shift($comments);
                 }
             } catch (\Exception $e) {
                 $this->log($e->getMessage(), LogLevel::CRITICAL);
             }
         }
         // always update the comments attribute so that standard comments
         // do not stop DocBlock from being attached to an element
         $node->setAttribute('comments', $comments);
         $nodes[$key] = $node;
     }
     if (class_exists('phpDocumentor\\Event\\Dispatcher')) {
         Dispatcher::getInstance()->dispatch('reflection.docblock-extraction.post', PostDocBlockExtractionEvent::createInstance($this)->setDocblock($this->doc_block));
     }
     return $nodes;
 }
Пример #15
0
 /**
  * Dispatches a logging request.
  *
  * @param string   $message  The message to log.
  * @param string   $priority The logging priority as declared in the LogLevel PSR-3 class.
  * @param string[] $parameters
  *
  * @return void
  */
 protected function log($message, $priority = LogLevel::INFO, $parameters = array())
 {
     Dispatcher::getInstance()->dispatch('system.log', LogEvent::createInstance($this->parser)->setContext($parameters)->setMessage($message)->setPriority($priority));
 }
Пример #16
0
 /**
  * This method combines the structure.xml and the given target template
  * and creates a static html page at the artifact location.
  *
  * @param ProjectDescriptor $project        Document containing the structure.
  * @param Transformation    $transformation Transformation to execute.
  *
  * @return void
  */
 public function transform(ProjectDescriptor $project, Transformation $transformation)
 {
     if (!class_exists('XSLTProcessor')) {
         throw new Exception('The XSL writer was unable to find your XSLTProcessor; ' . 'please check if you have installed the PHP XSL extension');
     }
     $artifact = $transformation->getTransformer()->getTarget() . DIRECTORY_SEPARATOR . $transformation->getArtifact();
     $xsl = new \DOMDocument();
     $xsl->load($transformation->getSourceAsPath());
     $structureFilename = $transformation->getTransformer()->getTarget() . DIRECTORY_SEPARATOR . 'structure.xml';
     if (!is_readable($structureFilename)) {
         throw new RuntimeException('Structure.xml file was not found in the target directory, is the XML writer missing from the ' . 'template definition?');
     }
     // load the structure file (ast)
     $structure = new \DOMDocument('1.0', 'utf-8');
     libxml_use_internal_errors(true);
     $structure->load($structureFilename);
     $proc = new \XSLTProcessor();
     $proc->importStyleSheet($xsl);
     if (empty($structure->documentElement)) {
         $message = 'Specified DOMDocument lacks documentElement, cannot transform.';
         if (libxml_get_last_error()) {
             $message .= PHP_EOL . 'Apparently an error occurred with reading the structure.xml file, the reported ' . 'error was "' . trim(libxml_get_last_error()->message) . '" on line ' . libxml_get_last_error()->line;
         }
         throw new Exception($message);
     }
     $proc->setParameter('', 'title', $structure->documentElement->getAttribute('title'));
     $proc->setParameter('', 'root', str_repeat('../', substr_count($transformation->getArtifact(), '/')));
     $proc->setParameter('', 'search_template', $transformation->getParameter('search', 'none'));
     $proc->setParameter('', 'version', \phpDocumentor\Application::$VERSION);
     $proc->setParameter('', 'generated_datetime', date('r'));
     // check parameters for variables and add them when found
     $this->setProcessorParameters($transformation, $proc);
     // if a query is given, then apply a transformation to the artifact
     // location by replacing ($<var>} with the sluggified node-value of the
     // search result
     if ($transformation->getQuery() !== '') {
         $xpath = new \DOMXPath($structure);
         /** @var \DOMNodeList $qry */
         $qry = $xpath->query($transformation->getQuery());
         $count = $qry->length;
         foreach ($qry as $key => $element) {
             \phpDocumentor\Event\Dispatcher::getInstance()->dispatch('transformer.writer.xsl.pre', \phpDocumentor\Transformer\Event\PreXslWriterEvent::createInstance($this)->setElement($element)->setProgress(array($key + 1, $count)));
             $proc->setParameter('', $element->nodeName, $element->nodeValue);
             $file_name = $transformation->getTransformer()->generateFilename($element->nodeValue);
             $filename = str_replace('{$' . $element->nodeName . '}', $file_name, $artifact);
             if (!file_exists(dirname($filename))) {
                 mkdir(dirname($filename), 0755, true);
             }
             $proc->transformToURI($structure, $this->getXsltUriFromFilename($filename));
         }
     } else {
         if (substr($transformation->getArtifact(), 0, 1) == '$') {
             // not a file, it must become a variable!
             $variable_name = substr($transformation->getArtifact(), 1);
             $this->xsl_variables[$variable_name] = $proc->transformToXml($structure);
         } else {
             if (!file_exists(dirname($artifact))) {
                 mkdir(dirname($artifact), 0755, true);
             }
             $proc->transformToURI($structure, $this->getXsltUriFromFilename($artifact));
         }
     }
 }
Пример #17
0
 /**
  * Connect a series of output messages to various events to display progress.
  *
  * @param OutputInterface $output
  *
  * @return void
  */
 private function connectOutputToEvents(OutputInterface $output)
 {
     $this->getHelper('phpdocumentor_logger')->connectOutputToLogging($output, $this);
     Dispatcher::getInstance()->addListener(Transformer::EVENT_PRE_TRANSFORM, function (PreTransformEvent $event) use($output) {
         $transformations = $event->getSubject()->getTemplates()->getTransformations();
         $output->writeln(sprintf("\nApplying %d transformations", count($transformations)));
     });
     Dispatcher::getInstance()->addListener(Transformer::EVENT_PRE_INITIALIZATION, function (WriterInitializationEvent $event) use($output) {
         $output->writeln('  Initialize writer "' . get_class($event->getWriter()) . '"');
     });
     Dispatcher::getInstance()->addListener(Transformer::EVENT_PRE_TRANSFORMATION, function (PreTransformationEvent $event) use($output) {
         $output->writeln('  Execute transformation using writer "' . $event->getTransformation()->getWriter() . '"');
     });
 }
Пример #18
0
 /**
  * This method combines the structure.xml and the given target template
  * and creates a static html page at the artifact location.
  *
  * @param ProjectDescriptor $project        Document containing the structure.
  * @param Transformation    $transformation Transformation to execute.
  *
  * @throws \RuntimeException if the structure.xml file could not be found.
  * @throws Exception        if the structure.xml file's documentRoot could not be read because of encoding issues
  *    or because it was absent.
  *
  * @return void
  */
 public function transform(ProjectDescriptor $project, Transformation $transformation)
 {
     $structure = $this->loadAst($this->getAstPath($transformation));
     $proc = $this->getXslProcessor($transformation);
     $proc->registerPHPFunctions();
     $this->registerDefaultVariables($transformation, $proc, $structure);
     $this->setProcessorParameters($transformation, $proc);
     $artifact = $this->getArtifactPath($transformation);
     $this->checkForSpacesInPath($artifact);
     // if a query is given, then apply a transformation to the artifact
     // location by replacing ($<var>} with the sluggified node-value of the
     // search result
     if ($transformation->getQuery() !== '') {
         $xpath = new \DOMXPath($structure);
         /** @var \DOMNodeList $qry */
         $qry = $xpath->query($transformation->getQuery());
         $count = $qry->length;
         foreach ($qry as $key => $element) {
             Dispatcher::getInstance()->dispatch('transformer.writer.xsl.pre', PreXslWriterEvent::createInstance($this)->setElement($element)->setProgress(array($key + 1, $count)));
             $proc->setParameter('', $element->nodeName, $element->nodeValue);
             $file_name = $transformation->getTransformer()->generateFilename($element->nodeValue);
             if (!$artifact) {
                 $url = $this->generateUrlForXmlElement($project, $element);
                 if ($url === false || $url[0] !== DIRECTORY_SEPARATOR) {
                     continue;
                 }
                 $filename = $transformation->getTransformer()->getTarget() . str_replace('/', DIRECTORY_SEPARATOR, $url);
             } else {
                 $filename = str_replace('{$' . $element->nodeName . '}', $file_name, $artifact);
             }
             $relativeFileName = substr($filename, strlen($transformation->getTransformer()->getTarget()) + 1);
             $proc->setParameter('', 'root', str_repeat('../', substr_count($relativeFileName, '/')));
             $this->writeToFile($filename, $proc, $structure);
         }
     } else {
         if (substr($transformation->getArtifact(), 0, 1) == '$') {
             // not a file, it must become a variable!
             $variable_name = substr($transformation->getArtifact(), 1);
             $this->xsl_variables[$variable_name] = $proc->transformToXml($structure);
         } else {
             $relativeFileName = substr($artifact, strlen($transformation->getTransformer()->getTarget()) + 1);
             $proc->setParameter('', 'root', str_repeat('../', substr_count($relativeFileName, '/')));
             $this->writeToFile($artifact, $proc, $structure);
         }
     }
 }
Пример #19
0
 /**
  * Adds the event dispatcher to phpDocumentor's container.
  *
  * @return void
  */
 protected function addEventDispatcher()
 {
     $this['event_dispatcher'] = $this->share(function () {
         return Event\Dispatcher::getInstance();
     });
 }
Пример #20
0
 /**
  * Extracts a parsed DocBlock from an object.
  * 
  * @param object $node Any object with a "getDocComment()" method.
  * 
  * @return DocBlock|null
  */
 protected function extractDocBlock($node)
 {
     $doc_block = null;
     $comment = $node->getDocComment();
     if ($comment) {
         try {
             $doc_block = new DocBlock((string) $comment, $this->context, new Location($comment->getLine()));
         } catch (Exception $e) {
             $this->log($e->getMessage(), 2);
         }
     }
     Dispatcher::getInstance()->dispatch('reflection.docblock-extraction.post', PostDocBlockExtractionEvent::createInstance($this)->setDocblock($doc_block));
     return $doc_block;
 }
Пример #21
0
 /**
  * Executes each transformation.
  *
  * @return void
  */
 public function execute()
 {
     $source = $this->getSource();
     if (!$source) {
         throw new Exception('Unable to process transformations; the source was not set ' . 'correctly');
     }
     // invoke pre-transform actions (i.e. enhance source file with additional
     // meta-data)
     \phpDocumentor\Event\Dispatcher::getInstance()->dispatch('transformer.transform.pre', \phpDocumentor\Transformer\Event\PreTransformEvent::createInstance($this)->setSource($source));
     foreach ($this->getTransformations() as $transformation) {
         \phpDocumentor\Event\Dispatcher::getInstance()->dispatch('transformer.transformation.pre', \phpDocumentor\Transformer\Event\PreTransformationEvent::createInstance($this)->setSource($source));
         $this->log('Applying transformation' . ($transformation->getQuery() ? ' query "' . $transformation->getQuery() . '"' : '') . ' using writer ' . get_class($transformation->getWriter()) . ' on ' . $transformation->getArtifact());
         $transformation->execute($source);
         \phpDocumentor\Event\Dispatcher::getInstance()->dispatch('transformer.transformation.post', \phpDocumentor\Transformer\Event\PostTransformationEvent::createInstance($this)->setSource($source));
     }
     \phpDocumentor\Event\Dispatcher::getInstance()->dispatch('transformer.transform.post', \phpDocumentor\Transformer\Event\PostTransformEvent::createInstance($this)->setSource($source));
 }
Пример #22
0
 /**
  * Dispatches a logging request to log a debug message.
  *
  * @param string $message The message to log.
  *
  * @return void
  */
 public function debug($message)
 {
     if (class_exists('phpDocumentor\\Event\\Dispatcher')) {
         Dispatcher::getInstance()->dispatch('system.debug', DebugEvent::createInstance($this)->setMessage($message));
     }
 }