Trunk updated to 0.9 git-svn-id: http://kusabax.cultnet.net/svn/repo/stable@176 73d99b7e-4f53-4972-b7b7-2ecd3c4d89ee
127 lines
4.8 KiB
PHP
127 lines
4.8 KiB
PHP
<?php
|
|
|
|
/**
|
|
* Extends another template, read more about template inheritance at {@link http://wiki.dwoo.org/index.php/TemplateInheritance}
|
|
* <pre>
|
|
* * file : the template to extend
|
|
* </pre>
|
|
* This software is provided 'as-is', without any express or implied warranty.
|
|
* In no event will the authors be held liable for any damages arising from the use of this software.
|
|
*
|
|
* @author Jordi Boggiano <j.boggiano@seld.be>
|
|
* @copyright Copyright (c) 2008, Jordi Boggiano
|
|
* @license http://dwoo.org/LICENSE Modified BSD License
|
|
* @link http://dwoo.org/
|
|
* @version 1.0.0
|
|
* @date 2008-10-23
|
|
* @package Dwoo
|
|
*/
|
|
class Dwoo_Plugin_extends extends Dwoo_Plugin implements Dwoo_ICompilable
|
|
{
|
|
protected static $childSource;
|
|
protected static $l;
|
|
protected static $r;
|
|
protected static $lastReplacement;
|
|
|
|
public static function compile(Dwoo_Compiler $compiler, $file)
|
|
{
|
|
list($l, $r) = $compiler->getDelimiters();
|
|
self::$l = preg_quote($l,'/');
|
|
self::$r = preg_quote($r,'/');
|
|
|
|
if ($compiler->getLooseOpeningHandling()) {
|
|
self::$l .= '\s*';
|
|
self::$r = '\s*'.self::$r;
|
|
}
|
|
$inheritanceTree = array(array('source'=>$compiler->getTemplateSource()));
|
|
$curPath = dirname($compiler->getDwoo()->getTemplate()->getResourceIdentifier()) . DIRECTORY_SEPARATOR;
|
|
$curTpl = $compiler->getDwoo()->getTemplate();
|
|
|
|
while (!empty($file)) {
|
|
if ($file === '""' || $file === "''" || (substr($file, 0, 1) !== '"' && substr($file, 0, 1) !== '\'')) {
|
|
throw new Dwoo_Compilation_Exception($compiler, 'Extends : The file name must be a non-empty string');
|
|
return;
|
|
}
|
|
|
|
if (preg_match('#^["\']([a-z]{2,}):(.*?)["\']$#i', $file, $m)) {
|
|
// resource:identifier given, extract them
|
|
$resource = $m[1];
|
|
$identifier = $m[2];
|
|
} else {
|
|
// get the current template's resource
|
|
$resource = $curTpl->getResourceName();
|
|
$identifier = substr($file, 1, -1);
|
|
}
|
|
|
|
try {
|
|
$parent = $compiler->getDwoo()->templateFactory($resource, $identifier, null, null, null, $curTpl);
|
|
} catch (Dwoo_Security_Exception $e) {
|
|
throw new Dwoo_Compilation_Exception($compiler, 'Extends : Security restriction : '.$e->getMessage());
|
|
} catch (Dwoo_Exception $e) {
|
|
throw new Dwoo_Compilation_Exception($compiler, 'Extends : '.$e->getMessage());
|
|
}
|
|
|
|
if ($parent === null) {
|
|
throw new Dwoo_Compilation_Exception($compiler, 'Extends : Resource "'.$resource.':'.$identifier.'" not found.');
|
|
} elseif ($parent === false) {
|
|
throw new Dwoo_Compilation_Exception($compiler, 'Extends : Resource "'.$resource.'" does not support extends.');
|
|
}
|
|
|
|
$curTpl = $parent;
|
|
$newParent = array('source'=>$parent->getSource(), 'resource'=>$resource, 'identifier'=>$parent->getResourceIdentifier(), 'uid'=>$parent->getUid());
|
|
if (array_search($newParent, $inheritanceTree, true) !== false) {
|
|
throw new Dwoo_Compilation_Exception($compiler, 'Extends : Recursive template inheritance detected');
|
|
}
|
|
|
|
$inheritanceTree[] = $newParent;
|
|
|
|
if (preg_match('/^'.self::$l.'extends\s+(?:file=)?\s*(\S+?|(["\']).+?\2)'.self::$r.'/i', $parent->getSource(), $match)) {
|
|
$curPath = dirname($identifier) . DIRECTORY_SEPARATOR;
|
|
$file = (substr($match[1], 0, 1) !== '"' && substr($match[1], 0, 1) !== '"') ? '"'.str_replace('"', '\\"', $match[1]).'"' : $match[1];
|
|
} else {
|
|
$file = false;
|
|
}
|
|
}
|
|
|
|
while (true) {
|
|
$parent = array_pop($inheritanceTree);
|
|
$child = end($inheritanceTree);
|
|
self::$childSource = $child['source'];
|
|
self::$lastReplacement = count($inheritanceTree) === 1;
|
|
if (!isset($newSource)) {
|
|
$newSource = $parent['source'];
|
|
}
|
|
$newSource = preg_replace_callback('/'.self::$l.'block (["\']?)(.+?)\1'.self::$r.'(?:\r?\n?)(.*?)(?:\r?\n?)'.self::$l.'\/block'.self::$r.'/is', array('Dwoo_Plugin_extends', 'replaceBlock'), $newSource);
|
|
|
|
$newSource = $l.'do extendsCheck("'.$parent['resource'].':'.$parent['identifier'].'" "'.str_replace('"', '\\"', $parent['uid']).'")'.$r.$newSource;
|
|
|
|
if (self::$lastReplacement) {
|
|
break;
|
|
}
|
|
}
|
|
|
|
$compiler->setTemplateSource($newSource);
|
|
$compiler->setPointer(0);
|
|
}
|
|
|
|
protected static function replaceBlock(array $matches)
|
|
{
|
|
if (preg_match('/'.self::$l.'block (["\']?)'.preg_quote($matches[2],'/').'\1'.self::$r.'(?:\r?\n?)(.*?)(?:\r?\n?)'.self::$l.'\/block'.self::$r.'/is', self::$childSource, $override)) {
|
|
$l = stripslashes(self::$l);
|
|
$r = stripslashes(self::$r);
|
|
|
|
if (self::$lastReplacement) {
|
|
return preg_replace('/'.self::$l.'\$dwoo\.parent'.self::$r.'/is', $matches[3], $override[2]);
|
|
} else {
|
|
return $l.'block '.$matches[1].$matches[2].$matches[1].$r.preg_replace('/'.self::$l.'\$dwoo\.parent'.self::$r.'/is', $matches[3], $override[2]).$l.'/block'.$r;
|
|
}
|
|
} else {
|
|
if (self::$lastReplacement) {
|
|
return $matches[3];
|
|
} else {
|
|
return $matches[0];
|
|
}
|
|
}
|
|
}
|
|
}
|