Completed
Pull Request — v3 (#279)
by Gabriel
11:00
created

Engine::setResolveTemplatePath()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 6

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 1
CRAP Score 1.125

Importance

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

Let’s take a look at an example:

interface User
{
    /** @return string */
    public function getPassword();
}

class MyUser implements User
{
    public function getPassword()
    {
        // return something
    }

    public function getDisplayName()
    {
        // return some name.
    }
}

class AuthSystem
{
    public function authenticate(User $user)
    {
        $this->logger->info(sprintf('Authenticating %s.', $user->getDisplayName()));
        // do something.
    }
}

In the above example, the authenticate() method works fine as long as you just pass instances of MyUser. However, if you now also want to pass a different implementation of User which does not have a getDisplayName() method, the code will break.

Available Fixes

  1. Change the type-hint for the parameter:

    class AuthSystem
    {
        public function authenticate(MyUser $user) { /* ... */ }
    }
    
  2. Add an additional type-check:

    class AuthSystem
    {
        public function authenticate(User $user)
        {
            if ($user instanceof MyUser) {
                $this->logger->info(/** ... */);
            }
    
            // or alternatively
            if ( ! $user instanceof MyUser) {
                throw new \LogicException(
                    '$user must be an instance of MyUser, '
                   .'other instances are not supported.'
                );
            }
    
        }
    }
    
Note: PHP Analyzer uses reverse abstract interpretation to narrow down the types inside the if block in such a case.
  1. Add the method to the interface:

    interface User
    {
        /** @return string */
        public function getPassword();
    
        /** @return string */
        public function getDisplayName();
    }
    
Loading history...
269
    }
270
271
    /**
272
     * Check if a template exists.
273
     * @param  string|Name  $name
274
     * @return boolean
275 6
     */
276
    public function exists($name)
277 6
    {
278
        $name = $name instanceof Name ? $name : new Name($this, $name);
279
280
        return $this->getResolveTemplatePath()->exists($name);
281
    }
282
283
    /**
284
     * Create a new template.
285
     * @param  string   $name
286
     * @return Template
287
     */
288
    public function make($name)
289
    {
290
        return new Template($this, $name);
291
    }
292
293
    /**
294
     * Create a new template and render it.
295
     * @param  string $name
296
     * @param  array  $data
297
     * @return string
298
     */
299
    public function render($name, array $data = array())
300
    {
301
        return $this->make($name)->render($data);
302
    }
303
}
304