/** * @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)); } }
/** * 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)); } } }
/** * 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; }
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; }
protected function thenDispatcherShouldReceiveLoggingEvents() { $this->dispatcherMock->shouldReceive('dispatch')->atLeast(1)->with('system.log', m::type('phpDocumentor\\Event\\LogEvent')); }
/** * 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); }
/** * 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; }
/** * 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)); }
/** * 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'])); }
/** * 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(); }
/** * 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(); }
/** * 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)); }
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; }
/** * 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)); }
/** * 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)); } } }
/** * 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() . '"'); }); }
/** * 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); } } }
/** * Adds the event dispatcher to phpDocumentor's container. * * @return void */ protected function addEventDispatcher() { $this['event_dispatcher'] = $this->share(function () { return Event\Dispatcher::getInstance(); }); }
/** * 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; }
/** * 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)); }
/** * 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)); } }