HEX
Server: Apache
System: Linux pdx1-shared-a1-38 6.6.104-grsec-jammy+ #3 SMP Tue Sep 16 00:28:11 UTC 2025 x86_64
User: mmickelson (3396398)
PHP: 8.1.31
Disabled: NONE
Upload Files
File: /home/mmickelson/theflexguy.com/wp-content/themes/vanilla/PHPTAL/Php/TalesInternal.php
<?php
/* vim: set expandtab tabstop=4 shiftwidth=4: */
//
//  Copyright (c) 2004-2005 Laurent Bedubourg
//
//  This library is free software; you can redistribute it and/or
//  modify it under the terms of the GNU Lesser General Public
//  License as published by the Free Software Foundation; either
//  version 2.1 of the License, or (at your option) any later version.
//
//  This library is distributed in the hope that it will be useful,
//  but WITHOUT ANY WARRANTY; without even the implied warranty of
//  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
//  Lesser General Public License for more details.
//
//  You should have received a copy of the GNU Lesser General Public
//  License along with this library; if not, write to the Free Software
//  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
//
//  Authors: Laurent Bedubourg <lbedubourg@motion-twin.com>
//			 Moritz Bechler <mbechler@eenterphace.org>
//

require_once PHPTAL_DIR.'PHPTAL/TalesRegistry.php';

class PHPTAL_TalesInternal implements PHPTAL_Tales {

	//
	// This function registers all internal expression modifiers
	//
	static public function registerInternalTales() {

		static $registered = false;

		if($registered) {
			return;
		}

		$registry = PHPTAL_TalesRegistry::getInstance();

		$registry->registerPrefix('not', array(__CLASS__, 'not'));
		$registry->registerPrefix('path', array(__CLASS__, 'path'));
		$registry->registerPrefix('string', array(__CLASS__, 'string'));
		$registry->registerPrefix('php', array(__CLASS__, 'php'));
		$registry->registerPrefix('exists', array(__CLASS__, 'exists'));
		$registry->registerPrefix('number', array(__CLASS__, 'number'));
        $registry->registerPrefix('true', array(__CLASS__, 'true'));

		$registered = true;
	}

    static public function true($src, $nothrow)
    {
	    return sprintf('phptal_true($ctx, %s)', self::string(trim($src), $nothrow));
    }

	//
	// not:
	//
	//      not: Expression
	//
	// evaluate the expression string (recursively) as a full expression,
	// and returns the boolean negation of its value
	//
	// return boolean based on the following rules:
	//
	//     1. integer 0 is false
	//     2. integer > 0 is true
	//     3. an empty string or other sequence is false
	//     4. a non-empty string or other sequence is true
	//     5. a non-value (e.g. void, None, Nil, NULL, etc) is false
	//     6. all other values are implementation-dependent.
	//
	// Examples:
	//
	//      not: exists: foo/bar/baz
	//      not: php: object.hasChildren()
	//      not: string:${foo}
	//      not: foo/bar/booleancomparable
	//
	static public function not($expression, $nothrow)
	{
		return '!(' . phptal_tales($expression, $nothrow) . ')';
	}


	//
	// path:
	//
	//      PathExpr  ::= Path [ '|' Path ]*
	//      Path      ::= variable [ '/' URL_Segment ]*
	//      variable  ::= Name
	//
	// Examples:
	//
	//      path: username
	//      path: user/name
	//      path: object/method/10/method/member
	//      path: object/${dynamicmembername}/method
	//      path: maybethis | path: maybethat | path: default
	//
	// PHPTAL:
	//
	// 'default' may lead to some 'difficult' attributes implementation
	//
	// For example, the tal:content will have to insert php code like:
	//
	// if (isset($ctx->maybethis)) {
	//     echo $ctx->maybethis;
	// }
	// else if (isset($ctx->maybethat) {
	//     echo $ctx->maybethat;
	// }
	// else {
	//     // process default tag content
	// }
	//
	// @returns string or array
	//
	static public function path($expression, $nothrow=false)
	{
	    $expression = trim($expression);
	    if ($expression == 'default') return PHPTAL_TALES_DEFAULT_KEYWORD;
	    if ($expression == 'nothing') return PHPTAL_TALES_NOTHING_KEYWORD;
	    if ($expression == '')        return PHPTAL_TALES_NOTHING_KEYWORD;

	    // split OR expressions terminated by a string
	    if (preg_match('/^(.*?)\s*\|\s*?(string:.*)$/sm', $expression, $m)){
	        list(, $expression, $string) = $m;
	    }
	    // split OR expressions terminated by a 'fast' string
	    else if (preg_match('/^(.*?)\s*\|\s*\'((?:[^\'\\\\]|\\\\.)*)\'\s*$/sm', $expression, $m)){
	        list(, $expression, $string) = $m;
	        $string = 'string:'.stripslashes($string);
	    }

	    // split OR expressions
	    $exps = preg_split('/\s*\|\s*/sm', $expression);

	    // if (many expressions) or (expressions or terminating string) found then
	    // generate the array of sub expressions and return it.
	    if (count($exps) > 1 || isset($string)) {
	        $result = array();
	        foreach ($exps as $exp) {
	            $result[] = phptal_tales(trim($exp), true);
	        }
	        if (isset($string)){
	            $result[] = phptal_tales($string, true);
	        }
	        return $result;
	    }

	    // only one expression to process

	    // first evaluate ${foo} inside the expression and threat the expression
	    // as if it was a string to interpolate
	    $expression = self::string($expression);
	    $expression = substr($expression, 1, -1);

	    $pos = strpos($expression, '/');
	    // if no sub part for this expression, just optimize the generated code
	    // and access the $ctx->var
	    if ($pos === false) {
	        if (!self::checkExpressionPart($expression)) throw new PHPTAL_Exception("Invalid TALES path: '$expression', expected variable name");
	        return '$ctx->'.$expression;
	    }

	    // otherwise we have to call phptal_path() to resolve the path at runtime
	    // extract the first part of the expression (it will be the phptal_path()
	    // $base and pass the remaining of the path to phptal_path()
	    $next = substr($expression, 0, $pos);
	    $expression = substr($expression, $pos+1);

        if (!self::checkExpressionPart($next))  throw new PHPTAL_Exception("Invalid TALES path: '$next/$expression', expected '$next' to be variable name");
        
	    // return php code invoking phptal_path($next, $expression, $notrhow)
	    return 'phptal_path($ctx->'.$next.', \''.$expression.'\''.($nothrow ? ', true' : '').')';
	}

    private static function checkExpressionPart($expression)
    {
        return preg_match('/^(\$?[a-z_][a-z0-9_]*|{.*})$/i',$expression);
    }

	//
	// string:
	//
	//      string_expression ::= ( plain_string | [ varsub ] )*
	//      varsub            ::= ( '$' Path ) | ( '${' Path '}' )
	//      plain_string      ::= ( '$$' | non_dollar )*
	//      non_dollar        ::= any character except '$'
	//
	// Examples:
	//
	//      string:my string
	//      string:hello, $username how are you
	//      string:hello, ${user/name}
	//      string:you have $$130 in your bank account
	//
	static public function string($expression, $nothrow=false)
	{
	    // This is a simple parser which evaluates ${foo} inside
	    // 'string:foo ${foo} bar' expressions, it returns the php code which will
	    // print the string with correct interpollations.
	    // Nothing special there :)

	    $inPath = false;
	    $inAccoladePath = false;
	    $lastWasDollar = false;
	    $result = '';
	    $len = strlen($expression);
	    for ($i=0; $i<$len; $i++) {
	        $c = $expression[$i];
	        switch ($c) {
	            case '$':
	                if ($lastWasDollar) {
	                    $lastWasDollar = false;
	                }
	                else {
	                    $lastWasDollar = true;
	                    $c = '';
	                }
	                break;

                case '\\':
                    $c = '\\\\';
                    break;

	            case '\'':
	                $c = '\\\'';
	                break;

	            case '{':
	                if ($lastWasDollar) {
	                    $lastWasDollar = false;
	                    $inAccoladePath = true;
	                    $subPath = '';
	                    $c = '';
	                }
	                break;

	            case '}':
	                if ($inAccoladePath) {
	                    $inAccoladePath = false;
	                    $subEval = self::path($subPath);
	                    if (is_array($subEval)) {
	                        $err = 'cannot use | operator in evaluated expressions';
	                        throw new PHPTAL_Exception($err);
	                    }
	                    $result .= "'." . $subEval . ".'";
	                    $subPath = '';
	                    $lastWasDollar = false;
	                    $c = '';
	                }
	                break;

	            default:
	                if ($lastWasDollar) {
	                    $lastWasDollar = false;
	                    $inPath = true;
	                    $subPath = $c;
	                    $c = '';
	                }
	                else if ($inAccoladePath) {
	                    $subPath .= $c;
	                    $c = '';
	                }
	                else if ($inPath) {
	                    $t = strtolower($c);
	                    if (($t >= 'a' && $t <= 'z') || ($t >= '0' && $t <= '9') || ($t == '_')){
	                        $subPath .= $c;
	                        $c = '';
	                    }
	                    else {
	                        $inPath = false;
	                        $subEval = self::path($subPath);
	                        if (is_array($subEval)) {
	                            $err = 'cannot use | operator in evaluated expressions';
	                            throw new PHPTAL_Exception($err);
	                        }
	                        $result .= "'." . $subEval . ".'";
	                    }
	                }
	                break;
	        }
	        $result .= $c;
	    }
	    if ($inPath){
	        $subEval = self::path($subPath);
	        if (is_array($subEval)){
	            $err = 'cannot use | operator in evaluated expressions';
	            throw new PHPTAL_Exception($err);
	        }
	        $result .= "'." . $subEval . ".'";
	    }
	    return '\''.$result.'\'';
	}

	/**
	 * php: modifier.
	 *
	 * Transform the expression into a regular PHP expression.
	 */
	static public function php($src)
	{
	    require_once PHPTAL_DIR.'PHPTAL/Php/Transformer.php';
	    return PHPTAL_Php_Transformer::transform($src, '$ctx->');
	}

	/**
	 * exists: modifier.
	 *
	 * Returns the code required to invoke phptal_exists() on specified path.
	 */
	static public function exists($src, $nothrow)
	{
	    return sprintf('phptal_exists($ctx, %s)', self::string(trim($src), $nothrow));
	}

	/**
	 * number: modifier.
	 *
	 * Returns the number as is.
	 */
	static public function number($src, $nothrow)
	{
	    return trim($src);
	}
}

?>