Source for file extends.php

Documentation is available at extends.php

  1. <?php
  2.  
  3. /**
  4.  * Extends another template, read more about template inheritance at {@link http://wiki.dwoo.org/index.php/TemplateInheritance}
  5.  * <pre>
  6.  *  * file : the template to extend
  7.  * </pre>
  8.  * This software is provided 'as-is', without any express or implied warranty.
  9.  * In no event will the authors be held liable for any damages arising from the use of this software.
  10.  *
  11.  * @author     Jordi Boggiano <j.boggiano@seld.be>
  12.  * @copyright  Copyright (c) 2008, Jordi Boggiano
  13.  * @license    http://dwoo.org/LICENSE   Modified BSD License
  14.  * @link       http://dwoo.org/
  15.  * @version    1.1.0
  16.  * @date       2009-07-18
  17.  * @package    Dwoo
  18.  */
  19. class Dwoo_Plugin_extends extends Dwoo_Plugin implements Dwoo_ICompilable
  20. {
  21.     protected static $childSource;
  22.     protected static $l;
  23.     protected static $r;
  24.     protected static $lastReplacement;
  25.  
  26.     public static function compile(Dwoo_Compiler $compiler, $file)
  27.     {
  28.         list($l, $r) = $compiler->getDelimiters();
  29.         self::$l = preg_quote($l,'/');
  30.         self::$r = preg_quote($r,'/');
  31.  
  32.         if ($compiler->getLooseOpeningHandling()) {
  33.             self::$l .= '\s*';
  34.             self::$r = '\s*'.self::$r;
  35.         }
  36.         $inheritanceTree = array(array('source'=>$compiler->getTemplateSource()));
  37.         $curPath = dirname($compiler->getDwoo()->getTemplate()->getResourceIdentifier()) . DIRECTORY_SEPARATOR;
  38.         $curTpl = $compiler->getDwoo()->getTemplate();
  39.  
  40.         while (!empty($file)) {
  41.             if ($file === '""' || $file === "''" || (substr($file, 0, 1) !== '"' && substr($file, 0, 1) !== '\'')) {
  42.                 throw new Dwoo_Compilation_Exception($compiler, 'Extends : The file name must be a non-empty string');
  43.                 return;
  44.             }
  45.  
  46.             if (preg_match('#^["\']([a-z]{2,}):(.*?)["\']$#i', $file, $m)) {
  47.                 // resource:identifier given, extract them
  48.                 $resource = $m[1];
  49.                 $identifier = $m[2];
  50.             } else {
  51.                 // get the current template's resource
  52.                 $resource = $curTpl->getResourceName();
  53.                 $identifier = substr($file, 1, -1);
  54.             }
  55.  
  56.             try {
  57.                 $parent = $compiler->getDwoo()->templateFactory($resource, $identifier, null, null, null, $curTpl);
  58.             } catch (Dwoo_Security_Exception $e) {
  59.                 throw new Dwoo_Compilation_Exception($compiler, 'Extends : Security restriction : '.$e->getMessage());
  60.             } catch (Dwoo_Exception $e) {
  61.                 throw new Dwoo_Compilation_Exception($compiler, 'Extends : '.$e->getMessage());
  62.             }
  63.  
  64.             if ($parent === null) {
  65.                 throw new Dwoo_Compilation_Exception($compiler, 'Extends : Resource "'.$resource.':'.$identifier.'" not found.');
  66.             } elseif ($parent === false) {
  67.                 throw new Dwoo_Compilation_Exception($compiler, 'Extends : Resource "'.$resource.'" does not support extends.');
  68.             }
  69.  
  70.             $curTpl = $parent;
  71.             $newParent = array('source'=>$parent->getSource(), 'resource'=>$resource, 'identifier'=>$parent->getResourceIdentifier(), 'uid'=>$parent->getUid());
  72.             if (array_search($newParent, $inheritanceTree, true) !== false) {
  73.                 throw new Dwoo_Compilation_Exception($compiler, 'Extends : Recursive template inheritance detected');
  74.             }
  75.             $inheritanceTree[] = $newParent;
  76.  
  77.             if (preg_match('/^'.self::$l.'extends\s+(?:file=)?\s*((["\']).+?\2|\S+?)'.self::$r.'/i', $parent->getSource(), $match)) {
  78.                 $curPath = dirname($identifier) . DIRECTORY_SEPARATOR;
  79.                 if (isset($match[2]) && $match[2] == '"') {
  80.                     $file = '"'.str_replace('"', '\\"', substr($match[1], 1, -1)).'"';
  81.                 } elseif (isset($match[2]) && $match[2] == "'") {
  82.                     $file = '"'.substr($match[1], 1, -1).'"';
  83.                 } else {
  84.                     $file = '"'.$match[1].'"';
  85.                 }
  86.             } else {
  87.                 $file = false;
  88.             }
  89.         }
  90.  
  91.         while (true) {
  92.             $parent = array_pop($inheritanceTree);
  93.             $child = end($inheritanceTree);
  94.             self::$childSource = $child['source'];
  95.             self::$lastReplacement = count($inheritanceTree) === 1;
  96.             if (!isset($newSource)) {
  97.                 $newSource = $parent['source'];
  98.             }
  99.  
  100.             // TODO parse blocks tree for child source and new source
  101.             // TODO replace blocks that are found in the child and in the parent recursively
  102.             $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);
  103.  
  104.             $newSource = $l.'do extendsCheck("'.$parent['resource'].':'.$parent['identifier'].'")'.$r.$newSource;
  105.  
  106.             if (self::$lastReplacement) {
  107.                 break;
  108.             }
  109.         }
  110.  
  111.         $compiler->setTemplateSource($newSource);
  112.         $compiler->recompile();
  113.     }
  114.  
  115.     protected static function replaceBlock(array $matches)
  116.     {
  117.         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)) {
  118.             $l = stripslashes(self::$l);
  119.             $r = stripslashes(self::$r);
  120.  
  121.             if (self::$lastReplacement) {
  122.                 return preg_replace('/'.self::$l.'\$dwoo\.parent'.self::$r.'/is', $matches[3], $override[2]);
  123.             } else {
  124.                 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;
  125.             }
  126.         } else {
  127.             if (self::$lastReplacement) {
  128.                 return $matches[3];
  129.             } else {
  130.                 return $matches[0];
  131.             }
  132.         }
  133.     }
  134. }

Documentation generated on Sun, 07 Feb 2010 17:53:43 +0000 by phpDocumentor 1.4.0