1<?php
2/**
3 *
4 * @category  Xamin
5 * @package   Handlebars
6 * @author    fzerorubigd <fzerorubigd@gmail.com>
7 * @author    Behrooz Shabani <everplays@gmail.com>
8 * @author    Craig Bass <craig@clearbooks.co.uk>
9 * @author    ^^         <craig@devls.co.uk>
10 * @copyright 2012 (c) ParsPooyesh Co
11 * @copyright 2013 (c) Behrooz Shabani
12 * @license   MIT
13 * @link      http://voodoophp.org/docs/handlebars
14 */
15
16namespace Handlebars\Loader;
17use Handlebars\Loader;
18use Handlebars\HandlebarsString;
19
20
21class FilesystemLoader implements Loader
22{
23    private $_baseDir;
24    private $_extension = '.handlebars';
25    private $_prefix = '';
26    private $_templates = array();
27
28    /**
29     * Handlebars filesystem Loader constructor.
30     *
31     * $options array allows overriding certain Loader options during instantiation:
32     *
33     *     $options = array(
34     *         // extension used for Handlebars templates. Defaults to '.handlebars'
35     *         'extension' => '.other',
36     *     );
37     *
38     * @param string|array $baseDirs A path contain template files or array of paths
39     * @param array        $options  Array of Loader options (default: array())
40     *
41     * @throws \RuntimeException if $baseDir does not exist.
42     */
43    public function __construct($baseDirs, Array $options = [])
44    {
45        if (is_string($baseDirs)) {
46            $baseDirs = array(rtrim(realpath($baseDirs), '/'));
47        } else {
48            foreach ($baseDirs as &$dir) {
49                $dir = rtrim(realpath($dir), '/');
50            } unset( $dir );
51        }
52
53        $this->_baseDir = $baseDirs;
54
55        foreach ($this->_baseDir as $dir) {
56            if (!is_dir($dir)) {
57                throw new \RuntimeException(
58                    'FilesystemLoader baseDir must be a directory: ' . $dir
59                );
60            }
61        }
62
63        if (isset($options['extension'])) {
64            $this->_extension = '.' . ltrim($options['extension'], '.');
65        }
66
67        if (isset($options['prefix'])) {
68            $this->_prefix = $options['prefix'];
69        }
70    }
71
72    /**
73     * Load a Template by name.
74     *
75     *     $loader = new FilesystemLoader(dirname(__FILE__).'/views');
76     *     // loads "./views/admin/dashboard.handlebars";
77     *     $loader->load('admin/dashboard');
78     *
79     * @param string $name template name
80     *
81     * @return HandlebarsString Handlebars Template source
82     */
83    public function load($name)
84    {
85        if (!isset($this->_templates[$name])) {
86            $this->_templates[$name] = $this->loadFile($name);
87        }
88
89        return new HandlebarsString($this->_templates[$name]);
90    }
91
92    /**
93     * Helper function for loading a Handlebars file by name.
94     *
95     * @param string $name template name
96     *
97     * @throws \InvalidArgumentException if a template file is not found.
98     * @return string Handlebars Template source
99     */
100    protected function loadFile($name)
101    {
102        $fileName = $this->getFileName($name);
103
104        if ($fileName === false) {
105            throw new \InvalidArgumentException('Template ' . $name . ' not found.');
106        }
107
108        return file_get_contents($fileName);
109    }
110
111    /**
112     * Helper function for getting a Handlebars template file name.
113     *
114     * @param string $name template name
115     *
116     * @return string Template file name
117     */
118    protected function getFileName($name)
119    {
120        foreach ($this->_baseDir as $baseDir) {
121            $fileName = $baseDir . '/';
122            $fileParts = explode('/', $name);
123            $file = array_pop($fileParts);
124
125            if (substr($file, strlen($this->_prefix)) !== $this->_prefix) {
126                $file = $this->_prefix . $file;
127            }
128
129            $fileParts[] = $file;
130            $fileName .= implode('/', $fileParts);
131            $lastCharacters = substr($fileName, 0 - strlen($this->_extension));
132
133            if ($lastCharacters !== $this->_extension) {
134                $fileName .= $this->_extension;
135            }
136            if (file_exists($fileName)) {
137                return $fileName;
138            }
139        }
140
141        return false;
142    }
143
144}
145