Passed
Push — develop ( 3e8c8e...6a4b14 )
by Brent
02:58
created

TemplatePlugin::css()   B

Complexity

Conditions 4
Paths 6

Size

Total Lines 24
Code Lines 14

Duplication

Lines 0
Ratio 0 %

Importance

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