source: sandbox/newExpressoMail/newExpressoMail/Assetic/Filter/CompassFilter.php @ 7265

Revision 7265, 9.8 KB checked in by gustavo, 12 years ago (diff)

Ticket #0000 - Criado novo modulo para o desenvolvimento do novo ExpressoMail?

  • Property svn:executable set to *
Line 
1<?php
2
3/*
4 * This file is part of the Assetic package, an OpenSky project.
5 *
6 * (c) 2010-2012 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;
13
14use Assetic\Exception\FilterException;
15use Assetic\Asset\AssetInterface;
16use Assetic\Filter\FilterInterface;
17use Symfony\Component\Process\ProcessBuilder;
18
19/**
20 * Loads Compass files.
21 *
22 * @link http://compass-style.org/
23 * @author Maxime Thirouin <maxime.thirouin@gmail.com>
24 */
25class CompassFilter implements FilterInterface
26{
27    private $compassPath;
28    private $rubyPath;
29    private $scss;
30
31    // sass options
32    private $unixNewlines;
33    private $debugInfo;
34    private $cacheLocation;
35    private $noCache;
36
37    // compass options
38    private $force;
39    private $style;
40    private $quiet;
41    private $boring;
42    private $noLineComments;
43    private $imagesDir;
44    private $javascriptsDir;
45
46    // compass configuration file options
47    private $plugins = array();
48    private $loadPaths = array();
49    private $httpPath;
50    private $httpImagesPath;
51    private $httpGeneratedImagesPath;
52    private $generatedImagesPath;
53    private $httpJavascriptsPath;
54    private $homeEnv = true;
55
56    public function __construct($compassPath = '/usr/bin/compass', $rubyPath = null)
57    {
58        $this->compassPath = $compassPath;
59        $this->rubyPath = $rubyPath;
60        $this->cacheLocation = sys_get_temp_dir();
61
62        if ('cli' !== php_sapi_name()) {
63            $this->boring = true;
64        }
65    }
66
67    public function setScss($scss)
68    {
69        $this->scss = $scss;
70    }
71
72    // sass options setters
73    public function setUnixNewlines($unixNewlines)
74    {
75        $this->unixNewlines = $unixNewlines;
76    }
77
78    public function setDebugInfo($debugInfo)
79    {
80        $this->debugInfo = $debugInfo;
81    }
82
83    public function setCacheLocation($cacheLocation)
84    {
85        $this->cacheLocation = $cacheLocation;
86    }
87
88    public function setNoCache($noCache)
89    {
90        $this->noCache = $noCache;
91    }
92
93    // compass options setters
94    public function setForce($force)
95    {
96        $this->force = $force;
97    }
98
99    public function setStyle($style)
100    {
101        $this->style = $style;
102    }
103
104    public function setQuiet($quiet)
105    {
106        $this->quiet = $quiet;
107    }
108
109    public function setBoring($boring)
110    {
111        $this->boring = $boring;
112    }
113
114    public function setNoLineComments($noLineComments)
115    {
116        $this->noLineComments = $noLineComments;
117    }
118
119    public function setImagesDir($imagesDir)
120    {
121        $this->imagesDir = $imagesDir;
122    }
123
124    public function setJavascriptsDir($javascriptsDir)
125    {
126        $this->javascriptsDir = $javascriptsDir;
127    }
128
129    // compass configuration file options setters
130    public function setPlugins(array $plugins)
131    {
132        $this->plugins = $plugins;
133    }
134
135    public function addPlugin($plugin)
136    {
137        $this->plugins[] = $plugin;
138    }
139
140    public function setLoadPaths(array $loadPaths)
141    {
142        $this->loadPaths = $loadPaths;
143    }
144
145    public function addLoadPath($loadPath)
146    {
147        $this->loadPaths[] = $loadPath;
148    }
149
150    public function setHttpPath($httpPath)
151    {
152        $this->httpPath = $httpPath;
153    }
154
155    public function setHttpImagesPath($httpImagesPath)
156    {
157        $this->httpImagesPath = $httpImagesPath;
158    }
159
160    public function setHttpGeneratedImagesPath($httpGeneratedImagesPath)
161    {
162        $this->httpGeneratedImagesPath = $httpGeneratedImagesPath;
163    }
164
165    public function setGeneratedImagesPath($generatedImagesPath)
166    {
167        $this->generatedImagesPath = $generatedImagesPath;
168    }
169
170    public function setHttpJavascriptsPath($httpJavascriptsPath)
171    {
172        $this->httpJavascriptsPath = $httpJavascriptsPath;
173    }
174
175    public function setHomeEnv($homeEnv)
176    {
177        $this->homeEnv = $homeEnv;
178    }
179
180    public function filterLoad(AssetInterface $asset)
181    {
182        $root = $asset->getSourceRoot();
183        $path = $asset->getSourcePath();
184
185        $loadPaths = $this->loadPaths;
186        if ($root && $path) {
187            $loadPaths[] = dirname($root.'/'.$path);
188        }
189
190        // compass does not seems to handle symlink, so we use realpath()
191        $tempDir = realpath(sys_get_temp_dir());
192
193        $compassProcessArgs = array(
194            $this->compassPath,
195            'compile',
196            $tempDir,
197        );
198        if (null !== $this->rubyPath) {
199            $compassProcessArgs = array_merge(explode(' ', $this->rubyPath), $compassProcessArgs);
200        }
201
202        $pb = new ProcessBuilder($compassProcessArgs);
203        $pb->inheritEnvironmentVariables();
204
205        if ($this->force) {
206            $pb->add('--force');
207        }
208
209        if ($this->style) {
210            $pb->add('--output-style')->add($this->style);
211        }
212
213        if ($this->quiet) {
214            $pb->add('--quiet');
215        }
216
217        if ($this->boring) {
218            $pb->add('--boring');
219        }
220
221        if ($this->noLineComments) {
222            $pb->add('--no-line-comments');
223        }
224
225        // these two options are not passed into the config file
226        // because like this, compass adapts this to be xxx_dir or xxx_path
227        // whether it's an absolute path or not
228        if ($this->imagesDir) {
229            $pb->add('--images-dir')->add($this->imagesDir);
230        }
231
232        if ($this->javascriptsDir) {
233            $pb->add('--javascripts-dir')->add($this->javascriptsDir);
234        }
235
236        // options in config file
237        $optionsConfig = array();
238
239        if (!empty($loadPaths)) {
240            $optionsConfig['additional_import_paths'] = $loadPaths;
241        }
242
243        if ($this->unixNewlines) {
244            $optionsConfig['sass_options']['unix_newlines'] = true;
245        }
246
247        if ($this->debugInfo) {
248            $optionsConfig['sass_options']['debug_info'] = true;
249        }
250
251        if ($this->cacheLocation) {
252            $optionsConfig['sass_options']['cache_location'] = $this->cacheLocation;
253        }
254
255        if ($this->noCache) {
256            $optionsConfig['sass_options']['no_cache'] = true;
257        }
258
259        if ($this->httpPath) {
260            $optionsConfig['http_path'] = $this->httpPath;
261        }
262
263        if ($this->httpImagesPath) {
264            $optionsConfig['http_images_path'] = $this->httpImagesPath;
265        }
266
267        if ($this->httpGeneratedImagesPath) {
268            $optionsConfig['http_generated_images_path'] = $this->httpGeneratedImagesPath;
269        }
270
271        if ($this->generatedImagesPath) {
272            $optionsConfig['generated_images_path'] = $this->generatedImagesPath;
273        }
274
275        if ($this->httpJavascriptsPath) {
276            $optionsConfig['http_javascripts_path'] = $this->httpJavascriptsPath;
277        }
278
279        // options in configuration file
280        if (count($optionsConfig)) {
281            $config = array();
282            foreach ($this->plugins as $plugin) {
283                $config[] = sprintf("require '%s'", addcslashes($plugin, '\\'));
284            }
285            foreach ($optionsConfig as $name => $value) {
286                if (!is_array($value)) {
287                    $config[] = sprintf('%s = "%s"', $name, addcslashes($value, '\\'));
288                } elseif (!empty($value)) {
289                    $config[] = sprintf('%s = %s', $name, $this->formatArrayToRuby($value));
290                }
291            }
292
293            $configFile = tempnam($tempDir, 'assetic_compass');
294            file_put_contents($configFile, implode("\n", $config)."\n");
295            $pb->add('--config')->add($configFile);
296        }
297
298        $pb->add('--sass-dir')->add('')->add('--css-dir')->add('');
299
300        // compass choose the type (sass or scss from the filename)
301        if (null !== $this->scss) {
302            $type = $this->scss ? 'scss' : 'sass';
303        } elseif ($path) {
304            // FIXME: what if the extension is something else?
305            $type = pathinfo($path, PATHINFO_EXTENSION);
306        } else {
307            $type = 'scss';
308        }
309
310        $tempName = tempnam($tempDir, 'assetic_compass');
311        unlink($tempName); // FIXME: don't use tempnam() here
312
313        // input
314        $input = $tempName.'.'.$type;
315
316        // work-around for https://github.com/chriseppstein/compass/issues/748
317        if (defined('PHP_WINDOWS_VERSION_MAJOR')) {
318            $input = str_replace('\\', '/', $input);
319        }
320
321        $pb->add($input);
322        file_put_contents($input, $asset->getContent());
323
324        // output
325        $output = $tempName.'.css';
326
327        if ($this->homeEnv) {
328            // it's not really usefull but... https://github.com/chriseppstein/compass/issues/376
329            $pb->setEnv('HOME', sys_get_temp_dir());
330        }
331
332        $proc = $pb->getProcess();
333        $code = $proc->run();
334
335        if (0 < $code) {
336            unlink($input);
337            if (isset($configFile)) {
338                unlink($configFile);
339            }
340
341            throw FilterException::fromProcess($proc)->setInput($asset->getContent());
342        }
343
344        $asset->setContent(file_get_contents($output));
345
346        unlink($input);
347        unlink($output);
348        if (isset($configFile)) {
349            unlink($configFile);
350        }
351    }
352
353    public function filterDump(AssetInterface $asset)
354    {
355    }
356
357    private function formatArrayToRuby($array)
358    {
359        $output = array();
360
361        // does we have an associative array ?
362        if (count(array_filter(array_keys($array), "is_numeric")) != count($array)) {
363            foreach ($array as $name => $value) {
364                $output[] = sprintf('    :%s => "%s"', $name, addcslashes($value, '\\'));
365            }
366            $output = "{\n".implode(",\n", $output)."\n}";
367        } else {
368            foreach ($array as $name => $value) {
369                $output[] = sprintf('    "%s"', addcslashes($value, '\\'));
370            }
371            $output = "[\n".implode(",\n", $output)."\n]";
372        }
373
374        return $output;
375    }
376}
Note: See TracBrowser for help on using the repository browser.