Completed
Push — master ( 14a89c...6d8b44 )
by Vladimir
11s
created

SassEngine::stringToFormatter()   A

Complexity

Conditions 4
Paths 4

Size

Total Lines 17

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 8
CRAP Score 4

Importance

Changes 0
Metric Value
dl 0
loc 17
ccs 8
cts 8
cp 1
rs 9.7
c 0
b 0
f 0
cc 4
nc 4
nop 1
crap 4
1
<?php
2
3
/**
4
 * @copyright 2018 Vladimir Jimenez
5
 * @license   https://github.com/stakx-io/stakx/blob/master/LICENSE.md MIT
6
 */
7
8
namespace allejo\stakx\AssetEngine\Sass;
9
10
use __;
11
use allejo\stakx\AssetEngine\AssetEngineInterface;
12
use allejo\stakx\Configuration;
13
use allejo\stakx\Document\BasePageView;
14
use allejo\stakx\Document\StaticPageView;
15
use allejo\stakx\Filesystem\FilesystemLoader as fs;
16
use allejo\stakx\Manager\PageManager;
17
use allejo\stakx\Service;
18
use Leafo\ScssPhp\Compiler;
19
use Leafo\ScssPhp\Formatter\Compact;
20
use Leafo\ScssPhp\Formatter\Crunched;
21
use Leafo\ScssPhp\Formatter\Expanded;
22
use Leafo\ScssPhp\Formatter\Nested;
23
24
class SassEngine implements AssetEngineInterface
25
{
26
    private $fileSourceMap = false;
27
    private $configuration;
28
    /** @var PageManager */
29
    private $pageManager;
30
    private $compiler;
31
    private $options = [];
32
33 7
    public function __construct(Configuration $configuration)
34
    {
35 7
        $this->configuration = $configuration;
36 7
        $this->compiler = new Compiler();
37 7
    }
38
39 7
    public function getConfigurationNamespace()
40
    {
41 7
        return 'scss';
42
    }
43
44 7
    public function getDefaultConfiguration()
45
    {
46
        return [
47 7
            'style' => 'compressed',
48 7
            'sourcemap' => false,
49 7
        ];
50
    }
51
52 7
    public function getFolder()
53
    {
54 7
        return '_sass';
55
    }
56
57 7
    public function getExtensions()
58
    {
59 7
        return ['scss'];
60
    }
61
62
    /**
63
     * @param string $content
64
     * @param $options = [
65
     *     'pageview' => new StaticPageView()
66
     * ]
67
     *
68
     * @return string
69
     */
70 7
    public function parse($content, array $options = [])
71
    {
72
        $sourceMapOptions = [
73 7
            'sourceMapBasepath' => Service::getWorkingDirectory(),
74 7
        ];
75
76 7
        $this->handleThemeImports($content);
77
78
        // We don't need to write the source map to a file
79 7
        if (!$this->fileSourceMap)
80 7
        {
81 6
            $this->compiler->setSourceMapOptions($sourceMapOptions);
82
83 6
            return $this->compiler->compile($content);
84
        }
85
86
        /** @var StaticPageView $pageView */
87 1
        $pageView = $options['pageview'];
88
89
        // Always put our source map next to the respective CSS file
90 1
        $sourceMapTargetPath = $this->getSourceMapTargetFile($pageView);
91 1
        $sourceMapFilename = fs::getFilename($sourceMapTargetPath);
92
93 1
        $sourceMapOptions = array_merge($sourceMapOptions, [
94 1
            'sourceMapFilename' => $sourceMapFilename,
95 1
            'sourceMapURL' => $pageView->getPermalink() . '.map',
96 1
            'sourceMapWriteTo' => $sourceMapTargetPath,
97 1
        ]);
98
99 1
        $sourceMapGenerator = new SourceMapGenerator($sourceMapOptions);
100 1
        $this->compiler->setSourceMap($sourceMapGenerator);
0 ignored issues
show
Documentation introduced by
$sourceMapGenerator is of type object<allejo\stakx\Asse...ass\SourceMapGenerator>, but the function expects a integer.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
101
102 1
        $sass = $this->compiler->compile($content);
103
104 1
        $sourceMapPageView = BasePageView::createVirtual([
105 1
            'permalink' => $pageView->getPermalink() . '.map',
106 1
        ], $sourceMapGenerator->getSourceMapContents());
107
108 1
        $this->pageManager->trackNewPageView($sourceMapPageView);
109
110 1
        return $sass;
111
    }
112
113 7
    public function setOptions(array $options)
114
    {
115 7
        $this->options = $options;
116
117 7
        $this->configureImportPath();
118 7
        $this->configureOutputStyle();
119 7
        $this->configureSourceMap();
120 7
    }
121
122 1
    public function setPageManager(PageManager $pageManager)
123
    {
124 1
        $this->pageManager = $pageManager;
125 1
    }
126
127 7
    private function configureImportPath()
128
    {
129 7
        $this->compiler->setImportPaths(Service::getWorkingDirectory() . '/_sass/');
130 7
    }
131
132 7
    private function configureOutputStyle()
133
    {
134 7
        $style = __::get($this->options, 'style', 'compressed');
135
136 7
        $this->compiler->setFormatter(self::stringToFormatter($style));
137 7
    }
138
139 7
    private function configureSourceMap()
140
    {
141 7
        $sourceMap = __::get($this->options, 'sourcemap');
142
143 7
        if ($sourceMap === 'inline')
144 7
        {
145 1
            $this->compiler->setSourceMap(Compiler::SOURCE_MAP_INLINE);
146 1
        }
147 6
        elseif ($sourceMap === true)
148
        {
149 1
            $this->compiler->setSourceMap(Compiler::SOURCE_MAP_FILE);
150 1
            $this->fileSourceMap = true;
151 1
        }
152
        else
153
        {
154 5
            $this->compiler->setSourceMap(Compiler::SOURCE_MAP_NONE);
155
        }
156 7
    }
157
158 1
    private function getSourceMapTargetFile(StaticPageView $pageView)
159
    {
160 1
        return fs::absolutePath(
161 1
            $this->configuration->getTargetFolder(),
0 ignored issues
show
Documentation introduced by
$this->configuration->getTargetFolder() is of type string, but the function expects a object<string>.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
162 1
            $pageView->getTargetFile() . '.map'
0 ignored issues
show
Unused Code introduced by
The call to FilesystemLoader::absolutePath() has too many arguments starting with $pageView->getTargetFile() . '.map'.

This check compares calls to functions or methods with their respective definitions. If the call has more arguments than are defined, it raises an issue.

If a function is defined several times with a different number of parameters, the check may pick up the wrong definition and report false positives. One codebase where this has been known to happen is Wordpress.

In this case you can add the @ignore PhpDoc annotation to the duplicate definition and it will be ignored.

Loading history...
163 1
        );
164
    }
165
166 7
    private function handleThemeImports(&$content)
167
    {
168 7
        if (($themeName = $this->configuration->getTheme()))
169 7
        {
170
            $themePath = "../_themes/${themeName}/_sass";
171
            $content = preg_replace("/(@import ['\"])(@theme)(.+)/", "$1${themePath}$3", $content);
172
        }
173 7
    }
174
175
    public static function stringToFormatter($format)
0 ignored issues
show
Documentation introduced by
The return type could not be reliably inferred; please add a @return annotation.

Our type inference engine in quite powerful, but sometimes the code does not provide enough clues to go by. In these cases we request you to add a @return annotation as described here.

Loading history...
176
    {
177 7
        if ($format == 'nested')
178 7
        {
179 1
            return Nested::class;
180
        }
181 6
        elseif ($format == 'expanded')
182
        {
183 1
            return Expanded::class;
184
        }
185 5
        elseif ($format == 'compact')
186
        {
187 1
            return Compact::class;
188
        }
189
190 4
        return Crunched::class;
191
    }
192
}
193