Passed
Push — master ( d28afb...917474 )
by Brent
02:33
created

TemplatePlugin::image()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 13
Code Lines 8

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 2
eloc 8
nc 2
nop 1
dl 0
loc 13
rs 9.4285
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
        $this->meta = is_array($meta) ? $meta : [$meta];
72
    }
73
74
    /**
75
     * This function will read meta configuration from `meta` and output the corresponding meta tags.
76
     *
77
     * @return string
78
     */
79
    public function meta() {
80
        $result = [];
81
82
        foreach ($this->meta as $name => $content) {
83
            if (!is_string($content)) {
84
                continue;
85
            }
86
87
            $result[] = "<meta name=\"{$name}\" content=\"{$content}\">";
88
        }
89
90
        return implode("\n", $result);
91
    }
92
93
    /**
94
     * This function will take a source path and an optional inline parameter.
95
     * The CSS file will be copied from the source path to the public directory.
96
     * If the `minify` option is set to true in config.yml, the output will be minified.
97
     *
98
     * If the inline parameter is set, the output won't be copied to a public file,
99
     * but instead be outputted to an HTML string which can be included in a template.
100
     *
101
     * Files with the .scss and .sass extensions will be compiled to normal CSS files.
102
     *
103
     * @param string $src
104
     * @param bool   $inline
105
     *
106
     * @return string
107
     */
108
    public function css($src, $inline = false) {
109
        $parser = $this->parserFactory->getByFileName($src);
110
        $data = $parser->parse($src);
111
112
        if ($this->minify) {
113
            $data = $this->cssMinifier->run($data);
114
        }
115
116
        if ($inline) {
117
            return "<style>{$data}</style>";
118
        }
119
120
        $srcParsed = preg_replace('/\.scss|\.sass/', '.css', $src);
121
        $fs = new Filesystem();
122
        $dst = "{$this->publicDir}/$srcParsed";
123
124
        if ($fs->exists($dst)) {
125
            $fs->remove($dst);
126
        }
127
128
        $fs->dumpFile($dst, $data);
129
130
        return "<link rel=\"stylesheet\" type=\"text/css\" href=\"{$srcParsed}\">";
131
    }
132
133
    /**
134
     * This function will take a source path and an optional inline parameter.
135
     * The JS file will be copied from the source path to the public directory.
136
     * If the `minify` option is set to true in config.yml, the output will be minified.
137
     *
138
     * If the inline parameter is set, the output won't be copied to a public file,
139
     * but instead be outputted to an HTML string which can be included in a template.
140
     *
141
     * @param string $src
142
     * @param bool   $inline
143
     * @param bool   $async
144
     *
145
     * @return string
146
     */
147
    public function js($src, $inline = false, $async = false) {
148
        $parser = $this->parserFactory->getByFileName($src);
149
        $data = $parser->parse($src);
150
151
        if ($this->minify) {
152
            $data = JSMin::minify($data);
153
        }
154
155
        if ($inline) {
156
            return "<script>{$data}</script>";
157
        }
158
159
        $fs = new Filesystem();
160
        $dst = "{$this->publicDir}/$src";
161
162
        if ($fs->exists($dst)) {
163
            $fs->remove($dst);
164
        }
165
166
        $fs->dumpFile($dst, $data);
167
        $result = "<script src=\"{$src}\"";
168
169
        if ($async) {
170
            $result .= ' async';
171
        }
172
173
        $result .= "></script>";
174
175
        return $result;
176
    }
177
178
    /**
179
     * Create a responsive image using brendt\responsive-images.
180
     *
181
     * @param $src
182
     *
183
     * @return array
184
     *
185
     * @see \Brendt\Image\ResponsiveFactory
186
     */
187
    public function image($src) {
188
        $image = $this->responsiveFactory->create($src);
189
190
        if (!$image) {
191
            return ['src' => null, 'srcset' => null, 'sizes' => null];
192
        }
193
194
        return [
195
            'src'    => $image->src(),
196
            'srcset' => $image->srcset(),
197
            'sizes'  => $image->sizes(),
198
        ];
199
    }
200
201
    /**
202
     * Create a public file from the src directory and return its path.
203
     *
204
     * @param $src
205
     *
206
     * @return null|string
207
     */
208
    public function file($src) {
209
        $src = trim($src, '/');
210
        $files = Finder::create()->in($this->srcDir)->path($src)->getIterator();
211
        $files->rewind();
212
        /** @var SplFileInfo $file */
213
        $file = $files->current();
214
215
        if (!$file) {
216
            return null;
217
        }
218
219
        $fs = new Filesystem();
220
        $dst = "{$this->publicDir}/{$src}";
221
222
        if ($fs->exists($dst)) {
223
            $fs->remove($dst);
224
        }
225
226
        $fs->dumpFile($dst, $file->getContents());
227
228
        return "/{$src}";
229
    }
230
231
}
232