Completed
Push — master ( 39e8a2...6136fb )
by Alex
02:27
created

FilesystemLoader   A

Complexity

Total Complexity 18

Size/Duplication

Total Lines 150
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 0

Test Coverage

Coverage 0%

Importance

Changes 1
Bugs 0 Features 1
Metric Value
wmc 18
c 1
b 0
f 1
lcom 1
cbo 0
dl 0
loc 150
ccs 0
cts 71
cp 0
rs 10

10 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 8 2
A getSource() 0 4 1
A getCacheKey() 0 4 1
A isFresh() 0 4 1
A exists() 0 8 2
A template() 0 13 3
A findTemplate() 0 13 3
A possibleTemplateFiles() 0 11 2
A normalizeName() 0 6 1
A realFilePath() 0 9 2
1
<?php
2
3
namespace Asmaster\EquipTwig\Loader;
4
5
use Asmaster\EquipTwig\Exception\LoaderException;
6
use Twig_ExistsLoaderInterface as TwigExistsLoader;
7
use Twig_LoaderInterface as TwigLoader;
8
9
final class FilesystemLoader implements TwigLoader, TwigExistsLoader
1 ignored issue
show
Deprecated Code introduced by
The interface Twig_ExistsLoaderInterface has been deprecated with message: since 1.12 (to be removed in 3.0)

This class, trait or interface has been deprecated. The supplier of the file has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the type will be removed from the class and what other constant to use instead.

Loading history...
10
{
11
    /**
12
     * @var array
13
     */
14
    private $path;
15
16
    /**
17
     * @var array
18
     */
19
    private $fileExtensions = ['html.twig', 'twig'];
20
21
    /**
22
     * @var array
23
     */
24
    private $cache = [];
25
26
    /**
27
     * @param string $path           The template directory path
28
     * @param array  $fileExtensions The template file extensions
29
     */
30
    public function __construct($path, array $fileExtensions = null)
31
    {
32
        $this->path = $this->realFilePath($path);
0 ignored issues
show
Documentation Bug introduced by
It seems like $this->realFilePath($path) of type string is incompatible with the declared type array of property $path.

Our type inference engine has found an assignment to a property that is incompatible with the declared type of that property.

Either this assignment is in error or the assigned type should be added to the documentation/type hint for that property..

Loading history...
33
34
        if ($fileExtensions) {
35
            $this->fileExtensions = $fileExtensions;
36
        }
37
    }
38
39
    /**
40
     * @inheritDoc
41
     */
42
    public function getSource($name)
43
    {
44
        return file_get_contents($this->template($name));
45
    }
46
47
    /**
48
     * @inheritDoc
49
     */
50
    public function getCacheKey($name)
51
    {
52
        return $this->template($name);
53
    }
54
55
    /**
56
     * @inheritDoc
57
     */
58
    public function isFresh($name, $time)
59
    {
60
        return filemtime($this->template($name)) <= $time;
61
    }
62
63
    /**
64
     * @inheritDoc
65
     */
66
    public function exists($name)
67
    {
68
        if (isset($this->cache[$name])) {
69
            return true;
70
        }
71
72
        return (bool) $this->findTemplate($name);
73
    }
74
75
    /**
76
     * @throws LoaderException When $name is not found
77
     *
78
     * @param string $name
79
     *
80
     * @return string
81
     */
82
    private function template($name)
83
    {
84
        if (isset($this->cache[$name])) {
85
            return $this->cache[$name];
86
        }
87
88
        $found = $this->findTemplate($name);
89
        if (!$found) {
1 ignored issue
show
Bug Best Practice introduced by
The expression $found of type string|null is loosely compared to false; this is ambiguous if the string can be empty. You might want to explicitly use === null instead.

In PHP, under loose comparison (like ==, or !=, or switch conditions), values of different types might be equal.

For string values, the empty string '' is a special case, in particular the following results might be unexpected:

''   == false // true
''   == null  // true
'ab' == false // false
'ab' == null  // false

// It is often better to use strict comparison
'' === false // false
'' === null  // false
Loading history...
90
            throw LoaderException::notFound($name, $this->path);
91
        }
92
93
        return $this->cache[$name] = $found;
94
    }
95
96
    /**
97
     * @param string $name
98
     *
99
     * @return string|null
100
     */
101
    private function findTemplate($name)
102
    {
103
        $files = $this->possibleTemplateFiles($name);
104
105
        foreach($files as $file) {
106
            $filepath = $this->path . DIRECTORY_SEPARATOR . $file;
107
            if (is_file($filepath)) {
108
                return $filepath;
109
            }
110
        }
111
112
        return null;
113
    }
114
115
    /**
116
     * @param string $name
117
     *
118
     * @return array
119
     */
120
    private function possibleTemplateFiles($name)
121
    {
122
        $name = $this->normalizeName($name);
123
124
        $templates = [$name];
125
        foreach($this->fileExtensions as $extension) {
126
            $templates[] = "$name.$extension";
127
        }
128
129
        return $templates;
130
    }
131
132
    /**
133
     * @param string $name
134
     *
135
     * @return string
136
     */
137
    private function normalizeName($name)
138
    {
139
        return preg_replace('#/{2,}#', DIRECTORY_SEPARATOR,
140
            str_replace('\\', DIRECTORY_SEPARATOR, $name)
141
        );
142
    }
143
144
    /**
145
     * @param string $file
146
     *
147
     * @return string
148
     */
149
    private function realFilePath($file)
150
    {
151
        $realpath = realpath($file);
152
        if (false !== $realpath) {
153
            return $realpath;
154
        }
155
156
        return $file;
157
    }
158
}
159