Passed
Push — master ( 5615bd...a8f353 )
by Eugene
27s
created

Processor::processFiles()   B

Complexity

Conditions 6
Paths 6

Size

Total Lines 23
Code Lines 17

Duplication

Lines 0
Ratio 0 %

Importance

Changes 3
Bugs 0 Features 0
Metric Value
c 3
b 0
f 0
dl 0
loc 23
rs 8.5906
cc 6
eloc 17
nc 6
nop 1
1
<?php
2
3
namespace EM\CssCompiler\Processor;
4
5
use Composer\IO\IOInterface;
6
use EM\CssCompiler\Container\File;
7
use EM\CssCompiler\Exception\CompilerException;
8
use Leafo\ScssPhp\Compiler as SASSCompiler;
9
use lessc as LESSCompiler;
10
use scss_compass as CompassCompiler;
11
12
class Processor
13
{
14
    const FORMATTER_COMPRESSED = 'compressed';
15
    const FORMATTER_CRUNCHED   = 'crunched';
16
    const FORMATTER_EXPANDED   = 'expanded';
17
    const FORMATTER_NESTED     = 'nested';
18
    const FORMATTER_COMPACT    = 'compact';
19
    const SUPPORTED_FORMATTERS = [
20
        self::FORMATTER_COMPRESSED,
21
        self::FORMATTER_CRUNCHED,
22
        self::FORMATTER_EXPANDED,
23
        self::FORMATTER_NESTED,
24
        self::FORMATTER_COMPACT
25
    ];
26
    /**
27
     * @var IOInterface
28
     */
29
    private $io;
30
    /**
31
     * @var File[]
32
     */
33
    private $files = [];
34
    /**
35
     * @var SASSCompiler
36
     */
37
    private $sass;
38
    /**
39
     * @var LESSCompiler
40
     */
41
    private $less;
42
    /**
43
     * @var CompassCompiler
44
     */
45
    private $compass;
46
47
    public function __construct(IOInterface $io)
48
    {
49
        $this->io = $io;
50
        $this->initCompilers();
51
    }
52
53
    protected function initCompilers()
54
    {
55
        $this->less = new LESSCompiler();
56
        $this->sass = new SASSCompiler();
57
        /** attaches compass functionality to the SASS compiler */
58
        $this->compass = new CompassCompiler($this->sass);
59
    }
60
61
    /**
62
     * @param string $inputPath
63
     * @param string $outputPath
64
     *
65
     * @throws \Exception
66
     */
67
    public function attachFiles($inputPath, $outputPath)
68
    {
69
        if (is_dir($inputPath)) {
70
            $files = scandir($inputPath);
71
            unset($files[0], $files[1]);
72
73
            foreach ($files as $file) {
74
                $absolutePath = "$inputPath/$file";
75
                if (is_file($absolutePath)) {
76
                    $this->files[] = new File($absolutePath, $outputPath);
77
                } else {
78
                    $this->attachFiles($absolutePath, $outputPath);
79
                }
80
            }
81
        } else if (is_file($inputPath)) {
82
            $this->files[] = new File($inputPath, $outputPath);
83
        } else {
84
            throw new \Exception('file doesn\'t exists');
85
        }
86
    }
87
88
    /**
89
     * @return string[]
90
     */
91
    public function concatOutput()
92
    {
93
        $outputMap = [];
94
        foreach ($this->files as $file) {
95
            if (!isset($outputMap[$file->getOutputPath()])) {
96
                $outputMap[$file->getOutputPath()] = $file->getParsedContent();
97
            } else {
98
                $outputMap[$file->getOutputPath()] .= $file->getParsedContent();
99
            }
100
        }
101
102
        return $outputMap;
103
    }
104
105
    /**
106
     * save output into file
107
     */
108
    public function saveOutput()
109
    {
110
        foreach ($this->concatOutput() as $path => $content) {
111
112
            $directory = dirname($path);
113
            if (!is_dir($dir = $directory)) {
114
                $this->io->write("<info>creating directory</info>: {$directory}");
115
                mkdir($directory, 0755, true);
116
            }
117
118
            $this->io->write("<info>save output into</info>: {$path}");
119
            file_put_contents($path, $content);
120
        }
121
    }
122
123
    /**
124
     * @param string $formatter
125
     *
126
     * @throws CompilerException
127
     */
128
    public function processFiles($formatter)
129
    {
130
        foreach ($this->files as $file) {
131
            $this->io->write("<info>processing</info>: {$file->getSourcePath()}");
132
            $file->setSourceContentFromSourcePath();
133
134
            switch ($file->getType()) {
135
                case File::TYPE_COMPASS:
136
                case File::TYPE_SCSS:
137
                case File::TYPE_SASS:
138
                    $this->sass->setFormatter($this->getFormatterClass($formatter));
139
                    $content = $this->sass->compile($file->getSourceContent());
140
                    break;
141
                case File::TYPE_LESS:
142
                    $content = $this->less->compile($file->getSourceContent());
143
                    break;
144
                default:
145
                    throw new CompilerException('unknown compiler');
146
            }
147
148
            $file->setParsedContent($content);
149
        }
150
    }
151
152
    /**
153
     * @param string $formatter
154
     *
155
     * @return string
156
     */
157
    protected function getFormatterClass($formatter)
158
    {
159
        if (!in_array($formatter, static::SUPPORTED_FORMATTERS)) {
160
            throw new \InvalidArgumentException('unknown formatter, available options are: ' . print_r(static::SUPPORTED_FORMATTERS, true));
161
        }
162
163
        return 'Leafo\\ScssPhp\\Formatter\\' . ucfirst($formatter);
164
    }
165
}
166