1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081 |
- <?php
-
-
-
-
- class Twig_Environment
- {
- const VERSION = '1.7.0';
-
- protected $charset;
- protected $loader;
- protected $debug;
- protected $autoReload;
- protected $cache;
- protected $lexer;
- protected $parser;
- protected $compiler;
- protected $baseTemplateClass;
- protected $extensions;
- protected $parsers;
- protected $visitors;
- protected $filters;
- protected $tests;
- protected $functions;
- protected $globals;
- protected $runtimeInitialized;
- protected $loadedTemplates;
- protected $strictVariables;
- protected $unaryOperators;
- protected $binaryOperators;
- protected $templateClassPrefix = '__TwigTemplate_';
- protected $functionCallbacks;
- protected $filterCallbacks;
- protected $staging;
-
-
-
- public function __construct(Twig_LoaderInterface $loader = null, $options = array())
- {
- if (null !== $loader) {
- $this->setLoader($loader);
- }
-
- $options = array_merge(array(
- 'debug' => false,
- 'charset' => 'UTF-8',
- 'base_template_class' => 'Twig_Template',
- 'strict_variables' => false,
- 'autoescape' => true,
- 'cache' => false,
- 'auto_reload' => null,
- 'optimizations' => -1,
- ), $options);
-
- $this->debug = (bool) $options['debug'];
- $this->charset = $options['charset'];
- $this->baseTemplateClass = $options['base_template_class'];
- $this->autoReload = null === $options['auto_reload'] ? $this->debug : (bool) $options['auto_reload'];
- $this->extensions = array(
- 'core' => new Twig_Extension_Core(),
- 'escaper' => new Twig_Extension_Escaper((bool) $options['autoescape']),
- 'optimizer' => new Twig_Extension_Optimizer($options['optimizations']),
- );
- $this->strictVariables = (bool) $options['strict_variables'];
- $this->runtimeInitialized = false;
- $this->setCache($options['cache']);
- $this->functionCallbacks = array();
- $this->filterCallbacks = array();
- }
-
-
-
- public function getBaseTemplateClass()
- {
- return $this->baseTemplateClass;
- }
-
-
-
- public function setBaseTemplateClass($class)
- {
- $this->baseTemplateClass = $class;
- }
-
-
-
- public function enableDebug()
- {
- $this->debug = true;
- }
-
-
-
- public function disableDebug()
- {
- $this->debug = false;
- }
-
-
-
- public function isDebug()
- {
- return $this->debug;
- }
-
-
-
- public function enableAutoReload()
- {
- $this->autoReload = true;
- }
-
-
-
- public function disableAutoReload()
- {
- $this->autoReload = false;
- }
-
-
-
- public function isAutoReload()
- {
- return $this->autoReload;
- }
-
-
-
- public function enableStrictVariables()
- {
- $this->strictVariables = true;
- }
-
-
-
- public function disableStrictVariables()
- {
- $this->strictVariables = false;
- }
-
-
-
- public function isStrictVariables()
- {
- return $this->strictVariables;
- }
-
-
-
- public function getCache()
- {
- return $this->cache;
- }
-
-
-
- public function setCache($cache)
- {
- $this->cache = $cache ? $cache : false;
- }
-
-
-
- public function getCacheFilename($name)
- {
- if (false === $this->cache) {
- return false;
- }
-
- $class = substr($this->getTemplateClass($name), strlen($this->templateClassPrefix));
-
- return $this->getCache().'/'.substr($class, 0, 2).'/'.substr($class, 2, 2).'/'.substr($class, 4).'.php';
- }
-
-
-
- public function getTemplateClass($name)
- {
- return $this->templateClassPrefix.md5($this->loader->getCacheKey($name));
- }
-
-
-
- public function getTemplateClassPrefix()
- {
- return $this->templateClassPrefix;
- }
-
-
-
- public function render($name, array $context = array())
- {
- return $this->loadTemplate($name)->render($context);
- }
-
-
-
- public function display($name, array $context = array())
- {
- $this->loadTemplate($name)->display($context);
- }
-
-
-
- public function loadTemplate($name)
- {
- $cls = $this->getTemplateClass($name);
-
- if (isset($this->loadedTemplates[$cls])) {
- return $this->loadedTemplates[$cls];
- }
-
- if (!class_exists($cls, false)) {
- if (false === $cache = $this->getCacheFilename($name)) {
- eval('?>'.$this->compileSource($this->loader->getSource($name), $name));
- } else {
- if (!is_file($cache) || ($this->isAutoReload() && !$this->isTemplateFresh($name, filemtime($cache)))) {
- $this->writeCacheFile($cache, $this->compileSource($this->loader->getSource($name), $name));
- }
-
- require_once $cache;
- }
- }
-
- if (!$this->runtimeInitialized) {
- $this->initRuntime();
- }
-
- return $this->loadedTemplates[$cls] = new $cls($this);
- }
-
-
-
- public function isTemplateFresh($name, $time)
- {
- foreach ($this->extensions as $extension) {
- $r = new ReflectionObject($extension);
- if (filemtime($r->getFileName()) > $time) {
- return false;
- }
- }
-
- return $this->loader->isFresh($name, $time);
- }
-
- public function resolveTemplate($names)
- {
- if (!is_array($names)) {
- $names = array($names);
- }
-
- foreach ($names as $name) {
- if ($name instanceof Twig_Template) {
- return $name;
- }
-
- try {
- return $this->loadTemplate($name);
- } catch (Twig_Error_Loader $e) {
- }
- }
-
- if (1 === count($names)) {
- throw $e;
- }
-
- throw new Twig_Error_Loader(sprintf('Unable to find one of the following templates: "%s".', implode('", "', $names)));
- }
-
-
-
- public function clearTemplateCache()
- {
- $this->loadedTemplates = array();
- }
-
-
-
- public function clearCacheFiles()
- {
- if (false === $this->cache) {
- return;
- }
-
- foreach (new RecursiveIteratorIterator(new RecursiveDirectoryIterator($this->cache), RecursiveIteratorIterator::LEAVES_ONLY) as $file) {
- if ($file->isFile()) {
- @unlink($file->getPathname());
- }
- }
- }
-
-
-
- public function getLexer()
- {
- if (null === $this->lexer) {
- $this->lexer = new Twig_Lexer($this);
- }
-
- return $this->lexer;
- }
-
-
-
- public function setLexer(Twig_LexerInterface $lexer)
- {
- $this->lexer = $lexer;
- }
-
-
-
- public function tokenize($source, $name = null)
- {
- return $this->getLexer()->tokenize($source, $name);
- }
-
-
-
- public function getParser()
- {
- if (null === $this->parser) {
- $this->parser = new Twig_Parser($this);
- }
-
- return $this->parser;
- }
-
-
-
- public function setParser(Twig_ParserInterface $parser)
- {
- $this->parser = $parser;
- }
-
-
-
- public function parse(Twig_TokenStream $tokens)
- {
- return $this->getParser()->parse($tokens);
- }
-
-
-
- public function getCompiler()
- {
- if (null === $this->compiler) {
- $this->compiler = new Twig_Compiler($this);
- }
-
- return $this->compiler;
- }
-
-
-
- public function setCompiler(Twig_CompilerInterface $compiler)
- {
- $this->compiler = $compiler;
- }
-
-
-
- public function compile(Twig_NodeInterface $node)
- {
- return $this->getCompiler()->compile($node)->getSource();
- }
-
-
-
- public function compileSource($source, $name = null)
- {
- try {
- return $this->compile($this->parse($this->tokenize($source, $name)));
- } catch (Twig_Error $e) {
- $e->setTemplateFile($name);
- throw $e;
- } catch (Exception $e) {
- throw new Twig_Error_Runtime(sprintf('An exception has been thrown during the compilation of a template ("%s").', $e->getMessage()), -1, $name, $e);
- }
- }
-
-
-
- public function setLoader(Twig_LoaderInterface $loader)
- {
- $this->loader = $loader;
- }
-
-
-
- public function getLoader()
- {
- return $this->loader;
- }
-
-
-
- public function setCharset($charset)
- {
- $this->charset = $charset;
- }
-
-
-
- public function getCharset()
- {
- return $this->charset;
- }
-
-
-
- public function initRuntime()
- {
- $this->runtimeInitialized = true;
-
- foreach ($this->getExtensions() as $extension) {
- $extension->initRuntime($this);
- }
- }
-
-
-
- public function hasExtension($name)
- {
- return isset($this->extensions[$name]);
- }
-
-
-
- public function getExtension($name)
- {
- if (!isset($this->extensions[$name])) {
- throw new Twig_Error_Runtime(sprintf('The "%s" extension is not enabled.', $name));
- }
-
- return $this->extensions[$name];
- }
-
-
-
- public function addExtension(Twig_ExtensionInterface $extension)
- {
- $this->extensions[$extension->getName()] = $extension;
- $this->parsers = null;
- $this->visitors = null;
- $this->filters = null;
- $this->tests = null;
- $this->functions = null;
- $this->globals = null;
- }
-
-
-
- public function removeExtension($name)
- {
- unset($this->extensions[$name]);
- $this->parsers = null;
- $this->visitors = null;
- $this->filters = null;
- $this->tests = null;
- $this->functions = null;
- $this->globals = null;
- }
-
-
-
- public function setExtensions(array $extensions)
- {
- foreach ($extensions as $extension) {
- $this->addExtension($extension);
- }
- }
-
-
-
- public function getExtensions()
- {
- return $this->extensions;
- }
-
-
-
- public function addTokenParser(Twig_TokenParserInterface $parser)
- {
- $this->staging['token_parsers'][] = $parser;
- $this->parsers = null;
- }
-
-
-
- public function getTokenParsers()
- {
- if (null === $this->parsers) {
- $this->parsers = new Twig_TokenParserBroker();
-
- if (isset($this->staging['token_parsers'])) {
- foreach ($this->staging['token_parsers'] as $parser) {
- $this->parsers->addTokenParser($parser);
- }
- }
-
- foreach ($this->getExtensions() as $extension) {
- $parsers = $extension->getTokenParsers();
- foreach($parsers as $parser) {
- if ($parser instanceof Twig_TokenParserInterface) {
- $this->parsers->addTokenParser($parser);
- } elseif ($parser instanceof Twig_TokenParserBrokerInterface) {
- $this->parsers->addTokenParserBroker($parser);
- } else {
- throw new Twig_Error_Runtime('getTokenParsers() must return an array of Twig_TokenParserInterface or Twig_TokenParserBrokerInterface instances');
- }
- }
- }
- }
-
- return $this->parsers;
- }
-
-
-
- public function getTags()
- {
- $tags = array();
- foreach ($this->getTokenParsers()->getParsers() as $parser) {
- if ($parser instanceof Twig_TokenParserInterface) {
- $tags[$parser->getTag()] = $parser;
- }
- }
-
- return $tags;
- }
-
-
-
- public function addNodeVisitor(Twig_NodeVisitorInterface $visitor)
- {
- $this->staging['visitors'][] = $visitor;
- $this->visitors = null;
- }
-
-
-
- public function getNodeVisitors()
- {
- if (null === $this->visitors) {
- $this->visitors = isset($this->staging['visitors']) ? $this->staging['visitors'] : array();
- foreach ($this->getExtensions() as $extension) {
- $this->visitors = array_merge($this->visitors, $extension->getNodeVisitors());
- }
- }
-
- return $this->visitors;
- }
-
-
-
- public function addFilter($name, Twig_FilterInterface $filter)
- {
- $this->staging['filters'][$name] = $filter;
- $this->filters = null;
- }
-
-
-
- public function getFilter($name)
- {
- if (null === $this->filters) {
- $this->getFilters();
- }
-
- if (isset($this->filters[$name])) {
- return $this->filters[$name];
- }
-
- foreach ($this->filters as $pattern => $filter) {
- $pattern = str_replace('\\*', '(.*?)', preg_quote($pattern, '#'), $count);
-
- if ($count) {
- if (preg_match('#^'.$pattern.'$#', $name, $matches)) {
- array_shift($matches);
- $filter->setArguments($matches);
-
- return $filter;
- }
- }
- }
-
- foreach ($this->filterCallbacks as $callback) {
- if (false !== $filter = call_user_func($callback, $name)) {
- return $filter;
- }
- }
-
- return false;
- }
-
- public function registerUndefinedFilterCallback($callable)
- {
- $this->filterCallbacks[] = $callable;
- }
-
-
-
- public function getFilters()
- {
- if (null === $this->filters) {
- $this->filters = isset($this->staging['filters']) ? $this->staging['filters'] : array();
- foreach ($this->getExtensions() as $extension) {
- $this->filters = array_merge($this->filters, $extension->getFilters());
- }
- }
-
- return $this->filters;
- }
-
-
-
- public function addTest($name, Twig_TestInterface $test)
- {
- $this->staging['tests'][$name] = $test;
- $this->tests = null;
- }
-
-
-
- public function getTests()
- {
- if (null === $this->tests) {
- $this->tests = isset($this->staging['tests']) ? $this->staging['tests'] : array();
- foreach ($this->getExtensions() as $extension) {
- $this->tests = array_merge($this->tests, $extension->getTests());
- }
- }
-
- return $this->tests;
- }
-
-
-
- public function addFunction($name, Twig_FunctionInterface $function)
- {
- $this->staging['functions'][$name] = $function;
- $this->functions = null;
- }
-
-
-
- public function getFunction($name)
- {
- if (null === $this->functions) {
- $this->getFunctions();
- }
-
- if (isset($this->functions[$name])) {
- return $this->functions[$name];
- }
-
- foreach ($this->functions as $pattern => $function) {
- $pattern = str_replace('\\*', '(.*?)', preg_quote($pattern, '#'), $count);
-
- if ($count) {
- if (preg_match('#^'.$pattern.'$#', $name, $matches)) {
- array_shift($matches);
- $function->setArguments($matches);
-
- return $function;
- }
- }
- }
-
- foreach ($this->functionCallbacks as $callback) {
- if (false !== $function = call_user_func($callback, $name)) {
- return $function;
- }
- }
-
- return false;
- }
-
- public function registerUndefinedFunctionCallback($callable)
- {
- $this->functionCallbacks[] = $callable;
- }
-
-
-
- public function getFunctions()
- {
- if (null === $this->functions) {
- $this->functions = isset($this->staging['functions']) ? $this->staging['functions'] : array();
- foreach ($this->getExtensions() as $extension) {
- $this->functions = array_merge($this->functions, $extension->getFunctions());
- }
- }
-
- return $this->functions;
- }
-
-
-
- public function addGlobal($name, $value)
- {
- $this->staging['globals'][$name] = $value;
- $this->globals = null;
- }
-
-
-
- public function getGlobals()
- {
- if (null === $this->globals) {
- $this->globals = isset($this->staging['globals']) ? $this->staging['globals'] : array();
- foreach ($this->getExtensions() as $extension) {
- $this->globals = array_merge($this->globals, $extension->getGlobals());
- }
- }
-
- return $this->globals;
- }
-
-
-
- public function mergeGlobals(array $context)
- {
-
-
- foreach ($this->getGlobals() as $key => $value) {
- if (!array_key_exists($key, $context)) {
- $context[$key] = $value;
- }
- }
-
- return $context;
- }
-
-
-
- public function getUnaryOperators()
- {
- if (null === $this->unaryOperators) {
- $this->initOperators();
- }
-
- return $this->unaryOperators;
- }
-
-
-
- public function getBinaryOperators()
- {
- if (null === $this->binaryOperators) {
- $this->initOperators();
- }
-
- return $this->binaryOperators;
- }
-
- public function computeAlternatives($name, $items)
- {
- $alternatives = array();
- foreach ($items as $item) {
- $lev = levenshtein($name, $item);
- if ($lev <= strlen($name) / 3 || false !== strpos($item, $name)) {
- $alternatives[$item] = $lev;
- }
- }
- asort($alternatives);
-
- return array_keys($alternatives);
- }
-
- protected function initOperators()
- {
- $this->unaryOperators = array();
- $this->binaryOperators = array();
- foreach ($this->getExtensions() as $extension) {
- $operators = $extension->getOperators();
-
- if (!$operators) {
- continue;
- }
-
- if (2 !== count($operators)) {
- throw new InvalidArgumentException(sprintf('"%s::getOperators()" does not return a valid operators array.', get_class($extension)));
- }
-
- $this->unaryOperators = array_merge($this->unaryOperators, $operators[0]);
- $this->binaryOperators = array_merge($this->binaryOperators, $operators[1]);
- }
- }
-
- protected function writeCacheFile($file, $content)
- {
- $dir = dirname($file);
- if (!is_dir($dir)) {
- if (false === @mkdir($dir, 0777, true) && !is_dir($dir)) {
- throw new RuntimeException(sprintf("Unable to create the cache directory (%s).", $dir));
- }
- } elseif (!is_writable($dir)) {
- throw new RuntimeException(sprintf("Unable to write in the cache directory (%s).", $dir));
- }
-
- $tmpFile = tempnam(dirname($file), basename($file));
- if (false !== @file_put_contents($tmpFile, $content)) {
-
- if (@rename($tmpFile, $file) || (@copy($tmpFile, $file) && unlink($tmpFile))) {
- @chmod($file, 0644);
-
- return;
- }
- }
-
- throw new Twig_Error_Runtime(sprintf('Failed to write cache file "%s".', $file));
- }
- }
|