*/
class Twig_Environment
{
- const VERSION = '1.33.0';
- const VERSION_ID = 13300;
+ const VERSION = '1.35.4';
+ const VERSION_ID = 13504;
const MAJOR_VERSION = 1;
- const MINOR_VERSION = 33;
- const RELEASE_VERSION = 0;
+ const MINOR_VERSION = 35;
+ const RELEASE_VERSION = 4;
const EXTRA_VERSION = '';
protected $charset;
private $runtimeLoaders = array();
private $runtimes = array();
private $optionsHash;
+ private $loading = array();
/**
* Constructor.
// For BC
if (is_string($this->originalCache)) {
$r = new ReflectionMethod($this, 'writeCacheFile');
- if ($r->getDeclaringClass()->getName() !== __CLASS__) {
+ if (__CLASS__ !== $r->getDeclaringClass()->getName()) {
@trigger_error('The Twig_Environment::writeCacheFile method is deprecated since version 1.22 and will be removed in Twig 2.0.', E_USER_DEPRECATED);
$this->bcWriteCacheFile = true;
}
$r = new ReflectionMethod($this, 'getCacheFilename');
- if ($r->getDeclaringClass()->getName() !== __CLASS__) {
+ if (__CLASS__ !== $r->getDeclaringClass()->getName()) {
@trigger_error('The Twig_Environment::getCacheFilename method is deprecated since version 1.22 and will be removed in Twig 2.0.', E_USER_DEPRECATED);
$this->bcGetCacheFilename = true;
*
* @param string|Twig_TemplateWrapper|Twig_Template $name The template name
*
+ * @throws Twig_Error_Loader When the template cannot be found
+ * @throws Twig_Error_Runtime When a previously generated cache is corrupted
+ * @throws Twig_Error_Syntax When an error occurred during compilation
+ *
* @return Twig_TemplateWrapper
*/
public function load($name)
$this->initRuntime();
}
- return $this->loadedTemplates[$cls] = new $cls($this);
+ if (isset($this->loading[$cls])) {
+ throw new Twig_Error_Runtime(sprintf('Circular reference detected for Twig template "%s", path: %s.', $name, implode(' -> ', array_merge($this->loading, array($name)))));
+ }
+
+ $this->loading[$cls] = $name;
+
+ try {
+ $this->loadedTemplates[$cls] = new $cls($this);
+ unset($this->loading[$cls]);
+ } catch (\Exception $e) {
+ unset($this->loading[$cls]);
+
+ throw $e;
+ }
+
+ return $this->loadedTemplates[$cls];
}
/**
*/
public function createTemplate($template)
{
- $name = sprintf('__string_template__%s', hash('sha256', uniqid(mt_rand(), true), false));
+ $name = sprintf('__string_template__%s', hash('sha256', $template, false));
$loader = new Twig_Loader_Chain(array(
new Twig_Loader_Array(array($name => $template)),
/**
* Tries to load a template consecutively from an array.
*
- * Similar to loadTemplate() but it also accepts Twig_TemplateInterface instances and an array
- * of templates where each is tried to be loaded.
+ * Similar to loadTemplate() but it also accepts instances of Twig_Template and
+ * Twig_TemplateWrapper, and an array of templates where each is tried to be loaded.
*
- * @param string|Twig_Template|array $names A template or an array of templates to try consecutively
+ * @param string|Twig_Template|Twig_TemplateWrapper|array $names A template or an array of templates to try consecutively
*
- * @return Twig_Template
+ * @return Twig_Template|Twig_TemplateWrapper
*
* @throws Twig_Error_Loader When none of the templates can be found
* @throws Twig_Error_Syntax When an error occurred during compilation
return $name;
}
+ if ($name instanceof Twig_TemplateWrapper) {
+ return $name;
+ }
+
try {
return $this->loadTemplate($name);
} catch (Twig_Error_Loader $e) {
public function setLoader(Twig_LoaderInterface $loader)
{
- if (!$loader instanceof Twig_SourceContextLoaderInterface && 0 !== strpos(get_class($loader), 'Mock_Twig_LoaderInterface')) {
+ if (!$loader instanceof Twig_SourceContextLoaderInterface && 0 !== strpos(get_class($loader), 'Mock_')) {
@trigger_error(sprintf('Twig loader "%s" should implement Twig_SourceContextLoaderInterface since version 1.27.', get_class($loader)), E_USER_DEPRECATED);
}
public function hasExtension($class)
{
$class = ltrim($class, '\\');
+ if (!isset($this->extensionsByClass[$class]) && class_exists($class, false)) {
+ // For BC/FC with namespaced aliases
+ $class = new ReflectionClass($class);
+ $class = $class->name;
+ }
+
if (isset($this->extensions[$class])) {
if ($class !== get_class($this->extensions[$class])) {
@trigger_error(sprintf('Referencing the "%s" extension by its name (defined by getName()) is deprecated since 1.26 and will be removed in Twig 2.0. Use the Fully Qualified Extension Class Name instead.', $class), E_USER_DEPRECATED);
public function getExtension($class)
{
$class = ltrim($class, '\\');
+ if (!isset($this->extensionsByClass[$class]) && class_exists($class, false)) {
+ // For BC/FC with namespaced aliases
+ $class = new ReflectionClass($class);
+ $class = $class->name;
+ }
if (isset($this->extensions[$class])) {
if ($class !== get_class($this->extensions[$class])) {
}
$class = ltrim($name, '\\');
+ if (!isset($this->extensionsByClass[$class]) && class_exists($class, false)) {
+ // For BC/FC with namespaced aliases
+ $class = new ReflectionClass($class);
+ $class = $class->name;
+ }
+
if (isset($this->extensions[$class])) {
if ($class !== get_class($this->extensions[$class])) {
@trigger_error(sprintf('Referencing the "%s" extension by its name (defined by getName()) is deprecated since 1.26 and will be removed in Twig 2.0. Use the Fully Qualified Extension Class Name instead.', $class), E_USER_DEPRECATED);
$this->optionsHash = implode(':', $hashParts);
}
}
+
+class_alias('Twig_Environment', 'Twig\Environment', false);