Completed
Push — develop ( 8eb671...133594 )
by Mike
19:30 queued 09:24
created

Scrybe/Converter/RestructuredText/ToHtml.php (1 issue)

Upgrade to new PHP Analysis Engine

These results are based on our legacy PHP analysis, consider migrating to our new PHP analysis engine instead. Learn more

1
<?php
2
declare(strict_types=1);
3
4
/**
5
 * This file is part of phpDocumentor.
6
 *
7
 * For the full copyright and license information, please view the LICENSE
8
 * file that was distributed with this source code.
9
 *
10
 * @author    Mike van Riel <[email protected]>
11
 * @copyright 2010-2018 Mike van Riel / Naenius (http://www.naenius.com)
12
 * @license   http://www.opensource.org/licenses/mit-license.php MIT
13
 * @link      http://phpdoc.org
14
 */
15
16
namespace phpDocumentor\Plugin\Scrybe\Converter\RestructuredText;
17
18
use Exception;
19
use phpDocumentor\Plugin\Scrybe\Converter\BaseConverter;
20
use phpDocumentor\Plugin\Scrybe\Converter\Metadata\TableOfContents\File;
21
use phpDocumentor\Plugin\Scrybe\Converter\ToHtmlInterface;
22
use phpDocumentor\Plugin\Scrybe\Template\TemplateInterface;
23
24
/**
25
 * Class used to convert one or more RestructuredText documents to their HTML representation.
26
 *
27
 * This class uses a two-phase process to interpret and parse the RestructuredText documents, namely Discovery
28
 * and Creation.
29
 *
30
 * @see manual://internals for a detailed description of the process.
31
 */
32
class ToHtml extends BaseConverter implements ToHtmlInterface
33
{
34
    /**
35
     * Discovers the data that is spanning all files.
36
     *
37
     * This method tries to find any data that needs to be collected before the actual creation and substitution
38
     * phase begins.
39
     *
40
     * Examples of data that needs to be collected during an initial phase is a table of contents, list of document
41
     * titles for references, assets and more.
42
     *
43
     * @throws Exception
44
     * @see manual://internals#build_cycle for more information regarding the build process.
45
     */
46
    protected function discover(): void
47
    {
48
        /** @var File $file */
49
        foreach ($this->fileset as $file) {
50
            $rst = new Document($this, $file);
51
            $rst->options->xhtmlVisitor = 'phpDocumentor\Plugin\Scrybe\Converter\RestructuredText\Visitors\Discover';
52
53
            if ($this->getLogger()) {
54
                $this->getLogger()->info('Scanning file "' . $file->getRealPath() . '"');
55
            }
56
57
            try {
58
                $rst->getAsXhtml();
59
            } catch (Exception $e) {
60
                continue;
61
            }
62
        }
63
    }
64
65
    /**
66
     * Converts the input files into one or more output files in the intended format.
67
     *
68
     * This method reads the files, converts them into the correct format and returns the contents of the conversion.
69
     *
70
     * The template is provided using the $template parameter and is used to decorate the individual files. It can be
71
     * obtained using the `\phpDocumentor\Plugin\Scrybe\Template\Factory` class.
72
     *
73
     * @see manual://internals#build_cycle for more information regarding the build process.
74
     * @return string[]|null The contents of the resulting file(s) or null if the files are written directly to file.
75
     */
76
    protected function create(TemplateInterface $template): ?string
77
    {
78
        $result = [];
79
80
        /** @var File $file */
81
        foreach ($this->fileset as $file) {
82
            $rst = new Document($this, $file);
83
            $destination = $this->getDestinationFilenameRelativeToProjectRoot($file);
84
            $this->setDestinationRoot($destination);
85
86
            if ($this->getLogger()) {
87
                $this->getLogger()->info('Parsing file "' . $file->getRealPath() . '"');
88
            }
89
90
            try {
91
                $xhtml_document = $rst->getAsXhtml();
92
                $converted_contents = $template->decorate($xhtml_document->save(), $this->options);
93
                $rst->logStats(null, $this->getLogger());
94
            } catch (\Exception $e) {
95
                $rst->logStats($e, $this->getLogger());
96
                continue;
97
            }
98
99
            $result[$destination] = $converted_contents;
100
        }
101
102
        return $result;
0 ignored issues
show
Bug Best Practice introduced by
The return type of return $result; (array) is incompatible with the return type declared by the abstract method phpDocumentor\Plugin\Scr...r\BaseConverter::create of type string[]|null.

If you return a value from a function or method, it should be a sub-type of the type that is given by the parent type f.e. an interface, or abstract method. This is more formally defined by the Lizkov substitution principle, and guarantees that classes that depend on the parent type can use any instance of a child type interchangably. This principle also belongs to the SOLID principles for object oriented design.

Let’s take a look at an example:

class Author {
    private $name;

    public function __construct($name) {
        $this->name = $name;
    }

    public function getName() {
        return $this->name;
    }
}

abstract class Post {
    public function getAuthor() {
        return 'Johannes';
    }
}

class BlogPost extends Post {
    public function getAuthor() {
        return new Author('Johannes');
    }
}

class ForumPost extends Post { /* ... */ }

function my_function(Post $post) {
    echo strtoupper($post->getAuthor());
}

Our function my_function expects a Post object, and outputs the author of the post. The base class Post returns a simple string and outputting a simple string will work just fine. However, the child class BlogPost which is a sub-type of Post instead decided to return an object, and is therefore violating the SOLID principles. If a BlogPost were passed to my_function, PHP would not complain, but ultimately fail when executing the strtoupper call in its body.

Loading history...
103
    }
104
105
    /**
106
     * Sets the relative path to the root of the generated contents.
107
     *
108
     * Basically this method takes the depth of the given destination and replaces it with `..` unless the destination
109
     * directory name is `.`.
110
     *
111
     * @param string $destination The destination path relative to the target folder.
112
     *
113
     * @see BaseConverter::$options for where the 'root' variable is set.
114
     */
115
    protected function setDestinationRoot(string $destination): void
116
    {
117
        $this->options['root'] = dirname($destination) !== '.'
118
            ? implode('/', array_fill(0, count(explode('/', dirname($destination))), '..')) . '/'
119
            : './';
120
    }
121
}
122