Modified some paths to be more generic and not require rewrite. Some instances of phase names have been changed, others are still in process.
261 lines
6.8 KiB
PHP
261 lines
6.8 KiB
PHP
<?php
|
|
|
|
/*
|
|
* This file is part of Twig.
|
|
*
|
|
* (c) 2009 Fabien Potencier
|
|
*
|
|
* For the full copyright and license information, please view the LICENSE
|
|
* file that was distributed with this source code.
|
|
*/
|
|
|
|
/**
|
|
* Loads template from the filesystem.
|
|
*
|
|
* @author Fabien Potencier <fabien@symfony.com>
|
|
*/
|
|
class Twig_Loader_Filesystem implements Twig_LoaderInterface, Twig_ExistsLoaderInterface
|
|
{
|
|
/** Identifier of the main namespace. */
|
|
const MAIN_NAMESPACE = '__main__';
|
|
|
|
protected $paths = array();
|
|
protected $cache = array();
|
|
protected $errorCache = array();
|
|
|
|
/**
|
|
* Constructor.
|
|
*
|
|
* @param string|array $paths A path or an array of paths where to look for templates
|
|
*/
|
|
public function __construct($paths = array())
|
|
{
|
|
if ($paths) {
|
|
$this->setPaths($paths);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Returns the paths to the templates.
|
|
*
|
|
* @param string $namespace A path namespace
|
|
*
|
|
* @return array The array of paths where to look for templates
|
|
*/
|
|
public function getPaths($namespace = self::MAIN_NAMESPACE)
|
|
{
|
|
return isset($this->paths[$namespace]) ? $this->paths[$namespace] : array();
|
|
}
|
|
|
|
/**
|
|
* Returns the path namespaces.
|
|
*
|
|
* The main namespace is always defined.
|
|
*
|
|
* @return array The array of defined namespaces
|
|
*/
|
|
public function getNamespaces()
|
|
{
|
|
return array_keys($this->paths);
|
|
}
|
|
|
|
/**
|
|
* Sets the paths where templates are stored.
|
|
*
|
|
* @param string|array $paths A path or an array of paths where to look for templates
|
|
* @param string $namespace A path namespace
|
|
*/
|
|
public function setPaths($paths, $namespace = self::MAIN_NAMESPACE)
|
|
{
|
|
if (!is_array($paths)) {
|
|
$paths = array($paths);
|
|
}
|
|
|
|
$this->paths[$namespace] = array();
|
|
foreach ($paths as $path) {
|
|
$this->addPath($path, $namespace);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Adds a path where templates are stored.
|
|
*
|
|
* @param string $path A path where to look for templates
|
|
* @param string $namespace A path name
|
|
*
|
|
* @throws Twig_Error_Loader
|
|
*/
|
|
public function addPath($path, $namespace = self::MAIN_NAMESPACE)
|
|
{
|
|
// invalidate the cache
|
|
$this->cache = $this->errorCache = array();
|
|
|
|
if (!is_dir($path)) {
|
|
throw new Twig_Error_Loader(sprintf('The "%s" directory does not exist.', $path));
|
|
}
|
|
|
|
$this->paths[$namespace][] = rtrim($path, '/\\');
|
|
}
|
|
|
|
/**
|
|
* Prepends a path where templates are stored.
|
|
*
|
|
* @param string $path A path where to look for templates
|
|
* @param string $namespace A path name
|
|
*
|
|
* @throws Twig_Error_Loader
|
|
*/
|
|
public function prependPath($path, $namespace = self::MAIN_NAMESPACE)
|
|
{
|
|
// invalidate the cache
|
|
$this->cache = $this->errorCache = array();
|
|
|
|
if (!is_dir($path)) {
|
|
throw new Twig_Error_Loader(sprintf('The "%s" directory does not exist.', $path));
|
|
}
|
|
|
|
$path = rtrim($path, '/\\');
|
|
|
|
if (!isset($this->paths[$namespace])) {
|
|
$this->paths[$namespace][] = $path;
|
|
} else {
|
|
array_unshift($this->paths[$namespace], $path);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* {@inheritdoc}
|
|
*/
|
|
public function getSource($name)
|
|
{
|
|
return file_get_contents($this->findTemplate($name));
|
|
}
|
|
|
|
/**
|
|
* {@inheritdoc}
|
|
*/
|
|
public function getCacheKey($name)
|
|
{
|
|
return $this->findTemplate($name);
|
|
}
|
|
|
|
/**
|
|
* {@inheritdoc}
|
|
*/
|
|
public function exists($name)
|
|
{
|
|
$name = $this->normalizeName($name);
|
|
|
|
if (isset($this->cache[$name])) {
|
|
return true;
|
|
}
|
|
|
|
try {
|
|
return false !== $this->findTemplate($name, false);
|
|
} catch (Twig_Error_Loader $exception) {
|
|
return false;
|
|
}
|
|
}
|
|
|
|
/**
|
|
* {@inheritdoc}
|
|
*/
|
|
public function isFresh($name, $time)
|
|
{
|
|
return filemtime($this->findTemplate($name)) <= $time;
|
|
}
|
|
|
|
protected function findTemplate($name)
|
|
{
|
|
$throw = func_num_args() > 1 ? func_get_arg(1) : true;
|
|
$name = $this->normalizeName($name);
|
|
|
|
if (isset($this->cache[$name])) {
|
|
return $this->cache[$name];
|
|
}
|
|
|
|
if (isset($this->errorCache[$name])) {
|
|
if (!$throw) {
|
|
return false;
|
|
}
|
|
|
|
throw new Twig_Error_Loader($this->errorCache[$name]);
|
|
}
|
|
|
|
$this->validateName($name);
|
|
|
|
list($namespace, $shortname) = $this->parseName($name);
|
|
|
|
if (!isset($this->paths[$namespace])) {
|
|
$this->errorCache[$name] = sprintf('There are no registered paths for namespace "%s".', $namespace);
|
|
|
|
if (!$throw) {
|
|
return false;
|
|
}
|
|
|
|
throw new Twig_Error_Loader($this->errorCache[$name]);
|
|
}
|
|
|
|
foreach ($this->paths[$namespace] as $path) {
|
|
if (is_file($path.'/'.$shortname)) {
|
|
if (false !== $realpath = realpath($path.'/'.$shortname)) {
|
|
return $this->cache[$name] = $realpath;
|
|
}
|
|
|
|
return $this->cache[$name] = $path.'/'.$shortname;
|
|
}
|
|
}
|
|
|
|
$this->errorCache[$name] = sprintf('Unable to find template "%s" (looked into: %s).', $name, implode(', ', $this->paths[$namespace]));
|
|
|
|
if (!$throw) {
|
|
return false;
|
|
}
|
|
|
|
throw new Twig_Error_Loader($this->errorCache[$name]);
|
|
}
|
|
|
|
protected function parseName($name, $default = self::MAIN_NAMESPACE)
|
|
{
|
|
if (isset($name[0]) && '@' == $name[0]) {
|
|
if (false === $pos = strpos($name, '/')) {
|
|
throw new Twig_Error_Loader(sprintf('Malformed namespaced template name "%s" (expecting "@namespace/template_name").', $name));
|
|
}
|
|
|
|
$namespace = substr($name, 1, $pos - 1);
|
|
$shortname = substr($name, $pos + 1);
|
|
|
|
return array($namespace, $shortname);
|
|
}
|
|
|
|
return array($default, $name);
|
|
}
|
|
|
|
protected function normalizeName($name)
|
|
{
|
|
return preg_replace('#/{2,}#', '/', str_replace('\\', '/', (string) $name));
|
|
}
|
|
|
|
protected function validateName($name)
|
|
{
|
|
if (false !== strpos($name, "\0")) {
|
|
throw new Twig_Error_Loader('A template name cannot contain NUL bytes.');
|
|
}
|
|
|
|
$name = ltrim($name, '/');
|
|
$parts = explode('/', $name);
|
|
$level = 0;
|
|
foreach ($parts as $part) {
|
|
if ('..' === $part) {
|
|
--$level;
|
|
} elseif ('.' !== $part) {
|
|
++$level;
|
|
}
|
|
|
|
if ($level < 0) {
|
|
throw new Twig_Error_Loader(sprintf('Looks like you try to load a template outside configured directories (%s).', $name));
|
|
}
|
|
}
|
|
}
|
|
}
|