File: //opt/cloudlinux/alt-php54/root/usr/share/pear/HTML/Template/Flexy/Compiler/Standard.php
<?php
/* vim: set expandtab tabstop=4 shiftwidth=4: */
// +----------------------------------------------------------------------+
// | PHP Version 4 |
// +----------------------------------------------------------------------+
// | Copyright (c) 1997-2002 The PHP Group |
// +----------------------------------------------------------------------+
// | This source file is subject to version 2.02 of the PHP license, |
// | that is bundled with this package in the file LICENSE, and is |
// | available at through the world-wide-web at |
// | http://www.php.net/license/2_02.txt. |
// | If you did not receive a copy of the PHP license and are unable to |
// | obtain it through the world-wide-web, please send a note to |
// | license@php.net so we can mail you a copy immediately. |
// +----------------------------------------------------------------------+
// | Authors: Alan Knowles <alan@akbkhome.com> |
// +----------------------------------------------------------------------+
//
// $Id: Standard.php 334846 2014-09-12 04:50:56Z alan_k $
//
// Base Compiler Class
// Standard 'Original Flavour' Flexy compiler
/*------------------------------------------------------------------------------------------
NOTICE:
THIS COMPILER IS DEPRECIATED
USE THE FLEXY COMPILER
The Flexy Compiler should be Compatible
------------------------------------------------------------------------------------------*/
require_once 'HTML/Template/Flexy/Tokenizer.php';
require_once 'HTML/Template/Flexy/Token.php';
// cache for po files..
$GLOBALS['_html_template_flexy_compiler_standard']['PO'] = array();
class HTML_Template_Flexy_Compiler_Standard extends HTML_Template_Flexy_Compiler
{
var $flexy;
/**
* The compile method.
*
* @params object HTML_Template_Flexy
* @params string|false string to compile of false to use a file.
* @return string filename of template
* @access public
*/
function compile($flexy,$string=false)
{
// read the entire file into one variable
// note this should be moved to new HTML_Template_Flexy_Token
// and that can then manage all the tokens in one place..
global $_HTML_TEMPLATE_FLEXY_COMPILER;
$this->flexy = $flexy;
$gettextStrings = &$_HTML_TEMPLATE_FLEXY_COMPILER['gettextStrings'];
$gettextStrings = array(); // reset it.
if (@$this->options['debug']) {
echo "compiling template $flexy->currentTemplate<BR>";
}
// reset the elements.
$flexy->_elements = array();
// replace this with a singleton??
$GLOBALS['_HTML_TEMPLATE_FLEXY']['currentOptions'] = $this->options;
$GLOBALS['_HTML_TEMPLATE_FLEXY']['elements'] = array();
$GLOBALS['_HTML_TEMPLATE_FLEXY']['filename'] = $flexy->currentTemplate;
$GLOBALS['_HTML_TEMPLATE_FLEXY']['prefixOutput'] = '';
$GLOBALS['_HTML_TEMPLATE_FLEXY']['compiledTemplate'] = $flexy->compiledTemplate;
if (is_array($this->options['Translation2'])) {
require_once 'Translation2.php';
$this->options['Translation2'] = new Translation2(
$this->options['Translation2']['driver'],
@$this->options['Translation2']['options']
);
}
if ($this->is_a($this->options['Translation2'],'Translation2')) {
$this->options['Translation2']->setLang($this->options['locale']);
// fixme - needs to be more specific to which template to use..
foreach ($this->options['templateDir'] as $tt) {
$n = basename($flexy->currentTemplate);
if (substr($flexy->currentTemplate,0,strlen($tt)) == $tt) {
$n = substr($flexy->currentTemplate,strlen($tt)+1);
}
//echo $n;
}
$this->options['Translation2']->setPageID($n);
} else {
setlocale(LC_ALL, $this->options['locale']);
}
$data = $string;
$res = false;
if ($string === false) {
$data = file_get_contents($flexy->currentTemplate);
}
// PRE PROCESS {_(.....)} translation markers.
$got_gettext_markup = false;
if (strpos($data,'{_(') !== false) {
$matches = array();
$lmatches = explode ('{_(', $data);
array_shift($lmatches);
// shift the first..
foreach ($lmatches as $k) {
if (false === strpos($k,')_}')) {
continue;
}
$x = explode(')_}',$k);
$matches[] = $x[0];
}
//echo '<PRE>';print_r($matches);
// we may need to do some house cleaning here...
$gettextStrings = $matches;
$got_gettext_markup = true;
// replace them now..
// ** leaving in the tag (which should be ignored by the parser..
// we then get rid of the tags during the toString method in this class.
foreach($matches as $v) {
$data = str_replace('{_('.$v.')_}', '{_('.$this->flexy->translateString($v).')_}',$data);
}
}
if (isset($_HTML_TEMPLATE_FLEXY_COMPILER['cache'][md5($data)])) {
$res = $_HTML_TEMPLATE_FLEXY_COMPILER['cache'][md5($data)];
} else {
$tokenizer = new HTML_Template_Flexy_Tokenizer($data);
$tokenizer->fileName = $flexy->currentTemplate;
//$tokenizer->debug=1;
$tokenizer->options['ignore_html'] = $this->options['nonHTML'];
$tokenizer->options['ignore_php'] = !$this->options['allowPHP'];
$res = HTML_Template_Flexy_Token::buildTokens($tokenizer);
$_HTML_TEMPLATE_FLEXY_COMPILER['cache'][md5($data)] = $res;
}
if ($this->is_a($res,'PEAR_Error')) {
return $res;
}
// turn tokens into Template..
$data = $res->compile($this);
if ($this->is_a($data,'PEAR_Error')) {
return $data;
}
$data = $GLOBALS['_HTML_TEMPLATE_FLEXY']['prefixOutput'] . $data;
if ( @$this->options['debug']) {
echo "<B>Result: </B><PRE>".htmlspecialchars($data)."</PRE><BR>";
}
if ($this->options['nonHTML']) {
$data = str_replace("?>\n","?>\n\n",$data);
}
// at this point we are into writing stuff...
if ($this->options['compileToString']) {
$flexy->elements = $GLOBALS['_HTML_TEMPLATE_FLEXY']['elements'];
return $data;
}
// error checking?
$file = $flexy->compiledTemplate;
if (isset($flexy->options['output.block'])) {
list($file,$part) = explode('#',$file );
}
if( ($cfp = fopen( $file , 'w' )) ) {
if (@$this->options['debug']) {
echo "<B>Writing: </B>".htmlspecialchars($data)."<BR>";
}
fwrite($cfp,$data);
fclose($cfp);
chmod($file,0775);
// make the timestamp of the two items match.
clearstatcache();
touch($file, filemtime($flexy->currentTemplate));
if ($file != $flexy->compiledTemplate) {
chmod($flexy->compiledTemplate,0775);
// make the timestamp of the two items match.
clearstatcache();
touch($flexy->compiledTemplate, filemtime($flexy->currentTemplate));
}
} else {
return HTML_Template_Flexy::staticRaiseError('HTML_Template_Flexy::failed to write to '.$flexy->compiledTemplate,
HTML_TEMPLATE_FLEXY_ERROR_FILE ,HTML_TEMPLATE_FLEXY_ERROR_RETURN);
}
// gettext strings
if (file_exists($flexy->getTextStringsFile)) {
unlink($flexy->getTextStringsFile);
}
if($gettextStrings && ($cfp = fopen( $flexy->getTextStringsFile, 'w') ) ) {
fwrite($cfp,serialize(array_unique($gettextStrings)));
fclose($cfp);
}
// elements
if (file_exists($flexy->elementsFile)) {
unlink($flexy->elementsFile);
}
if( $GLOBALS['_HTML_TEMPLATE_FLEXY']['elements'] &&
($cfp = fopen( $flexy->elementsFile, 'w') ) ) {
fwrite($cfp,serialize( $GLOBALS['_HTML_TEMPLATE_FLEXY']['elements']));
fclose($cfp);
// now clear it.
}
return true;
}
/**
* Flag indicating compiler is inside {_( .... )_} block, and should not
* add to the gettextstrings array.
*
* @var boolean
* @access public
*/
var $inGetTextBlock = false;
/**
* This is the base toString Method, it relays into toString{TokenName}
*
* @param object HTML_Template_Flexy_Token_*
*
* @return string string to build a template
* @access public
* @see toString*
*/
function toString($element)
{
static $len = 26; // strlen('HTML_Template_Flexy_Token_');
if ($this->options['debug']) {
$x = $element;
unset($x->children);
echo htmlspecialchars(print_r($x,true))."<BR>\n";
}
if ($element->token == 'GetTextStart') {
$this->inGetTextBlock = true;
return '';
}
if ($element->token == 'GetTextEnd') {
$this->inGetTextBlock = false;
return '';
}
$class = get_class($element);
if (strlen($class) >= $len) {
$type = substr($class,$len);
return $this->{'toString'.$type}($element);
}
$ret = $element->value;
$add = $element->compileChildren($this);
if ($this->is_a($add,'PEAR_Error')) {
return $add;
}
$ret .= $add;
if ($element->close) {
$add = $element->close->compile($this);
if ($this->is_a($add,'PEAR_Error')) {
return $add;
}
$ret .= $add;
}
return $ret;
}
/**
* HTML_Template_Flexy_Token_Else toString
*
* @param object HTML_Template_Flexy_Token_Else
*
* @return string string to build a template
* @access public
* @see toString*
*/
function toStringElse($element)
{
// pushpull states to make sure we are in an area.. - should really check to see
// if the state it is pulling is a if...
if ($element->pullState() === false) {
return $this->appendHTML(
"<font color=\"red\">Unmatched {else:} on line: {$element->line}</font>"
);
}
$element->pushState();
return $this->appendPhp("} else {");
}
/**
* HTML_Template_Flexy_Token_End toString
*
* @param object HTML_Template_Flexy_Token_Else
*
* @return string string to build a template
* @access public
* @see toString*
*/
function toStringEnd($element)
{
// pushpull states to make sure we are in an area.. - should really check to see
// if the state it is pulling is a if...
if ($element->pullState() === false) {
return $this->appendHTML(
"<font color=\"red\">Unmatched {end:} on line: {$element->line}</font>"
);
}
return $this->appendPhp("}");
}
/**
* HTML_Template_Flexy_Token_EndTag toString
*
* @param object HTML_Template_Flexy_Token_EndTag
*
* @return string string to build a template
* @access public
* @see toString*
*/
function toStringEndTag($element)
{
return $this->toStringTag($element);
}
/**
* HTML_Template_Flexy_Token_Foreach toString
*
* @param object HTML_Template_Flexy_Token_Foreach
*
* @return string string to build a template
* @access public
* @see toString*
*/
function toStringForeach($element)
{
$loopon = $element->toVar($element->loopOn);
if ($this->is_a($loopon,'PEAR_Error')) {
return $loopon;
}
$ret = 'if ($this->options[\'strict\'] || ('.
'is_array('. $loopon. ') || ' .
'is_object(' . $loopon . '))) ' .
'foreach(' . $loopon . " ";
$ret .= "as \${$element->key}";
if ($element->value) {
$ret .= " => \${$element->value}";
}
$ret .= ") {";
$element->pushState();
$element->pushVar($element->key);
$element->pushVar($element->value);
return $this->appendPhp($ret);
}
/**
* HTML_Template_Flexy_Token_If toString
*
* @param object HTML_Template_Flexy_Token_If
*
* @return string string to build a template
* @access public
* @see toString*
*/
function toStringIf($element)
{
$var = $element->toVar($element->condition);
if ($this->is_a($var,'PEAR_Error')) {
return $var;
}
$ret = "if (".$element->isNegative . $var .") {";
$element->pushState();
return $this->appendPhp($ret);
}
/**
* get Modifier Wrapper
*
* converts :h, :u, :r , .....
* @param object HTML_Template_Flexy_Token_Method|Var
*
* @return array prefix,suffix
* @access public
* @see toString*
*/
function getModifierWrapper($element)
{
$prefix = 'echo ';
$suffix = '';
$modifier = strlen(trim($element->modifier)) ? $element->modifier : ' ';
switch ($modifier{0}) {
case 'h':
break;
case 'u':
$prefix = 'echo urlencode(';
$suffix = ')';
break;
case 'r':
$prefix = 'echo \'<pre>\'; echo htmlspecialchars(print_r(';
$suffix = ',true)); echo \'</pre>\';';
break;
case 'n':
// blank or value..
$numberformat = @$GLOBALS['_HTML_TEMPLATE_FLEXY']['currentOptions']['numberFormat'];
$prefix = 'echo number_format(';
$suffix = $GLOBALS['_HTML_TEMPLATE_FLEXY']['currentOptions']['numberFormat'] . ')';
break;
case 'b': // nl2br + htmlspecialchars
$prefix = 'echo nl2br(htmlspecialchars(';
// add language ?
$suffix = '))';
break;
case ' ':
$prefix = 'echo htmlspecialchars(';
// add language ?
$suffix = ')';
break;
default:
$prefix = 'echo $this->plugin("'.trim($element->modifier) .'",';
$suffix = ')';
}
return array($prefix,$suffix);
}
/**
* HTML_Template_Flexy_Token_Var toString
*
* @param object HTML_Template_Flexy_Token_Method
*
* @return string string to build a template
* @access public
* @see toString*
*/
function toStringVar($element)
{
// ignore modifier at present!!
$var = $element->toVar($element->value);
if ($this->is_a($var,'PEAR_Error')) {
return $var;
}
list($prefix,$suffix) = $this->getModifierWrapper($element);
return $this->appendPhp( $prefix . $var . $suffix .';');
}
/**
* HTML_Template_Flexy_Token_Method toString
*
* @param object HTML_Template_Flexy_Token_Method
*
* @return string string to build a template
* @access public
* @see toString*
*/
function toStringMethod($element)
{
// set up the modifier at present!!
list($prefix,$suffix) = $this->getModifierWrapper($element);
// add the '!' to if
if ($element->isConditional) {
$prefix = 'if ('.$element->isNegative;
$element->pushState();
$suffix = ')';
}
// check that method exists..
// if (method_exists($object,'method');
$bits = explode('.',$element->method);
$method = array_pop($bits);
$object = implode('.',$bits);
$var = $element->toVar($object);
if ($this->is_a($var,'PEAR_Error')) {
return $var;
}
if (($object == 'GLOBALS') &&
$GLOBALS['_HTML_TEMPLATE_FLEXY']['currentOptions']['globalfunctions']) {
// we should check if they something weird like: GLOBALS.xxxx[sdf](....)
$var = $method;
} else {
$prefix = 'if ($this->options[\'strict\'] || (isset('.$var.
') && method_exists('.$var .",'{$method}'))) " . $prefix;
$var = $element->toVar($element->method);
}
if ($this->is_a($var,'PEAR_Error')) {
return $var;
}
$ret = $prefix;
$ret .= $var . "(";
$s =0;
foreach($element->args as $a) {
if ($s) {
$ret .= ",";
}
$s =1;
if ($a{0} == '#') {
$ret .= '"'. addslashes(substr($a,1,-1)) . '"';
continue;
}
$var = $element->toVar($a);
if ($this->is_a($var,'PEAR_Error')) {
return $var;
}
$ret .= $var;
}
$ret .= ")" . $suffix;
if ($element->isConditional) {
$ret .= ' { ';
} else {
$ret .= ";";
}
return $this->appendPhp($ret);
}
/**
* HTML_Template_Flexy_Token_Processing toString
*
* @param object HTML_Template_Flexy_Token_Processing
*
* @return string string to build a template
* @access public
* @see toString*
*/
function toStringProcessing($element)
{
// if it's XML then quote it..
if (strtoupper(substr($element->value,2,3)) == 'XML') {
return $this->appendPhp("echo '" . str_replace("'","\\"."'", $element->value) . "';");
}
// otherwise it's PHP code - so echo it..
return $element->value;
}
/**
* HTML_Template_Flexy_Token_Text toString
*
* @param object HTML_Template_Flexy_Token_Text
*
* @return string string to build a template
* @access public
* @see toString*
*/
function toStringText($element)
{
// first get rid of stuff thats not translated etc.
// empty strings => output.
// comments -> just output
// our special tags -> output..
if (!strlen(trim($element->value) )) {
return $this->appendHtml($element->value);
}
// dont add comments to translation lists.
if (substr($element->value,0,4) == '<!--') {
return $this->appendHtml($element->value);
}
// ignore anything wrapped with {_( .... )_}
if ($this->inGetTextBlock) {
return $this->appendHtml($element->value);
}
// argTokens is built before the tag matching (it combined
// flexy tags into %s, into the string,
// and made a list of tokens in argTokens.
if (!count($element->argTokens) && !$element->isWord()) {
return $this->appendHtml($element->value);
}
// grab the white space at start and end (and keep it!
$value = ltrim($element->value);
$front = substr($element->value,0,-strlen($value));
$value = rtrim($element->value);
$rear = substr($element->value,strlen($value));
$value = trim($element->value);
// convert to escaped chars.. (limited..)
//$value = strtr($value,$cleanArray);
$this->addStringToGettext($value);
$value = $this->flexy->translateString($value);
// its a simple word!
if (!count($element->argTokens)) {
return $this->appendHtml($front . $value . $rear);
}
// there are subtokens..
// print_r($element->argTokens );
$args = array();
// these should only be text or vars..
foreach($element->argTokens as $i=>$token) {
$args[] = $token->compile($this);
}
// we break up the translated string, and put the compiled tags
// in between the values here.
$bits = explode('%s',$value);
$ret = $front;
foreach($bits as $i=>$v) {
$ret .= $v . @$args[$i];
}
return $ret . $rear;
}
/**
* addStringToGettext
*
* Adds a string to the gettext array.
*
* @param mixed preferably.. string to store
*
* @return none
* @access public
*/
function addStringToGettext($string)
{
if (!is_string($string)) {
return;
}
if (!preg_match('/[a-z]+/i', $string)) {
return;
}
$string = trim($string);
if (substr($string,0,4) == '<!--') {
return;
}
$GLOBALS['_HTML_TEMPLATE_FLEXY_COMPILER']['gettextStrings'][] = $string;
}
/**
* HTML_Template_Flexy_Token_Tag toString
*
* @param object HTML_Template_Flexy_Token_Tag
*
* @return string string to build a template
* @access public
* @see toString*
*/
function toStringTag($element) {
if (strpos($element->tag,':') === false) {
$namespace = 'Tag';
} else {
$bits = explode(':',$element->tag);
$namespace = $bits[0];
}
if ($namespace{0} == '/') {
$namespace = substr($namespace,1);
}
if (empty($this->tagHandlers[$namespace])) {
require_once 'HTML/Template/Flexy/Compiler/Standard/Tag.php';
$this->tagHandlers[$namespace] = &HTML_Template_Flexy_Compiler_Standard_Tag::factory($namespace,$this);
if (!$this->tagHandlers[$namespace] ) {
return HTML_Template_Flexy::staticRaiseError('HTML_Template_Flexy::failed to create Namespace Handler '.$namespace .
' in file ' . $GLOBALS['_HTML_TEMPLATE_FLEXY']['filename'],
HTML_TEMPLATE_FLEXY_ERROR_SYNTAX ,HTML_TEMPLATE_FLEXY_ERROR_RETURN);
}
}
return $this->tagHandlers[$namespace]->toString($element);
}
}