Twig   A
last analyzed

Complexity

Total Complexity 6

Size/Duplication

Total Lines 57
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 6

Test Coverage

Coverage 0%

Importance

Changes 0
Metric Value
dl 0
loc 57
ccs 0
cts 29
cp 0
rs 10
c 0
b 0
f 0
wmc 6
lcom 1
cbo 6

3 Methods

Rating   Name   Duplication   Size   Complexity  
A getTemplatePath() 0 6 1
A __construct() 0 5 1
A transform() 0 24 4
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;
17
18
use InvalidArgumentException;
19
use phpDocumentor\Descriptor\DescriptorAbstract;
20
use phpDocumentor\Descriptor\ProjectDescriptor;
21
use phpDocumentor\Transformer\Router\ForFileProxy;
22
use phpDocumentor\Transformer\Router\Queue;
23
use phpDocumentor\Transformer\Transformation;
24
use phpDocumentor\Transformer\Writer\Twig\EnvironmentFactory;
25
use UnexpectedValueException;
26
27
/**
28
 * A specialized writer which uses the Twig templating engine to convert
29
 * templates to HTML output.
30
 *
31
 * This writer support the Query attribute of a Transformation to generate
32
 * multiple templates in one transformation.
33
 *
34
 * The Query attribute supports a simplified version of Twig queries and will
35
 * use each individual result as the 'node' global variable in the Twig template.
36
 *
37
 * Example:
38
 *
39
 *   Suppose a Query `indexes.classes` is given then this writer will be
40
 *   invoked as many times as there are classes in the project and the
41
 *   'node' global variable in twig will be filled with each individual
42
 *   class entry.
43
 *
44
 * When using the Query attribute in the transformation it is important to
45
 * use a variable in the Artifact attribute as well (otherwise the same file
46
 * would be overwritten several times).
47
 *
48
 * A simple example transformation line could be:
49
 *
50
 *     ```
51
 *     <transformation
52
 *         writer="twig"
53
 *         source="templates/twig/index.twig"
54
 *         artifact="index.html"/>
55
 *     ```
56
 *
57
 *     This example transformation would use this writer to transform the
58
 *     index.twig template file in the twig template folder into index.html at
59
 *     the destination location.
60
 *     Since no Query is provided the 'node' global variable will contain
61
 *     the Project Descriptor of the Object Graph.
62
 *
63
 * A complex example transformation line could be:
64
 *
65
 *     ```
66
 *     <transformation
67
 *         query="indexes.classes"
68
 *         writer="twig"
69
 *         source="templates/twig/class.twig"
70
 *         artifact="{{name}}.html"/>
71
 *     ```
72
 *
73
 *     This example transformation would use this writer to transform the
74
 *     class.twig template file in the twig template folder into a file with
75
 *     the 'name' property for an individual class inside the Object Graph.
76
 *     Since a Query *is* provided will the 'node' global variable contain a
77
 *     specific instance of a class applicable to the current iteration.
78
 *
79
 * @see self::getDestinationPath() for more information about variables in the
80
 *     Artifact attribute.
81
 */
82
final class Twig extends WriterAbstract
83
{
84
    private $environmentFactory;
85
    private $routers;
86
87
    public function __construct(EnvironmentFactory $environmentFactory, Queue $routers)
88
    {
89
        $this->environmentFactory = $environmentFactory;
90
        $this->routers = $routers;
91
    }
92
93
    /**
94
     * This method combines the ProjectDescriptor and the given target template
95
     * and creates a static html page at the artifact location.
96
     *
97
     * @param ProjectDescriptor $project Document containing the structure.
98
     * @param Transformation $transformation Transformation to execute.
99
     *
100
     * @throws \Twig\Error\LoaderError
101
     * @throws \Twig\Error\RuntimeError
102
     * @throws \Twig\Error\SyntaxError
103
     */
104
    public function transform(ProjectDescriptor $project, Transformation $transformation): void
105
    {
106
        $template_path = $this->getTemplatePath($transformation);
107
108
        $finder = new Pathfinder();
109
        $nodes = $finder->find($project, $transformation->getQuery());
110
111
        foreach ($nodes as $node) {
112
            if (!$node) {
113
                continue;
114
            }
115
116
            $destination = $this->routers->destination($node, $transformation);
117
            if ($destination === null) {
118
                continue;
119
            }
120
121
            $environment = $this->environmentFactory->create($project, $transformation, $destination);
122
            $environment->addGlobal('node', $node);
123
124
            $html = $environment->render(substr($transformation->getSource(), strlen($template_path)));
125
            file_put_contents($destination, $html);
126
        }
127
    }
128
129
    /**
130
     * Returns the path belonging to the template.
131
     */
132
    private function getTemplatePath(Transformation $transformation): string
133
    {
134
        $parts = preg_split('[\\\\|/]', $transformation->getSource());
135
136
        return $parts[0] . DIRECTORY_SEPARATOR . $parts[1];
137
    }
138
}
139