示例#1
0
 /**
  * Creates a class inheritance diagram.
  *
  * @param ProjectDescriptor $project
  * @param Transformation    $transformation
  *
  * @return void
  */
 public function processClass(ProjectDescriptor $project, Transformation $transformation)
 {
     try {
         $this->checkIfGraphVizIsInstalled();
     } catch (\Exception $e) {
         echo $e->getMessage();
         return;
     }
     if ($transformation->getParameter('font') !== null && $transformation->getParameter('font')->getValue()) {
         $this->nodeFont = $transformation->getParameter('font')->getValue();
     } else {
         $this->nodeFont = 'Courier';
     }
     $filename = $this->getDestinationPath($transformation);
     $graph = GraphVizGraph::create()->setRankSep('1.0')->setCenter('true')->setRank('source')->setRankDir('RL')->setSplines('true')->setConcentrate('true');
     $this->buildNamespaceTree($graph, $project->getNamespace());
     $classes = $project->getIndexes()->get('classes', new Collection())->getAll();
     $interfaces = $project->getIndexes()->get('interfaces', new Collection())->getAll();
     $traits = $project->getIndexes()->get('traits', new Collection())->getAll();
     /** @var ClassDescriptor[]|InterfaceDescriptor[]|TraitDescriptor[] $containers  */
     $containers = array_merge($classes, $interfaces, $traits);
     foreach ($containers as $container) {
         $from_name = $container->getFullyQualifiedStructuralElementName();
         $parents = array();
         $implemented = array();
         if ($container instanceof ClassDescriptor) {
             if ($container->getParent()) {
                 $parents[] = $container->getParent();
             }
             $implemented = $container->getInterfaces()->getAll();
         }
         if ($container instanceof InterfaceDescriptor) {
             $parents = $container->getParent()->getAll();
         }
         /** @var string|ClassDescriptor|InterfaceDescriptor $parent */
         foreach ($parents as $parent) {
             $edge = $this->createEdge($graph, $from_name, $parent);
             $edge->setArrowHead('empty');
             $graph->link($edge);
         }
         /** @var string|ClassDescriptor|InterfaceDescriptor $parent */
         foreach ($implemented as $parent) {
             $edge = $this->createEdge($graph, $from_name, $parent);
             $edge->setStyle('dotted');
             $edge->setArrowHead('empty');
             $graph->link($edge);
         }
     }
     $graph->export('svg', $filename);
 }
示例#2
0
 /**
  * Calls the wkhtmltopdf executable to generate a PDF.
  *
  * @param \DOMDocument                        $structure      Structure source
  *     use as basis for the transformation.
  * @param \phpDocumentor\Transformer\Transformation $transformation Transformation
  *     that supplies the meta-data for this writer.
  *
  * @return void
  */
 public function transform(\DOMDocument $structure, \phpDocumentor\Transformer\Transformation $transformation)
 {
     $artifact = $transformation->getTransformer()->getTarget() . DIRECTORY_SEPARATOR . $transformation->getArtifact();
     $transformation->setArtifact($artifact);
     $source = substr($transformation->getSource(), 0, 1) != DIRECTORY_SEPARATOR ? $transformation->getTransformer()->getTarget() . DIRECTORY_SEPARATOR . $transformation->getSource() : $transformation->getSource();
     $transformation->setSource($source);
     $options = '';
     if ($transformation->getParameter('toc', 'false') == 'true') {
         $options = ' toc ';
     }
     // TODO: add parameter to provide a cover HTML
     // TODO: add a parameter to provide a header HTML
     // TODO: add a parameter to provide a footer HTML
     // first try if there is a wkhtmltopdf in the global path, this helps
     // windows users
     exec('wkhtmltopdf ' . $options . ' ' . $transformation->getSource() . ' ' . $transformation->getArtifact() . ' 2>&1', $output, $error);
     $output = implode(PHP_EOL, $output);
     // this notice is linux specific; if it is found no global wkhtmltopdf
     // was installed; try the one which is included with phpDocumentor
     if (strpos($output, 'wkhtmltopdf: not found') !== false) {
         // TODO: replace the below with a decent way to find the executable
         exec(dirname(__FILE__) . '/../../../src/wkhtmltopdf/wkhtmltopdf-i386 ' . $options . ' ' . $transformation->getSource() . ' ' . $transformation->getArtifact() . ' 2>&1', $output, $error);
         $output = implode(PHP_EOL, $output) . PHP_EOL;
     }
     // log message and output
     $this->log('Generating PDF file ' . $transformation->getArtifact() . ' from ' . $transformation->getSource());
     $this->log($output, $error == 0 ? \phpDocumentor\Plugin\Core\Log::INFO : \phpDocumentor\Plugin\Core\Log::CRIT);
     // CRASH!
     if ($error != 0) {
         throw new \phpDocumentor\Plugin\Core\Exception('Conversion to PDF failed, see output for details');
     }
 }
示例#3
0
 /**
  * Generates an array containing class to path references and then invokes
  * the Source specific method.
  *
  * @param \DOMDocument                        $structure      Structure source
  *     use as basis for the transformation.
  * @param \phpDocumentor\Transformer\Transformation $transformation Transformation
  *     that supplies the meta-data for this writer.
  *
  * @return void
  */
 public function transform(\DOMDocument $structure, \phpDocumentor\Transformer\Transformation $transformation)
 {
     // NOTE: the -V flag sends output using STDERR and STDOUT
     exec('dot -V 2>&1', $output, $error);
     if ($error != 0) {
         $this->log('Unable to find the `dot` command of the GraphViz package. ' . 'Is GraphViz correctly installed and present in your path?', \phpDocumentor\Plugin\Core\Log::ERR);
         return;
     }
     $this->node_font = $transformation->getParameter('font', 'Courier');
     // add to classes
     $xpath = new \DOMXPath($structure);
     $qry = $xpath->query('//class[full_name]/..');
     $class_paths = array();
     /** @var \DOMElement $element */
     foreach ($qry as $element) {
         $path = $element->getAttribute('generated-path');
         foreach ($element->getElementsByTagName('class') as $class) {
             $class_paths[$class->getElementsByTagName('full_name')->item(0)->nodeValue] = $path;
         }
     }
     // add to interfaces
     $qry = $xpath->query('//interface[full_name]/..');
     /** @var \DOMElement $element */
     foreach ($qry as $element) {
         $path = $element->getAttribute('generated-path');
         foreach ($element->getElementsByTagName('interface') as $class) {
             $class_paths[$class->getElementsByTagName('full_name')->item(0)->nodeValue] = $path;
         }
     }
     $this->class_paths = $class_paths;
     $type_method = 'process' . ucfirst($transformation->getSource());
     $this->{$type_method}($structure, $transformation);
 }
示例#4
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\Plugin\EventDispatcher::getInstance()->dispatch('transformer.writer.xsl.pre', \phpDocumentor\Transformer\Events\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));
         }
     }
 }
示例#5
0
 /**
  * Tries to add any custom extensions that have been defined in the template or the transformation's configuration.
  *
  * This method will read the `twig-extension` parameter of the transformation (which inherits the template's
  * parameter set) and try to add those extensions to the environment.
  *
  * @param Transformation    $transformation
  * @param ProjectDescriptor $project
  * @param \Twig_Environment $twigEnvironment
  *
  * @throws \InvalidArgumentException if a twig-extension should be loaded but it could not be found.
  *
  * @return void
  */
 protected function addExtensionsFromTemplateConfiguration(Transformation $transformation, ProjectDescriptor $project, \Twig_Environment $twigEnvironment)
 {
     /** @var \SimpleXMLElement $extension */
     foreach ((array) $transformation->getParameter('twig-extension', array()) as $extension) {
         $extension = (string) $extension;
         if (!class_exists($extension)) {
             throw new \InvalidArgumentException('Unknown twig extension: ' . $extension);
         }
         // to support 'normal' Twig extensions we check the interface to determine what instantiation to do.
         $implementsInterface = in_array('phpDocumentor\\Plugin\\Core\\Twig\\ExtensionInterface', class_implements($extension));
         $twigEnvironment->addExtension($implementsInterface ? new $extension($project, $transformation) : new $extension());
     }
 }
示例#6
0
 /**
  * Tries to add any custom extensions that have been defined in the
  * template or the transformation's configuration.
  *
  * This method will read the `twig-extension` parameter of the
  * transformation (which inherits the template's parameter set) and
  * try to add those extensions to the environment.
  *
  * @param Transformation    $transformation
  * @param \SimpleXMLElement $structure
  * @param \Twig_Environment $env
  *
  * @throws \InvalidArgumentException if a twig-extension should be loaded
  *     but it could not be found.
  *
  * @return void
  */
 protected function addExtensionsFromTemplateConfiguration($transformation, $structure, $env)
 {
     /** @var \SimpleXMLElement $extension */
     foreach ((array) $transformation->getParameter('twig-extension', array()) as $extension) {
         $extension = (string) $extension;
         if (!class_exists($extension)) {
             throw new \InvalidArgumentException('Unknown twig extension: ' . $extension);
         }
         // to support 'normal' Twig extensions we check the interface
         // to determine what instantiation to do.
         $implements_interface = in_array('phpDocumentor\\Plugin\\Twig\\ExtensionInterface', class_implements($extension));
         $extension_object = $implements_interface ? new $extension($structure, $transformation) : new $extension();
         $env->addExtension($extension_object);
     }
 }
示例#7
0
 /**
  * Tries to add any custom extensions that have been defined in the template or the transformation's configuration.
  *
  * This method will read the `twig-extension` parameter of the transformation (which inherits the template's
  * parameter set) and try to add those extensions to the environment.
  *
  * @param Transformation    $transformation
  * @param ProjectDescriptor $project
  * @param \Twig_Environment $twigEnvironment
  *
  * @throws \InvalidArgumentException if a twig-extension should be loaded but it could not be found.
  *
  * @return void
  */
 protected function addExtensionsFromTemplateConfiguration(Transformation $transformation, ProjectDescriptor $project, \Twig_Environment $twigEnvironment)
 {
     $isDebug = $transformation->getParameter('twig-debug') ? $transformation->getParameter('twig-debug')->getValue() : false;
     if ($isDebug == 'true') {
         $twigEnvironment->enableDebug();
         $twigEnvironment->enableAutoReload();
         $twigEnvironment->addExtension(new \Twig_Extension_Debug());
     }
     /** @var Template\Parameter $extension */
     foreach ($transformation->getParametersWithKey('twig-extension') as $extension) {
         $extensionValue = $extension->getValue();
         if (!class_exists($extensionValue)) {
             throw new \InvalidArgumentException('Unknown twig extension: ' . $extensionValue);
         }
         // to support 'normal' Twig extensions we check the interface to determine what instantiation to do.
         $implementsInterface = in_array('phpDocumentor\\Plugin\\Twig\\ExtensionInterface', class_implements($extensionValue));
         $twigEnvironment->addExtension($implementsInterface ? new $extensionValue($project, $transformation) : new $extensionValue());
     }
 }
示例#8
0
 /**
  * @param Transformation $transformation
  * @param $proc
  * @param $structure
  */
 private function registerDefaultVariables(Transformation $transformation, $proc, $structure)
 {
     $proc->setParameter('', 'title', $structure->documentElement->getAttribute('title'));
     if ($transformation->getParameter('search') !== null && $transformation->getParameter('search')->getValue()) {
         $proc->setParameter('', 'search_template', $transformation->getParameter('search')->getValue());
     } else {
         $proc->setParameter('', 'search_template', 'none');
     }
     $proc->setParameter('', 'version', Application::$VERSION);
     $proc->setParameter('', 'generated_datetime', date('r'));
 }
示例#9
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));
         }
     }
 }