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\Asset;
13
14use Assetic\Filter\FilterCollection;
15use Assetic\Filter\FilterInterface;
16
17/**
18 * A base abstract asset.
19 *
20 * The methods load() and getLastModified() are left undefined, although a
21 * reusable doLoad() method is available to child classes.
22 *
23 * @author Kris Wallsmith <kris.wallsmith@gmail.com>
24 */
25abstract class BaseAsset implements AssetInterface
26{
27    private $filters;
28    private $sourceRoot;
29    private $sourcePath;
30    private $sourceDir;
31    private $targetPath;
32    private $content;
33    private $loaded;
34    private $vars;
35    private $values;
36
37    /**
38     * Constructor.
39     *
40     * @param array  $filters    Filters for the asset
41     * @param string $sourceRoot The root directory
42     * @param string $sourcePath The asset path
43     * @param array  $vars
44     */
45    public function __construct($filters = array(), $sourceRoot = null, $sourcePath = null, array $vars = array())
46    {
47        $this->filters = new FilterCollection($filters);
48        $this->sourceRoot = $sourceRoot;
49        $this->sourcePath = $sourcePath;
50        if ($sourcePath && $sourceRoot) {
51            $this->sourceDir = dirname("$sourceRoot/$sourcePath");
52        }
53        $this->vars = $vars;
54        $this->values = array();
55        $this->loaded = false;
56    }
57
58    public function __clone()
59    {
60        $this->filters = clone $this->filters;
61    }
62
63    public function ensureFilter(FilterInterface $filter)
64    {
65        $this->filters->ensure($filter);
66    }
67
68    public function getFilters()
69    {
70        return $this->filters->all();
71    }
72
73    public function clearFilters()
74    {
75        $this->filters->clear();
76    }
77
78    /**
79     * Encapsulates asset loading logic.
80     *
81     * @param string          $content          The asset content
82     * @param FilterInterface $additionalFilter An additional filter
83     */
84    protected function doLoad($content, FilterInterface $additionalFilter = null)
85    {
86        $filter = clone $this->filters;
87        if ($additionalFilter) {
88            $filter->ensure($additionalFilter);
89        }
90
91        $asset = clone $this;
92        $asset->setContent($content);
93
94        $filter->filterLoad($asset);
95        $this->content = $asset->getContent();
96
97        $this->loaded = true;
98    }
99
100    public function dump(FilterInterface $additionalFilter = null)
101    {
102        if (!$this->loaded) {
103            $this->load();
104        }
105
106        $filter = clone $this->filters;
107        if ($additionalFilter) {
108            $filter->ensure($additionalFilter);
109        }
110
111        $asset = clone $this;
112        $filter->filterDump($asset);
113
114        return $asset->getContent();
115    }
116
117    public function getContent()
118    {
119        return $this->content;
120    }
121
122    public function setContent($content)
123    {
124        $this->content = $content;
125    }
126
127    public function getSourceRoot()
128    {
129        return $this->sourceRoot;
130    }
131
132    public function getSourcePath()
133    {
134        return $this->sourcePath;
135    }
136
137    public function getSourceDirectory()
138    {
139        return $this->sourceDir;
140    }
141
142    public function getTargetPath()
143    {
144        return $this->targetPath;
145    }
146
147    public function setTargetPath($targetPath)
148    {
149        if ($this->vars) {
150            foreach ($this->vars as $var) {
151                if (false === strpos($targetPath, $var)) {
152                    throw new \RuntimeException(sprintf('The asset target path "%s" must contain the variable "{%s}".', $targetPath, $var));
153                }
154            }
155        }
156
157        $this->targetPath = $targetPath;
158    }
159
160    public function getVars()
161    {
162        return $this->vars;
163    }
164
165    public function setValues(array $values)
166    {
167        foreach ($values as $var => $v) {
168            if (!in_array($var, $this->vars, true)) {
169                throw new \InvalidArgumentException(sprintf('The asset with source path "%s" has no variable named "%s".', $this->sourcePath, $var));
170            }
171        }
172
173        $this->values = $values;
174        $this->loaded = false;
175    }
176
177    public function getValues()
178    {
179        return $this->values;
180    }
181}
182