1<?php
2
3/*
4 * This file is part of the Assetic package, an OpenSky project.
5 *
6 * (c) 2010-2014 OpenSky Project Inc
7 *
8 * For the full copyright and license information, please view the LICENSE
9 * file that was distributed with this source code.
10 */
11
12namespace Assetic\Filter\Sass;
13
14use Assetic\Asset\AssetInterface;
15use Assetic\Exception\FilterException;
16use Assetic\Util\FilesystemUtils;
17
18/**
19 * Loads SASS files.
20 *
21 * @link http://sass-lang.com/
22 * @author Kris Wallsmith <kris.wallsmith@gmail.com>
23 */
24class SassFilter extends BaseSassFilter
25{
26    const STYLE_NESTED     = 'nested';
27    const STYLE_EXPANDED   = 'expanded';
28    const STYLE_COMPACT    = 'compact';
29    const STYLE_COMPRESSED = 'compressed';
30
31    private $sassPath;
32    private $rubyPath;
33    private $unixNewlines;
34    private $scss;
35    private $style;
36    private $precision;
37    private $quiet;
38    private $debugInfo;
39    private $lineNumbers;
40    private $sourceMap;
41    private $cacheLocation;
42    private $noCache;
43    private $compass;
44
45    public function __construct($sassPath = '/usr/bin/sass', $rubyPath = null)
46    {
47        $this->sassPath = $sassPath;
48        $this->rubyPath = $rubyPath;
49        $this->cacheLocation = FilesystemUtils::getTemporaryDirectory();
50    }
51
52    public function setUnixNewlines($unixNewlines)
53    {
54        $this->unixNewlines = $unixNewlines;
55    }
56
57    public function setScss($scss)
58    {
59        $this->scss = $scss;
60    }
61
62    public function setStyle($style)
63    {
64        $this->style = $style;
65    }
66
67    public function setPrecision($precision)
68    {
69        $this->precision = $precision;
70    }
71
72    public function setQuiet($quiet)
73    {
74        $this->quiet = $quiet;
75    }
76
77    public function setDebugInfo($debugInfo)
78    {
79        $this->debugInfo = $debugInfo;
80    }
81
82    public function setLineNumbers($lineNumbers)
83    {
84        $this->lineNumbers = $lineNumbers;
85    }
86
87    public function setSourceMap($sourceMap)
88    {
89        $this->sourceMap = $sourceMap;
90    }
91
92    public function setCacheLocation($cacheLocation)
93    {
94        $this->cacheLocation = $cacheLocation;
95    }
96
97    public function setNoCache($noCache)
98    {
99        $this->noCache = $noCache;
100    }
101
102    public function setCompass($compass)
103    {
104        $this->compass = $compass;
105    }
106
107    public function filterLoad(AssetInterface $asset)
108    {
109        $sassProcessArgs = array($this->sassPath);
110        if (null !== $this->rubyPath) {
111            $sassProcessArgs = array_merge(explode(' ', $this->rubyPath), $sassProcessArgs);
112        }
113
114        $pb = $this->createProcessBuilder($sassProcessArgs);
115
116        if ($dir = $asset->getSourceDirectory()) {
117            $pb->add('--load-path')->add($dir);
118        }
119
120        if ($this->unixNewlines) {
121            $pb->add('--unix-newlines');
122        }
123
124        if (true === $this->scss || (null === $this->scss && 'scss' == pathinfo($asset->getSourcePath(), PATHINFO_EXTENSION))) {
125            $pb->add('--scss');
126        }
127
128        if ($this->style) {
129            $pb->add('--style')->add($this->style);
130        }
131
132        if ($this->precision) {
133            $pb->add('--precision')->add($this->precision);
134        }
135
136        if ($this->quiet) {
137            $pb->add('--quiet');
138        }
139
140        if ($this->debugInfo) {
141            $pb->add('--debug-info');
142        }
143
144        if ($this->lineNumbers) {
145            $pb->add('--line-numbers');
146        }
147
148        if ($this->sourceMap) {
149            $pb->add('--sourcemap');
150        }
151
152        foreach ($this->loadPaths as $loadPath) {
153            $pb->add('--load-path')->add($loadPath);
154        }
155
156        if ($this->cacheLocation) {
157            $pb->add('--cache-location')->add($this->cacheLocation);
158        }
159
160        if ($this->noCache) {
161            $pb->add('--no-cache');
162        }
163
164        if ($this->compass) {
165            $pb->add('--compass');
166        }
167
168        // input
169        $pb->add($input = FilesystemUtils::createTemporaryFile('sass'));
170        file_put_contents($input, $asset->getContent());
171
172        $proc = $pb->getProcess();
173        $code = $proc->run();
174        unlink($input);
175
176        if (0 !== $code) {
177            throw FilterException::fromProcess($proc)->setInput($asset->getContent());
178        }
179
180        $asset->setContent($proc->getOutput());
181    }
182
183    public function filterDump(AssetInterface $asset)
184    {
185    }
186}
187