예제 #1
0
파일: tif.php 프로젝트: ircoco/BlackCatCMS
/**
 * Ternary if operation
 *
 * It evaluates the first argument and returns the second if it's true, or the third if it's false
 * <pre>
 *  * rest : you can not use named parameters to call this, use it either with three arguments in the correct order (expression, true result, false result) or write it as in php (expression ? true result : false result)
 * </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 <*****@*****.**>
 * @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
 */
function Dwoo_Plugin_tif_compile(Dwoo_Compiler $compiler, array $rest)
{
    // load if plugin
    if (!class_exists('Dwoo_Plugin_if', false)) {
        try {
            $compiler->getDwoo()->getLoader()->loadPlugin('if');
        } catch (Exception $e) {
            throw new Dwoo_Compilation_Exception($compiler, 'Tif: the if plugin is required to use Tif');
        }
    }
    if (count($rest) == 1) {
        return $rest[0];
    }
    // fetch false result and remove the ":" if it was present
    $falseResult = array_pop($rest);
    if (trim(end($rest), '"\'') === ':') {
        // remove the ':' if present
        array_pop($rest);
    } elseif (trim(end($rest), '"\'') === '?' || count($rest) === 1) {
        if ($falseResult === '?' || $falseResult === ':') {
            throw new Dwoo_Compilation_Exception($compiler, 'Tif: incomplete tif statement, value missing after ' . $falseResult);
        }
        // there was in fact no false result provided, so we move it to be the true result instead
        $trueResult = $falseResult;
        $falseResult = "''";
    }
    // fetch true result if needed
    if (!isset($trueResult)) {
        $trueResult = array_pop($rest);
        // no true result provided so we use the expression arg
        if ($trueResult === '?') {
            $trueResult = true;
        }
    }
    // remove the '?' if present
    if (trim(end($rest), '"\'') === '?') {
        array_pop($rest);
    }
    // check params were correctly provided
    if (empty($rest) || $trueResult === null || $falseResult === null) {
        throw new Dwoo_Compilation_Exception($compiler, 'Tif: you must provide three parameters serving as <expression> ? <true value> : <false value>');
    }
    // parse condition
    $condition = Dwoo_Plugin_if::replaceKeywords($rest, $compiler);
    return '((' . implode(' ', $condition) . ') ? ' . ($trueResult === true ? implode(' ', $condition) : $trueResult) . ' : ' . $falseResult . ')';
}
예제 #2
0
 /**
  * entry point of the parser, it redirects calls to other parse* functions
  *
  * @param string $in the string within which we must parse something
  * @param int $from the starting offset of the parsed area
  * @param int $to the ending offset of the parsed area
  * @param mixed $parsingParams must be an array if we are parsing a function or modifier's parameters, or false by default
  * @param string $curBlock the current parser-block being processed
  * @param mixed $pointer a reference to a pointer that will be increased by the amount of characters parsed, or null by default
  * @return string parsed values
  */
 protected function parse($in, $from, $to, $parsingParams = false, $curBlock = '', &$pointer = null)
 {
     if ($to === null) {
         $to = strlen($in);
     }
     $first = substr($in, $from, 1);
     if ($first === false) {
         throw new Dwoo_Compilation_Exception($this, 'Unexpected EOF, a template tag was not closed');
     }
     while ($first === " " || $first === "\n" || $first === "\t" || $first === "\r") {
         if ($curBlock === 'root' && substr($in, $from, strlen($this->rd)) === $this->rd) {
             // end template tag
             $pointer += strlen($this->rd);
             if ($this->debug) {
                 echo 'TEMPLATE PARSING ENDED<br />';
             }
             return false;
         }
         $from++;
         if ($pointer !== null) {
             $pointer++;
         }
         if ($from >= $to) {
             if (is_array($parsingParams)) {
                 return $parsingParams;
             } else {
                 return '';
             }
         }
         $first = $in[$from];
     }
     $substr = substr($in, $from, $to - $from);
     if ($this->debug) {
         echo '<br />PARSE CALL : PARSING "<strong>' . htmlentities(substr($in, $from, min($to - $from, 50))) . ($to - $from > 50 ? '...' : '') . '</strong>" @ ' . $from . ':' . $to . ' in ' . $curBlock . ' : pointer=' . $pointer . '<br/>';
     }
     $parsed = "";
     if ($curBlock === 'root' && $first === '*') {
         $src = $this->getTemplateSource();
         $startpos = $this->getPointer() - strlen($this->ld);
         if (substr($src, $startpos, strlen($this->ld)) === $this->ld) {
             do {
                 $char = substr($src, --$startpos, 1);
                 if ($char == "\n") {
                     $startpos++;
                     $whitespaceStart = true;
                     break;
                 }
             } while ($char == ' ' || $char == "\t");
             if (!isset($whitespaceStart)) {
                 $startpos = $this->getPointer();
             } else {
                 $pointer -= $this->getPointer() - $startpos;
             }
             if ($this->allowNestedComments && strpos($src, $this->ld . '*', $this->getPointer()) !== false) {
                 $comOpen = $this->ld . '*';
                 $comClose = '*' . $this->rd;
                 $level = 1;
                 $start = $startpos;
                 $ptr = $this->getPointer() + '*';
                 while ($level > 0 && $ptr < strlen($src)) {
                     $open = strpos($src, $comOpen, $ptr);
                     $close = strpos($src, $comClose, $ptr);
                     if ($open !== false && $close !== false) {
                         if ($open < $close) {
                             $ptr = $open + strlen($comOpen);
                             $level++;
                         } else {
                             $ptr = $close + strlen($comClose);
                             $level--;
                         }
                     } elseif ($open !== false) {
                         $ptr = $open + strlen($comOpen);
                         $level++;
                     } elseif ($close !== false) {
                         $ptr = $close + strlen($comClose);
                         $level--;
                     } else {
                         $ptr = strlen($src);
                     }
                 }
                 $endpos = $ptr - strlen('*' . $this->rd);
             } else {
                 $endpos = strpos($src, '*' . $this->rd, $startpos);
                 if ($endpos == false) {
                     throw new Dwoo_Compilation_Exception($this, 'Un-ended comment');
                 }
             }
             $pointer += $endpos - $startpos + strlen('*' . $this->rd);
             if (isset($whitespaceStart) && preg_match('#^[\\t ]*\\r?\\n#', substr($src, $endpos + strlen('*' . $this->rd)), $m)) {
                 $pointer += strlen($m[0]);
                 $this->curBlock['buffer'] = substr($this->curBlock['buffer'], 0, strlen($this->curBlock['buffer']) - ($this->getPointer() - $startpos - strlen($this->ld)));
             }
             return false;
         }
     }
     if ($first === '$') {
         // var
         $out = $this->parseVar($in, $from, $to, $parsingParams, $curBlock, $pointer);
         $parsed = 'var';
     } elseif ($first === '%' && preg_match('#^%[a-z]#i', $substr)) {
         // const
         $out = $this->parseConst($in, $from, $to, $parsingParams, $curBlock, $pointer);
     } elseif ($first === '"' || $first === "'") {
         // string
         $out = $this->parseString($in, $from, $to, $parsingParams, $curBlock, $pointer);
     } elseif (preg_match('/^[a-z][a-z0-9_]*(?:::[a-z][a-z0-9_]*)?(' . (is_array($parsingParams) || $curBlock != 'root' ? '' : '\\s+[^(]|') . '\\s*\\(|\\s*' . $this->rdr . '|\\s*;)/i', $substr)) {
         // func
         $out = $this->parseFunction($in, $from, $to, $parsingParams, $curBlock, $pointer);
         $parsed = 'func';
     } elseif ($first === ';') {
         // instruction end
         if ($this->debug) {
             echo 'END OF INSTRUCTION<br />';
         }
         if ($pointer !== null) {
             $pointer++;
         }
         return $this->parse($in, $from + 1, $to, false, 'root', $pointer);
     } elseif ($curBlock === 'root' && preg_match('#^/([a-z][a-z0-9_]*)?#i', $substr, $match)) {
         // close block
         if (!empty($match[1]) && $match[1] == 'else') {
             throw new Dwoo_Compilation_Exception($this, 'Else blocks must not be closed explicitly, they are automatically closed when their parent block is closed');
         }
         if (!empty($match[1]) && $match[1] == 'elseif') {
             throw new Dwoo_Compilation_Exception($this, 'Elseif blocks must not be closed explicitly, they are automatically closed when their parent block is closed or a new else/elseif block is declared after them');
         }
         if ($pointer !== null) {
             $pointer += strlen($match[0]);
         }
         if (empty($match[1])) {
             if ($this->curBlock['type'] == 'else' || $this->curBlock['type'] == 'elseif') {
                 $pointer -= strlen($match[0]);
             }
             if ($this->debug) {
                 echo 'TOP BLOCK CLOSED<br />';
             }
             return $this->removeTopBlock();
         } else {
             if ($this->debug) {
                 echo 'BLOCK OF TYPE ' . $match[1] . ' CLOSED<br />';
             }
             return $this->removeBlock($match[1]);
         }
     } elseif ($curBlock === 'root' && substr($substr, 0, strlen($this->rd)) === $this->rd) {
         // end template tag
         if ($this->debug) {
             echo 'TAG PARSING ENDED<br />';
         }
         $pointer += strlen($this->rd);
         return false;
     } elseif (is_array($parsingParams) && preg_match('#^([a-z0-9_]+\\s*=)(?:\\s+|[^=]).*#i', $substr, $match)) {
         // named parameter
         if ($this->debug) {
             echo 'NAMED PARAM FOUND<br />';
         }
         $len = strlen($match[1]);
         while (substr($in, $from + $len, 1) === ' ') {
             $len++;
         }
         if ($pointer !== null) {
             $pointer += $len;
         }
         $output = array(trim(substr(trim($match[1]), 0, -1)), $this->parse($in, $from + $len, $to, false, 'namedparam', $pointer));
         $parsingParams[] = $output;
         return $parsingParams;
     } elseif ($substr !== '' && (is_array($parsingParams) || $curBlock === 'namedparam' || $curBlock === 'condition')) {
         // unquoted string, bool or number
         $out = $this->parseOthers($in, $from, $to, $parsingParams, $curBlock, $pointer);
     } else {
         // parse error
         throw new Dwoo_Compilation_Exception($this, 'Parse error in "' . substr($in, $from, $to - $from) . '"');
     }
     if (empty($out)) {
         return '';
     }
     $substr = substr($in, $pointer, $to - $pointer);
     // var parsed, check if any var-extension applies
     if ($parsed === 'var' && $curBlock !== 'condition') {
         if (preg_match('#^\\s*([/%+*-])\\s*([0-9]|\\$)#', $substr, $match)) {
             if ($this->debug) {
                 echo 'PARSING POST-VAR EXPRESSION ' . $substr . '<br />';
             }
             // parse expressions
             $pointer += strlen($match[0]) - 1;
             if (is_array($parsingParams)) {
                 if ($match[2] == '$') {
                     $expr = $this->parseVar($in, $pointer, $to, array(), $curBlock, $pointer);
                 } else {
                     $expr = $this->parseOthers($in, $pointer, $to, array(), 'expression', $pointer);
                 }
                 $out[count($out) - 1][0] .= $match[1] . $expr[0][0];
                 $out[count($out) - 1][1] .= $match[1] . $expr[0][1];
             } else {
                 if ($match[2] == '$') {
                     $out .= $match[1] . $this->parseVar($in, $pointer, $to, false, $curBlock, $pointer);
                 } else {
                     $out .= $match[1] . $this->parseOthers($in, $pointer, $to, false, 'expression', $pointer);
                 }
             }
         } else {
             if ($curBlock === 'root' && preg_match('#^(\\s*(?:[+/*%-]=|=|\\+\\+|--)\\s*)(.*)#', $substr, $match)) {
                 if ($this->debug) {
                     echo 'PARSING POST-VAR ASSIGNMENT ' . $substr . '<br />';
                 }
                 // parse assignment
                 $value = $match[2];
                 $operator = trim($match[1]);
                 if (substr($value, 0, 1) == '=') {
                     throw new Dwoo_Compilation_Exception($this, 'Unexpected "=" in <em>' . $substr . '</em>');
                 }
                 if ($pointer !== null) {
                     $pointer += strlen($match[1]);
                 }
                 $parts = array();
                 $parts = $this->parse($value, 0, strlen($value), $parts, 'condition', $pointer);
                 // load if plugin
                 try {
                     $this->getPluginType('if');
                 } catch (Dwoo_Exception $e) {
                     throw new Dwoo_Compilation_Exception($this, 'Assignments require the "if" plugin to be accessible');
                 }
                 $parts = $this->mapParams($parts, array('Dwoo_Plugin_if', 'init'), 1);
                 $parts = $this->getCompiledParams($parts);
                 $value = Dwoo_Plugin_if::replaceKeywords($parts['*'], $this);
                 $out = Dwoo_Compiler::PHP_OPEN . $out . $operator . implode(' ', $value) . Dwoo_Compiler::PHP_CLOSE;
             }
         }
     }
     if ($curBlock !== 'modifier' && ($parsed === 'func' || $parsed === 'var') && preg_match('#^\\|@?[a-z0-9_]+(:.*)?#i', $substr, $match)) {
         // parse modifier on funcs or vars
         $srcPointer = $pointer;
         if (is_array($parsingParams)) {
             $tmp = $this->replaceModifiers(array(null, null, $out[count($out) - 1][0], $match[0]), 'var', $pointer);
             $out[count($out) - 1][0] = $tmp;
             $out[count($out) - 1][1] .= substr($substr, $srcPointer, $srcPointer - $pointer);
         } else {
             $out = $this->replaceModifiers(array(null, null, $out, $match[0]), 'var', $pointer);
         }
     }
     // func parsed, check if any func-extension applies
     if ($parsed === 'func' && preg_match('#^->[a-z0-9_]+(\\s*\\(.+|->[a-z].*)?#is', $substr, $match)) {
         // parse method call or property read
         $ptr = 0;
         if (is_array($parsingParams)) {
             $output = $this->parseMethodCall($out[count($out) - 1][1], $match[0], $curBlock, $ptr);
             $out[count($out) - 1][0] .= substr($match[0], 0, $ptr);
             $out[count($out) - 1][1] .= $output;
         } else {
             $out = $this->parseMethodCall($out, $match[0], $curBlock, $ptr);
         }
         $pointer += $ptr;
     }
     if ($curBlock === 'root' && substr($out, 0, strlen(self::PHP_OPEN)) !== self::PHP_OPEN) {
         return self::PHP_OPEN . 'echo ' . $out . ';' . self::PHP_CLOSE;
     } else {
         return $out;
     }
 }
예제 #3
0
 /**
  * parses a function call
  *
  * @param string $in the string within which we must parse something
  * @param int $from the starting offset of the parsed area
  * @param int $to the ending offset of the parsed area
  * @param mixed $parsingParams must be an array if we are parsing a function or modifier's parameters, or false by default
  * @param string $curBlock the current parser-block being processed
  * @param mixed $pointer a reference to a pointer that will be increased by the amount of characters parsed, or null by default
  * @return string parsed values
  */
 protected function parseFunction($in, $from, $to, $parsingParams = false, $curBlock = '', &$pointer = null)
 {
     $cmdstr = substr($in, $from, $to - $from);
     preg_match('/^(\\\\?[a-z_](?:\\\\?[a-z0-9_]+)*(?:::[a-z_][a-z0-9_]*)?)(\\s*' . $this->rdr . '|\\s*;)?/i', $cmdstr, $match);
     if (empty($match[1])) {
         throw new Dwoo_Compilation_Exception($this, 'Parse error, invalid function name : ' . substr($cmdstr, 0, 15));
     }
     $func = $match[1];
     if (!empty($match[2])) {
         $cmdstr = $match[1];
     }
     if ($this->debug) {
         echo 'FUNC FOUND (' . $func . ')<br />';
     }
     $paramsep = '';
     if (is_array($parsingParams) || $curBlock != 'root') {
         $paramspos = strpos($cmdstr, '(');
         $paramsep = ')';
     } elseif (preg_match_all('#[a-z0-9_]+(\\s*\\(|\\s+[^(])#i', $cmdstr, $match, PREG_OFFSET_CAPTURE)) {
         $paramspos = $match[1][0][1];
         $paramsep = substr($match[1][0][0], -1) === '(' ? ')' : '';
         if ($paramsep === ')') {
             $paramspos += strlen($match[1][0][0]) - 1;
             if (substr($cmdstr, 0, 2) === 'if' || substr($cmdstr, 0, 6) === 'elseif') {
                 $paramsep = '';
                 if (strlen($match[1][0][0]) > 1) {
                     $paramspos--;
                 }
             }
         }
     } else {
         $paramspos = false;
     }
     $state = 0;
     if ($paramspos === false) {
         $params = array();
         if ($curBlock !== 'root') {
             return $this->parseOthers($in, $from, $to, $parsingParams, $curBlock, $pointer);
         }
     } else {
         if ($curBlock === 'condition') {
             // load if plugin
             $this->getPluginType('if');
             if (Dwoo_Plugin_if::replaceKeywords(array($func), array(self::T_UNQUOTED_STRING), $this) !== array($func)) {
                 return $this->parseOthers($in, $from, $to, $parsingParams, $curBlock, $pointer);
             }
         }
         $whitespace = strlen(substr($cmdstr, strlen($func), $paramspos - strlen($func)));
         $paramstr = substr($cmdstr, $paramspos + 1);
         if (substr($paramstr, -1, 1) === $paramsep) {
             $paramstr = substr($paramstr, 0, -1);
         }
         if (strlen($paramstr) === 0) {
             $params = array();
             $paramstr = '';
         } else {
             $ptr = 0;
             $params = array();
             if ($func === 'empty') {
                 $params = $this->parseVar($paramstr, $ptr, strlen($paramstr), $params, 'root', $ptr);
             } else {
                 while ($ptr < strlen($paramstr)) {
                     while (true) {
                         if ($ptr >= strlen($paramstr)) {
                             break 2;
                         }
                         if ($func !== 'if' && $func !== 'elseif' && $paramstr[$ptr] === ')') {
                             if ($this->debug) {
                                 echo 'PARAM PARSING ENDED, ")" FOUND, POINTER AT ' . $ptr . '<br/>';
                             }
                             break 2;
                         } elseif ($paramstr[$ptr] === ';') {
                             $ptr++;
                             if ($this->debug) {
                                 echo 'PARAM PARSING ENDED, ";" FOUND, POINTER AT ' . $ptr . '<br/>';
                             }
                             break 2;
                         } elseif ($func !== 'if' && $func !== 'elseif' && $paramstr[$ptr] === '/') {
                             if ($this->debug) {
                                 echo 'PARAM PARSING ENDED, "/" FOUND, POINTER AT ' . $ptr . '<br/>';
                             }
                             break 2;
                         } elseif (substr($paramstr, $ptr, strlen($this->rd)) === $this->rd) {
                             if ($this->debug) {
                                 echo 'PARAM PARSING ENDED, RIGHT DELIMITER FOUND, POINTER AT ' . $ptr . '<br/>';
                             }
                             break 2;
                         }
                         if ($paramstr[$ptr] === ' ' || $paramstr[$ptr] === ',' || $paramstr[$ptr] === "\r" || $paramstr[$ptr] === "\n" || $paramstr[$ptr] === "\t") {
                             $ptr++;
                         } else {
                             break;
                         }
                     }
                     if ($this->debug) {
                         echo 'FUNC START PARAM PARSING WITH POINTER AT ' . $ptr . '<br/>';
                     }
                     if ($func === 'if' || $func === 'elseif' || $func === 'tif') {
                         $params = $this->parse($paramstr, $ptr, strlen($paramstr), $params, 'condition', $ptr);
                     } elseif ($func === 'array') {
                         $params = $this->parse($paramstr, $ptr, strlen($paramstr), $params, 'array', $ptr);
                     } else {
                         $params = $this->parse($paramstr, $ptr, strlen($paramstr), $params, 'function', $ptr);
                     }
                     if ($this->debug) {
                         echo 'PARAM PARSED, POINTER AT ' . $ptr . ' (' . substr($paramstr, $ptr - 1, 3) . ')<br/>';
                     }
                 }
             }
             $paramstr = substr($paramstr, 0, $ptr);
             $state = 0;
             foreach ($params as $k => $p) {
                 if (is_array($p) && is_array($p[1])) {
                     $state |= 2;
                 } else {
                     if ($state & 2 && preg_match('#^(["\'])(.+?)\\1$#', $p[0], $m) && $func !== 'array') {
                         $params[$k] = array($m[2], array('true', 'true'));
                     } else {
                         if ($state & 2 && $func !== 'array') {
                             throw new Dwoo_Compilation_Exception($this, 'You can not use an unnamed parameter after a named one');
                         }
                         $state |= 1;
                     }
                 }
             }
         }
     }
     if ($pointer !== null) {
         $pointer += (isset($paramstr) ? strlen($paramstr) : 0) + (')' === $paramsep ? 2 : ($paramspos === false ? 0 : 1)) + strlen($func) + (isset($whitespace) ? $whitespace : 0);
         if ($this->debug) {
             echo 'FUNC ADDS ' . ((isset($paramstr) ? strlen($paramstr) : 0) + (')' === $paramsep ? 2 : ($paramspos === false ? 0 : 1)) + strlen($func)) . ' TO POINTER<br/>';
         }
     }
     if ($curBlock === 'method' || $func === 'do' || strstr($func, '::') !== false) {
         // handle static method calls with security policy
         if (strstr($func, '::') !== false && $this->securityPolicy !== null && $this->securityPolicy->isMethodAllowed(explode('::', strtolower($func))) !== true) {
             throw new Dwoo_Security_Exception('Call to a disallowed php function : ' . $func);
         }
         $pluginType = Dwoo::NATIVE_PLUGIN;
     } else {
         $pluginType = $this->getPluginType($func);
     }
     // blocks
     if ($pluginType & Dwoo_Core::BLOCK_PLUGIN) {
         if ($curBlock !== 'root' || is_array($parsingParams)) {
             throw new Dwoo_Compilation_Exception($this, 'Block plugins can not be used as other plugin\'s arguments');
         }
         if ($pluginType & Dwoo_Core::CUSTOM_PLUGIN) {
             return $this->addCustomBlock($func, $params, $state);
         } else {
             return $this->addBlock($func, $params, $state);
         }
     } elseif ($pluginType & Dwoo_Core::SMARTY_BLOCK) {
         if ($curBlock !== 'root' || is_array($parsingParams)) {
             throw new Dwoo_Compilation_Exception($this, 'Block plugins can not be used as other plugin\'s arguments');
         }
         if ($state & 2) {
             array_unshift($params, array('__functype', array($pluginType, $pluginType)));
             array_unshift($params, array('__funcname', array($func, $func)));
         } else {
             array_unshift($params, array($pluginType, $pluginType));
             array_unshift($params, array($func, $func));
         }
         return $this->addBlock('smartyinterface', $params, $state);
     }
     // funcs
     if ($pluginType & Dwoo_Core::NATIVE_PLUGIN || $pluginType & Dwoo_Core::SMARTY_FUNCTION || $pluginType & Dwoo_Core::SMARTY_BLOCK) {
         $params = $this->mapParams($params, null, $state);
     } elseif ($pluginType & Dwoo_Core::CLASS_PLUGIN) {
         if ($pluginType & Dwoo_Core::CUSTOM_PLUGIN) {
             $params = $this->mapParams($params, array($this->customPlugins[$func]['class'], $this->customPlugins[$func]['function']), $state);
         } else {
             $params = $this->mapParams($params, array('Dwoo_Plugin_' . $func, $pluginType & Dwoo_Core::COMPILABLE_PLUGIN ? 'compile' : 'process'), $state);
         }
     } elseif ($pluginType & Dwoo_Core::FUNC_PLUGIN) {
         if ($pluginType & Dwoo_Core::CUSTOM_PLUGIN) {
             $params = $this->mapParams($params, $this->customPlugins[$func]['callback'], $state);
         } else {
             $params = $this->mapParams($params, 'Dwoo_Plugin_' . $func . ($pluginType & Dwoo_Core::COMPILABLE_PLUGIN ? '_compile' : ''), $state);
         }
     } elseif ($pluginType & Dwoo_Core::SMARTY_MODIFIER) {
         $output = 'smarty_modifier_' . $func . '(' . implode(', ', $params) . ')';
     } elseif ($pluginType & Dwoo_Core::PROXY_PLUGIN) {
         $params = $this->mapParams($params, $this->getDwoo()->getPluginProxy()->getCallback($func), $state);
     } elseif ($pluginType & Dwoo_Core::TEMPLATE_PLUGIN) {
         // transforms the parameter array from (x=>array('paramname'=>array(values))) to (paramname=>array(values))
         $map = array();
         foreach ($this->templatePlugins[$func]['params'] as $param => $defValue) {
             if ($param == 'rest') {
                 $param = '*';
             }
             $hasDefault = $defValue !== null;
             if ($defValue === 'null') {
                 $defValue = null;
             } elseif ($defValue === 'false') {
                 $defValue = false;
             } elseif ($defValue === 'true') {
                 $defValue = true;
             } elseif (preg_match('#^([\'"]).*?\\1$#', $defValue)) {
                 $defValue = substr($defValue, 1, -1);
             }
             $map[] = array($param, $hasDefault, $defValue);
         }
         $params = $this->mapParams($params, null, $state, $map);
     }
     // only keep php-syntax-safe values for non-block plugins
     $tokens = array();
     foreach ($params as $k => $p) {
         $tokens[$k] = isset($p[2]) ? $p[2] : 0;
         $params[$k] = $p[0];
     }
     if ($pluginType & Dwoo_Core::NATIVE_PLUGIN) {
         if ($func === 'do') {
             if (isset($params['*'])) {
                 $output = implode(';', $params['*']) . ';';
             } else {
                 $output = '';
             }
             if (is_array($parsingParams) || $curBlock !== 'root') {
                 throw new Dwoo_Compilation_Exception($this, 'Do can not be used inside another function or block');
             } else {
                 return self::PHP_OPEN . $output . self::PHP_CLOSE;
             }
         } else {
             if (isset($params['*'])) {
                 $output = $func . '(' . implode(', ', $params['*']) . ')';
             } else {
                 $output = $func . '()';
             }
         }
     } elseif ($pluginType & Dwoo_Core::FUNC_PLUGIN) {
         if ($pluginType & Dwoo_Core::COMPILABLE_PLUGIN) {
             if ($pluginType & Dwoo_Core::CUSTOM_PLUGIN) {
                 $funcCompiler = $this->customPlugins[$func]['callback'];
             } else {
                 $funcCompiler = 'Dwoo_Plugin_' . $func . '_compile';
             }
             array_unshift($params, $this);
             if ($func === 'tif') {
                 $params[] = $tokens;
             }
             $output = call_user_func_array($funcCompiler, $params);
         } else {
             array_unshift($params, '$this');
             $params = self::implode_r($params);
             if ($pluginType & Dwoo_Core::CUSTOM_PLUGIN) {
                 $callback = $this->customPlugins[$func]['callback'];
                 $output = 'call_user_func(\'' . $callback . '\', ' . $params . ')';
             } else {
                 $output = 'Dwoo_Plugin_' . $func . '(' . $params . ')';
             }
         }
     } elseif ($pluginType & Dwoo_Core::CLASS_PLUGIN) {
         if ($pluginType & Dwoo_Core::COMPILABLE_PLUGIN) {
             if ($pluginType & Dwoo_Core::CUSTOM_PLUGIN) {
                 $callback = $this->customPlugins[$func]['callback'];
                 if (!is_array($callback)) {
                     if (!method_exists($callback, 'compile')) {
                         throw new Dwoo_Exception('Custom plugin ' . $func . ' must implement the "compile" method to be compilable, or you should provide a full callback to the method to use');
                     }
                     if (($ref = new ReflectionMethod($callback, 'compile')) && $ref->isStatic()) {
                         $funcCompiler = array($callback, 'compile');
                     } else {
                         $funcCompiler = array(new $callback(), 'compile');
                     }
                 } else {
                     $funcCompiler = $callback;
                 }
             } else {
                 $funcCompiler = array('Dwoo_Plugin_' . $func, 'compile');
                 array_unshift($params, $this);
             }
             $output = call_user_func_array($funcCompiler, $params);
         } else {
             $params = self::implode_r($params);
             if ($pluginType & Dwoo_Core::CUSTOM_PLUGIN) {
                 $callback = $this->customPlugins[$func]['callback'];
                 if (!is_array($callback)) {
                     if (!method_exists($callback, 'process')) {
                         throw new Dwoo_Exception('Custom plugin ' . $func . ' must implement the "process" method to be usable, or you should provide a full callback to the method to use');
                     }
                     if (($ref = new ReflectionMethod($callback, 'process')) && $ref->isStatic()) {
                         $output = 'call_user_func(array(\'' . $callback . '\', \'process\'), ' . $params . ')';
                     } else {
                         $output = 'call_user_func(array($this->getObjectPlugin(\'' . $callback . '\'), \'process\'), ' . $params . ')';
                     }
                 } elseif (is_object($callback[0])) {
                     $output = 'call_user_func(array($this->plugins[\'' . $func . '\'][\'callback\'][0], \'' . $callback[1] . '\'), ' . $params . ')';
                 } elseif (($ref = new ReflectionMethod($callback[0], $callback[1])) && $ref->isStatic()) {
                     $output = 'call_user_func(array(\'' . $callback[0] . '\', \'' . $callback[1] . '\'), ' . $params . ')';
                 } else {
                     $output = 'call_user_func(array($this->getObjectPlugin(\'' . $callback[0] . '\'), \'' . $callback[1] . '\'), ' . $params . ')';
                 }
                 if (empty($params)) {
                     $output = substr($output, 0, -3) . ')';
                 }
             } else {
                 $output = '$this->classCall(\'' . $func . '\', array(' . $params . '))';
             }
         }
     } elseif ($pluginType & Dwoo_Core::PROXY_PLUGIN) {
         $output = call_user_func(array($this->dwoo->getPluginProxy(), 'getCode'), $func, $params);
     } elseif ($pluginType & Dwoo_Core::SMARTY_FUNCTION) {
         if (isset($params['*'])) {
             $params = self::implode_r($params['*'], true);
         } else {
             $params = '';
         }
         if ($pluginType & Dwoo_Core::CUSTOM_PLUGIN) {
             $callback = $this->customPlugins[$func]['callback'];
             if (is_array($callback)) {
                 if (is_object($callback[0])) {
                     $output = 'call_user_func_array(array($this->plugins[\'' . $func . '\'][\'callback\'][0], \'' . $callback[1] . '\'), array(array(' . $params . '), $this))';
                 } else {
                     $output = 'call_user_func_array(array(\'' . $callback[0] . '\', \'' . $callback[1] . '\'), array(array(' . $params . '), $this))';
                 }
             } else {
                 $output = $callback . '(array(' . $params . '), $this)';
             }
         } else {
             $output = 'smarty_function_' . $func . '(array(' . $params . '), $this)';
         }
     } elseif ($pluginType & Dwoo_Core::TEMPLATE_PLUGIN) {
         array_unshift($params, '$this');
         $params = self::implode_r($params);
         $output = 'Dwoo_Plugin_' . $func . '_' . $this->templatePlugins[$func]['uuid'] . '(' . $params . ')';
         $this->templatePlugins[$func]['called'] = true;
     }
     if (is_array($parsingParams)) {
         $parsingParams[] = array($output, $output);
         return $parsingParams;
     } elseif ($curBlock === 'namedparam') {
         return array($output, $output);
     } else {
         return $output;
     }
 }
예제 #4
0
 public function testIf()
 {
     $tpl = new Dwoo_Template_String('{if "BAR"==reverse($foo|reverse|upper)}true{/if}');
     $tpl->forceCompilation();
     $this->assertEquals('true', $this->dwoo->get($tpl, array('foo' => 'bar'), $this->compiler));
     // fixes the init call not being called (which is normal)
     $fixCall = new Dwoo_Plugin_if($this->dwoo);
     $fixCall->init(array());
 }