1<?php
2
3namespace Assetic\Filter\Sass;
4
5use Assetic\Asset\AssetInterface;
6use Assetic\Factory\AssetFactory;
7use Assetic\Filter\BaseProcessFilter;
8use Assetic\Filter\DependencyExtractorInterface;
9use Assetic\Util\SassUtils;
10
11abstract class BaseSassFilter extends BaseProcessFilter implements DependencyExtractorInterface
12{
13    protected $loadPaths = array();
14
15    public function setLoadPaths(array $loadPaths)
16    {
17        $this->loadPaths = $loadPaths;
18    }
19
20    public function addLoadPath($loadPath)
21    {
22        $this->loadPaths[] = $loadPath;
23    }
24
25    public function getChildren(AssetFactory $factory, $content, $loadPath = null)
26    {
27        $loadPaths = $this->loadPaths;
28        if ($loadPath) {
29            array_unshift($loadPaths, $loadPath);
30        }
31
32        if (!$loadPaths) {
33            return array();
34        }
35
36        $children = array();
37        foreach (SassUtils::extractImports($content) as $reference) {
38            if ('.css' === substr($reference, -4)) {
39                // skip normal css imports
40                // todo: skip imports with media queries
41                continue;
42            }
43
44            // the reference may or may not have an extension or be a partial
45            if (pathinfo($reference, PATHINFO_EXTENSION)) {
46                $needles = array(
47                    $reference,
48                    self::partialize($reference),
49                );
50            } else {
51                $needles = array(
52                    $reference.'.scss',
53                    $reference.'.sass',
54                    self::partialize($reference).'.scss',
55                    self::partialize($reference).'.sass',
56                );
57            }
58
59            foreach ($loadPaths as $loadPath) {
60                foreach ($needles as $needle) {
61                    if (file_exists($file = $loadPath.'/'.$needle)) {
62                        $coll = $factory->createAsset($file, array(), array('root' => $loadPath));
63                        foreach ($coll as $leaf) {
64                            /** @var $leaf AssetInterface */
65                            $leaf->ensureFilter($this);
66                            $children[] = $leaf;
67                            goto next_reference;
68                        }
69                    }
70                }
71            }
72
73            next_reference:
74        }
75
76        return $children;
77    }
78
79    private static function partialize($reference)
80    {
81        $parts = pathinfo($reference);
82
83        if ('.' === $parts['dirname']) {
84            $partial = '_'.$parts['filename'];
85        } else {
86            $partial = $parts['dirname'].DIRECTORY_SEPARATOR.'_'.$parts['filename'];
87        }
88
89        if (isset($parts['extension'])) {
90            $partial .= '.'.$parts['extension'];
91        }
92
93        return $partial;
94    }
95}
96