-
Notifications
You must be signed in to change notification settings - Fork 1
/
TemplateNameMapper.php
107 lines (93 loc) · 2.95 KB
/
TemplateNameMapper.php
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
<?php
/*
* This file is part of Mannequin.
*
* (c) 2017 Last Call Media, Rob Bayliss <[email protected]>
*
* This source file is subject to the MIT license that is bundled
* with this source code in the file LICENSE.
*/
namespace LastCall\Mannequin\Twig;
/**
* Maps an absolute file path back to a name that Twig will know it by.
*
* Used to convert SplFileInfo objects returned by a Finder to usable template
* names.
*/
class TemplateNameMapper
{
private $twigRoot;
private $namespaces = [];
private $_map;
const MAIN_NAMESPACE = '__main__';
public function __construct(string $twigRoot)
{
$this->twigRoot = $twigRoot;
$this->addNamespace(self::MAIN_NAMESPACE, $twigRoot);
}
public function addNamespace($namespace, $paths)
{
// Destroy the lookup map and cache. It will be recreated.
$this->_map = $this->_cache = null;
$this->namespaces[$namespace] = [];
foreach ((array) $paths as $path) {
$this->namespaces[$namespace][] = rtrim($path, '/\\');
}
}
/**
* Lookup the possible twig names that correspond with a given filename.
*
* This method is performance-sensitive.
*
* @param $filename
*
* @return mixed
*/
public function getTemplateNamesForFilename($filename)
{
$map = $this->getMap();
$matching = array_filter(array_keys($map), function ($path) use ($filename) {
return $filename[0] === $path[0] && 0 === strpos($filename, $path);
});
$templateNames = [];
foreach ($matching as $match) {
$namespace = $map[$match];
$templateNames[] = self::MAIN_NAMESPACE === $namespace
? ltrim(substr($filename, strlen($match)), '/\\')
: '@'.$namespace.substr($filename, strlen($match));
}
return $templateNames;
}
public function __invoke($templateNameOrFilename)
{
if ($templateNameOrFilename instanceof \SplFileInfo) {
return $this->getTemplateNamesForFilename($templateNameOrFilename->getPathname());
}
return $templateNameOrFilename;
}
private function getMap()
{
if (!isset($this->_map)) {
$this->_map = [];
foreach ($this->namespaces as $namespace => $paths) {
foreach ($paths as $path) {
if (!$this->isAbsolutePath($path)) {
$path = $this->twigRoot.'/'.$path;
}
$this->_map[$path] = $namespace;
}
}
}
return $this->_map;
}
private function isAbsolutePath($file)
{
return strspn($file, '/\\', 0, 1)
|| (strlen($file) > 3 && ctype_alpha($file[0])
&& ':' === substr($file, 1, 1)
&& strspn($file, '/\\', 2, 1)
)
|| null !== parse_url($file, PHP_URL_SCHEME)
;
}
}