1<?php
2
3namespace League\Plates;
4
5use League\Plates\Extension\ExtensionInterface;
6use League\Plates\Template\Data;
7use League\Plates\Template\Directory;
8use League\Plates\Template\FileExtension;
9use League\Plates\Template\Folders;
10use League\Plates\Template\Func;
11use League\Plates\Template\Functions;
12use League\Plates\Template\Name;
13use League\Plates\Template\Template;
14
15/**
16 * Template API and environment settings storage.
17 */
18class Engine
19{
20    /**
21     * Default template directory.
22     * @var Directory
23     */
24    protected $directory;
25
26    /**
27     * Template file extension.
28     * @var FileExtension
29     */
30    protected $fileExtension;
31
32    /**
33     * Collection of template folders.
34     * @var Folders
35     */
36    protected $folders;
37
38    /**
39     * Collection of template functions.
40     * @var Functions
41     */
42    protected $functions;
43
44    /**
45     * Collection of preassigned template data.
46     * @var Data
47     */
48    protected $data;
49
50    /**
51     * Create new Engine instance.
52     * @param string $directory
53     * @param string $fileExtension
54     */
55    public function __construct($directory = null, $fileExtension = 'php')
56    {
57        $this->directory = new Directory($directory);
58        $this->fileExtension = new FileExtension($fileExtension);
59        $this->folders = new Folders();
60        $this->functions = new Functions();
61        $this->data = new Data();
62    }
63
64    /**
65     * Set path to templates directory.
66     * @param  string|null $directory Pass null to disable the default directory.
67     * @return Engine
68     */
69    public function setDirectory($directory)
70    {
71        $this->directory->set($directory);
72
73        return $this;
74    }
75
76    /**
77     * Get path to templates directory.
78     * @return string
79     */
80    public function getDirectory()
81    {
82        return $this->directory->get();
83    }
84
85    /**
86     * Set the template file extension.
87     * @param  string|null $fileExtension Pass null to manually set it.
88     * @return Engine
89     */
90    public function setFileExtension($fileExtension)
91    {
92        $this->fileExtension->set($fileExtension);
93
94        return $this;
95    }
96
97    /**
98     * Get the template file extension.
99     * @return string
100     */
101    public function getFileExtension()
102    {
103        return $this->fileExtension->get();
104    }
105
106    /**
107     * Add a new template folder for grouping templates under different namespaces.
108     * @param  string  $name
109     * @param  string  $directory
110     * @param  boolean $fallback
111     * @return Engine
112     */
113    public function addFolder($name, $directory, $fallback = false)
114    {
115        $this->folders->add($name, $directory, $fallback);
116
117        return $this;
118    }
119
120    /**
121     * Remove a template folder.
122     * @param  string $name
123     * @return Engine
124     */
125    public function removeFolder($name)
126    {
127        $this->folders->remove($name);
128
129        return $this;
130    }
131
132    /**
133     * Get collection of all template folders.
134     * @return Folders
135     */
136    public function getFolders()
137    {
138        return $this->folders;
139    }
140
141    /**
142     * Add preassigned template data.
143     * @param  array             $data;
144     * @param  null|string|array $templates;
145     * @return Engine
146     */
147    public function addData(array $data, $templates = null)
148    {
149        $this->data->add($data, $templates);
150
151        return $this;
152    }
153
154    /**
155     * Get all preassigned template data.
156     * @param  null|string $template;
157     * @return array
158     */
159    public function getData($template = null)
160    {
161        return $this->data->get($template);
162    }
163
164    /**
165     * Register a new template function.
166     * @param  string   $name;
167     * @param  callback $callback;
168     * @return Engine
169     */
170    public function registerFunction($name, $callback)
171    {
172        $this->functions->add($name, $callback);
173
174        return $this;
175    }
176
177    /**
178     * Remove a template function.
179     * @param  string $name;
180     * @return Engine
181     */
182    public function dropFunction($name)
183    {
184        $this->functions->remove($name);
185
186        return $this;
187    }
188
189    /**
190     * Get a template function.
191     * @param  string $name
192     * @return Func
193     */
194    public function getFunction($name)
195    {
196        return $this->functions->get($name);
197    }
198
199    /**
200     * Check if a template function exists.
201     * @param  string  $name
202     * @return boolean
203     */
204    public function doesFunctionExist($name)
205    {
206        return $this->functions->exists($name);
207    }
208
209    /**
210     * Load an extension.
211     * @param  ExtensionInterface $extension
212     * @return Engine
213     */
214    public function loadExtension(ExtensionInterface $extension)
215    {
216        $extension->register($this);
217
218        return $this;
219    }
220
221    /**
222     * Load multiple extensions.
223     * @param  array  $extensions
224     * @return Engine
225     */
226    public function loadExtensions(array $extensions = array())
227    {
228        foreach ($extensions as $extension) {
229            $this->loadExtension($extension);
230        }
231
232        return $this;
233    }
234
235    /**
236     * Get a template path.
237     * @param  string $name
238     * @return string
239     */
240    public function path($name)
241    {
242        $name = new Name($this, $name);
243
244        return $name->getPath();
245    }
246
247    /**
248     * Check if a template exists.
249     * @param  string  $name
250     * @return boolean
251     */
252    public function exists($name)
253    {
254        $name = new Name($this, $name);
255
256        return $name->doesPathExist();
257    }
258
259    /**
260     * Create a new template.
261     * @param  string   $name
262     * @return Template
263     */
264    public function make($name)
265    {
266        return new Template($this, $name);
267    }
268
269    /**
270     * Create a new template and render it.
271     * @param  string $name
272     * @param  array  $data
273     * @return string
274     */
275    public function render($name, array $data = array())
276    {
277        return $this->make($name)->render($data);
278    }
279}
280