Skip to content

Commit 6ef13d1

Browse files
committed
Resolves twigphp#4200
1 parent b9b8d52 commit 6ef13d1

File tree

2 files changed

+53
-15
lines changed

2 files changed

+53
-15
lines changed

src/Loader/ChainLoader.php

+29-11
Original file line numberDiff line numberDiff line change
@@ -21,22 +21,33 @@
2121
*/
2222
final class ChainLoader implements LoaderInterface
2323
{
24+
/**
25+
* @var \Traversable<LoaderInterface>|LoaderInterface[]
26+
*/
27+
private $loaders;
28+
29+
/**
30+
* @var array<string, bool>
31+
*/
2432
private $hasSourceCache = [];
25-
private $loaders = [];
2633

2734
/**
28-
* @param LoaderInterface[] $loaders
35+
* @param iterable<LoaderInterface> $loaders
2936
*/
30-
public function __construct(array $loaders = [])
37+
public function __construct(iterable $loaders = [])
3138
{
32-
foreach ($loaders as $loader) {
33-
$this->addLoader($loader);
34-
}
39+
$this->loaders = $loaders;
3540
}
3641

3742
public function addLoader(LoaderInterface $loader): void
3843
{
39-
$this->loaders[] = $loader;
44+
$current = $this->loaders;
45+
46+
$this->loaders = (static function () use ($current, $loader): \Generator {
47+
yield from $current;
48+
yield $loader;
49+
})();
50+
4051
$this->hasSourceCache = [];
4152
}
4253

@@ -45,13 +56,18 @@ public function addLoader(LoaderInterface $loader): void
4556
*/
4657
public function getLoaders(): array
4758
{
59+
if (!\is_array($this->loaders)) {
60+
$this->loaders = \iterator_to_array($this->loaders, false);
61+
}
62+
4863
return $this->loaders;
4964
}
5065

5166
public function getSourceContext(string $name): Source
5267
{
5368
$exceptions = [];
54-
foreach ($this->loaders as $loader) {
69+
70+
foreach ($this->getLoaders() as $loader) {
5571
if (!$loader->exists($name)) {
5672
continue;
5773
}
@@ -72,7 +88,7 @@ public function exists(string $name): bool
7288
return $this->hasSourceCache[$name];
7389
}
7490

75-
foreach ($this->loaders as $loader) {
91+
foreach ($this->getLoaders() as $loader) {
7692
if ($loader->exists($name)) {
7793
return $this->hasSourceCache[$name] = true;
7894
}
@@ -84,7 +100,8 @@ public function exists(string $name): bool
84100
public function getCacheKey(string $name): string
85101
{
86102
$exceptions = [];
87-
foreach ($this->loaders as $loader) {
103+
104+
foreach ($this->getLoaders() as $loader) {
88105
if (!$loader->exists($name)) {
89106
continue;
90107
}
@@ -102,7 +119,8 @@ public function getCacheKey(string $name): string
102119
public function isFresh(string $name, int $time): bool
103120
{
104121
$exceptions = [];
105-
foreach ($this->loaders as $loader) {
122+
123+
foreach ($this->getLoaders() as $loader) {
106124
if (!$loader->exists($name)) {
107125
continue;
108126
}

tests/Loader/ChainTest.php

+24-4
Original file line numberDiff line numberDiff line change
@@ -72,10 +72,30 @@ public function testGetCacheKeyWhenTemplateDoesNotExist()
7272

7373
public function testAddLoader()
7474
{
75-
$loader = new ChainLoader();
76-
$loader->addLoader(new ArrayLoader(['foo' => 'bar']));
77-
78-
$this->assertEquals('bar', $loader->getSourceContext('foo')->getCode());
75+
$fooLoader = new ArrayLoader(['foo' => 'foo:code']);
76+
$barLoader = new ArrayLoader(['bar' => 'bar:code']);
77+
$bazLoader = new ArrayLoader(['baz' => 'baz:code']);
78+
$quxLoader = new ArrayLoader(['qux' => 'qux:code']);
79+
80+
$loader = new ChainLoader((static function () use ($fooLoader, $barLoader): \Generator {
81+
yield $fooLoader;
82+
yield $barLoader;
83+
})());
84+
85+
$loader->addLoader($bazLoader);
86+
$loader->addLoader($quxLoader);
87+
88+
$this->assertEquals('foo:code', $loader->getSourceContext('foo')->getCode());
89+
$this->assertEquals('bar:code', $loader->getSourceContext('bar')->getCode());
90+
$this->assertEquals('baz:code', $loader->getSourceContext('baz')->getCode());
91+
$this->assertEquals('qux:code', $loader->getSourceContext('qux')->getCode());
92+
93+
$this->assertEquals([
94+
$fooLoader,
95+
$barLoader,
96+
$bazLoader,
97+
$quxLoader,
98+
], $loader->getLoaders());
7999
}
80100

81101
public function testExists()

0 commit comments

Comments
 (0)