Completed
Push — master ( eb4259...12744d )
by Thijs
02:22
created

ScssAssetConverter::shouldConvert()   A

Complexity

Conditions 4
Paths 4

Size

Total Lines 15
Code Lines 10

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 9
CRAP Score 4

Importance

Changes 0
Metric Value
dl 0
loc 15
ccs 9
cts 9
cp 1
rs 9.2
c 0
b 0
f 0
cc 4
eloc 10
nc 4
nop 2
crap 4
1
<?php
2
3
namespace lucidtaz\yii2scssphp;
4
5
use Leafo\ScssPhp\Compiler;
6
use lucidtaz\yii2scssphp\storage\FsStorage;
7
use lucidtaz\yii2scssphp\storage\Storage;
8
use RuntimeException;
9
use Yii;
10
use yii\base\Component;
11
use yii\web\AssetConverterInterface;
12
13
class ScssAssetConverter extends Component implements AssetConverterInterface
14
{
15
    /**
16
     * @var Storage
17
     */
18
    public $storage;
19
20
    /**
21
     * @var boolean whether the source asset file should be converted even if
22
     * its result already exists. You may want to set this to be `true` during
23
     * the development stage to make sure the converted assets are always up-to-
24
     * date. Do not set this to true on production servers as it will
25
     * significantly degrade the performance.
26
     */
27
    public $forceConvert = false;
28
29
    private $compiler;
30
31 10
    public function init()
32
    {
33 10
        parent::init();
34 10
        if (!isset($this->storage)) {
35 1
            $this->storage = new FsStorage;
36
        }
37 10
        $this->compiler = Yii::createObject(Compiler::class);
38 10
    }
39
40
    /**
41
     * Converts a given SCSS asset file into a CSS file.
42
     * @param string $asset the asset file path, relative to $basePath
43
     * @param string $basePath the directory the $asset is relative to.
44
     * @return string the converted asset file path, relative to $basePath.
45
     */
46 9
    public function convert($asset, $basePath)
47
    {
48 9
        $extension = $this->getExtension($asset);
49 9
        if ($extension !== 'scss') {
50 2
            return $asset;
51
        }
52 7
        $cssAsset = $this->replaceExtension($asset, 'css');
53
54 7
        $inFile = "$basePath/$asset";
55 7
        $outFile = "$basePath/$cssAsset";
56
57 7
        if (!$this->storage->exists($inFile)) {
58 1
            Yii::error("Input file $inFile not found.", __METHOD__);
59 1
            return $asset;
60
        }
61
62 6
        $this->convertAndSaveIfNeeded($inFile, $outFile);
63
64 6
        return $cssAsset;
65
    }
66
67 9
    private function getExtension(string $filename): string
68
    {
69 9
        return pathinfo($filename, PATHINFO_EXTENSION);
70
    }
71
72 7
    private function replaceExtension(string $filename, string $newExtension): string
73
    {
74 7
        $extensionlessFilename = pathinfo($filename, PATHINFO_FILENAME);
75 7
        return "$extensionlessFilename.$newExtension";
76
    }
77
78 6
    private function convertAndSaveIfNeeded(string $inFile, string $outFile)
79
    {
80 6
        if ($this->shouldConvert($inFile, $outFile)) {
81 5
            $css = $this->compiler->compile($this->storage->get($inFile), $inFile);
82 5
            $this->storage->put($outFile, $css);
83
        }
84 6
    }
85
86 6
    private function shouldConvert(string $inFile, string $outFile): bool
87
    {
88 6
        if (!$this->storage->exists($outFile)) {
89 2
            return true;
90
        }
91 4
        if ($this->forceConvert) {
92 1
            return true;
93
        }
94
        try {
95 3
            return $this->isOlder($outFile, $inFile);
96 1
        } catch (RuntimeException $e) {
97 1
            Yii::warning('Encountered RuntimeException message "' . $e->getMessage() . '", going to convert.', __METHOD__);
98 1
            return true;
99
        }
100
    }
101
102 3
    private function isOlder(string $fileA, string $fileB): bool
103
    {
104 3
        return $this->storage->getMtime($fileA) < $this->storage->getMtime($fileB);
105
    }
106
}
107