Ejemplo n.º 1
0
 /**
  * Tal extension to translate the values in an array.
  *
  * This Tal accepts an array and, via its helper function, returns a new
  * array with identical keys but with values translated using the current
  * translator.
  *
  * This Tal is most useful in translating an array before sorting it based
  * on the translated content. Note that variable replacement in the post-
  * translated string should still work but plurals won't.
  *
  * Example use within template:
  * <span
  *    tal:define="translatedArray Ztal_Tales_Translation.translateArrayValues:originalArray"
  *    tal:repeat="item translatedArray"
  *    tal:content="item"
  * />
  *
  * @param string $src     The original string from the source template.
  * @param bool   $nothrow Whether to throw an exception on error or not.
  *
  * @return string
  */
 public static function translateArrayValues($src, $nothrow)
 {
     $break = strpos($src, '|');
     if ($break !== false) {
         $src = substr($src, 0, $break);
     }
     return 'Ztal_Tales_Translation::arrayTranslationHelper(' . phptal_tale($src, $nothrow) . ', $_translator)';
 }
Ejemplo n.º 2
0
function phptal_tales_calcxp($src, $nothrow)
{
    $exp = Template::SplitSRC($src);
    $args = explode(' ', trim($src));
    if (count($args) !== 2) {
        throw new PHPTAL_InvalidVariableNameException("calcxp takes two arguments, XP and CHG.");
    }
    $xp = phptal_tale($args[0]);
    $chg = phptal_tale($args[1]);
    array_unshift($exp, 'phptal_func_calcxp(' . $xp . ',' . $chg . ')');
    return $exp;
}
Ejemplo n.º 3
0
 private function _getTranslationCode($key)
 {
     $code = '<?php ';
     if (preg_match_all('/\\$\\{(.*?)\\}/', $key, $m)) {
         array_shift($m);
         $m = array_shift($m);
         foreach ($m as $name) {
             $code .= "\n" . '$_translator->setVar(\'' . $name . '\',' . phptal_tale($name) . ');';
             // allow more complex TAL expressions
         }
         $code .= "\n";
     }
     // notice the false boolean which indicate that the html is escaped
     // elsewhere looks like an hack doesn't it ? :)
     $result = $this->tag->generator->escapeCode(sprintf('$_translator->translate(%s, false)', $key));
     $code .= 'echo ' . $result . '?>';
     return $code;
 }
Ejemplo n.º 4
0
 function testTaleNeverReturnsArray()
 {
     $this->assertInternalType('string', phptal_tale('foo | bar | baz | nothing'));
 }
Ejemplo n.º 5
0
 /**
  * urlencode: modifier. Escapes a string.
  */
 public static function urlencode($src, $nothrow)
 {
     return 'rawurlencode(' . phptal_tale($src, $nothrow) . ')';
 }
Ejemplo n.º 6
0
 /**
  * Tal extension to inject slot content into a variable.
  *
  * Slot names cannot (currently) be dynamic in phptal so this tale
  * allows us to grab the content of a slot with a dynamic name and
  * assign it to a variable which we can then output.
  *
  * Example use within template:
  * <tal:block tal:define="slotContent Ztal\Tales\Form.getSlotContent:slotName" />
  *
  * @param string $src     The original template string.
  * @param bool   $nothrow Whether to throw an exception on error.
  *
  * @return string
  */
 public static function getSlotContent($src, $nothrow)
 {
     $break = strpos($src, '|');
     if ($break === false) {
         $slotName = $src;
         $notTrue = 'NULL';
     } else {
         $slotName = substr($src, 0, $break);
         $notTrue = substr($src, $break + 1);
     }
     return '($ctx->hasSlot(' . phptal_tale($slotName, $nothrow) . ')?$ctx->getSlot(' . phptal_tale($slotName, $nothrow) . '):' . phptal_tale($notTrue, $nothrow) . ')';
 }
Ejemplo n.º 7
0
 /**
  * Tal for doing PHP's array merging.
  *
  * Return an array of the items in array1 unioned with the items in array2.
  *
  * Note that if key mode is used, the php + operator is applied to merge
  * the arrays (which prefers array1's value for a key that exists in both
  * arrays) but the values are not compared and filtered for uniqueness.
  * If value mode is selected, keys are discarded and the arrays merged
  * using array_merge before filtered for uniqueness with array_unique.
  *
  * Example usage:
  * <span tal:define="complement Ztal\Tales\ArrayUtils.complement:mode,array1,array2" />
  *
  * mode may be:
  *  key - diff on keys
  *  value - diff on values
  *
  * See the php array_diff and array_diff_key functions for more details
  *
  * @param string $src     The original template string.
  * @param bool   $nothrow Whether to throw an exception on error.
  *
  * @return string
  */
 public static function union($src, $nothrow)
 {
     $break = strpos($src, '|');
     if ($break !== false) {
         $src = substr($src, 0, $break);
     }
     $parts = explode(',', $src);
     return '(' . phptal_tale($parts[0], $nothrow) . ' == \'key\' ? (' . phptal_tale($parts[1], $nothrow) . '+' . phptal_tale($parts[2], $nothrow) . ')) : array_unique(array_values(' . phptal_tale($parts[1], $nothrow) . '), array_values(' . phptal_tale($parts[2], $nothrow) . ')))';
 }
Ejemplo n.º 8
0
 public static function nozero($src, $nothrow)
 {
     $exp = Template::SplitSRC($src, $nothrow);
     array_unshift($exp, 'Template_Tales::nozeroFUNC(' . phptal_tale($src, $nothrow) . ')');
     return $exp;
 }
Ejemplo n.º 9
0
 public static function json($src, $nothrow)
 {
     return 'json_encode(' . phptal_tale($src, $nothrow) . ')';
 }
Ejemplo n.º 10
0
function phptal_tales_lang($attr)
{
    list($index, $current) = explode(' ', $attr, 2);
    return 't(\'' . $index . '\'' . ($current ? ', ' . phptal_tale($current) : '') . ')';
}
Ejemplo n.º 11
0
 /**
  * Tal to support filtering of an array.
  *
  * Example usage:
  *
  * <span
  *  tal:define="keys string:key1,key2"
  *  tal:repeat="arr Ztal_Tales_Generic.arrayFilter:string:mode,keys,array
  * />
  *
  * mode may be:
  *    key   - Filter items by the array key.
  *    value - Filter items by the array value.
  *
  * The last parameter is the original array to filter, this should be a
  * PHPTAL variable.
  *
  * @param string $src     The original template string.
  * @param bool   $nothrow Whether to throw an exception on error.
  *
  * @return string
  */
 public static function arrayFilter($src, $nothrow)
 {
     $regex = "/([a-zA-Z:]+)\\s*?,\\s*?([a-zA-Z0-9:]+)\\s*?,\\s*?([^|\$]+)\$/";
     $src = trim($src);
     // If we can't find a match for our parameters simply return NULL.
     if (!preg_match($regex, $src, $items)) {
         return phptal_tales('NULL', $nothrow);
     }
     // Call the array filtering helper with:
     //
     // $items[1] = Type of filtering (e.g. key or value).
     // $items[2] = PHPTAL variable (array) of items to filter with, or a
     //             string of comma seperated items,
     // $items[3] = PHPTAL variable of haystack array.
     // true = Exclude rather than filter.
     return "Ztal_Tales_Generic::arrayFilterHelper(\n\n\t\t\t" . phptal_tale($items[1], $nothrow) . ",\n\t\t\t" . phptal_tale($items[2], $nothrow) . ",\n\t\t\t" . phptal_tale($items[3], $nothrow) . ")";
 }
Ejemplo n.º 12
0
 /**
  * returns PHP code that will evaluate given TALES expression.
  * e.g. "string:foo${bar}" may be transformed to "'foo'.phptal_escape($ctx->bar)"
  *
  * Expressions with alternatives ("foo | bar") will cause it to return array
  * Use PHPTAL_Php_TalesInternal::compileToPHPExpression() if you always want string.
  *
  * @param bool $nothrow if true, invalid expression will return NULL (at run time) rather than throwing exception
  * @return string or array
  */
 public static function compileToPHPStatements($expression, $nothrow = false)
 {
     $expression = trim($expression);
     // Look for tales modifier (string:, exists:, etc...)
     //if (preg_match('/^([-a-z]+):(.*?)$/', $expression, $m)) {
     #if (preg_match('/^([_a-z][.a-z_-]*[a-z]):(.*)$/si', $expression, $m)) {
     if (preg_match('/^([a-z_][a-z0-9_]*):(.*)$/si', $expression, $m)) {
         list(, $typePrefix, $expression) = $m;
     } elseif (preg_match('/^\'((?:[^\']|\\\\.)*)\'$/s', $expression, $m)) {
         $expression = stripslashes($m[1]);
         $typePrefix = 'string';
     } else {
         $typePrefix = 'path';
     }
     // is a registered TALES expression modifier
     if (PHPTAL_TalesRegistry::getInstance()->isRegistered($typePrefix)) {
         $callback = PHPTAL_TalesRegistry::getInstance()->getCallback($typePrefix);
         return call_user_func($callback, $expression, $nothrow);
     }
     // class method
     if (strpos($typePrefix, '.')) {
         $classCallback = explode('.', $typePrefix, 2);
         $callbackName = null;
         if (!is_callable($classCallback, FALSE, $callbackName)) {
             throw new PHPTAL_UnknownModifierException("Unknown phptal modifier {$typePrefix}. Function {$callbackName} does not exists or is not statically callable");
         }
         $ref = new ReflectionClass($classCallback[0]);
         if (!$ref->implementsInterface('PHPTAL_Tales')) {
             throw new PHPTAL_UnknownModifierException("Unable to use phptal modifier {$typePrefix} as the class {$callbackName} does not implement the PHPTAL_Tales interface");
         }
         return call_user_func($classCallback, $expression, $nothrow);
     }
     // check if it is implemented via code-generating function
     $func = 'phptal_tales_' . str_replace('-', '_', $typePrefix);
     if (function_exists($func)) {
         return $func($expression, $nothrow);
     } elseif (function_exists($func2 = str_replace('-', '_', $typePrefix))) {
         return $func2 . '(' . phptal_tale($expression) . ')';
     }
     // check if it is implemented via runtime function
     $runfunc = 'phptal_runtime_tales_' . str_replace('-', '_', $typePrefix);
     if (function_exists($runfunc)) {
         return "{$runfunc}(" . self::compileToPHPExpression($expression, $nothrow) . ")";
     }
     throw new PHPTAL_UnknownModifierException("Unknown phptal modifier '{$typePrefix}'. Function '{$func}' does not exist");
 }
Ejemplo n.º 13
0
/**
 * Generic tales modifier for Zend_View helpers
 *
 * @param string $exp
 * @param bool $nothrow
 */
function phptal_tales_helper($exp, $nothrow)
{
    if (preg_match('/^([A-Za-z_]+)\\(([^)]*)\\)/', $exp, $m)) {
        $args = explode(',', $m[2]);
        foreach ($args as &$arg) {
            $arg = phptal_tale($arg, $nothrow);
        }
        $exp = 'php:this->' . $m[1] . '(' . implode(', ', $args) . ')';
    } else {
        list($helper, $param) = explode(' ', $exp, 2);
        $exp = 'php:this->' . $helper . '(' . phptal_tales($param, $nothrow) . ')';
    }
    return phptal_tale($exp, $nothrow);
}
Ejemplo n.º 14
0
 private function _interpolateTalesVarsEscaped($matches)
 {
     return '<?php echo phptal_escape(' . phptal_tale($matches[1]) . ', ENT_QUOTES, \'' . $this->_encoding . '\');?>';
 }
Ejemplo n.º 15
0
function phptal_tales($expression, $nothrow = false)
{
    $expression = trim($expression);
    // Look for tales modifier (string:, exists:, etc...)
    //if (preg_match('/^([-a-z]+):(.*?)$/', $expression, $m)) {
    if (preg_match('/^([a-z][-.a-z]*[a-z]):(.*?)$/i', $expression, $m)) {
        list(, $typePrefix, $expression) = $m;
    } else {
        if (preg_match('/^\'((?:[^\']|\\\\.)*)\'$/', $expression, $m)) {
            $expression = stripslashes($m[1]);
            $typePrefix = 'string';
        } else {
            $typePrefix = 'path';
        }
    }
    // is a registered TALES expression modifier
    if (PHPTAL_TalesRegistry::getInstance()->isRegistered($typePrefix)) {
        $callback = PHPTAL_TalesRegistry::getInstance()->getCallback($typePrefix);
        return call_user_func($callback, $expression, $nothrow);
    }
    // class method
    if (strpos($typePrefix, '.')) {
        $classCallback = explode('.', $typePrefix, 2);
        $callbackName = NULL;
        if (!is_callable($classCallback, FALSE, $callbackName)) {
            $err = 'Unknown phptal modifier %s function %s does not exists or is not statically callable.';
            $err = sprintf($err, $typePrefix, $callbackName);
            throw new PHPTAL_Exception($err);
        }
        $ref = new ReflectionClass($classCallback[0]);
        if (!$ref->implementsInterface('PHPTAL_Tales')) {
            $err = 'Unable to use phptal modifier %s as the class %s does not implement the PHPTAL_Tales interface.';
            $err = sprintf($err, $typePrefix, $callbackName);
            throw new PHPTAL_Exception($err);
        }
        return call_user_func($classCallback, $expression, $nothrow);
    }
    // check if it is implemented via code-generating function
    $func = 'phptal_tales_' . str_replace('-', '_', $typePrefix);
    if (function_exists($func)) {
        return $func($expression, $nothrow);
    }
    // check if it is implemented via runtime function
    $runfunc = 'phptal_runtime_tales_' . str_replace('-', '_', $typePrefix);
    if (function_exists($runfunc)) {
        return "{$runfunc}(" . phptal_tale($expression, $nothrow) . ")";
    }
    throw new PHPTAL_Exception("Unknown phptal modifier '{$typePrefix}'. Function '{$func}' does not exist");
}
Ejemplo n.º 16
0
 /**
  * Formats a number to a certain decimal place.
  *
  * Formats the number to the provided decimal place - that's numberwang!
  * Example use within template:
  *
  * <span
  *   tal:content="Ztal\Tales\Generic.numberFormatDecimal:numberVar,string:2"
  * />.
  *
  * @param string $src     The original template string.
  * @param bool   $nothrow Whether to throw an exception on error.
  *
  * @return string
  */
 public static function numberFormatDecimal($src, $nothrow)
 {
     $break = strpos($src, ',');
     $variable = substr($src, 0, $break);
     $src = substr($src, $break + 1);
     $break = strpos($src, '|');
     if ($break === false) {
         $decimal = $src;
     } else {
         $decimal = substr($src, 0, $break);
     }
     return 'number_format(' . phptal_tale($variable, $nothrow) . ', ' . phptal_tale($decimal, $nothrow) . ')';
 }