Completed
Push — master ( ee9d02...8bba70 )
by Alex
04:07
created

FilesystemLoader::normalizeName()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 7
Code Lines 4

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 4
CRAP Score 1

Importance

Changes 0
Metric Value
c 0
b 0
f 0
dl 0
loc 7
ccs 4
cts 4
cp 1
rs 9.4285
cc 1
eloc 4
nc 1
nop 1
crap 1
1
<?php
2
3
namespace AlexMasterov\EquipTwig\Loader;
4
5
use AlexMasterov\EquipTwig\Exception\LoaderException;
6
use Twig_LoaderInterface;
7
use Twig_Source;
8
9
final class FilesystemLoader implements Twig_LoaderInterface
10
{
11
    /**
12
     * @var string
13
     */
14
    private $path;
15
16
    /**
17
     * @var array
18
     */
19
    private $fileExtensions = [];
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 8
    public function __construct($path, array $fileExtensions = [])
31
    {
32 8
        $this->path = $path;
33 8
        $this->fileExtensions = $fileExtensions;
34 8
    }
35
36
    /**
37
     * For Twig 1.x compatibility.
38
     */
39 1
    public function getSource($name)
40
    {
41 1
        return file_get_contents($this->template($name));
42
    }
43
44
    /**
45
     * @inheritDoc
46
     */
47 4
    public function getSourceContext($name)
48
    {
49 4
        $code = file_get_contents($this->template($name));
50
51 3
        return new Twig_Source($code, $name);
52
    }
53
54
    /**
55
     * @inheritDoc
56
     */
57 1
    public function getCacheKey($name)
58
    {
59 1
        return $this->template($name);
60
    }
61
62
    /**
63
     * @inheritDoc
64
     */
65 1
    public function isFresh($name, $time)
66
    {
67 1
        return filemtime($this->template($name)) <= $time;
68
    }
69
70
    /**
71
     * @inheritDoc
72
     */
73 1
    public function exists($name)
74
    {
75 1
        if (isset($this->cache[$name])) {
76 1
            return true;
77
        }
78
79 1
        return (bool) $this->findTemplate($name);
80
    }
81
82
    /**
83
     * @param string $name
84
     *
85
     * @return string
86
     *
87
     * @throws LoaderException
88
     *  When $name is not found.
89
     */
90 6
    private function template($name)
91
    {
92 6
        if (isset($this->cache[$name])) {
93 1
            return $this->cache[$name];
94
        }
95
96 6
        $found = $this->findTemplate($name);
97 6
        if (null === $found) {
98 1
            throw LoaderException::notFound($name, $this->path);
99
        }
100
101 5
        return $this->cache[$name] = $found;
102
    }
103
104
    /**
105
     * @param string $name
106
     *
107
     * @return string|null
108
     */
109 6
    private function findTemplate($name)
110
    {
111 6
        $files = $this->possibleTemplateFiles($name);
112
113 6
        foreach ($files as $file) {
114 6
            $filepath = $this->path . DIRECTORY_SEPARATOR . $file;
115 6
            if (is_file($filepath) && is_readable($filepath)) {
116 6
                return realpath($filepath);
117
            }
118
        }
119
120 1
        return null;
121
    }
122
123
    /**
124
     * @param string $name
125
     *
126
     * @return Generator
127
     */
128 6
    private function possibleTemplateFiles($name)
129
    {
130 6
        yield $name = $this->normalizeName($name);
131
132 2
        foreach ($this->fileExtensions as $extension) {
133 1
            yield "{$name}.{$extension}";
134
        }
135 1
    }
136
137
    /**
138
     * @param string $name
139
     *
140
     * @return string
141
     */
142 6
    private function normalizeName($name)
143
    {
144 6
        return preg_replace('#/{2,}#',
145 6
            DIRECTORY_SEPARATOR,
146 6
            str_replace('\\', DIRECTORY_SEPARATOR, $name)
147
        );
148
    }
149
}
150