This commit is contained in:
Nikola Svitlica a.k.a TheCelavi
2024-08-17 19:45:41 +02:00
parent b9b8d52572
commit 6ef13d1e0b
2 changed files with 53 additions and 15 deletions
+30 -12
View File
@@ -21,22 +21,33 @@ use Twig\Source;
*/ */
final class ChainLoader implements LoaderInterface final class ChainLoader implements LoaderInterface
{ {
private $hasSourceCache = []; /**
private $loaders = []; * @var \Traversable<LoaderInterface>|LoaderInterface[]
*/
private $loaders;
/** /**
* @param LoaderInterface[] $loaders * @var array<string, bool>
*/ */
public function __construct(array $loaders = []) private $hasSourceCache = [];
/**
* @param iterable<LoaderInterface> $loaders
*/
public function __construct(iterable $loaders = [])
{ {
foreach ($loaders as $loader) { $this->loaders = $loaders;
$this->addLoader($loader);
}
} }
public function addLoader(LoaderInterface $loader): void public function addLoader(LoaderInterface $loader): void
{ {
$this->loaders[] = $loader; $current = $this->loaders;
$this->loaders = (static function () use ($current, $loader): \Generator {
yield from $current;
yield $loader;
})();
$this->hasSourceCache = []; $this->hasSourceCache = [];
} }
@@ -45,13 +56,18 @@ final class ChainLoader implements LoaderInterface
*/ */
public function getLoaders(): array public function getLoaders(): array
{ {
if (!\is_array($this->loaders)) {
$this->loaders = \iterator_to_array($this->loaders, false);
}
return $this->loaders; return $this->loaders;
} }
public function getSourceContext(string $name): Source public function getSourceContext(string $name): Source
{ {
$exceptions = []; $exceptions = [];
foreach ($this->loaders as $loader) {
foreach ($this->getLoaders() as $loader) {
if (!$loader->exists($name)) { if (!$loader->exists($name)) {
continue; continue;
} }
@@ -72,7 +88,7 @@ final class ChainLoader implements LoaderInterface
return $this->hasSourceCache[$name]; return $this->hasSourceCache[$name];
} }
foreach ($this->loaders as $loader) { foreach ($this->getLoaders() as $loader) {
if ($loader->exists($name)) { if ($loader->exists($name)) {
return $this->hasSourceCache[$name] = true; return $this->hasSourceCache[$name] = true;
} }
@@ -84,7 +100,8 @@ final class ChainLoader implements LoaderInterface
public function getCacheKey(string $name): string public function getCacheKey(string $name): string
{ {
$exceptions = []; $exceptions = [];
foreach ($this->loaders as $loader) {
foreach ($this->getLoaders() as $loader) {
if (!$loader->exists($name)) { if (!$loader->exists($name)) {
continue; continue;
} }
@@ -102,7 +119,8 @@ final class ChainLoader implements LoaderInterface
public function isFresh(string $name, int $time): bool public function isFresh(string $name, int $time): bool
{ {
$exceptions = []; $exceptions = [];
foreach ($this->loaders as $loader) {
foreach ($this->getLoaders() as $loader) {
if (!$loader->exists($name)) { if (!$loader->exists($name)) {
continue; continue;
} }
+23 -3
View File
@@ -72,10 +72,30 @@ class ChainTest extends TestCase
public function testAddLoader() public function testAddLoader()
{ {
$loader = new ChainLoader(); $fooLoader = new ArrayLoader(['foo' => 'foo:code']);
$loader->addLoader(new ArrayLoader(['foo' => 'bar'])); $barLoader = new ArrayLoader(['bar' => 'bar:code']);
$bazLoader = new ArrayLoader(['baz' => 'baz:code']);
$quxLoader = new ArrayLoader(['qux' => 'qux:code']);
$this->assertEquals('bar', $loader->getSourceContext('foo')->getCode()); $loader = new ChainLoader((static function () use ($fooLoader, $barLoader): \Generator {
yield $fooLoader;
yield $barLoader;
})());
$loader->addLoader($bazLoader);
$loader->addLoader($quxLoader);
$this->assertEquals('foo:code', $loader->getSourceContext('foo')->getCode());
$this->assertEquals('bar:code', $loader->getSourceContext('bar')->getCode());
$this->assertEquals('baz:code', $loader->getSourceContext('baz')->getCode());
$this->assertEquals('qux:code', $loader->getSourceContext('qux')->getCode());
$this->assertEquals([
$fooLoader,
$barLoader,
$bazLoader,
$quxLoader,
], $loader->getLoaders());
} }
public function testExists() public function testExists()