Completed
Push — master ( 83f315...077de2 )
by Demonchaux
02:12
created

Render::setTemplatePath()   B

Complexity

Conditions 5
Paths 6

Size

Total Lines 23
Code Lines 12

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 30

Importance

Changes 3
Bugs 1 Features 1
Metric Value
c 3
b 1
f 1
dl 0
loc 23
ccs 0
cts 16
cp 0
rs 8.5907
cc 5
eloc 12
nc 6
nop 1
crap 30
1
<?php
2
3
/**
4
 * This file is part of the Clover to Html package.
5
 *
6
 * (c) Stéphane Demonchaux <[email protected]>
7
 *
8
 * For the full copyright and license information, please view the LICENSE
9
 * file that was distributed with this source code.
10
 */
11
namespace CloverToHtml;
12
13
class Render
14
{
15
    /**
16
     * @var \Twig_Environment
17
     */
18
    private $twig;
19
20
    /**
21
     * Construct.
22
     *
23
     * @param \Twig_Environment $twig
24
     */
25 4
    public function __construct(\Twig_Environment $twig)
26
    {
27 4
        $this->twig = $twig;
28 4
    }
29
30
    /**
31
     * @param Root   $root
32
     * @param string $target
33
     * @param string $templatePath
34
     */
35
    public function render(Root $root, $target, $templatePath = false)
36
    {
37
        $templatePath = $this->setTemplatePath($templatePath);
38
39
        foreach ($root->getFileCollection() as $file) {
40
            $this->renderFile($file, $target, $root->getBasePath());
41
        }
42
43
        foreach ($root->getDirectoryCollection() as $directory) {
44
            $this->renderDirectory($directory, $root, $target);
45
            foreach ($directory->getFileCollection() as $file) {
46
                $this->renderFile($file, $target, $root->getBasePath());
47
            }
48
        }
49
50
        $this->copyAssets($templatePath, $target);
51
    }
52
53
    /**
54
     * @param string|false $templatePath
55
     *
56
     * @throws \InvalidArgumentException
57
     *
58
     * @return string
59
     */
60
    private function setTemplatePath($templatePath = false)
61
    {
62
        if ($templatePath === false) {
63
            $templatePath = __DIR__.'/Template/';
64
        }
65
66
        if (($this->twig->getLoader() instanceof \Twig_Loader_Filesystem) === false) {
67
            throw new \InvalidArgumentException(
68
                sprintf('Twig loader "%s" not supported', get_class($this->twig->getLoader()))
69
            );
70
        }
71
72
        $this->twig->getLoader()->setPaths($templatePath);
73
74
        if ($this->hasConfig($templatePath, 'extension') === true) {
75
            $config = $this->loadConfig($templatePath);
76
            foreach ($config['extension'] as $extensionName => $extension) {
77
                $this->twig->addGlobal($extensionName, new $extension);
78
            }
79
        }
80
81
        return $templatePath;
82
    }
83
84
    /**
85
     * @param string $templatePath
86
     * @return string
87
     */
88
    private function getConfigPath($templatePath)
89
    {
90
        return $templatePath.'/config.json';
91
    }
92
93
    /**
94
     * @param string $templatePath
95
     * @return boolean
96
     */
97
    private function hasConfig($templatePath, $key = null)
98
    {
99
        if (is_file($this->getConfigPath($templatePath)) === false) {
100
            return false;
101
        }
102
103
        if ($key === null) {
104
            return true;
105
        }
106
107
        $config = $this->loadConfig($templatePath);
108
109
        if (isset($config[$key])) {
110
            return true;
111
        }
112
113
        return false;
114
    }
115
116
    /**
117
     * @param string $templatePath
118
     * @return array
119
     */
120
    private function loadConfig($templatePath)
121
    {
122
        return json_decode(file_get_contents($this->getConfigPath($templatePath)), true);
123
    }
124
125
    /**
126
     * @param string $templatePath
127
     * @param string $target
128
     */
129
    private function copyAssets($templatePath, $target)
130
    {
131
        if ($this->hasConfig($templatePath, 'files') === true) {
132
            $config = $this->loadConfig($templatePath);
133
134
            foreach ($config['files'] as $file) {
135
                $this->createDirIfNotExist($target.'/'.$file);
136
                copy($templatePath.$file, $target.'/'.$file);
137
            }
138
        }
139
    }
140
141
    /**
142
     * @param string $path
143
     */
144
    private function createDirIfNotExist($path)
145
    {
146
        if (is_dir(dirname($path)) === false) {
147
            mkdir(dirname($path), 0777, true);
148
        }
149
    }
150
151
    /**
152
     * @param File   $file
153
     * @param string $target
154
     * @param string $basePath
155
     */
156
    private function renderFile(File $file, $target, $basePath)
157
    {
158
        $path = $target.'/'.$file->getDestination($basePath);
159
160
        $this->createDirIfNotExist($path);
161
162
        file_put_contents(
163
            $path,
164
            $this->twig->render(
165
                'file.twig',
166
                array(
167
                    'file' => $file,
168
                    'assets' => $this->assetsPath($target, $path),
169
                )
170
            )
171
         );
172
    }
173
174
    /**
175
     * @param string $base
176
     * @param string $actual
177
     *
178
     * @return string
179
     */
180
    private function assetsPath($base, $actual)
181
    {
182
        return str_repeat('../', (substr_count($actual, '/') - substr_count($base, '/')) - 1);
183
    }
184
185
    /**
186
     * @param Directory $directory
187
     * @param string    $target
188
     * @param string    $basePath
189
     */
190
    private function renderDirectory(Directory $directory, Root $root, $target)
191
    {
192
        $path = $target.'/'.$directory->getDestination();
193
194
        $this->createDirIfNotExist($path);
195
196
        file_put_contents(
197
            $path,
198
            $this->twig->render(
199
                'directory.twig',
200
                array(
201
                    'directory' => $directory,
202
                    'directoryCollection' => $root->getAllDirIn($directory),
203
                    'assets' => $this->assetsPath($target, $path),
204
                )
205
            )
206
        );
207
    }
208
}
209