Completed
Push — master ( 9f8479...404bd9 )
by Filipe
02:34
created

Template::getExtension()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 9
Code Lines 5

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 5
CRAP Score 2

Importance

Changes 1
Bugs 0 Features 1
Metric Value
c 1
b 0
f 1
dl 0
loc 9
ccs 5
cts 5
cp 1
rs 9.6666
cc 2
eloc 5
nc 2
nop 2
crap 2
1
<?php
2
3
/**
4
 * This file is part of slick/template package
5
 *
6
 * For the full copyright and license information, please view the LICENSE
7
 * file that was distributed with this source code.
8
 */
9
10
namespace Slick\Template;
11
12
use Slick\Common\Base;
13
use ReflectionClass;
14
15
/**
16
 * Template factory class
17
 *
18
 * @package Slick\Template
19
 * @author  Filipe Silva <[email protected]>
20
 *
21
 * @property string $engine
22
 */
23
final class Template extends Base
24
{
25
26
    /** Known engines */
27
    const ENGINE_TWIG = 'Slick\Template\Engine\Twig';
28
29
    /** Known engine extensions */
30
    const EXTENSION_TWIG_TEXT = 'Slick\Template\Extension\Text';
31
    const EXTENSION_TWIG_I18N = 'Slick\Template\Extension\I18n';
32
33
    /** @var string Engine interface */
34
    private static $interface = 'Slick\Template\TemplateEngineInterface';
35
    private static $extensionInterface =
36
        'Slick\Template\EngineExtensionInterface';
37
38
    /**
39
     * @readwrite
40
     * @var string The engine to use
41
     */
42
    protected $engine = self::ENGINE_TWIG;
43
44
    /**
45
     * @readwrite
46
     * @var array Options for template initializing
47
     */
48
    protected $options = array();
49
50
    /**
51
     * @var string[] a list of available paths
52
     */
53
    protected static $paths = ['./'];
54
55
    /**
56
     * @var array Array containing template extensions
57
     */
58
    private static $extensions = [
59
        self::EXTENSION_TWIG_TEXT => null,
60
        self::EXTENSION_TWIG_I18N => null,
61
    ];
62
63
    /**
64
     * Prepends a searchable path to available paths list.
65
     *
66
     * @param string $path
67
     */
68 2 View Code Duplication
    public static function addPath($path)
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
69
    {
70 2
        $path = str_replace('//', '/', rtrim($path, '/'));
71 2
        if (is_dir($path) && !in_array($path, self::$paths)) {
72 2
            array_unshift(self::$paths, $path);
73 2
        }
74 2
    }
75
76
    /**
77
     * Prepends a searchable path to available paths list.
78
     *
79
     * @param string $path
80
     */
81 2 View Code Duplication
    public static function appendPath($path)
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
82
    {
83 2
        $path = str_replace('//', '/', rtrim($path, '/'));
84 2
        if (is_dir($path) && !in_array($path, self::$paths)) {
85 2
            array_push(self::$paths, $path);
86 2
        }
87 2
    }
88
89
    /**
90
     * Gets the list of defined paths
91
     *
92
     * @return \string[]
93
     */
94 4
    public static function getPaths()
95
    {
96 4
        return self::$paths;
97
    }
98
99
    /**
100
     * Initializes the engine
101
     *
102
     * @throws Exception\InvalidArgumentException
103
     *
104
     * @return TemplateEngineInterface
105
     */
106 4
    public function initialize()
107
    {
108 4
        $this->checkClass();
109
        /** @var TemplateEngineInterface $engine */
110 2
        $engine = new $this->engine($this->options);
111 2
        $engine->setLocations(self::$paths);
112 2
        return $this->applyExtensions($engine);
113
    }
114
115
    /**
116
     * Adds an extension to the template engine
117
     *
118
     * @param string|object $className The class name or an instance
119
     *                                 of EngineExtensionInterface interface
120
     *
121
     * @return self|$this|Template
122
     */
123 6
    public function addExtension($className)
124
    {
125 6
        $object = is_object($className) ? $className : null;
126 6
        $className = is_object($className) ? get_class($object) : $className;
127
128 6
        $this->checkClass($className, self::$extensionInterface);
129
130 4
        self::$extensions[$className] = $object;
131 4
        return $this;
132
    }
133
134
    /**
135
     * Registers the provided class name as an extension
136
     * 
137
     * @param string|object $extension The class name or an instance
138
     *                                 of EngineExtensionInterface interface
139
     *
140
     * @return Template
141
     */
142 2
    public static function register($extension)
143
    {
144 2
        $template = new Template;
145 2
        return $template->addExtension($extension);
146
    }
147
148
    /**
149
     * Apply defined extensions to the provided template engine
150
     *
151
     * @param TemplateEngineInterface $engine
152
     *
153
     * @return TemplateEngineInterface
154
     */
155 2
    protected function applyExtensions(TemplateEngineInterface $engine)
156
    {
157 2
        foreach (static::$extensions as $className => $extension) {
0 ignored issues
show
Comprehensibility introduced by
Since Slick\Template\Template is declared final, using late-static binding will have no effect. You might want to replace static with self instead.

Late static binding only has effect in subclasses. A final class cannot be extended anymore so late static binding cannot occurr. Consider replacing static:: with self::.

To learn more about late static binding, please refer to the PHP core documentation.

Loading history...
158 2
            $ext = $this->getExtension($className, $extension);
159 2
            if ($ext->appliesTo($engine)) {
160 2
                $ext->update($engine);
161 2
            }
162 2
        }
163 2
        return $engine;
164
    }
165
166
    /**
167
     * @param string $class
168
     * @param EngineExtensionInterface $extension
169
     *
170
     * @return EngineExtensionInterface
171
     */
172 2
    protected function getExtension($class, $extension)
173
    {
174 2
        if (is_object($extension)) {
175 2
            return $extension;
176
        }
177
178 2
        $this->checkClass($class, self::$extensionInterface);
179 2
        return new $class();
180
    }
181
182
    /**
183
     * Check if type is a valid configuration driver
184
     *
185
     * @param null $name
186
     * @param null $interface
187
     */
188 10
    protected function checkClass($name = null, $interface = null)
189
    {
190 10
        $name = null == $name ? $this->engine : $name;
191 10
        $interface = null == $interface ? self::$interface : $interface;
192
193 10
        if (!class_exists($name)) {
194 2
            throw new Exception\InvalidArgumentException(
195 2
                "The class '{$name}' was not found"
196 2
            );
197
        }
198
199 8
        $reflection = new ReflectionClass($name);
200 8
        if (!$reflection->implementsInterface($interface)) {
201 2
            throw new Exception\InvalidArgumentException(
202 2
                "Class '{$name}' does not implement {$interface}"
203 2
            );
204
        }
205 6
    }
206
207
    /**
208
     * Get current configured extensions
209
     * 
210
     * @return array
211
     */
212 4
    public function getExtensions()
213
    {
214 4
        return self::$extensions;
215
    }
216
217
    /**
218
     * Set or reset the list of extensions
219
     * 
220
     * @param array $extensions
221
     * 
222
     * @return Template
223
     */
224 2
    public function setExtensions(array $extensions)
225
    {
226 2
        self::$extensions = $extensions;
227 2
        return $this;
228
    }
229
}
230