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
<?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>
//

define('PHPTAL_VERSION', '1_1_14');

//{{{PHPTAL_DIR
if (!defined('PHPTAL_DIR')) define('PHPTAL_DIR',dirname(__FILE__).DIRECTORY_SEPARATOR);
else assert('substr(PHPTAL_DIR,-1) == DIRECTORY_SEPARATOR');
//}}}

/* Please don't use the following constants. They have been replaced by methods in the PHPTAL class and are kept for backwards compatibility only. */
//{{{
if (!defined('PHPTAL_PHP_CODE_DESTINATION')) {
    if (function_exists('sys_get_temp_dir')) define('PHPTAL_PHP_CODE_DESTINATION',rtrim(sys_get_temp_dir(), DIRECTORY_SEPARATOR).DIRECTORY_SEPARATOR);
    else if (substr(PHP_OS,0,3) == 'WIN') {
        if (file_exists('c:\\WINNT\\Temp\\')) define('PHPTAL_PHP_CODE_DESTINATION', 'c:\\WINNT\\Temp\\');
        else define('PHPTAL_PHP_CODE_DESTINATION', 'c:\\WINDOWS\\Temp\\');
    }
    else define('PHPTAL_PHP_CODE_DESTINATION', '/tmp/');
}
if (!defined('PHPTAL_DEFAULT_ENCODING')) define('PHPTAL_DEFAULT_ENCODING', 'UTF-8');
if (!defined('PHPTAL_PHP_CODE_EXTENSION')) define('PHPTAL_PHP_CODE_EXTENSION', 'php');
//}}}

define('PHPTAL_XHTML', 1);
define('PHPTAL_XML',   2);

require_once PHPTAL_DIR.'PHPTAL/FileSource.php';
require_once PHPTAL_DIR.'PHPTAL/RepeatController.php';
require_once PHPTAL_DIR.'PHPTAL/Context.php';
require_once PHPTAL_DIR.'PHPTAL/Exception.php';
require_once PHPTAL_DIR.'PHPTAL/TalesRegistry.php';
require_once PHPTAL_DIR.'PHPTAL/Filter.php';

/**
 * PHPTAL template entry point.
 *
 * <code>
 * <?php
 * require_once 'PHPTAL.php';
 * try {
 *      $tpl = new PHPTAL('mytemplate.html');
 *      $tpl->title = 'Welcome here';
 *      $tpl->result = range(1, 100);
 *      ...
 *      echo $tpl->execute();
 * }
 * catch (Exception $e) {
 *      echo $e;
 * }
 * ?>
 * </code>
 *
 * @author Laurent Bedubourg <lbedubourg@motion-twin.com>
 */
class PHPTAL
{
    const XHTML = 1;
    const XML   = 2;

    /**
     * PHPTAL Constructor.
     *
     * @param string $path Template file path.
     */
    public function __construct($path=false)
    {
        $this->_path = $path;
        $this->_repositories = array();
        if (defined('PHPTAL_TEMPLATE_REPOSITORY')){
            $this->_repositories[] = PHPTAL_TEMPLATE_REPOSITORY;
        }
        $this->_resolvers = array();
        $this->_globalContext = new StdClass();
        $this->_context = new PHPTAL_Context();
        $this->_context->setGlobal($this->_globalContext);
    }

    /**
     * create
     * returns a new PHPTAL object
     *
     * @param string $path Template file path.
     * @return PHPTAL
     */
    public static function create($path=false)
    {
        return new PHPTAL($path);
    }

    /**
     * Clone template state and context.
     */
    public function __clone()
    {
        $context = $this->_context;
        $this->_context = clone $this->_context;
        $this->_context->setParent($context);
        $this->_context->setGlobal($this->_globalContext);
    }

    /**
     * Set template from file path.
     * @param $path string
     */
    public function setTemplate($path)
    {
        $this->_prepared = false;
        $this->_functionName = null;
        $this->_path = $path;
        $this->_source = null;
        return $this;
    }

    /**
     * Set template from source.
     *
     * Should be used only with temporary template sources. Use setTemplate() whenever possible.
     *
     * @param $src string The phptal template source.
     * @param path string Fake and 'unique' template path.
     */
    public function setSource($src, $path=false)
    {
        if ($path == false)
            $path = '<string> '.md5($src);

        require_once PHPTAL_DIR.'PHPTAL/StringSource.php';
        $this->_source = new PHPTAL_StringSource($src, $path);
        $this->_path = $path;
        return $this;
    }

    /**
     * Specify where to look for templates.
     *
     * @param $rep mixed string or Array of repositories
     */
    public function setTemplateRepository($rep)
    {
        if (is_array($rep)){
            $this->_repositories = $rep;
        }
        else {
            $this->_repositories[] = $rep;
        }
        return $this;
    }

    /**
     * Get template repositories.
     */
    public function getTemplateRepositories()
    {
        return $this->_repositories;
    }

    /**
     * Clears the template repositories.
     */
    public function clearTemplateRepositories()
    {
        $this->_repositories = array();
        return $this;
    }

    /**
     * Ignore XML/XHTML comments on parsing.
     * @param $bool bool
     */
    public function stripComments($bool)
    {
        $this->_stripComments = $bool;
        return $this;
    }

    /**
     * Set output mode
     * XHTML output mode will force elements like <link/>, <meta/> and <img/>, etc. to be empty
     * and threats attributes like selected, checked to be boolean attributes.
     *
     * XML output mode outputs XML without such modifications and is neccessary to generate RSS feeds properly.
     * @param $mode int (PHPTAL::XML or PHPTAL::XHTML).
     */
    public function setOutputMode($mode=PHPTAL_XHTML)
    {
        if ($mode != PHPTAL::XHTML && $mode != PHPTAL::XML){
            throw new PHPTAL_Exception('Unsupported output mode '.$mode);
        }
        $this->_outputMode = $mode;
        return $this;
    }

    /**
     * Get output mode
     */
    public function getOutputMode()
    {
        return $this->_outputMode;
    }

    /**
     * Set input and ouput encoding.
     * @param $enc string example: 'UTF-8'
     */
    public function setEncoding($enc)
    {
        $this->_encoding = $enc;
        if ($this->_translator) $this->_translator->setEncoding($enc);
        return $this;
    }

    /**
     * Get input and ouput encoding.
     * @param $enc string example: 'UTF-8'
     */
    public function getEncoding()
    {
        return $this->_encoding;
    }

    /**
     * Set the storage location for intermediate PHP files. The path cannot contain characters that would be interpreted by glob() (e.g. * or ?)
     * @param string $path Intermediate file path.
     */
    public function setPhpCodeDestination($path)
    {
        $this->_phpCodeDestination = rtrim($path, DIRECTORY_SEPARATOR).DIRECTORY_SEPARATOR;
        return $this;
    }

    /**
     * Get the storage location for intermediate PHP files.
     */
    public function getPhpCodeDestination()
    {
        return $this->_phpCodeDestination;
    }

    /**
     * Set the file extension for intermediate PHP files.
     * @param string $extension The file extension.
     */
    public function setPhpCodeExtension($extension)
    {
        $this->_phpCodeExtension = $extension;
        return $this;
    }

    /**
     * Get the file extension for intermediate PHP files.
     */
    public function getPhpCodeExtension()
    {
        return $this->_phpCodeExtension;
    }

    /**
     * Flags whether to ignore intermediate php files and to
     * reparse templates every time (if set to true).
     * Don't use in production - this makes PHPTAL significantly slower.
     * @param bool bool Forced reparse state.
     */
    public function setForceReparse($bool)
    {
        $this->_forceReparse = (bool) $bool;
        return $this;
    }

    /**
     * Get the value of the force reparse state.
     */
    public function getForceReparse()
    {
        return $this->_forceReparse !== NULL ? $this->_forceReparse : (defined('PHPTAL_FORCE_REPARSE') && PHPTAL_FORCE_REPARSE);
    }

    /**
     * Set I18N translator.
     * This sets encoding used by the translator, so be sure to use encoding-dependent features of the translator (e.g. addDomain) _after_ calling setTranslator. 
     */
    public function setTranslator(PHPTAL_TranslationService $t)
    {
        $this->_translator = $t;
        $this->_translator->setEncoding($this->getEncoding());
        return $this;
    }

    /**
     * Set template pre filter. It will be called once before template is compiled.
     */
    public function setPreFilter(PHPTAL_Filter $filter)
    {
        $this->_prefilter = $filter;
        return $this;
    }

    /**
     * Set template post filter. It will be called every time after template generates output.
     */
    public function setPostFilter(PHPTAL_Filter $filter)
    {
        $this->_postfilter = $filter;
        return $this;
    }

    /**
     * Register a trigger for specified phptal:id.
     * @param $id string phptal:id to look for
     */
    public function addTrigger($id, PHPTAL_Trigger $trigger)
    {
        $this->_triggers[$id] = $trigger;
        return $this;
    }

    /**
     * Returns trigger for specified phptal:id.
     * @param $id string phptal:id
     */
    public function getTrigger($id)
    {
        if (array_key_exists($id, $this->_triggers)){
            return $this->_triggers[$id];
        }
        return null;
    }

    /**
     * Set a context variable.
     * @param $varname string
     * @param $value mixed
     */
    public function __set($varname, $value)
    {
        $this->_context->__set($varname, $value);
    }

    /**
     * Set a context variable.
     * @param $varname string
     * @param $value mixed
     */
    public function set($varname, $value)
    {
        $this->_context->__set($varname, $value);
        return $this;
    }

    /**
     * Execute the template code.
     *
     * @return string
     */
    public function execute()
    {
        if (!$this->_prepared) {
            $this->prepare();
        }

        // includes generated template PHP code
        $this->_context->__file = $this->__file;
        require_once $this->getCodePath();
        $templateFunction = $this->getFunctionName();
        try {
            ob_start();
            $templateFunction($this, $this->_context);
            $res = ob_get_clean();
        }
        catch (Exception $e){
            ob_end_clean();
            throw $e;
        }

        // unshift doctype
        $docType = $this->_context->__docType;
        if ($docType){
            $res = $docType . "\n" . $res;
        }
        // unshift xml declaration
        $xmlDec = $this->_context->__xmlDeclaration;
        if ($xmlDec){
            $res = $xmlDec . "\n" . $res;
        }

        if ($this->_postfilter != null){
            return $this->_postfilter->filter($res);
        }
        return $res;
    }

    protected function setConfigurationFrom(PHPTAL $from)
    {
        // use references - this way config of both objects will be more-or-less in sync
        $this->_encoding = &$from->_encoding;
        $this->_outputMode = &$from->_outputMode;
        $this->_stripComments = &$from->_stripComments;
        $this->_forceReparse = &$from->_forceReparse;
        $this->_phpCodeDestination = &$from->_phpCodeDestination;
        $this->_phpCodeExtension = &$from->_phpCodeExtension;
        $this->_cacheLifetime = &$from->_cacheLifetime;
        $this->_cachePurgeFrequency = &$from->_cachePurgeFrequency;
        $this->setTemplateRepository($from->_repositories);
        array_unshift($this->_repositories, dirname($from->_source->getRealPath()));
        $this->_resolvers = &$from->_resolvers;
        $this->_prefilter = &$from->_prefilter;
        $this->_postfilter = &$from->_postfilter;
    }

    private $externalMacroTempaltesCache = array();

    /**
     * Execute a template macro.
     * Should be used only from within generated template code!
     *
     * @param $path string Template macro path
     */
    public function executeMacro($path)
    {
        // extract macro source file from macro name, if not source file
        // found in $path, then the macro is assumed to be local
        if (preg_match('/^(.*?)\/([a-z0-9_]*)$/i', $path, $m)){
            list(,$file,$macroName) = $m;

            if (isset($this->externalMacroTempaltesCache[$file]))
            {
                $tpl = $this->externalMacroTempaltesCache[$file];
            }
            else
            {
                $tpl = new PHPTAL($file);
                $tpl->setConfigurationFrom($this);
                $tpl->prepare();
                // require PHP generated code
                require_once $tpl->getCodePath();
                
                $this->externalMacroTempaltesCache[$file] = $tpl;
                if (count($this->externalMacroTempaltesCache) > 10) $this->externalMacroTempaltesCache = array(); // keep it small (typically only 1 or 2 external files are used)
            }

            // save current file
            $currentFile = $this->_context->__file;
            $this->_context->__file = $tpl->__file;

            $fun = $tpl->getFunctionName() . '_' . $macroName;
            if (!function_exists($fun)) throw new PHPTAL_Exception("Macro '$macroName' is not defined in $file",$this->_source->getRealPath());
            $fun($this, $this->_context);

            // restore current file
            $this->_context->__file = $currentFile;
        }
        else 
        {
            // call local macro
            $fun = $this->getFunctionName() . '_' . trim($path);
            if (!function_exists($fun)) throw new PHPTAL_Exception("Macro '$path' is not defined",$this->_source->getRealPath());
            $fun( $this, $this->_context );
        }
    }

    private function setCodeFile()
    {
        $this->_codeFile = $this->getPhpCodeDestination() . $this->getFunctionName() . '.' . $this->getPhpCodeExtension();
    }

    /**
     * Prepare template without executing it.
     */
    public function prepare()
    {
        // clear just in case settings changed and cache is out of date
        $this->externalMacroTempaltesCache = array();
        
        // find the template source file
        $this->findTemplate();
        $this->__file = $this->_source->getRealPath();
		$this->setCodeFile();
		
        // parse template if php generated code does not exists or template
        // source file modified since last generation of PHPTAL_FORCE_REPARSE
        // is defined.
        if ($this->getForceReparse() || !file_exists($this->_codeFile))
		{
	        if ($this->getCachePurgeFrequency() && mt_rand()%$this->getCachePurgeFrequency() == 0)
    		{
    		    $this->cleanUpGarbage();
    		}
            $this->parse();
        }
        $this->_prepared = true;
        return $this;
    }

    public function getCacheLifetime()
    {
        return $this->_cacheLifetime;
    }

    /**
     * how long compiled templates and phptal:cache files are kept, in days
     */
    public function setCacheLifetime($days)
    {
        $this->_cacheLifetime = max(0.5,$days);
        return $this;
    }

    /**
     * PHPTAL will scan cache and remove old files on every nth compile
     * Set to 0 to disable cleanups
     */
    public function setCachePurgeFrequency($n)
    {
        $this->_cachePurgeFrequency = (int)$n;
        return $this;
    }

    public function getCachePurgeFrequency()
    {
        return $this->_cachePurgeFrequency;
    }


	/**
	 * Removes all compiled templates from cache after PHPTAL_CACHE_LIFETIME days
	 */
	public function cleanUpGarbage()
	{
		$phptalCacheFilesExpire = time() - $this->getCacheLifetime() * 3600 * 24;
		$upperLimit = $this->getPhpCodeDestination() . 'tpl_' . $phptalCacheFilesExpire . '_';
		$lowerLimit = $this->getPhpCodeDestination() . 'tpl_0_';
		$phptalCacheFiles = glob($this->getPhpCodeDestination() . 'tpl_*.' . $this->getPhpCodeExtension() . '*');

		if ($phptalCacheFiles)
		{
			foreach($phptalCacheFiles as $index => $file)
	        {
				if ($file > $upperLimit && substr($file,0,strlen($lowerLimit)) !== $lowerLimit)
				{
				    unset($phptalCacheFiles[$index]);
				}
	        }
	        foreach($phptalCacheFiles as $file)
	        {
	            $time = filemtime($file);
	            if ($time && $time < $phptalCacheFilesExpire) @unlink($file);			 
		    }
	    }
	}

    /**
	 * Removes single compiled template from cache and all its fragments cached by phptal:cache.
	 * Must be called after setSource/setTemplate.
	 */
	public function cleanUpCache()
	{
		if (!$this->getCodePath()) 
		{
			$this->findTemplate(); $this->setCodeFile();
			if (!$this->getCodePath()) throw new PHPTAL_Exception("No codefile");
		}
		
		$filename = $this->getCodePath();		
		$phptalCacheFiles = glob($filename . '*');
		if ($phptalCacheFiles) foreach($phptalCacheFiles as $file)
		{
		    if (substr($file, 0, strlen($filename)) !== $filename) continue; // safety net
			@unlink($file);
	    }
        $this->_prepared = false;
	}	

    /**
     * Returns the path of the intermediate PHP code file.
     *
     * The returned file may be used to cleanup (unlink) temporary files
     * generated by temporary templates or more simply for debug.
     *
     * @return string
     */
    public function getCodePath()
    {
        return $this->_codeFile;
    }

    /**
     * Returns the generated template function name.
     * @return string
     */
    public function getFunctionName()
    {
        if (!$this->_functionName) {
            $this->_functionName = 'tpl_' . $this->_source->getLastModifiedTime() . '_' . PHPTAL_VERSION .
                substr(preg_replace('/[^a-zA-Z]/','',basename($this->_source->getRealPath())),0,10) . md5($this->_source->getRealPath());
        }
        return $this->_functionName;
    }

    /**
     * Returns template translator.
     * @return PHPTAL_TranslationService
     */
    public function getTranslator()
    {
        return $this->_translator;
    }

    /**
     * Returns array of exceptions caught by tal:on-error attribute.
     * @return array<Exception>
     */
    public function getErrors()
    {
        return $this->_errors;
    }

    /**
     * Public for phptal templates, private for user.
     * @access private
     */
    public function addError(Exception $error)
    {
        array_push($this->_errors, $error);
        return $this;
    }

    /**
     * Returns current context object.
     * Use only in Triggers.
     *
     * @return PHPTAL_Context
     */
    public function getContext()
    {
        return $this->_context;
    }

    /**
     * only for use in generated template code
     * @access private
     */
    public function getGlobalContext()
    {
        return $this->_globalContext;
    }

    /**
     * only for use in generated template code
     * @access private
     */
    public function pushContext()
    {
        $this->_context = $this->_context->pushContext();
        return $this->_context;
    }

    /**
     * only for use in generated template code
     * @access private
     */
    public function popContext()
    {
        $this->_context = $this->_context->popContext();
        return $this->_context;
    }

    protected function parse()
    {
        require_once PHPTAL_DIR.'PHPTAL/Dom/Parser.php';

        // instantiate the PHPTAL source parser
        $parser = new PHPTAL_Dom_Parser($this->_encoding);
        $parser->stripComments($this->_stripComments);

        $data = $this->_source->getData();
        $realpath = $this->_source->getRealPath();

        if ($this->_prefilter)
            $data = $this->_prefilter->filter($data);
        $tree = $parser->parseString($data, $realpath);

        require_once PHPTAL_DIR.'PHPTAL/Php/CodeGenerator.php';
        $generator = new PHPTAL_Php_CodeGenerator($this->getFunctionName(), $this->_source->getRealPath());
        $generator->setEncoding($this->_encoding);
        $generator->setOutputMode($this->_outputMode);
        $generator->generate($tree);

        if (!@file_put_contents($this->_codeFile, $generator->getResult())) {
            throw new PHPTAL_Exception('Unable to open '.$this->_codeFile.' for writing');
        }

        return $this;
    }

    /**
     * Search template source location.
     */
    protected function findTemplate()
    {
        if ($this->_path == false){
            throw new PHPTAL_Exception('No template file specified');
        }

        // template source already defined
        if ($this->_source != null){
            return;
        }

        array_push($this->_resolvers, new PHPTAL_FileSourceResolver($this->_repositories));
        foreach ($this->_resolvers as $resolver){
            $source = $resolver->resolve($this->_path);
            if ($source != null){
                $this->_source = $source;
                break;
            }
        }
        array_pop($this->_resolvers);

        if ($this->_source == null){
            throw new PHPTAL_Exception('Unable to locate template file '.$this->_path);
        }
    }

    protected $_prefilter = null;
    protected $_postfilter = null;

    // list of template source repositories
    protected $_repositories = array();
    // template path
    protected $_path = null;
    // template source resolvers
    protected $_resolvers = array();
    // template source (only set when not working with file)
    protected $_source = null;
    // destination of PHP intermediate file
    protected $_codeFile = null;
    // php function generated for the template
    protected $_functionName = null;
    // set to true when template is ready for execution
    protected $_prepared = false;

    // associative array of phptal:id => PHPTAL_Trigger
    protected $_triggers = array();
    // i18n translator
    protected $_translator = null;

    // global execution context
    protected $_globalContext = null;
    // current execution context
    protected $_context = null;
    // current template file (changes within macros)
    public  $__file = false;
    // list of on-error caught exceptions
    protected $_errors = array();

    protected $_encoding = PHPTAL_DEFAULT_ENCODING;
    protected $_outputMode = PHPTAL::XHTML;
    protected $_stripComments = false;

    // configuration properties
    protected $_forceReparse = NULL;
    protected $_phpCodeDestination = PHPTAL_PHP_CODE_DESTINATION;
    protected $_phpCodeExtension = PHPTAL_PHP_CODE_EXTENSION;

    protected $_cacheLifetime = 30;
    protected $_cachePurgeFrequency = 50;
}

?>