Completed
Push — develop ( 80740b...61b5c3 )
by Mike
10:20
created

Extension::getFilters()   B

Complexity

Conditions 7
Paths 1

Size

Total Lines 55

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 7
nc 1
nop 0
dl 0
loc 55
rs 8.0484
c 0
b 0
f 0

How to fix   Long Method   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

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\Transformer\Writer\Twig;
17
18
use Parsedown;
19
use phpDocumentor\Descriptor\Collection;
20
use phpDocumentor\Descriptor\ProjectDescriptor;
21
use phpDocumentor\Transformer\Writer\Twig\ExtensionInterface;
22
use phpDocumentor\Transformer\Router\Queue;
23
use phpDocumentor\Transformer\Router\Renderer;
24
use phpDocumentor\Transformer\Transformation;
25
use Twig_Extension;
26
use Twig_Extension_GlobalsInterface;
27
use Twig_SimpleFilter;
28
use Twig_SimpleFunction;
29
30
/**
31
 * Basic extension adding phpDocumentor specific functionality for Twig
32
 * templates.
33
 *
34
 * Global variables:
35
 *
36
 * - *ast_node*, the current $data element
37
 *
38
 * Functions:
39
 *
40
 * - *path(string) *, converts the given relative path to be based of the projects
41
 *   root instead of the current directory
42
 *
43
 * Filters:
44
 *
45
 * - *markdown*, converts the associated text from Markdown formatting to HTML.
46
 * - *trans*, translates the given string
47
 * - *route*, attempts to generate a URL for a given Descriptor
48
 * - *sort_desc*, sorts the given objects by their Name property/getter in a descending fashion
49
 * - *sort_asc*, sorts the given objects by their Name property/getter in a ascending fashion
50
 */
51
class Extension extends Twig_Extension implements ExtensionInterface, Twig_Extension_GlobalsInterface
52
{
53
    /**
54
     * @var ProjectDescriptor
55
     */
56
    protected $data;
57
58
    /** @var Renderer */
59
    protected $routeRenderer;
60
61
    /**
62
     * Registers the structure and transformation with this extension.
63
     *
64
     * @param ProjectDescriptor $project        Represents the complete Abstract Syntax Tree.
65
     * @param Transformation    $transformation Represents the transformation meta data used in the current generation
66
     *     cycle.
67
     */
68
    public function __construct(ProjectDescriptor $project, Transformation $transformation)
69
    {
70
        $this->data = $project;
71
        $this->routeRenderer = new Renderer(new Queue());
72
    }
73
74
    /**
75
     * Sets the router used to render the URL where a Descriptor can be found.
76
     */
77
    public function setRouters(Queue $routers): void
78
    {
79
        $this->routeRenderer->setRouters($routers);
80
    }
81
82
    /**
83
     * Sets the destination directory relative to the Project's Root.
84
     *
85
     * The destination is the target directory containing the resulting
86
     * file. This destination is relative to the Project's root and can
87
     * be used for the calculation of nesting depths, etc.
88
     *
89
     * @see Writer\Twig for the invocation of this method.
90
     */
91
    public function setDestination(string $destination): void
92
    {
93
        $this->routeRenderer->setDestination($destination);
94
    }
95
96
    /**
97
     * Returns the target directory relative to the Project's Root.
98
     */
99
    public function getDestination(): string
100
    {
101
        return $this->routeRenderer->getDestination();
102
    }
103
104
    /**
105
     * Returns an array of global variables to inject into a Twig template.
106
     *
107
     * @return mixed[]
108
     */
109
    public function getGlobals(): array
110
    {
111
        return [
112
            'project' => $this->data,
113
        ];
114
    }
115
116
    /**
117
     * Returns a listing of all functions that this extension adds.
118
     *
119
     * This method is automatically used by Twig upon registering this
120
     * extension (which is done automatically by phpDocumentor) to determine
121
     * an additional list of functions.
122
     *
123
     * See the Class' DocBlock for a listing of functionality added by this
124
     * Extension.
125
     *
126
     * @return Twig_SimpleFunction[]
127
     */
128
    public function getFunctions(): array
129
    {
130
        return [
131
            new Twig_SimpleFunction('path', [$this->routeRenderer, 'convertToRootPath']),
132
        ];
133
    }
134
135
    /**
136
     * Returns a list of all filters that are exposed by this extension.
137
     *
138
     * @return Twig_SimpleFilter[]
139
     */
140
    public function getFilters(): array
141
    {
142
        $parser = Parsedown::instance();
143
        $routeRenderer = $this->routeRenderer;
144
145
        return [
146
            'markdown' => new Twig_SimpleFilter(
147
                'markdown',
148
                function ($value) use ($parser) {
149
                    return $parser->text($value);
150
                }
151
            ),
152
            'trans' => new Twig_SimpleFilter(
153
                'trans',
154
                function ($value) {
155
                    return $value;
156
                }
157
            ),
158
            'route' => new Twig_SimpleFilter(
159
                'route',
160
                function ($value, $presentation = 'normal') use ($routeRenderer) {
161
                    return $routeRenderer->render($value, $presentation);
162
                }
163
            ),
164
            'sort' => new Twig_SimpleFilter(
165
                'sort_*',
166
                function ($direction, $collection) {
167
                    if (!$collection instanceof Collection) {
168
                        return $collection;
169
                    }
170
171
                    $iterator = $collection->getIterator();
172
                    $iterator->uasort(
173
                        function ($a, $b) use ($direction) {
174
                            $aElem = strtolower($a->getName());
175
                            $bElem = strtolower($b->getName());
176
                            if ($aElem === $bElem) {
177
                                return 0;
178
                            }
179
180
                            if (($direction === 'asc' && $aElem > $bElem) ||
181
                                ($direction === 'desc' && $aElem < $bElem)
182
                            ) {
183
                                return 1;
184
                            }
185
186
                            return -1;
187
                        }
188
                    );
189
190
                    return $iterator;
191
                }
192
            ),
193
        ];
194
    }
195
196
    /**
197
     * Converts the given path to be relative to the root of the documentation
198
     * target directory.
199
     *
200
     * It is not possible to use absolute paths in documentation templates since
201
     * they may be used locally, or in a subfolder. As such we need to calculate
202
     * the number of levels to go up from the current document's directory and
203
     * then append the given path.
204
     *
205
     * For example:
206
     *
207
     *     Suppose you are in <root>/classes/my/class.html and you want open
208
     *     <root>/my/index.html then you provide 'my/index.html' to this method
209
     *     and it will convert it into ../../my/index.html (<root>/classes/my is
210
     *     two nesting levels until the root).
211
     *
212
     * This method does not try to normalize or optimize the paths in order to
213
     * save on development time and performance, and because it adds no real
214
     * value.
215
     */
216
    public function convertToRootPath(string $relative_path): string
217
    {
218
        return $this->routeRenderer->convertToRootPath($relative_path);
219
    }
220
}
221