Passed
Push — master ( abacaa...bf55e7 )
by Eugene
27s
created

Processor::getFiles()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
c 1
b 0
f 0
dl 0
loc 4
rs 10
cc 1
eloc 2
nc 1
nop 0
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
    public function __construct(IOInterface $io)
44
    {
45
        $this->io = $io;
46
        $this->initCompilers();
47
    }
48
49
    protected function initCompilers()
50
    {
51
        $this->less = new LESSCompiler();
52
        $this->sass = new SASSCompiler();
53
        /** attaches compass functionality to the SASS compiler */
54
        new CompassCompiler($this->sass);
55
    }
56
57
    /**
58
     * @param string $inputPath
59
     * @param string $outputPath
60
     *
61
     * @throws \Exception
62
     */
63
    public function attachFiles($inputPath, $outputPath)
64
    {
65
        if (is_dir($inputPath)) {
66
            $files = scandir($inputPath);
67
            unset($files[0], $files[1]);
68
69
            foreach ($files as $file) {
70
                $this->attachFiles("$inputPath/$file", $outputPath);
71
            }
72
        } else if (is_file($inputPath)) {
73
            $this->files[] = new File($inputPath, $outputPath);
74
        } else {
75
            throw new \Exception("file doesn't exists");
76
        }
77
    }
78
79
    /**
80
     * @return File[]
81
     */
82
    public function getFiles()
83
    {
84
        return $this->files;
85
    }
86
87
    /**
88
     * @return string[]
89
     */
90
    protected function concatOutput()
91
    {
92
        $outputMap = [];
93
        foreach ($this->files as $file) {
94
            if (!isset($outputMap[$file->getOutputPath()])) {
95
                $outputMap[$file->getOutputPath()] = '';
96
            }
97
98
            $outputMap[$file->getOutputPath()] .= $file->getParsedContent();
99
        }
100
101
        return $outputMap;
102
    }
103
104
    /**
105
     * save output into file
106
     */
107
    public function saveOutput()
108
    {
109
        foreach ($this->concatOutput() as $path => $content) {
110
            $directory = dirname($path);
111
            if (!is_dir($directory)) {
112
                $this->io->write("<info>creating directory</info>: {$directory}");
113
                mkdir($directory, 0755, true);
114
            }
115
116
            $this->io->write("<info>save output into</info>: {$path}");
117
            file_put_contents($path, $content);
118
        }
119
    }
120
121
    /**
122
     * @param string $formatter
123
     *
124
     * @throws CompilerException
125
     */
126
    public function processFiles($formatter)
127
    {
128
        $this->sass->setFormatter($this->getFormatterClass($formatter));
129
        $this->io->write("<info>use '{$formatter}' formatting</info>");
130
131
        foreach ($this->files as $file) {
132
            $this->io->write("<info>processing</info>: {$file->getSourcePath()}");
133
            $file->setSourceContentFromSourcePath();
134
135
            try {
136
                $this->processFile($file);
137
            } catch (CompilerException $e) {
138
                $this->io->writeError("<error>failed to process: {$file->getSourcePath()}</error>");
139
            }
140
        }
141
    }
142
143
    /**
144
     * @param File $file
145
     *
146
     * @return File
147
     * @throws CompilerException
148
     */
149
    public function processFile(File $file)
150
    {
151
        switch ($file->getType()) {
152
            case File::TYPE_COMPASS:
153
            case File::TYPE_SCSS:
154
            case File::TYPE_SASS:
155
                return $file->setParsedContent($this->sass->compile($file->getSourceContent()));
156
            case File::TYPE_LESS:
157
                return $file->setParsedContent($this->less->compile($file->getSourceContent()));
158
        }
159
160
        throw new CompilerException('unknown compiler');
161
    }
162
163
    /**
164
     * @param string $formatter
165
     *
166
     * @return string
167
     */
168
    protected function getFormatterClass($formatter)
169
    {
170
        if (!in_array($formatter, static::SUPPORTED_FORMATTERS)) {
171
            throw new \InvalidArgumentException('unknown formatter, available options are: ' . print_r(static::SUPPORTED_FORMATTERS, true));
172
        }
173
174
        return 'Leafo\\ScssPhp\\Formatter\\' . ucfirst($formatter);
175
    }
176
}
177