/**
  * This method generates the checkstyle.xml report
  *
  * @param ProjectDescriptor $project        Document containing the structure.
  * @param Transformation    $transformation Transformation to execute.
  *
  * @return void
  */
 public function transform(ProjectDescriptor $project, Transformation $transformation)
 {
     $artifact = $this->getDestinationPath($transformation);
     $this->checkForSpacesInPath($artifact);
     $document = new \DOMDocument();
     $document->formatOutput = true;
     $report = $document->createElement('checkstyle');
     $report->setAttribute('version', '1.3.0');
     $document->appendChild($report);
     /** @var FileDescriptor $fileDescriptor */
     foreach ($project->getFiles()->getAll() as $fileDescriptor) {
         $file = $document->createElement('file');
         $file->setAttribute('name', $fileDescriptor->getPath());
         $report->appendChild($file);
         /** @var Error $error */
         foreach ($fileDescriptor->getAllErrors()->getAll() as $error) {
             $item = $document->createElement('error');
             $item->setAttribute('line', $error->getLine());
             $item->setAttribute('severity', $error->getSeverity());
             $item->setAttribute('message', vsprintf($this->getTranslator()->translate($error->getCode()), $error->getContext()));
             $item->setAttribute('source', 'phpDocumentor.file.' . $error->getCode());
             $file->appendChild($item);
         }
     }
     $this->saveCheckstyleReport($artifact, $document);
 }
 /**
  * Iterates through each element in the project and replaces its inline @see and @link tag with a markdown
  * representation.
  *
  * @param ProjectDescriptor $project
  *
  * @return void
  */
 public function execute(ProjectDescriptor $project)
 {
     /** @var Collection|DescriptorAbstract[] $elementCollection */
     $this->elementCollection = $project->getIndexes()->get('elements');
     foreach ($this->elementCollection as $descriptor) {
         $this->resolveSeeAndLinkTags($descriptor);
     }
 }
 /**
  * {@inheritDoc}
  */
 public function execute(ProjectDescriptor $project)
 {
     $elements = $project->getIndexes()->get('elements');
     /** @var DescriptorAbstract $element */
     foreach ($elements as $element) {
         $element->setDescription($this->replaceInlineExamples($element));
     }
 }
Example #4
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);
 }
 /**
  * {@inheritDoc}
  */
 public function execute(ProjectDescriptor $project)
 {
     $elementCollection = new Collection();
     $project->getIndexes()->set('elements', $elementCollection);
     $constantsIndex = $project->getIndexes()->get('constants', new Collection());
     $functionsIndex = $project->getIndexes()->get('functions', new Collection());
     $classesIndex = $project->getIndexes()->get('classes', new Collection());
     $interfacesIndex = $project->getIndexes()->get('interfaces', new Collection());
     $traitsIndex = $project->getIndexes()->get('traits', new Collection());
     foreach ($project->getFiles() as $file) {
         $this->addElementsToIndexes($file->getConstants()->getAll(), array($constantsIndex, $elementCollection));
         $this->addElementsToIndexes($file->getFunctions()->getAll(), array($functionsIndex, $elementCollection));
         foreach ($file->getClasses()->getAll() as $element) {
             $this->addElementsToIndexes($element, array($classesIndex, $elementCollection));
             $this->addElementsToIndexes($this->getSubElements($element), array($elementCollection));
         }
         foreach ($file->getInterfaces()->getAll() as $element) {
             $this->addElementsToIndexes($element, array($interfacesIndex, $elementCollection));
             $this->addElementsToIndexes($this->getSubElements($element), array($elementCollection));
         }
         foreach ($file->getTraits()->getAll() as $element) {
             $this->addElementsToIndexes($element, array($traitsIndex, $elementCollection));
             $this->addElementsToIndexes($this->getSubElements($element), array($elementCollection));
         }
     }
 }
 /**
  * {@inheritDoc}
  */
 public function execute(ProjectDescriptor $project)
 {
     /** @var DescriptorAbstract $element */
     foreach ($project->getIndexes()->get('elements', new Collection()) as $element) {
         $todos = $element->getTags()->get('todo');
         if (!$todos) {
             continue;
         }
         /** @var TagDescriptor $todo */
         foreach ($todos as $todo) {
             $fileDescriptor = $this->getFileDescriptor($element);
             $this->addTodoMarkerToFile($fileDescriptor, $todo, $element->getLine());
         }
     }
 }
 /**
  * Stores a Project Descriptor in the Cache.
  *
  * @param ProjectDescriptor $projectDescriptor
  *
  * @return void
  */
 public function save(ProjectDescriptor $projectDescriptor)
 {
     $keys = array();
     $cache = $this->getCache();
     /** @var IteratorInterface $iteratorInterface  */
     $iteratorInterface = $cache->getIterator();
     // FIXME: Workaround for: https://github.com/zendframework/zf2/pull/4154
     if ($iteratorInterface->valid()) {
         foreach ($cache as $key) {
             $keys[] = $key;
         }
     }
     // store the settings for this Project Descriptor
     $cache->setItem(self::KEY_SETTINGS, $projectDescriptor->getSettings());
     // store cache items
     $usedKeys = array();
     foreach ($projectDescriptor->getFiles() as $file) {
         $key = self::FILE_PREFIX . md5($file->getPath());
         $usedKeys[] = $key;
         $cache->setItem($key, $file);
     }
     // remove any keys that are no longer used.
     $invalidatedKeys = array_diff($keys, $usedKeys);
     if ($invalidatedKeys) {
         $cache->removeItems($invalidatedKeys);
     }
     if ($cache instanceof OptimizableInterface) {
         $cache->optimize();
     }
 }
 /**
  * Adds a class descriptor to the project's elements and add a parent file.
  *
  * @param FileDescriptor $fileDescriptor
  *
  * @return ClassDescriptor
  */
 protected function givenProjectHasClassDescriptorAssociatedWithFile($fileDescriptor)
 {
     $classDescriptor = new ClassDescriptor();
     if ($fileDescriptor) {
         $classDescriptor->setFile($fileDescriptor);
     }
     $elementIndex = $this->project->getIndexes()->get('elements', new Collection());
     $elementIndex->add($classDescriptor);
     return $classDescriptor;
 }
 /**
  * @covers phpDocumentor\Compiler\Pass\PackageTreeBuilder::execute
  * @covers phpDocumentor\Compiler\Pass\PackageTreeBuilder::addElementsOfTypeToPackage
  */
 public function testAddFunctionToNamespace()
 {
     $function = new FunctionDescriptor();
     $function->setPackage('My\\Space');
     $function->setFullyQualifiedStructuralElementName('My\\Space\\Function1');
     $this->project->getFiles()->get(0)->getFunctions()->add($function);
     // double check if a second function in the same deep namespace ends up at the right location
     $function2 = new FunctionDescriptor();
     $function2->setPackage('My\\Space');
     $function2->setFullyQualifiedStructuralElementName('My\\Space\\Function2');
     $this->project->getFiles()->get(0)->getFunctions()->add($function2);
     $this->fixture->execute($this->project);
     $this->assertSame(array($function, $function2), $this->project->getIndexes()->get('packages')->get('\\My\\Space')->getFunctions()->getAll());
 }
 /**
  * @covers phpDocumentor\Descriptor\ProjectDescriptor::isVisibilityAllowed
  */
 public function testIsVisibilityAllowed()
 {
     $this->assertTrue($this->fixture->isVisibilityAllowed(Settings::VISIBILITY_PUBLIC));
     $this->assertTrue($this->fixture->isVisibilityAllowed(Settings::VISIBILITY_PROTECTED));
     $this->assertTrue($this->fixture->isVisibilityAllowed(Settings::VISIBILITY_PRIVATE));
     $this->assertFalse($this->fixture->isVisibilityAllowed(Settings::VISIBILITY_INTERNAL));
     $settings = new Settings();
     $settings->setVisibility(Settings::VISIBILITY_PROTECTED);
     $this->fixture->setSettings($settings);
     $this->assertFalse($this->fixture->isVisibilityAllowed(Settings::VISIBILITY_PUBLIC));
     $this->assertTrue($this->fixture->isVisibilityAllowed(Settings::VISIBILITY_PROTECTED));
     $this->assertFalse($this->fixture->isVisibilityAllowed(Settings::VISIBILITY_PRIVATE));
     $this->assertFalse($this->fixture->isVisibilityAllowed(Settings::VISIBILITY_INTERNAL));
     $settings->setVisibility(Settings::VISIBILITY_PROTECTED | Settings::VISIBILITY_INTERNAL);
     $this->fixture->setSettings($settings);
     $this->assertFalse($this->fixture->isVisibilityAllowed(Settings::VISIBILITY_PUBLIC));
     $this->assertTrue($this->fixture->isVisibilityAllowed(Settings::VISIBILITY_PROTECTED));
     $this->assertFalse($this->fixture->isVisibilityAllowed(Settings::VISIBILITY_PRIVATE));
     $this->assertTrue($this->fixture->isVisibilityAllowed(Settings::VISIBILITY_INTERNAL));
 }
 /**
  * @covers phpDocumentor\Compiler\Pass\ElementsIndexBuilder::execute
  * @covers phpDocumentor\Compiler\Pass\ElementsIndexBuilder::addElementsToIndexes
  * @covers phpDocumentor\Compiler\Pass\ElementsIndexBuilder::getIndexKey
  * @covers phpDocumentor\Compiler\Pass\ElementsIndexBuilder::getSubElements
  */
 public function testAddMethodsToIndex()
 {
     $file1 = $this->project->getFiles()->get(0);
     $classDescriptor1 = new ClassDescriptor();
     $classDescriptor1->setFullyQualifiedStructuralElementName('My\\Space\\Class1');
     $file1->getClasses()->add($classDescriptor1);
     $classMethodDescriptor1 = new MethodDescriptor();
     $classMethodDescriptor1->setFullyQualifiedStructuralElementName('My\\Space\\Class1::METHOD');
     $classDescriptor1->getMethods()->add($classMethodDescriptor1);
     $file2 = $this->project->getFiles()->get(1);
     $classDescriptor2 = new ClassDescriptor();
     $classDescriptor2->setFullyQualifiedStructuralElementName('My\\Space\\Class2');
     $file2->getClasses()->add($classDescriptor2);
     $classMethodDescriptor2 = new MethodDescriptor();
     $classMethodDescriptor2->setFullyQualifiedStructuralElementName('My\\Space\\Class2::METHOD');
     $classDescriptor2->getMethods()->add($classMethodDescriptor2);
     $this->fixture->execute($this->project);
     $elements = $this->project->getIndexes()->get('elements')->getAll();
     $this->assertCount(4, $elements);
     $this->assertSame(array('My\\Space\\Class1', 'My\\Space\\Class1::METHOD', 'My\\Space\\Class2', 'My\\Space\\Class2::METHOD'), array_keys($elements));
     $this->assertSame(array($classDescriptor1, $classMethodDescriptor1, $classDescriptor2, $classMethodDescriptor2), array_values($elements));
     // class methods are not indexed separately
     $this->assertNull($this->project->getIndexes()->get('methods'));
 }
 /**
  * Creates a tree of NamespaceDescriptors based on the provided FQNN (namespace name).
  *
  * This method will examine the namespace name and create a namespace descriptor for each part of
  * the FQNN if it doesn't exist in the namespaces field of the current namespace (starting with the root
  * Namespace in the Project Descriptor),
  *
  * As an intended side effect this method also populates the *elements* index of the ProjectDescriptor with all
  * created NamespaceDescriptors. Each index key is prefixed with a tilde (~) so that it will not conflict with
  * other FQSEN's, such as classes or interfaces.
  *
  * @param ProjectDescriptor $project
  * @param string            $namespaceName A FQNN of the namespace (and parents) to create.
  *
  * @see ProjectDescriptor::getNamespace() for the root namespace.
  * @see NamespaceDescriptor::getNamespaces() for the child namespaces of a given namespace.
  *
  * @return void
  */
 protected function createNamespaceDescriptorTree(ProjectDescriptor $project, $namespaceName)
 {
     $parts = explode('\\', ltrim($namespaceName, '\\'));
     $fqnn = '';
     // this method does not use recursion to traverse the tree but uses a pointer that will be overridden with the
     // next item that is to be traversed (child namespace) at the end of the loop.
     $pointer = $project->getNamespace();
     foreach ($parts as $part) {
         $fqnn .= '\\' . $part;
         if ($pointer->getChildren()->get($part)) {
             $pointer = $pointer->getChildren()->get($part);
             continue;
         }
         // namespace does not exist, create it
         $interimNamespaceDescriptor = new NamespaceDescriptor();
         $interimNamespaceDescriptor->setParent($pointer);
         $interimNamespaceDescriptor->setName($part);
         $interimNamespaceDescriptor->setFullyQualifiedStructuralElementName($fqnn);
         // add to the pointer's list of children
         $pointer->getChildren()->set($part, $interimNamespaceDescriptor);
         // add to index
         $project->getIndexes()->elements['~' . $fqnn] = $interimNamespaceDescriptor;
         $project->getIndexes()->get('namespaces', new Collection())->add($interimNamespaceDescriptor);
         // move pointer forward
         $pointer = $interimNamespaceDescriptor;
     }
 }
 /**
  * @covers phpDocumentor\Descriptor\ProjectDescriptorBuilder::isVisibilityAllowed
  */
 public function testDeterminesWhetherASpecificVisibilityIsAllowedToBeIncluded()
 {
     $projectDescriptorName = 'My Descriptor';
     $projectDescriptorMock = new ProjectDescriptor($projectDescriptorName);
     $projectDescriptorMock->getSettings()->setVisibility(Settings::VISIBILITY_PUBLIC);
     $this->fixture->setProjectDescriptor($projectDescriptorMock);
     $this->assertTrue($this->fixture->isVisibilityAllowed(Settings::VISIBILITY_PUBLIC));
     $this->assertFalse($this->fixture->isVisibilityAllowed(Settings::VISIBILITY_PRIVATE));
 }
Example #14
0
 /**
  * @param ProjectDescriptor $project
  * @param $element
  * @return false|string
  */
 private function generateUrlForXmlElement(ProjectDescriptor $project, $element)
 {
     $elements = $project->getIndexes()->get('elements');
     $elementFqcn = ($element->parentNode->nodeName === 'namespace' ? '~\\' : '') . $element->nodeValue;
     $node = isset($elements[$elementFqcn]) ? $elements[$elementFqcn] : $element->nodeValue;
     // do not use the normalized version if the element is not found!
     $rule = $this->routers->match($node);
     if (!$rule) {
         throw new \InvalidArgumentException('No matching routing rule could be found for the given node, please provide an artifact location, ' . 'encountered: ' . ($node === null ? 'NULL' : get_class($node)));
     }
     $rule = new ForFileProxy($rule);
     $url = $rule->generate($node);
     return $url;
 }
 /**
  * Creates a tree of PackageDescriptors based on the provided FQNN (package name).
  *
  * This method will examine the package name and create a package descriptor for each part of
  * the FQNN if it doesn't exist in the packages field of the current package (starting with the root
  * Package in the Project Descriptor),
  *
  * As an intended side effect this method also populates the *elements* index of the ProjectDescriptor with all
  * created PackageDescriptors. Each index key is prefixed with a tilde (~) so that it will not conflict with
  * other FQSEN's, such as classes or interfaces.
  *
  * @param ProjectDescriptor $project
  * @param string            $packageName A FQNN of the package (and parents) to create.
  *
  * @see ProjectDescriptor::getPackage() for the root package.
  * @see PackageDescriptor::getChildren() for the child packages of a given package.
  *
  * @return void
  */
 protected function createPackageDescriptorTree(ProjectDescriptor $project, $packageName)
 {
     $parts = explode('\\', ltrim($packageName, '\\'));
     $fqnn = '';
     // this method does not use recursion to traverse the tree but uses a pointer that will be overridden with the
     // next item that is to be traversed (child package) at the end of the loop.
     /** @var PackageDescriptor $pointer  */
     $pointer = $project->getIndexes()->packages['\\'];
     foreach ($parts as $part) {
         $fqnn .= '\\' . $part;
         if ($pointer->getChildren()->get($part)) {
             $pointer = $pointer->getChildren()->get($part);
             continue;
         }
         // package does not exist, create it
         $interimPackageDescriptor = new PackageDescriptor();
         $interimPackageDescriptor->setParent($pointer);
         $interimPackageDescriptor->setName($part);
         $interimPackageDescriptor->setFullyQualifiedStructuralElementName($fqnn);
         // add to the pointer's list of children
         $pointer->getChildren()->set($part ?: 'UNKNOWN', $interimPackageDescriptor);
         // add to index
         $project->getIndexes()->packages[$fqnn] = $interimPackageDescriptor;
         // move pointer forward
         $pointer = $interimPackageDescriptor;
     }
 }
 /**
  * Ensures that the ProjectDescriptor has a root namespace with the provided array as children of that namespace.
  *
  * @param m\Mock|ProjectDescriptor $projectDescriptor
  * @param array $rootNamespaceChildren
  *
  * @return void
  */
 protected function whenProjectHasTheFollowingChildrenOfRootNamespace($projectDescriptor, $rootNamespaceChildren)
 {
     $projectDescriptor->shouldReceive('getNamespace->getChildren')->andReturn(new Collection($rootNamespaceChildren));
 }
Example #17
0
 /**
  * Executes the linker.
  *
  * @param ProjectDescriptor $project Representation of the Object Graph that can be manipulated.
  *
  * @return void
  */
 public function execute(ProjectDescriptor $project)
 {
     $this->setObjectAliasesList($project->getIndexes()->elements->getAll());
     $this->substitute($project);
 }
Example #18
0
 /**
  * Get number of markers.
  *
  * @param ProjectDescriptor $project
  *
  * @return int
  */
 protected function getMarkerCounter(ProjectDescriptor $project)
 {
     $markerCounter = 0;
     /* @var $fileDescriptor FileDescriptor */
     foreach ($project->getFiles()->getAll() as $fileDescriptor) {
         $markerCounter += $fileDescriptor->getMarkers()->count();
     }
     return $markerCounter;
 }
Example #19
0
 /**
  * This implements testing of the protected finalize method.
  *
  * @param ProjectDescriptor $projectDescriptor
  * @return void
  */
 protected function implementProtectedFinalize(ProjectDescriptor $projectDescriptor)
 {
     $this->projectDescriptor->shouldReceive('isVisibilityAllowed')->with(ProjectDescriptor\Settings::VISIBILITY_INTERNAL)->andReturn(true);
 }
Example #20
0
 /**
  * Finalizes the processing and executing all post-processing actions.
  *
  * This method is responsible for extracting and manipulating the data that
  * is global to the project, such as:
  *
  * - Package tree
  * - Namespace tree
  * - Marker list
  * - Deprecated elements listing
  * - Removal of objects related to visibility
  *
  * @return void
  */
 protected function finalize(ProjectDescriptor $projectDescriptor)
 {
     // TODO: move all these behaviours to a central location for all template parsers
     $behaviour = new AuthorTag();
     $behaviour->process($this->xml);
     $behaviour = new CoversTag();
     $behaviour->process($this->xml);
     $behaviour = new IgnoreTag();
     $behaviour->process($this->xml);
     $behaviour = new InternalTag($projectDescriptor->isVisibilityAllowed(ProjectDescriptor\Settings::VISIBILITY_INTERNAL));
     $behaviour->process($this->xml);
     $behaviour = new LicenseTag();
     $behaviour->process($this->xml);
     $behaviour = new MethodTag();
     $behaviour->process($this->xml);
     $behaviour = new ParamTag();
     $behaviour->process($this->xml);
     $behaviour = new PropertyTag();
     $behaviour->process($this->xml);
     $behaviour = new ReturnTag();
     $behaviour->process($this->xml);
     $behaviour = new UsesTag();
     $behaviour->process($this->xml);
     $behaviour = new VarTag();
     $behaviour->process($this->xml);
     $this->buildPackageTree($this->xml);
     $this->buildNamespaceTree($this->xml);
     $this->buildDeprecationList($this->xml);
 }
Example #21
0
    /**
     * This method writes every source code entry in the structure file to a highlighted file.
     *
     * @param ProjectDescriptor $project        Document containing the structure.
     * @param Transformation    $transformation Transformation to execute.
     *
     * @return void
     */
    public function transform(ProjectDescriptor $project, Transformation $transformation)
    {
        $artifact = $transformation->getTransformer()->getTarget() . DIRECTORY_SEPARATOR . ($transformation->getArtifact() ? $transformation->getArtifact() : 'source');
        /** @var FileDescriptor $file */
        foreach ($project->getFiles() as $file) {
            $filename = $file->getPath();
            $source = $file->getSource();
            $root = str_repeat('../', count(explode(DIRECTORY_SEPARATOR, $filename)));
            $path = $artifact . DIRECTORY_SEPARATOR . $filename;
            if (!file_exists(dirname($path))) {
                mkdir(dirname($path), 0755, true);
            }
            $source = htmlentities($source);
            file_put_contents($path . '.html', <<<HTML
<html>
    <head>
        <script
            type="text/javascript"
            src="{$root}js/jquery-1.4.2.min.js">
        </script>
        <script
            type="text/javascript"
            src="{$root}syntax_highlighter/scripts/shCore.js">
        </script>
        <script
            type="text/javascript"
            src="{$root}syntax_highlighter/scripts/shBrushJScript.js">
        </script>
        <script
            type="text/javascript"
            src="{$root}syntax_highlighter/scripts/shBrushPhp.js">
        </script>
        <script
            type="text/javascript"
            src="{$root}syntax_highlighter/scripts/shBrushXml.js">
        </script>
        <link
            href="{$root}syntax_highlighter/styles/shCore.css" rel="stylesheet"
            type="text/css"
        />
        <link
            href="{$root}syntax_highlighter/styles/shCoreEclipse.css"
            rel="stylesheet" type="text/css"
        />
        <link
            href="{$root}syntax_highlighter/styles/shThemeWordpress.css"
            rel="stylesheet" type="text/css"
        />
    </head>
    <body>
        <pre class="brush: php">{$source}</pre>
        <script type="text/javascript">
             SyntaxHighlighter.all()
             jQuery('.gutter div').each(function(key, data){
                jQuery(data).prepend('<a name="L'+jQuery(data).text()+'"/>');
             });
        </script>
    </body>
</html>
HTML
);
        }
    }