Test Failed
Push — develop ( 387e5c...98afd0 )
by Brent
04:42
created

TemplatePlugin::file()   A

Complexity

Conditions 3
Paths 3

Size

Total Lines 22
Code Lines 13

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 3
eloc 13
nc 3
nop 1
dl 0
loc 22
rs 9.2
c 0
b 0
f 0
1
<?php
2
3
namespace Brendt\Stitcher\Template;
4
5
use Brendt\Image\ResponsiveFactory;
6
use Brendt\Stitcher\Config;
7
use Brendt\Stitcher\Factory\ParserFactory;
8
use CSSmin;
9
use JSMin;
10
use Symfony\Component\Filesystem\Filesystem;
11
use Symfony\Component\Finder\Finder;
12
use Symfony\Component\Finder\SplFileInfo;
13
14
/**
15
 * This class provides functionality which can be used by template plugins/functions.
16
 */
17
class TemplatePlugin
18
{
19
20
    /**
21
     * @var string
22
     */
23
    private $publicDir;
24
25
    /**
26
     * @var string
27
     */
28
    private $srcDir;
29
30
    /**
31
     * @var ParserFactory
32
     */
33
    private $parserFactory;
34
35
    /**
36
     * @var ResponsiveFactory
37
     */
38
    private $responsiveFactory;
39
40
    /**
41
     * @var CSSmin
42
     */
43
    private $cssMinifier;
44
45
    /**
46
     * @var array
47
     */
48
    private $meta;
49
50
    /**
51
     * @var bool
52
     */
53
    private $minify;
54
55
    public function __construct(
56
        ParserFactory $parserFactory,
57
        ResponsiveFactory $responsiveFactory,
58
        CSSmin $cssMinifier,
59
        string $publicDir,
60
        string $srcDir,
61
        $minify,
62
        $meta
63
    ) {
64
        $this->parserFactory = $parserFactory;
65
        $this->responsiveFactory = $responsiveFactory;
66
        $this->cssMinifier = $cssMinifier;
67
        $this->publicDir = $publicDir;
68
        $this->srcDir = $srcDir;
69
        $this->minify = $minify;
70
71
        // TODO: meta will break because of flattened config
72
        $this->meta = is_array($meta) ? $meta : [$meta];
73
    }
74
75
    /**
76
     * This function will read meta configuration from `meta` and output the corresponding meta tags.
77
     *
78
     * @return string
79
     */
80
    public function meta() {
81
        $result = [];
82
83
        foreach ($this->meta as $name => $content) {
84
            if (!is_string($content)) {
85
                continue;
86
            }
87
88
            $result[] = "<meta name=\"{$name}\" content=\"{$content}\">";
89
        }
90
91
        return implode("\n", $result);
92
    }
93
94
    /**
95
     * This function will take a source path and an optional inline parameter.
96
     * The CSS file will be copied from the source path to the public directory.
97
     * If the `minify` option is set to true in config.yml, the output will be minified.
98
     *
99
     * If the inline parameter is set, the output won't be copied to a public file,
100
     * but instead be outputted to an HTML string which can be included in a template.
101
     *
102
     * Files with the .scss and .sass extensions will be compiled to normal CSS files.
103
     *
104
     * @param string $src
105
     * @param bool   $inline
106
     *
107
     * @return string
108
     */
109
    public function css($src, $inline = false) {
110
        $parser = $this->parserFactory->getByFileName($src);
111
        $data = $parser->parse($src);
112
113
        if ($this->minify) {
114
            $data = $this->cssMinifier->run($data);
115
        }
116
117
        if ($inline) {
118
            return "<style>{$data}</style>";
119
        }
120
121
        $srcParsed = preg_replace('/\.scss|\.sass/', '.css', $src);
122
        $fs = new Filesystem();
123
        $dst = "{$this->publicDir}/$srcParsed";
124
125
        if ($fs->exists($dst)) {
126
            $fs->remove($dst);
127
        }
128
129
        $fs->dumpFile($dst, $data);
130
131
        return "<link rel=\"stylesheet\" type=\"text/css\" href=\"{$srcParsed}\">";
132
    }
133
134
    /**
135
     * This function will take a source path and an optional inline parameter.
136
     * The JS file will be copied from the source path to the public directory.
137
     * If the `minify` option is set to true in config.yml, the output will be minified.
138
     *
139
     * If the inline parameter is set, the output won't be copied to a public file,
140
     * but instead be outputted to an HTML string which can be included in a template.
141
     *
142
     * @param string $src
143
     * @param bool   $inline
144
     * @param bool   $async
145
     *
146
     * @return string
147
     */
148
    public function js($src, $inline = false, $async = false) {
149
        $parser = $this->parserFactory->getByFileName($src);
150
        $data = $parser->parse($src);
151
152
        if ($this->minify) {
153
            $data = JSMin::minify($data);
154
        }
155
156
        if ($inline) {
157
            return "<script>{$data}</script>";
158
        }
159
160
        $fs = new Filesystem();
161
        $dst = "{$this->publicDir}/$src";
162
163
        if ($fs->exists($dst)) {
164
            $fs->remove($dst);
165
        }
166
167
        $fs->dumpFile($dst, $data);
168
        $result = "<script src=\"{$src}\"";
169
170
        if ($async) {
171
            $result .= ' async';
172
        }
173
174
        $result .= "></script>";
175
176
        return $result;
177
    }
178
179
    /**
180
     * Create a responsive image using brendt\responsive-images.
181
     *
182
     * @param $src
183
     *
184
     * @return array
185
     *
186
     * @see \Brendt\Image\ResponsiveFactory
187
     */
188
    public function image($src) {
189
        $image = $this->responsiveFactory->create($src);
190
191
        if (!$image) {
192
            return ['src' => null, 'srcset' => null, 'sizes' => null];
193
        }
194
195
        return [
196
            'src'    => $image->src(),
197
            'srcset' => $image->srcset(),
198
            'sizes'  => $image->sizes(),
199
        ];
200
    }
201
202
    /**
203
     * Create a public file from the src directory and return its path.
204
     *
205
     * @param $src
206
     *
207
     * @return null|string
208
     */
209
    public function file($src) {
210
        $src = trim($src, '/');
211
        $files = Finder::create()->in($this->srcDir)->path($src)->getIterator();
212
        $files->rewind();
213
        /** @var SplFileInfo $file */
214
        $file = $files->current();
215
216
        if (!$file) {
217
            return null;
218
        }
219
220
        $fs = new Filesystem();
221
        $dst = "{$this->publicDir}/{$src}";
222
223
        if ($fs->exists($dst)) {
224
            $fs->remove($dst);
225
        }
226
227
        $fs->dumpFile($dst, $file->getContents());
228
229
        return "/{$src}";
230
    }
231
232
}
233