1
|
|
|
<?php |
2
|
|
|
|
3
|
|
|
/* |
4
|
|
|
* This file is part of the puli/twig-puli-extension package. |
5
|
|
|
* |
6
|
|
|
* (c) Bernhard Schussek <[email protected]> |
7
|
|
|
* |
8
|
|
|
* For the full copyright and license information, please view the LICENSE |
9
|
|
|
* file that was distributed with this source code. |
10
|
|
|
*/ |
11
|
|
|
|
12
|
|
|
namespace Puli\TwigExtension; |
13
|
|
|
|
14
|
|
|
use InvalidArgumentException; |
15
|
|
|
use Puli\Repository\Api\Resource\BodyResource; |
16
|
|
|
use Puli\Repository\Api\ResourceNotFoundException; |
17
|
|
|
use Puli\Repository\Api\ResourceRepository; |
18
|
|
|
use Puli\Repository\Resource\LinkResource; |
19
|
|
|
use Twig_Error_Loader; |
20
|
|
|
use Twig_ExistsLoaderInterface; |
21
|
|
|
use Twig_LoaderInterface; |
22
|
|
|
|
23
|
|
|
/** |
24
|
|
|
* @since 1.0 |
25
|
|
|
* |
26
|
|
|
* @author Bernhard Schussek <[email protected]> |
27
|
|
|
*/ |
28
|
|
|
class PuliTemplateLoader implements Twig_LoaderInterface, Twig_ExistsLoaderInterface |
|
|
|
|
29
|
|
|
{ |
30
|
|
|
private $repo; |
31
|
|
|
|
32
|
26 |
|
public function __construct(ResourceRepository $repo) |
33
|
|
|
{ |
34
|
26 |
|
$this->repo = $repo; |
35
|
26 |
|
} |
36
|
|
|
|
37
|
|
|
/** |
38
|
|
|
* Gets the source code of a template, given its name. |
39
|
|
|
* |
40
|
|
|
* @param string $path The name of the template to load |
41
|
|
|
* |
42
|
|
|
* @return string The template source code |
43
|
|
|
* |
44
|
|
|
* @throws Twig_Error_Loader When $path is not found |
45
|
|
|
*/ |
46
|
20 |
View Code Duplication |
public function getSource($path) |
|
|
|
|
47
|
|
|
{ |
48
|
|
|
try { |
49
|
|
|
// The "loaded_by_puli" tag makes it possible to recognize node |
50
|
|
|
// trees of templates loaded through this loader. In this way, we |
51
|
|
|
// can turn relative Puli paths into absolute ones in those |
52
|
|
|
// templates. The "loaded_by_puli" tag is removed early on by the |
53
|
|
|
// PuliDirTagger visitor and does not appear in the final |
54
|
|
|
// output. |
55
|
20 |
|
return '{% loaded_by_puli %}'.$this->getResource($path)->getBody(); |
56
|
1 |
|
} catch (ResourceNotFoundException $e) { |
57
|
|
|
throw new Twig_Error_Loader($e->getMessage(), -1, null, $e); |
58
|
1 |
|
} catch (InvalidArgumentException $e) { |
59
|
|
|
throw new Twig_Error_Loader($e->getMessage(), -1, null, $e); |
60
|
|
|
} |
61
|
|
|
} |
62
|
|
|
|
63
|
|
|
/** |
64
|
|
|
* Gets the cache key to use for the cache for a given template name. |
65
|
|
|
* |
66
|
|
|
* @param string $path The name of the template to load |
67
|
|
|
* |
68
|
|
|
* @return string The cache key |
69
|
|
|
* |
70
|
|
|
* @throws Twig_Error_Loader When $path is not found |
71
|
|
|
*/ |
72
|
19 |
View Code Duplication |
public function getCacheKey($path) |
|
|
|
|
73
|
|
|
{ |
74
|
|
|
try { |
75
|
|
|
// Even though the path and $path are the same, call the locator to |
76
|
|
|
// make sure that the path actually exists |
77
|
|
|
// The result of this method MUST NOT be the real path (without |
78
|
|
|
// prefix), because then the generated file has the same cache |
79
|
|
|
// key as the same template loaded through a different loader. |
80
|
|
|
// If loaded through a different loader, relative paths won't be |
81
|
|
|
// resolved, so we'll have the wrong version of the template in |
82
|
|
|
// he cache. |
83
|
19 |
|
return '__puli__'.$this->getResource($path)->getPath(); |
84
|
1 |
|
} catch (ResourceNotFoundException $e) { |
85
|
1 |
|
throw new Twig_Error_Loader($e->getMessage(), -1, null, $e); |
86
|
|
|
} catch (InvalidArgumentException $e) { |
87
|
|
|
throw new Twig_Error_Loader($e->getMessage(), -1, null, $e); |
88
|
|
|
} |
89
|
|
|
} |
90
|
|
|
|
91
|
|
|
/** |
92
|
|
|
* Returns true if the template is still fresh. |
93
|
|
|
* |
94
|
|
|
* @param string $path The template name |
95
|
|
|
* @param int $time The last modification time of the cached template |
96
|
|
|
* |
97
|
|
|
* @return bool true if the template is fresh, false otherwise |
98
|
|
|
* |
99
|
|
|
* @throws Twig_Error_Loader When $path is not found |
100
|
|
|
*/ |
101
|
1 |
View Code Duplication |
public function isFresh($path, $time) |
|
|
|
|
102
|
|
|
{ |
103
|
|
|
try { |
104
|
1 |
|
return $this->getResource($path)->getMetadata()->getModificationTime() <= $time; |
105
|
1 |
|
} catch (ResourceNotFoundException $e) { |
106
|
|
|
throw new Twig_Error_Loader($e->getMessage(), -1, null, $e); |
107
|
1 |
|
} catch (InvalidArgumentException $e) { |
108
|
|
|
throw new Twig_Error_Loader($e->getMessage(), -1, null, $e); |
109
|
|
|
} |
110
|
|
|
} |
111
|
|
|
|
112
|
|
|
/** |
113
|
|
|
* Check if we have the source code of a template, given its name. |
114
|
|
|
* |
115
|
|
|
* @param string $name The name of the template to check if we can load |
116
|
|
|
* |
117
|
|
|
* @return bool If the template source code is handled by this loader or not |
118
|
|
|
*/ |
119
|
6 |
|
public function exists($name) |
120
|
|
|
{ |
121
|
|
|
try { |
122
|
6 |
|
return $this->repo->contains($name); |
123
|
5 |
|
} catch (InvalidArgumentException $e) { |
124
|
5 |
|
return false; |
125
|
|
|
} |
126
|
|
|
} |
127
|
|
|
|
128
|
21 |
|
private function getResource($path) |
129
|
|
|
{ |
130
|
21 |
|
$resource = $this->repo->get($path); |
131
|
|
|
|
132
|
21 |
|
while ($resource instanceof LinkResource) { |
133
|
1 |
|
$resource = $this->repo->get($resource->getTargetPath()); |
134
|
|
|
} |
135
|
|
|
|
136
|
21 |
|
if (!$resource instanceof BodyResource) { |
137
|
2 |
|
throw new Twig_Error_Loader(sprintf( |
138
|
2 |
|
'Can only load file resources. Resource "%s" is of type %s.', |
139
|
|
|
$path, |
140
|
2 |
|
is_object($resource) ? get_class($resource) : gettype($resource) |
141
|
|
|
)); |
142
|
|
|
} |
143
|
|
|
|
144
|
19 |
|
return $resource; |
145
|
|
|
} |
146
|
|
|
} |
147
|
|
|
|
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.