Exemplo n.º 1
0
    public static function compile(Compiler $compiler, $file)
    {
        list($l, $r) = $compiler->getDelimiters();
        self::$l = preg_quote($l, '/');
        self::$r = preg_quote($r, '/');
        self::$regex = '/
			' . self::$l . 'block\\s(["\']?)(.+?)\\1' . self::$r . '(?:\\r?\\n?)
			((?:
				(?R)
				|
				[^' . self::$l . ']*
				(?:
					(?! ' . self::$l . '\\/?block\\b )
					' . self::$l . '
					[^' . self::$l . ']*+
				)*
			)*)
			' . self::$l . '\\/block' . self::$r . '
			/six';
        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 CompilationException($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\Exception\SecurityException $e) {
                throw new CompilationException($compiler, 'Extends : Security restriction : ' . $e->getMessage());
            } catch (\Dwoo\Exception $e) {
                throw new Exception($compiler, 'Extends : ' . $e->getMessage());
            }
            if ($parent === null) {
                throw new CompilationException($compiler, 'Extends : Resource "' . $resource . ':' . $identifier . '" not found.');
            } elseif ($parent === false) {
                throw new CompilationException($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 CompilationException($compiler, 'Extends : Recursive template inheritance detected');
            }
            $inheritanceTree[] = $newParent;
            if (preg_match('/^' . self::$l . 'extends(?:\\(?\\s*|\\s+)(?:file=)?\\s*((["\']).+?\\2|\\S+?)\\s*\\)?\\s*?' . self::$r . '/i', $parent->getSource(), $match)) {
                $curPath = dirname($identifier) . DIRECTORY_SEPARATOR;
                if (isset($match[2]) && $match[2] == '"') {
                    $file = '"' . str_replace('"', '\\"', substr($match[1], 1, -1)) . '"';
                } elseif (isset($match[2]) && $match[2] == "'") {
                    $file = '"' . substr($match[1], 1, -1) . '"';
                } else {
                    $file = '"' . $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::$regex, array(__CLASS__, 'replaceBlock'), $newSource);
            $newSource = $l . 'do extendsCheck(' . var_export($parent['resource'] . ':' . $parent['identifier'], true) . ')' . $r . $newSource;
            if (self::$lastReplacement) {
                break;
            }
        }
        $compiler->setTemplateSource($newSource);
        $compiler->recompile();
    }