1<?php 2 3/* 4 * This file is part of Twig. 5 * 6 * (c) Fabien Potencier 7 * 8 * For the full copyright and license information, please view the LICENSE 9 * file that was distributed with this source code. 10 */ 11 12namespace Twig\Loader; 13 14use Twig\Error\LoaderError; 15 16/** 17 * Loads templates from other loaders. 18 * 19 * @author Fabien Potencier <fabien@symfony.com> 20 */ 21final class ChainLoader implements LoaderInterface, ExistsLoaderInterface, SourceContextLoaderInterface 22{ 23 private $hasSourceCache = []; 24 private $loaders = []; 25 26 /** 27 * @param LoaderInterface[] $loaders 28 */ 29 public function __construct(array $loaders = []) 30 { 31 foreach ($loaders as $loader) { 32 $this->addLoader($loader); 33 } 34 } 35 36 public function addLoader(LoaderInterface $loader) 37 { 38 $this->loaders[] = $loader; 39 $this->hasSourceCache = []; 40 } 41 42 /** 43 * @return LoaderInterface[] 44 */ 45 public function getLoaders() 46 { 47 return $this->loaders; 48 } 49 50 public function getSourceContext($name) 51 { 52 $exceptions = []; 53 foreach ($this->loaders as $loader) { 54 if (!$loader->exists($name)) { 55 continue; 56 } 57 58 try { 59 return $loader->getSourceContext($name); 60 } catch (LoaderError $e) { 61 $exceptions[] = $e->getMessage(); 62 } 63 } 64 65 throw new LoaderError(sprintf('Template "%s" is not defined%s.', $name, $exceptions ? ' ('.implode(', ', $exceptions).')' : '')); 66 } 67 68 public function exists($name) 69 { 70 if (isset($this->hasSourceCache[$name])) { 71 return $this->hasSourceCache[$name]; 72 } 73 74 foreach ($this->loaders as $loader) { 75 if ($loader->exists($name)) { 76 return $this->hasSourceCache[$name] = true; 77 } 78 } 79 80 return $this->hasSourceCache[$name] = false; 81 } 82 83 public function getCacheKey($name) 84 { 85 $exceptions = []; 86 foreach ($this->loaders as $loader) { 87 if (!$loader->exists($name)) { 88 continue; 89 } 90 91 try { 92 return $loader->getCacheKey($name); 93 } catch (LoaderError $e) { 94 $exceptions[] = \get_class($loader).': '.$e->getMessage(); 95 } 96 } 97 98 throw new LoaderError(sprintf('Template "%s" is not defined%s.', $name, $exceptions ? ' ('.implode(', ', $exceptions).')' : '')); 99 } 100 101 public function isFresh($name, $time) 102 { 103 $exceptions = []; 104 foreach ($this->loaders as $loader) { 105 if (!$loader->exists($name)) { 106 continue; 107 } 108 109 try { 110 return $loader->isFresh($name, $time); 111 } catch (LoaderError $e) { 112 $exceptions[] = \get_class($loader).': '.$e->getMessage(); 113 } 114 } 115 116 throw new LoaderError(sprintf('Template "%s" is not defined%s.', $name, $exceptions ? ' ('.implode(', ', $exceptions).')' : '')); 117 } 118} 119 120class_alias('Twig\Loader\ChainLoader', 'Twig_Loader_Chain'); 121