preparation release

This commit is contained in:
nojhan 2008-01-31 21:24:09 +00:00
commit f5e3a62ee8
196 changed files with 64314 additions and 0 deletions

11
AUTHORS Normal file
View file

@ -0,0 +1,11 @@
N:Johann Dréo
P:nojhan
E:nojhan@gmail.com
D:2007-11
C:Code initial, mainteneur
N:Simon Leblanc
P:Simon
E:contact@leblanc-simon.eu
D:2007-12
C:Patch internationalisation

340
COPYING Normal file
View file

@ -0,0 +1,340 @@
GNU GENERAL PUBLIC LICENSE
Version 2, June 1991
Copyright (C) 1989, 1991 Free Software Foundation, Inc.
59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
Everyone is permitted to copy and distribute verbatim copies
of this license document, but changing it is not allowed.
Preamble
The licenses for most software are designed to take away your
freedom to share and change it. By contrast, the GNU General Public
License is intended to guarantee your freedom to share and change free
software--to make sure the software is free for all its users. This
General Public License applies to most of the Free Software
Foundation's software and to any other program whose authors commit to
using it. (Some other Free Software Foundation software is covered by
the GNU Library General Public License instead.) You can apply it to
your programs, too.
When we speak of free software, we are referring to freedom, not
price. Our General Public Licenses are designed to make sure that you
have the freedom to distribute copies of free software (and charge for
this service if you wish), that you receive source code or can get it
if you want it, that you can change the software or use pieces of it
in new free programs; and that you know you can do these things.
To protect your rights, we need to make restrictions that forbid
anyone to deny you these rights or to ask you to surrender the rights.
These restrictions translate to certain responsibilities for you if you
distribute copies of the software, or if you modify it.
For example, if you distribute copies of such a program, whether
gratis or for a fee, you must give the recipients all the rights that
you have. You must make sure that they, too, receive or can get the
source code. And you must show them these terms so they know their
rights.
We protect your rights with two steps: (1) copyright the software, and
(2) offer you this license which gives you legal permission to copy,
distribute and/or modify the software.
Also, for each author's protection and ours, we want to make certain
that everyone understands that there is no warranty for this free
software. If the software is modified by someone else and passed on, we
want its recipients to know that what they have is not the original, so
that any problems introduced by others will not reflect on the original
authors' reputations.
Finally, any free program is threatened constantly by software
patents. We wish to avoid the danger that redistributors of a free
program will individually obtain patent licenses, in effect making the
program proprietary. To prevent this, we have made it clear that any
patent must be licensed for everyone's free use or not licensed at all.
The precise terms and conditions for copying, distribution and
modification follow.
GNU GENERAL PUBLIC LICENSE
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
0. This License applies to any program or other work which contains
a notice placed by the copyright holder saying it may be distributed
under the terms of this General Public License. The "Program", below,
refers to any such program or work, and a "work based on the Program"
means either the Program or any derivative work under copyright law:
that is to say, a work containing the Program or a portion of it,
either verbatim or with modifications and/or translated into another
language. (Hereinafter, translation is included without limitation in
the term "modification".) Each licensee is addressed as "you".
Activities other than copying, distribution and modification are not
covered by this License; they are outside its scope. The act of
running the Program is not restricted, and the output from the Program
is covered only if its contents constitute a work based on the
Program (independent of having been made by running the Program).
Whether that is true depends on what the Program does.
1. You may copy and distribute verbatim copies of the Program's
source code as you receive it, in any medium, provided that you
conspicuously and appropriately publish on each copy an appropriate
copyright notice and disclaimer of warranty; keep intact all the
notices that refer to this License and to the absence of any warranty;
and give any other recipients of the Program a copy of this License
along with the Program.
You may charge a fee for the physical act of transferring a copy, and
you may at your option offer warranty protection in exchange for a fee.
2. You may modify your copy or copies of the Program or any portion
of it, thus forming a work based on the Program, and copy and
distribute such modifications or work under the terms of Section 1
above, provided that you also meet all of these conditions:
a) You must cause the modified files to carry prominent notices
stating that you changed the files and the date of any change.
b) You must cause any work that you distribute or publish, that in
whole or in part contains or is derived from the Program or any
part thereof, to be licensed as a whole at no charge to all third
parties under the terms of this License.
c) If the modified program normally reads commands interactively
when run, you must cause it, when started running for such
interactive use in the most ordinary way, to print or display an
announcement including an appropriate copyright notice and a
notice that there is no warranty (or else, saying that you provide
a warranty) and that users may redistribute the program under
these conditions, and telling the user how to view a copy of this
License. (Exception: if the Program itself is interactive but
does not normally print such an announcement, your work based on
the Program is not required to print an announcement.)
These requirements apply to the modified work as a whole. If
identifiable sections of that work are not derived from the Program,
and can be reasonably considered independent and separate works in
themselves, then this License, and its terms, do not apply to those
sections when you distribute them as separate works. But when you
distribute the same sections as part of a whole which is a work based
on the Program, the distribution of the whole must be on the terms of
this License, whose permissions for other licensees extend to the
entire whole, and thus to each and every part regardless of who wrote it.
Thus, it is not the intent of this section to claim rights or contest
your rights to work written entirely by you; rather, the intent is to
exercise the right to control the distribution of derivative or
collective works based on the Program.
In addition, mere aggregation of another work not based on the Program
with the Program (or with a work based on the Program) on a volume of
a storage or distribution medium does not bring the other work under
the scope of this License.
3. You may copy and distribute the Program (or a work based on it,
under Section 2) in object code or executable form under the terms of
Sections 1 and 2 above provided that you also do one of the following:
a) Accompany it with the complete corresponding machine-readable
source code, which must be distributed under the terms of Sections
1 and 2 above on a medium customarily used for software interchange; or,
b) Accompany it with a written offer, valid for at least three
years, to give any third party, for a charge no more than your
cost of physically performing source distribution, a complete
machine-readable copy of the corresponding source code, to be
distributed under the terms of Sections 1 and 2 above on a medium
customarily used for software interchange; or,
c) Accompany it with the information you received as to the offer
to distribute corresponding source code. (This alternative is
allowed only for noncommercial distribution and only if you
received the program in object code or executable form with such
an offer, in accord with Subsection b above.)
The source code for a work means the preferred form of the work for
making modifications to it. For an executable work, complete source
code means all the source code for all modules it contains, plus any
associated interface definition files, plus the scripts used to
control compilation and installation of the executable. However, as a
special exception, the source code distributed need not include
anything that is normally distributed (in either source or binary
form) with the major components (compiler, kernel, and so on) of the
operating system on which the executable runs, unless that component
itself accompanies the executable.
If distribution of executable or object code is made by offering
access to copy from a designated place, then offering equivalent
access to copy the source code from the same place counts as
distribution of the source code, even though third parties are not
compelled to copy the source along with the object code.
4. You may not copy, modify, sublicense, or distribute the Program
except as expressly provided under this License. Any attempt
otherwise to copy, modify, sublicense or distribute the Program is
void, and will automatically terminate your rights under this License.
However, parties who have received copies, or rights, from you under
this License will not have their licenses terminated so long as such
parties remain in full compliance.
5. You are not required to accept this License, since you have not
signed it. However, nothing else grants you permission to modify or
distribute the Program or its derivative works. These actions are
prohibited by law if you do not accept this License. Therefore, by
modifying or distributing the Program (or any work based on the
Program), you indicate your acceptance of this License to do so, and
all its terms and conditions for copying, distributing or modifying
the Program or works based on it.
6. Each time you redistribute the Program (or any work based on the
Program), the recipient automatically receives a license from the
original licensor to copy, distribute or modify the Program subject to
these terms and conditions. You may not impose any further
restrictions on the recipients' exercise of the rights granted herein.
You are not responsible for enforcing compliance by third parties to
this License.
7. If, as a consequence of a court judgment or allegation of patent
infringement or for any other reason (not limited to patent issues),
conditions are imposed on you (whether by court order, agreement or
otherwise) that contradict the conditions of this License, they do not
excuse you from the conditions of this License. If you cannot
distribute so as to satisfy simultaneously your obligations under this
License and any other pertinent obligations, then as a consequence you
may not distribute the Program at all. For example, if a patent
license would not permit royalty-free redistribution of the Program by
all those who receive copies directly or indirectly through you, then
the only way you could satisfy both it and this License would be to
refrain entirely from distribution of the Program.
If any portion of this section is held invalid or unenforceable under
any particular circumstance, the balance of the section is intended to
apply and the section as a whole is intended to apply in other
circumstances.
It is not the purpose of this section to induce you to infringe any
patents or other property right claims or to contest validity of any
such claims; this section has the sole purpose of protecting the
integrity of the free software distribution system, which is
implemented by public license practices. Many people have made
generous contributions to the wide range of software distributed
through that system in reliance on consistent application of that
system; it is up to the author/donor to decide if he or she is willing
to distribute software through any other system and a licensee cannot
impose that choice.
This section is intended to make thoroughly clear what is believed to
be a consequence of the rest of this License.
8. If the distribution and/or use of the Program is restricted in
certain countries either by patents or by copyrighted interfaces, the
original copyright holder who places the Program under this License
may add an explicit geographical distribution limitation excluding
those countries, so that distribution is permitted only in or among
countries not thus excluded. In such case, this License incorporates
the limitation as if written in the body of this License.
9. The Free Software Foundation may publish revised and/or new versions
of the General Public License from time to time. Such new versions will
be similar in spirit to the present version, but may differ in detail to
address new problems or concerns.
Each version is given a distinguishing version number. If the Program
specifies a version number of this License which applies to it and "any
later version", you have the option of following the terms and conditions
either of that version or of any later version published by the Free
Software Foundation. If the Program does not specify a version number of
this License, you may choose any version ever published by the Free Software
Foundation.
10. If you wish to incorporate parts of the Program into other free
programs whose distribution conditions are different, write to the author
to ask for permission. For software which is copyrighted by the Free
Software Foundation, write to the Free Software Foundation; we sometimes
make exceptions for this. Our decision will be guided by the two goals
of preserving the free status of all derivatives of our free software and
of promoting the sharing and reuse of software generally.
NO WARRANTY
11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
REPAIR OR CORRECTION.
12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
POSSIBILITY OF SUCH DAMAGES.
END OF TERMS AND CONDITIONS
How to Apply These Terms to Your New Programs
If you develop a new program, and you want it to be of the greatest
possible use to the public, the best way to achieve this is to make it
free software which everyone can redistribute and change under these terms.
To do so, attach the following notices to the program. It is safest
to attach them to the start of each source file to most effectively
convey the exclusion of warranty; and each file should have at least
the "copyright" line and a pointer to where the full notice is found.
<one line to give the program's name and a brief idea of what it does.>
Copyright (C) <year> <name of author>
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program 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 General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
Also add information on how to contact you by electronic and paper mail.
If the program is interactive, make it output a short notice like this
when it starts in an interactive mode:
Gnomovision version 69, Copyright (C) year name of author
Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
This is free software, and you are welcome to redistribute it
under certain conditions; type `show c' for details.
The hypothetical commands `show w' and `show c' should show the appropriate
parts of the General Public License. Of course, the commands you use may
be called something other than `show w' and `show c'; they could even be
mouse-clicks or menu items--whatever suits your program.
You should also get your employer (if you work as a programmer) or your
school, if any, to sign a "copyright disclaimer" for the program, if
necessary. Here is a sample; alter the names:
Yoyodyne, Inc., hereby disclaims all copyright interest in the program
`Gnomovision' (which makes passes at compilers) written by James Hacker.
<signature of Ty Coon>, 1 April 1989
Ty Coon, President of Vice
This General Public License does not permit incorporating your program into
proprietary programs. If your program is a subroutine library, you may
consider it more useful to permit linking proprietary applications with the
library. If this is what you want to do, use the GNU Library General
Public License instead of this License.

798
HTML/Template/Flexy.php Normal file
View file

@ -0,0 +1,798 @@
<?php
//
// +----------------------------------------------------------------------+
// | PHP Version 4 |
// +----------------------------------------------------------------------+
// | Copyright (c) 1997-2003 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. |
// +----------------------------------------------------------------------+
// | Author: Alan Knowles <alan@akbkhome.com>
// | Original Author: Wolfram Kriesing <wolfram@kriesing.de> |
// +----------------------------------------------------------------------+
//
/**
* @package HTML_Template_Flexy
*/
// prevent disaster when used with xdebug!
@ini_set('xdebug.max_nesting_level', 1000);
/*
* Global variable - used to store active options when compiling a template.
*/
$GLOBALS['_HTML_TEMPLATE_FLEXY'] = array();
// ERRORS:
define('HTML_TEMPLATE_FLEXY_ERROR_SYNTAX',-1); // syntax error in template.
define('HTML_TEMPLATE_FLEXY_ERROR_INVALIDARGS',-2); // bad arguments to methods.
define('HTML_TEMPLATE_FLEXY_ERROR_FILE',-2); // file access problem
define('HTML_TEMPLATE_FLEXY_ERROR_RETURN',1); // RETURN ERRORS
define('HTML_TEMPLATE_FLEXY_ERROR_DIE',8); // FATAL DEATH
/**
* A Flexible Template engine - based on simpletemplate
*
* @abstract Long Description
* Have a look at the package description for details.
*
* usage:
* $template = new HTML_Template_Flexy($options);
* $template->compiler('/name/of/template.html');
* $data =new StdClass
* $data->text = 'xxxx';
* $template->outputObject($data,$elements)
*
* Notes:
* $options can be blank if so, it is read from
* PEAR::getStaticProperty('HTML_Template_Flexy','options');
*
* the first argument to outputObject is an object (which could even be an
* associateve array cast to an object) - I normally send it the controller class.
* the seconde argument '$elements' is an array of HTML_Template_Flexy_Elements
* eg. array('name'=> new HTML_Template_Flexy_Element('',array('value'=>'fred blogs'));
*
*
*
*
* @version $Id: Flexy.php,v 1.96 2005/12/20 01:45:06 alan_k Exp $
*/
class HTML_Template_Flexy
{
/*
* @var array $options the options for initializing the template class
*/
var $options = array(
'compileDir' => '', // where do you want to write to.. (defaults to session.save_path)
'templateDir' => '', // where are your templates
// where the template comes from. ------------------------------------------
'multiSource' => false, // Allow same template to exist in multiple places
// So you can have user themes....
'templateDirOrder' => '', // set to 'reverse' to assume that first template
'debug' => false, // prints a few messages
// compiling conditions ------------------------------------------
'compiler' => 'Flexy', // which compiler to use. (Flexy,Regex, Raw,Xipe)
'forceCompile' => false, // only suggested for debugging
// regex Compiler ------------------------------------------
'filters' => array(), // used by regex compiler.
// standard Compiler ------------------------------------------
'nonHTML' => false, // dont parse HTML tags (eg. email templates)
'allowPHP' => false, // allow PHP in template (use true=allow, 'delete' = remove it.)
'flexyIgnore' => 0, // turn on/off the tag to element code
'numberFormat' => ",2,'.',','", // default number format {xxx:n} format = eg. 1,200.00
'url_rewrite' => '', // url rewriting ability:
// eg. "images/:test1/images/,js/:test1/js"
// changes href="images/xxx" to href="test1/images/xxx"
// and src="js/xxx.js" to src="test1/js/xxx.js"
'compileToString' => false, // should the compiler return a string
// rather than writing to a file.
'privates' => false, // allow access to _variables (eg. suido privates
'globals' => false, // allow access to _GET/_POST/_REQUEST/GLOBALS/_COOKIES/_SESSION
'globalfunctions' => false, // allow GLOBALS.date(#d/m/Y#) to have access to all PHP's methods
// warning dont use unless you trust the template authors
// exec() becomes exposed.
// get text/transalation suppport ------------------------------------------
// (flexy compiler only)
'locale' => 'en', // works with gettext or File_Gettext
'textdomain' => '', // for gettext emulation with File_Gettext
// eg. 'messages' (or you can use the template name.
'textdomainDir' => '', // eg. /var/www/site.com/locale
// so the french po file is:
// /var/www/site.com/local/fr/LC_MESSAGE/{textdomain}.po
'Translation2' => false, // to make Translation2 a provider.
// rather than gettext.
// set to:
// 'Translation2' => array(
// 'driver' => 'dataobjectsimple',
// 'options' => array()
// );
// or the slower way..
// = as it requires loading the code..
//
// 'Translation2' => new Translation2('dataobjectsimple','')
'charset' => 'ISO-8859-1', // charset used with htmlspecialchars to render data.
// experimental
// output options ------------------------------------------
'strict' => false, // All elements in the template must be defined -
// makes php E_NOTICE warnings appear when outputing template.
'fatalError' => HTML_TEMPLATE_FLEXY_ERROR_DIE, // default behavior is to die on errors in template.
'plugins' => array(), // load classes to be made available via the plugin method
// eg. = array('Savant') - loads the Savant methods.
// = array('MyClass_Plugins' => 'MyClass/Plugins.php')
// Class, and where to include it from..
);
/**
* The compiled template filename (Full path)
*
* @var string
* @access public
*/
var $compiledTemplate;
/**
* The source template filename (Full path)
*
* @var string
* @access public
*/
var $currentTemplate;
/**
* The getTextStrings Filename
*
* @var string
* @access public
*/
var $getTextStringsFile;
/**
* The serialized elements array file.
*
* @var string
* @access public
*/
var $elementsFile;
/**
* Array of HTML_elements which is displayed on the template
*
* Technically it's private (eg. only the template uses it..)
*
*
* @var array of HTML_Template_Flexy_Elements
* @access private
*/
var $elements = array();
/**
* Constructor
*
* Initializes the Template engine, for each instance, accepts options or
* reads from PEAR::getStaticProperty('HTML_Template_Flexy','options');
*
* @access public
* @param array $options (Optional)
*/
function HTML_Template_Flexy( $options=array() )
{
$baseoptions = array();
if (class_exists('PEAR')) {
$baseoptions = &PEAR::getStaticProperty('HTML_Template_Flexy','options');
}
if ($baseoptions ) {
foreach( $baseoptions as $key=>$aOption) {
$this->options[$key] = $aOption;
}
}
foreach( $options as $key=>$aOption) {
$this->options[$key] = $aOption;
}
$filters = $this->options['filters'];
if (is_string($filters)) {
$this->options['filters']= explode(',',$filters);
}
if (is_string($this->options['templateDir'])) {
$this->options['templateDir'] = explode(PATH_SEPARATOR,$this->options['templateDir'] );
}
}
/**
* compile the template
*
* @access public
* @version 01/12/03
* @author Wolfram Kriesing <wolfram@kriesing.de>
* @param string $file relative to the 'templateDir' which you set when calling the constructor
* @return boolean true on success. (or string, if compileToString) PEAR_Error on failure..
*/
function compile( $file )
{
if (!$file) {
return $this->raiseError('HTML_Template_Flexy::compile no file selected',
HTML_TEMPLATE_FLEXY_ERROR_INVALIDARGS,HTML_TEMPLATE_FLEXY_ERROR_DIE);
}
if (!@$this->options['locale']) {
$this->options['locale']='en';
}
//Remove the slash if there is one in front, just to be safe.
$file = ltrim($file,DIRECTORY_SEPARATOR);
if (strpos($file,'#')) {
list($file,$this->options['output.block']) = explode('#', $file);
}
$parts = array();
$tmplDirUsed = false;
// PART A mulitlanguage support: ( part B is gettext support in the engine..)
// - user created language version of template.
// - compile('abcdef.html') will check for compile('abcdef.en.html')
// (eg. when locale=en)
$this->currentTemplate = false;
if (preg_match('/(.*)(\.[a-z]+)$/i',$file,$parts)) {
$newfile = $parts[1].'.'.$this->options['locale'] .$parts[2];
foreach ($this->options['templateDir'] as $tmplDir) {
if (@!file_exists($tmplDir . DIRECTORY_SEPARATOR .$newfile)) {
continue;
}
$file = $newfile;
$this->currentTemplate = $tmplDir . DIRECTORY_SEPARATOR .$newfile;
$tmplDirUsed = $tmplDir;
}
}
// look in all the posible locations for the template directory..
if ($this->currentTemplate === false) {
$dirs = array_unique($this->options['templateDir']);
if ($this->options['templateDirOrder'] == 'reverse') {
$dirs = array_reverse($dirs);
}
foreach ($dirs as $tmplDir) {
if (!@file_exists($tmplDir . DIRECTORY_SEPARATOR . $file)) {
continue;
}
if (!$this->options['multiSource'] && ($this->currentTemplate !== false)) {
return $this->raiseError("You have more than one template Named {$file} in your paths, found in both".
"<BR>{$this->currentTemplate }<BR>{$tmplDir}" . DIRECTORY_SEPARATOR . $file,
HTML_TEMPLATE_FLEXY_ERROR_INVALIDARGS , HTML_TEMPLATE_FLEXY_ERROR_DIE);
}
$this->currentTemplate = $tmplDir . DIRECTORY_SEPARATOR . $file;
$tmplDirUsed = $tmplDir;
}
}
if ($this->currentTemplate === false) {
// check if the compile dir has been created
return $this->raiseError("Could not find Template {$file} in any of the directories<br>" .
implode("<BR>",$this->options['templateDir']) ,
HTML_TEMPLATE_FLEXY_ERROR_INVALIDARGS, HTML_TEMPLATE_FLEXY_ERROR_DIE);
}
// Savant compatible compiler
if ($this->options['compiler'] == 'Raw') {
$this->compiledTemplate = $this->currentTemplate;
$this->debug("Using Raw Compiler");
return true;
}
// now for the compile target
//If you are working with mulitple source folders and $options['multiSource'] is set
//the template folder will be:
// compiled_tempaltes/{templatedir_basename}_{md5_of_dir}/
$compileSuffix = ((count($this->options['templateDir']) > 1) && $this->options['multiSource']) ?
DIRECTORY_SEPARATOR .basename($tmplDirUsed) . '_' .md5($tmplDirUsed) : '';
$compileDest = @$this->options['compileDir'];
$isTmp = false;
// Use a default compile directory if one has not been set.
if (!@$compileDest) {
// Use session.save_path + 'compiled_templates_' + md5(of sourcedir)
$compileDest = ini_get('session.save_path') . DIRECTORY_SEPARATOR . 'flexy_compiled_templates';
if (!file_exists($compileDest)) {
require_once 'System.php';
System::mkdir(array('-p',$compileDest));
}
$isTmp = true;
}
// we generally just keep the directory structure as the application uses it,
// so we dont get into conflict with names
// if we have multi sources we do md5 the basedir..
$base = $compileDest . $compileSuffix . DIRECTORY_SEPARATOR .$file;
$fullFile = $this->compiledTemplate = $base .'.'.$this->options['locale'].'.php';
$this->getTextStringsFile = $base .'.gettext.serial';
$this->elementsFile = $base .'.elements.serial';
if (isset($this->options['output.block'])) {
$this->compiledTemplate .= '#'.$this->options['output.block'];
}
$recompile = false;
$isuptodate = file_exists($this->compiledTemplate) ?
(filemtime($this->currentTemplate) == filemtime( $this->compiledTemplate)) : 0;
if( @$this->options['forceCompile'] || !$isuptodate ) {
$recompile = true;
} else {
$this->debug("File looks like it is uptodate.");
return true;
}
if( !@is_dir($compileDest) || !is_writeable($compileDest)) {
require_once 'System.php';
System::mkdir(array('-p',$compileDest));
}
if( !@is_dir($compileDest) || !is_writeable($compileDest)) {
return $this->raiseError( "can not write to 'compileDir', which is <b>'$compileDest'</b><br>".
"Please give write and enter-rights to it",
HTML_TEMPLATE_FLEXY_ERROR_FILE, HTML_TEMPLATE_FLEXY_ERROR_DIE);
}
if (!file_exists(dirname($this->compiledTemplate))) {
require_once 'System.php';
System::mkdir(array('-p','-m', 0770, dirname($this->compiledTemplate)));
}
// Compile the template in $file.
require_once 'HTML/Template/Flexy/Compiler.php';
$compiler = HTML_Template_Flexy_Compiler::factory($this->options);
$ret = $compiler->compile($this);
if (is_a($ret,'PEAR_Error')) {
return $this->raiseError('HTML_Template_Flexy fatal error:' .$ret->message,
$ret->code, HTML_TEMPLATE_FLEXY_ERROR_DIE);
}
return $ret;
//return $this->$method();
}
/**
* compiles all templates
* Used for offline batch compilation (eg. if your server doesn't have write access to the filesystem).
*
* @access public
* @author Alan Knowles <alan@akbkhome.com>
*
*/
function compileAll($dir = '',$regex='/.html$/')
{
require_once 'HTML/Template/Flexy/Compiler.php';
$c = new HTML_Template_Flexy_Compiler;
$c->compileAll($this,$dir,$regex);
}
/**
* Outputs an object as $t
*
* for example the using simpletags the object's variable $t->test
* would map to {test}
*
* @version 01/12/14
* @access public
* @author Alan Knowles
* @param object to output
* @param array HTML_Template_Flexy_Elements (or any object that implements toHtml())
* @return none
*/
function outputObject(&$t,$elements=array())
{
if (!is_array($elements)) {
return $this->raiseError(
'second Argument to HTML_Template_Flexy::outputObject() was an '.gettype($elements) . ', not an array',
HTML_TEMPLATE_FLEXY_ERROR_INVALIDARGS ,HTML_TEMPLATE_FLEXY_ERROR_DIE);
}
if (@$this->options['debug']) {
echo "output $this->compiledTemplate<BR>";
}
// this may disappear later it's a Backwards Compatibility fudge to try
// and deal with the first stupid design decision to not use a second argument
// to the method.
if (count($this->elements) && !count($elements)) {
$elements = $this->elements;
}
// end depreciated code
$this->elements = $this->getElements();
// Overlay values from $elements to $this->elements (which is created from the template)
// Remove keys with no corresponding value.
foreach($elements as $k=>$v) {
// Remove key-value pair from $this->elements if hasn't a value in $elements.
if (!$v) {
unset($this->elements[$k]);
}
// Add key-value pair to $this->$elements if it's not there already.
if (!isset($this->elements[$k])) {
$this->elements[$k] = $v;
continue;
}
// Call the clever element merger - that understands form values and
// how to display them...
$this->elements[$k] = $this->mergeElement($this->elements[$k] ,$v);
}
//echo '<PRE>'; print_r(array($elements,$this->elements));
// we use PHP's error handler to hide errors in the template.
// use $options['strict'] - if you want to force declaration of
// all variables in the template
$_error_reporting = false;
if (!$this->options['strict']) {
$_error_reporting = error_reporting(E_ALL ^ E_NOTICE);
}
if (!is_readable($this->compiledTemplate)) {
return $this->raiseError( "Could not open the template: <b>'{$this->compiledTemplate}'</b><BR>".
"Please check the file permissions on the directory and file ",
HTML_TEMPLATE_FLEXY_ERROR_FILE, HTML_TEMPLATE_FLEXY_ERROR_DIE);
}
// are we using the assign api!
if (isset($this->assign)) {
if (!$t) {
$t = (object) $this->assign->variables;
}
extract($this->assign->variables);
foreach(array_keys($this->assign->references) as $_k) {
$$_k = &$this->assign->references[$_k];
}
}
// used by Flexy Elements etc..
$GLOBALS['_HTML_TEMPLATE_FLEXY']['options'] = $this->options;
include($this->compiledTemplate);
// Return the error handler to its previous state.
if ($_error_reporting !== false) {
error_reporting($_error_reporting);
}
}
/**
* Outputs an object as $t, buffers the result and returns it.
*
* See outputObject($t) for more details.
*
* @version 01/12/14
* @access public
* @author Alan Knowles
* @param object object to output as $t
* @return string - result
*/
function bufferedOutputObject(&$t,$elements=array())
{
ob_start();
$this->outputObject($t,$elements);
$data = ob_get_contents();
ob_end_clean();
return $data;
}
/**
* static version which does new, compile and output all in one go.
*
* See outputObject($t) for more details.
*
* @version 01/12/14
* @access public
* @author Alan Knowles
* @param object object to output as $t
* @param filename of template
* @return string - result
*/
function &staticQuickTemplate($file,&$t)
{
$template = new HTML_Template_Flexy;
$template->compile($file);
$template->outputObject($t);
}
/**
* if debugging is on, print the debug info to the screen
*
* @access public
* @author Alan Knowles <alan@akbkhome.com>
* @param string $string output to display
* @return none
*/
function debug($string)
{
if (is_a($this,'HTML_Template_Flexy')) {
if (!$this->options['debug']) {
return;
}
} else if (!@$GLOBALS['_HTML_TEMPLATE_FLEXY']['debug']) {
return;
}
echo "<PRE><B>FLEXY DEBUG:</B> $string</PRE>";
}
/**
* A general Utility method that merges HTML_Template_Flexy_Elements
* Static method - no native debug avaiable..
*
* @param HTML_Template_Flexy_Element $original (eg. from getElements())
* @param HTML_Template_Flexy_Element $new (with data to replace/merge)
* @return HTML_Template_Flexy_Element the combined/merged data.
* @static
* @access public
*/
function mergeElement($original,$new)
{
// no original - return new
if (!$original) {
return $new;
}
// no new - return original
if (!$new) {
return $original;
}
// If the properties of $original differ from those of $new and
// they are set on $new, set them to $new's. Otherwise leave them
// as they are.
if ($new->tag && ($new->tag != $original->tag)) {
$original->tag = $new->tag;
}
if ($new->override !== false) {
$original->override = $new->override;
}
if (count($new->children)) {
//echo "<PRE> COPY CHILDREN"; print_r($from->children);
$original->children = $new->children;
}
if (is_array($new->attributes)) {
foreach ($new->attributes as $key => $value) {
$original->attributes[$key] = $value;
}
}
// originals never have prefixes or suffixes..
$original->prefix = $new->prefix;
$original->suffix = $new->suffix;
if ($new->value !== null) {
$original->setValue($new->value);
}
return $original;
}
/**
* Get an array of elements from the template
*
* All <form> elements (eg. <input><textarea) etc.) and anything marked as
* dynamic (eg. flexy:dynamic="yes") are converted in to elements
* (simliar to XML_Tree_Node)
* you can use this to build the default $elements array that is used by
* outputObject() - or just create them and they will be overlayed when you
* run outputObject()
*
*
* @return array of HTML_Template_Flexy_Element sDescription
* @access public
*/
function getElements() {
if ($this->elementsFile && file_exists($this->elementsFile)) {
require_once 'HTML/Template/Flexy/Element.php';
return unserialize(file_get_contents($this->elementsFile));
}
return array();
}
/**
* Lazy loading of PEAR, and the error handler..
* This should load HTML_Template_Flexy_Error really..
*
* @param string message
* @param int error type.
* @param int an equivalant to pear error return|die etc.
*
* @return object pear error.
* @access public
*/
function raiseError($message, $type = null, $fatal = HTML_TEMPLATE_FLEXY_ERROR_RETURN )
{
HTML_Template_Flexy::debug("<B>HTML_Template_Flexy::raiseError</B>$message");
require_once 'PEAR.php';
if (is_a($this,'HTML_Template_Flexy') && ($fatal == HTML_TEMPLATE_FLEXY_ERROR_DIE)) {
// rewrite DIE!
return PEAR::raiseError($message, $type, $this->options['fatalError']);
}
if (isset($GLOBALS['_HTML_TEMPLATE_FLEXY']['fatalError']) && ($fatal == HTML_TEMPLATE_FLEXY_ERROR_DIE)) {
return PEAR::raiseError($message, $type,$GLOBALS['_HTML_TEMPLATE_FLEXY']['fatalError']);
}
return PEAR::raiseError($message, $type, $fatal);
}
/**
*
* Assign API -
*
* read the docs on HTML_Template_Flexy_Assign::assign()
*
* @param varargs ....
*
*
* @return mixed PEAR_Error or true?
* @access public
* @see HTML_Template_Flexy_Assign::assign()
* @status alpha
*/
function setData() {
require_once 'HTML/Template/Flexy/Assign.php';
// load assigner..
if (!isset($this->assign)) {
$this->assign = new HTML_Template_Flexy_Assign;
}
return $this->assign->assign(func_get_args());
}
/**
*
* Assign API - by Reference
*
* read the docs on HTML_Template_Flexy_Assign::assign()
*
* @param key string
* @param value mixed
*
* @return mixed PEAR_Error or true?
* @access public
* @see HTML_Template_Flexy_Assign::assign()
* @status alpha
*/
function setDataByRef($k,&$v) {
require_once 'HTML/Template/Flexy/Assign.php';
// load assigner..
if (!isset($this->assign)) {
$this->assign = new HTML_Template_Flexy_Assign;
}
$this->assign->assignRef($k,$v);
}
/**
*
* Plugin (used by templates as $this->plugin(...) or {this.plugin(#...#,#....#)}
*
* read the docs on HTML_Template_Flexy_Plugin()
*
* @param varargs ....
*
* @return mixed PEAR_Error or true?
* @access public
* @see HTML_Template_Flexy_Plugin
* @status alpha
*/
function plugin() {
require_once 'HTML/Template/Flexy/Plugin.php';
// load pluginManager.
if (!isset($this->plugin)) {
$this->plugin = new HTML_Template_Flexy_Plugin;
$this->plugin->flexy = &$this;
}
return $this->plugin->call(func_get_args());
}
/**
*
* output / display ? - outputs an object, without copy by references..
*
* @param optional mixed object to output
*
* @return mixed PEAR_Error or true?
* @access public
* @see HTML_Template_Flexy::ouptutObject
* @status alpha
*/
function output($object = false)
{
return $this->outputObject($object);
}
/**
*
* render the template with data..
*
* @param optional mixed object to output
*
* @return mixed PEAR_Error or true?
* @access public
* @see HTML_Template_Flexy::ouptutObject
* @status alpha
*/
function toString($object = false)
{
return $this->bufferedOutputObject($object);
}
}

View file

@ -0,0 +1,204 @@
<?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: nobody <nobody@localhost> |
// +----------------------------------------------------------------------+
//
// $Id: Assign.php,v 1.5 2004/06/03 03:25:11 alan_k Exp $
//
// Provider for Assign API ( Eg. $flexy->assign(...) )
//
define('HTML_TEMPLATE_FLEXY_ASSIGN_ERROR_INVALIDARGS', -100);
class HTML_Template_Flexy_Assign {
/**
* The variables stored in the Assigner
*
* @var array
* @access public
*/
var $variables = array();
/**
* The references stored in the Assigner
*
* @var array
* @access public
*/
var $references = array();
/**
*
* Assigns a token-name and value to $this->_token_vars for use in a
* template.
*
* There are three valid ways to assign values to a template.
*
* Form 1: $args[0] is a string and $args[1] is mixed. This means
* $args[0] is a token name and $args[1] is the token value (which
* allows objects, arrays, strings, numbers, or anything else).
* $args[1] can be null, which means the corresponding token value in
* the template will also be null.
*
* Form 2: $args[0] is an array and $args[1] is not set. Assign a
* series of tokens where the key is the token name, and the value is
* token value.
*
* Form 3: $args[0] is an object and $args[1] is not set. Assigns
* copies of all object variables (properties) to tokens; the token
* name and value is a copy of each object property and value.
*
* @access public
*
* @param string|array|object $args[0] This param can be a string, an
* array, or an object. If $args[0] is a string, it is the name of a
* variable in the template. If $args[0] is an array, it must be an
* associative array of key-value pairs where the key is a variable
* name in the template and the value is the value for that variable
* in the template. If $args[0] is an object, copies of its
* properties will be assigned to the template.
*
* @param mixed $args[1] If $args[0] is an array or object, $args[1]
* should not be set. Otherwise, a copy of $args[1] is assigned to a
* template variable named after $args[0].
*
* @return bool|PEAR_Error Boolean true if all assignments were
* committed, or a PEAR_Error object if there was an error.
*
* @throws SAVANT_ERROR_ASSIGN Unknown reason for error, probably
* because you passed $args[1] when $args[0] is an array or object.
*
* @author Paul M. Jones <pmjones@ciaweb.net>
* @see assignRef()
*
* @see assignObject()
*
*/
function assign($args)
{
// in Form 1, $args[0] is a string name and $args[1] is mixed.
// in Form 2, $args[0] is an associative array.
// in Form 3, $args[0] is an object.
$count = count($args);
// -------------------------------------------------------------
//
// Now we assign variable copies.
//
// form 1 (string name and mixed value)
// don't check isset() on $args[1] becuase a 'null' is not set,
// and we might want to pass a null.
if (is_string($args[0]) && $count > 1) {
if (isset($this->references[$args[0]])) {
unset($this->references[$args[0]]);
}
// keep a copy in the token vars array
$this->variables[$args[0]] = $args[1];
// done!
return true;
}
// form 2 (assoc array)
if (is_array($args[0]) && $count == 1) {
foreach ($args[0] as $key=>$val) {
$this->assign($key, $val);
}
// done!
return true;
}
// form 3 (object props)
if (is_object($args[0]) && $count == 1) {
// get the object properties
$data = get_object_vars($args[0]);
foreach ($data as $key=>$val) {
$this->assign($key, $val);
}
// done!
return true;
}
// -------------------------------------------------------------
//
// Final error catch. We should not have gotten to this point.
//
return HTML_Template_Flexy::raiseError(
"invalid type sent to assign, ". print_r($args,true),
HTML_TEMPLATE_FLEXY_ASSIGN_ERROR_INVALIDARGS
);
}
/**
*
* Assign a token by reference. This allows you change variable
* values within the template and have those changes reflected back
* at the calling logic script. Works as with form 2 of assign().
*
* @access public
*
* @param string $name The template token-name for the reference.
*
* @param mixed &$ref The variable passed by-reference.
*
* @return bool|PEAR_Error Boolean true on success, or a PEAR_Error
* on failure.
*
* @throws SAVANT_ERROR_ASSIGN_REF Unknown reason for error.
*
* @see assign()
* @author Paul M. Jones <pmjones@ciaweb.net>
* @see assignObject()
*
*/
function assignRef($name, &$ref)
{
// look for the proper case: name and variable
if (is_string($name) && isset($ref)) {
if (isset($this->variables[$name])) {
unset($this->variables[$name]);
}
//
// assign the token as a reference
$this->references[$name] =& $ref;
// done!
return true;
}
// final error catch
return HTML_Template_Flexy::raiseError(
"invalid type sent to assignRef, ". print_r($name,true),
HTML_TEMPLATE_FLEXY_ASSIGN_ERROR_INVALIDARGS
);
}
}

View file

@ -0,0 +1,161 @@
<?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: Compiler.php,v 1.7 2004/07/08 04:56:30 alan_k Exp $
//
// Base Compiler Class (Interface)
//
/**
* Compiler Globals go here..
* public (to it's children)
*
* @var array
* @access public (to it's children)
*/
$GLOBAL['_HTML_TEMPLATE_FLEXY_COMPILER'] = array();
class HTML_Template_Flexy_Compiler {
/**
* Options
*
* @var array
* @access public
*/
var $options;
/**
* Factory constructor
*
* @param array options only ['compiler'] is used directly
*
* @return object The Compiler Object
* @access public
*/
function factory($options)
{
if (empty($options['compiler'])) {
$options['compiler'] = 'Flexy';
}
require_once 'HTML/Template/Flexy/Compiler/'.ucfirst( $options['compiler'] ) .'.php';
$class = 'HTML_Template_Flexy_Compiler_'.$options['compiler'];
$ret = new $class;
$ret->options = $options;
return $ret;
}
/**
* The compile method.
*
* @param object HTML_Template_Flexy that is requesting the compile
* @return object HTML_Template_Flexy
* @return string to compile (if not using a file as the source)
* @access public
*/
function compile(&$flexy,$string = false)
{
echo "No compiler implemented!";
}
/**
* Append HTML to compiled ouput
* These are hooks for passing data to other processes
*
* @param string to append to compiled
*
* @return string to be output
* @access public
*/
function appendHtml($string)
{
return $string;
}
/**
* Append PHP Code to compiled ouput
* These are hooks for passing data to other processes
*
* @param string PHP code to append to compiled
*
* @return string to be output
* @access public
*/
function appendPhp($string)
{
return '<?php '.$string.'?>';
}
/**
* Compile All templates in the
* These are hooks for passing data to other processes
*
* @param string PHP code to append to compiled
*
* @return string to be output
* @access public
*/
function compileAll(&$flexy, $dir = '',$regex='/.html$/')
{
$this->flexy = &$flexy;
$this->compileDir($dir,$regex);
}
function compileDir($dir = '',$regex='/.html$/')
{
foreach ($this->flexy->options['templateDir'] as $base) {
if (!file_exists($base . DIRECTORY_SEPARATOR . $dir)) {
continue;
}
$dh = opendir($base . DIRECTORY_SEPARATOR . $dir);
while (($name = readdir($dh)) !== false) {
if (!$name) { // empty!?
continue;
}
if ($name{0} == '.') {
continue;
}
if (is_dir($base . DIRECTORY_SEPARATOR . $dir . DIRECTORY_SEPARATOR . $name)) {
$this->compileDir($dir . DIRECTORY_SEPARATOR . $name,$regex);
continue;
}
if (!preg_match($regex,$name)) {
continue;
}
//echo "Compiling $dir". DIRECTORY_SEPARATOR . "$name \n";
$this->flexy->compile($dir . DIRECTORY_SEPARATOR . $name);
}
}
}
}

View file

@ -0,0 +1,985 @@
<?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: Flexy.php,v 1.20 2005/10/25 02:21:16 alan_k Exp $
//
// Base Compiler Class
// Standard 'Original Flavour' Flexy compiler
// this does the main conversion, (eg. for {vars and methods})
// it relays into Compiler/Tag & Compiler/Flexy for tags and namespace handling.
require_once 'HTML/Template/Flexy/Tokenizer.php';
require_once 'HTML/Template/Flexy/Token.php';
class HTML_Template_Flexy_Compiler_Flexy extends HTML_Template_Flexy_Compiler {
/**
* The current template (Full path)
*
* @var string
* @access public
*/
var $currentTemplate;
/**
* 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->currentTemplate = $flexy->currentTemplate;
$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;
// initialize Translation 2, and
$this->initializeTranslator();
// load the template!
$data = $string;
$res = false;
if ($string === false) {
$data = file_get_contents($flexy->currentTemplate);
}
// PRE PROCESS {_(.....)} translation markers.
if (strpos($data, '{_(') !== false) {
$data = $this->preProcessTranslation($data);
}
// Tree generation!!!
if (!$this->options['forceCompile'] && 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'];
require_once 'HTML/Template/Flexy/Token.php';
$res = HTML_Template_Flexy_Token::buildTokens($tokenizer);
if (is_a($res, 'PEAR_Error')) {
return $res;
}
$_HTML_TEMPLATE_FLEXY_COMPILER['cache'][md5($data)] = $res;
}
// technically we shouldnt get here as we dont cache errors..
if (is_a($res, 'PEAR_Error')) {
return $res;
}
// turn tokens into Template..
$data = $res->compile($this);
if (is_a($data, 'PEAR_Error')) {
return $data;
}
$data = $GLOBALS['_HTML_TEMPLATE_FLEXY']['prefixOutput'] . $data;
if ( $flexy->options['debug'] > 1) {
echo "<B>Result: </B><PRE>".htmlspecialchars($data)."</PRE><BR>\n";
}
if ($this->options['nonHTML']) {
$data = str_replace("?>\n", "?>\n\n", $data);
}
// at this point we are into writing stuff...
if ($flexy->options['compileToString']) {
if ( $flexy->options['debug']) {
echo "<B>Returning string:<BR>\n";
}
$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 ($flexy->options['debug']) {
echo "<B>Writing: </B>$file<BR>\n";
}
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::raiseError('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);
chmod($flexy->getTextStringsFile, 0664);
}
// 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);
chmod($flexy->elementsFile, 0664);
// now clear it.
}
return true;
}
/**
* Initilalize the translation methods.
*
* Loads Translation2 if required.
*
*
* @return none
* @access public
*/
function initializeTranslator() {
if (is_array($this->options['Translation2'])) {
require_once 'Translation2.php';
$this->options['Translation2'] = &Translation2::factory(
$this->options['Translation2']['driver'],
isset($this->options['Translation2']['options']) ? $this->options['Translation2']['options'] : array(),
isset($this->options['Translation2']['params']) ? $this->options['Translation2']['params'] : array()
);
}
if (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($this->currentTemplate);
if (substr($this->currentTemplate, 0, strlen($tt)) == $tt) {
$n = substr($this->currentTemplate, strlen($tt)+1);
}
//echo $n;
}
$this->options['Translation2']->setPageID($n);
} else {
setlocale(LC_ALL, $this->options['locale']);
}
}
/**
* do the early tranlsation of {_(......)_} text
*
*
* @param input string
* @return output string
* @access public
*/
function preProcessTranslation($data) {
global $_HTML_TEMPLATE_FLEXY_COMPILER;
$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...
$_HTML_TEMPLATE_FLEXY_COMPILER['gettextStrings'] = $matches;
// 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->translateString($v).')_}', $data);
}
return $data;
}
/**
* 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'] > 1) {
$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 (is_a($add, 'PEAR_Error')) {
return $add;
}
$ret .= $add;
if ($element->close) {
$add = $element->close->compile($this);
if (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 (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 (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) {
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 'e':
$prefix = 'echo htmlentities(';
// 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 (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 (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 (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} == '#') {
if (is_numeric(substr($a, 1, -1))) {
$ret .= substr($a, 1, -1);
} else {
$ret .= '"'. addslashes(substr($a, 1, -1)) . '"';
}
continue;
}
$var = $element->toVar($a);
if (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);
}
if (!$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->translateString($value);
// its a simple word!
return $this->appendHtml($front . $value . $rear);
}
/**
* HTML_Template_Flexy_Token_Cdata toString
*
* @param object HTML_Template_Flexy_Token_Cdata ?
*
* @return string string to build a template
* @access public
* @see toString*
*/
function toStringCdata($element)
{
return $this->appendHtml($element->value);
}
/**
* 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;
}
/**
* translateString - a gettextWrapper
*
* tries to do gettext or falls back on File_Gettext
* This has !!!NO!!! error handling - if it fails you just get english..
* no questions asked!!!
*
* @param string string to translate
*
* @return string translated string..
* @access public
*/
function translateString($string)
{
if (is_a($this->options['Translation2'], 'Translation2')) {
$result = $this->options['Translation2']->get($string);
if (!empty($result)) {
return $result;
}
return $string;
}
// note this stuff may have been broken by removing the \n replacement code
// since i dont have a test for it... it may remain broken..
// use Translation2 - it has gettext backend support
// and should sort out the mess that \n etc. entail.
$prefix = basename($GLOBALS['_HTML_TEMPLATE_FLEXY']['filename']).':';
if (@$this->options['debug']) {
echo __CLASS__.":TRANSLATING $string<BR>\n";
}
if (function_exists('gettext') && !$this->options['textdomain']) {
if (@$this->options['debug']) {
echo __CLASS__.":USING GETTEXT?<BR>";
}
$t = gettext($string);
if ($t != $string) {
return $t;
}
$tt = gettext($prefix.$string);
if ($tt != $prefix.$string) {
return $tt;
}
// give up it's not translated anywhere...
return $string;
}
if (!$this->options['textdomain'] || !$this->options['textdomainDir']) {
// text domain is not set..
if (@$this->options['debug']) {
echo __CLASS__.":MISSING textdomain settings<BR>";
}
return $string;
}
$pofile = $this->options['textdomainDir'] .
'/' . $this->options['locale'] .
'/LC_MESSAGES/' . $this->options['textdomain'] . '.po';
// did we try to load it already..
if (@$GLOBALS['_'.__CLASS__]['PO'][$pofile] === false) {
if (@$this->options['debug']) {
echo __CLASS__.":LOAD failed (Cached):<BR>";
}
return $string;
}
if (!@$GLOBALS['_'.__CLASS__]['PO'][$pofile]) {
// default - cant load it..
$GLOBALS['_'.__CLASS__]['PO'][$pofile] = false;
if (!file_exists($pofile)) {
if (@$this->options['debug']) {
echo __CLASS__.":LOAD failed: {$pofile}<BR>";
}
return $string;
}
if (!@include_once 'File/Gettext.php') {
if (@$this->options['debug']) {
echo __CLASS__.":LOAD no File_gettext:<BR>";
}
return $string;
}
$GLOBALS['_'.__CLASS__]['PO'][$pofile] = File_Gettext::factory('PO', $pofile);
$GLOBALS['_'.__CLASS__]['PO'][$pofile]->load();
//echo '<PRE>'.htmlspecialchars(print_r($GLOBALS['_'.__CLASS__]['PO'][$pofile]->strings,true));
}
$po = &$GLOBALS['_'.__CLASS__]['PO'][$pofile];
// we should have it loaded now...
// this is odd - data is a bit messed up with CR's
$string = str_replace('\n', "\n", $string);
if (isset($po->strings[$prefix.$string])) {
return $po->strings[$prefix.$string];
}
if (!isset($po->strings[$string])) {
if (@$this->options['debug']) {
echo __CLASS__.":no match:<BR>";
}
return $string;
}
if (@$this->options['debug']) {
echo __CLASS__.":MATCHED: {$po->strings[$string]}<BR>";
}
// finally we have a match!!!
return $po->strings[$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) {
$original = $element->getAttribute('ALT');
if (($element->tag == 'IMG') && is_string($original) && strlen($original)) {
$this->addStringToGettext($original);
$quote = $element->ucAttributes['ALT']{0};
$element->ucAttributes['ALT'] = $quote . $this->translateString($original). $quote;
}
$original = $element->getAttribute('TITLE');
if (($element->tag == 'A') && is_string($original) && strlen($original)) {
$this->addStringToGettext($original);
$quote = $element->ucAttributes['TITLE']{0};
$element->ucAttributes['TITLE'] = $quote . $this->translateString($original). $quote;
}
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/Flexy/Tag.php';
$this->tagHandlers[$namespace] = &HTML_Template_Flexy_Compiler_Flexy_Tag::factory($namespace, $this);
if (!$this->tagHandlers[$namespace] ) {
return HTML_Template_Flexy::raiseError('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);
}
}

View file

@ -0,0 +1,222 @@
<?php
/* vim: set expandtab tabstop=4 shiftwidth=4: */
// +----------------------------------------------------------------------+
// | PHP Version 4 |
// +----------------------------------------------------------------------+
// | Copyright (c) 1997-2003 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@akkbhome.com> |
// +----------------------------------------------------------------------+
//
// $Id: Flexy.php,v 1.6 2005/01/22 06:32:20 alan_k Exp $
//
// Handler code for the <flexy: namespace
//
/**
* the <flexy:XXXX namespace
*
*
* at present it handles
* <flexy:toJavascript flexy:prefix="Javascript_prefix" javscriptName="PHPvar" .....>
* <flexy:include src="xxx.htm">
*
*
*
* @version $Id: Flexy.php,v 1.6 2005/01/22 06:32:20 alan_k Exp $
*/
class HTML_Template_Flexy_Compiler_Flexy_Flexy {
/**
* Parent Compiler for
*
* @var object HTML_Template_Flexy_Compiler
*
* @access public
*/
var $compiler;
/**
* The current element to parse..
*
* @var object
* @access public
*/
var $element;
/**
* toString - display tag, attributes, postfix and any code in attributes.
* Relays into namspace::method to get results..
*
*
* @see parent::toString()
*/
function toString($element)
{
list($namespace,$method) = explode(':',$element->oTag);
if (!strlen($method)) {
return '';
}
// things we dont handle...
if (!method_exists($this,$method.'ToString')) {
return '';
}
return $this->{$method.'ToString'}($element);
}
/**
* toJavascript handler
* <flexy:toJavascript flexy:prefix="some_prefix_" javascriptval="php.val" ....>
*
* @see parent::toString()
*/
function toJavascriptToString($element)
{
$ret = $this->compiler->appendPhp( "require_once 'HTML/Javascript/Convert.php';");
$ret .= $this->compiler->appendHTML("\n<script type='text/javascript'>\n");
$prefix = ''. $element->getAttribute('FLEXY:PREFIX');
foreach ($element->attributes as $k=>$v) {
// skip directives..
if (strpos($k,':')) {
continue;
}
if ($k == '/') {
continue;
}
$v = substr($v,1,-1);
$ret .= $this->compiler->appendPhp(
'$__tmp = HTML_Javascript_Convert::convertVar('.$element->toVar($v) .',\''.$prefix . $k.'\',true);'.
'echo (is_a($__tmp,"PEAR_Error")) ? ("<pre>".print_r($__tmp,true)."</pre>") : $__tmp;');
$ret .= $this->compiler->appendHTML("\n");
}
$ret .= $this->compiler->appendHTML("</script>");
return $ret;
}
/**
* include handler
* <flexy:include src="test.html">
*
* @see parent::toString()
*/
function includeToString($element)
{
// this is disabled by default...
// we ignore modifier pre/suffix
$arg = $element->getAttribute('SRC');
if (!$arg) {
return $this->compiler->appendHTML("<B>Flexy:Include without a src=filename</B>");
}
// ideally it would be nice to embed the results of one template into another.
// however that would involve some complex test which would have to stat
// the child templates anyway..
// compile the child template....
// output... include $this->options['compiled_templates'] . $arg . $this->options['locale'] . '.php'
return $this->compiler->appendPHP( "\n".
"\$x = new HTML_Template_Flexy(\$this->options);\n".
"\$x->compile('{$arg}');\n".
"\$_t = function_exists('clone') ? clone(\$t) : \$t;\n".
"foreach(get_defined_vars() as \$k=>\$v) {\n" .
" if (\$k != 't') { \$_t->\$k = \$v; }\n" .
"}\n" .
"\$x->outputObject(\$_t, \$this->elements);\n"
);
}
/**
* Convert flexy tokens to HTML_Template_Flexy_Elements.
*
* @param object token to convert into a element.
* @return object HTML_Template_Flexy_Element
* @access public
*/
function toElement($element)
{
return '';
}
/**
* Handler for User defined functions in templates..
* <flexy:function name="xxxxx">.... </flexy:block> // equivilant to function xxxxx() {
* <flexy:function call="{xxxxx}">.... </flexy:block> // equivilant to function {$xxxxx}() {
* <flexy:function call="xxxxx">.... </flexy:block> // equivilant to function {$xxxxx}() {
*
* This will not handle nested blocks initially!! (and may cause even more problems with
* if /foreach stuff..!!
*
* @param object token to convert into a element.
* @access public
*/
function functionToString($element)
{
if ($arg = $element->getAttribute('NAME')) {
// this is a really kludgy way of doing this!!!
// hopefully the new Template Package will have a sweeter method..
$GLOBALS['_HTML_TEMPLATE_FLEXY']['prefixOutput'] .=
$this->compiler->appendPHP(
"\nfunction _html_template_flexy_compiler_flexy_flexy_{$arg}(\$t,\$this) {\n").
$element->compileChildren($this->compiler) .
$this->compiler->appendPHP( "\n}\n");
return '';
}
if (!isset($element->ucAttributes['CALL'])) {
return HTML_Template_Flexy::raiseError(
' tag flexy:function needs an argument call or name'.
" Error on Line {$element->line} &lt;{$element->tag}&gt;",
null, HTML_TEMPLATE_FLEXY_ERROR_DIE);
}
// call is a stirng : nice and simple..
if (is_string($element->ucAttributes['CALL'])) {
$arg = $element->getAttribute('CALL');
return $this->compiler->appendPHP(
"if (function_exists('_html_template_flexy_compiler_flexy_flexy_{$arg}')) " .
" _html_template_flexy_compiler_flexy_flexy_{$arg}(\$t,\$this);");
}
// we make a big assumption here.. - it should really be error checked..
// that the {xxx} element is item 1 in the list...
$e=$element->ucAttributes['CALL'][1];
$add = $e->toVar($e->value);
if (is_a($add,'PEAR_Error')) {
return $add;
}
return $this->compiler->appendPHP(
"if (function_exists('_html_template_flexy_compiler_flexy_flexy_'.{$add})) ".
"call_user_func_array('_html_template_flexy_compiler_flexy_flexy_'.{$add},array(\$t,\$this));");
}
}

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,98 @@
<?php
class HTML_Template_Flexy_Compiler_Regex {
/**
* The main flexy engine
*
* @var object HTML_Template_Flexy
* @access public
*/
var $flexy;
/**
* classicParse - the older regex based code generator.
* here all the replacing, filtering and writing of the compiled file is done
* well this is not much work, but still its in here :-)
*
* @access private
* @version 01/12/03
* @author Wolfram Kriesing <wolfram@kriesing.de>
* @author Alan Knowles <alan@akbkhome.com>
* @return boolean (basically true all the time here)
*/
function compile(&$flexy)
{
$this->flexy = &$flexy;
// read the entire file into one variable
$fileContent = file_get_contents($flexy->currentTemplate);
// apply pre filter
$fileContent = $this->applyFilters( $fileContent , "/^pre_/i" );
$fileContent = $this->applyFilters( $fileContent , "/^(pre_|post_)/i",TRUE);
$fileContent = $this->applyFilters( $fileContent , "/^post_/i" );
// write the compiled template into the compiledTemplate-File
if( ($cfp = fopen( $flexy->compiledTemplate , 'w' )) ) {
fwrite($cfp,$fileContent);
fclose($cfp);
@chmod($flexy->compiledTemplate,0775);
}
return true;
}
/**
* actually it will only be used to apply the pre and post filters
*
* @access public
* @version 01/12/10
* @author Alan Knowles <alan@akbkhome.com>
* @param string $input the string to filter
* @param array $prefix the subset of methods to use.
* @return string the filtered string
*/
function applyFilters( $input , $prefix = "",$negate=FALSE)
{
$this->flexy->debug("APPLY FILTER $prefix<BR>");
$filters = $this->options['filters'];
$this->flexy->debug(serialize($filters)."<BR>");
foreach($filters as $filtername) {
$class = "HTML_Template_Flexy_Compiler_Regex_{$filtername}";
require_once("HTML/Template/Flexy/Compiler/Regex/{$filtername}.php");
if (!class_exists($class)) {
return HTML_Template_Flexy::raiseError("Failed to load filter $filter",null,HTML_TEMPLATE_FLEXY_ERROR_DIE);
}
if (!@$this->filter_objects[$class]) {
$this->filter_objects[$class] = new $class;
$this->filter_objects[$class]->_set_engine($this);
}
$filter = &$this->filter_objects[$class];
$methods = get_class_methods($class);
$this->flexy->debug("METHODS:");
$this->flexy->debug(serialize($methods)."<BR>");
foreach($methods as $method) {
if ($method{0} == "_") {
continue; // private
}
if ($method == $class) {
continue; // constructor
}
$this->flexy->debug("TEST: $negate $prefix : $method");
if ($negate && preg_match($prefix,$method)) {
continue;
}
if (!$negate && !preg_match($prefix,$method)) {
continue;
}
$this->flexy->debug("APPLYING $filtername $method<BR>");
$input = $filter->$method($input);
}
}
return $input;
}
}

View file

@ -0,0 +1,81 @@
<?php
//
// +----------------------------------------------------------------------+
// | PHP Version 4 |
// +----------------------------------------------------------------------+
// | Copyright (c) 1997-2003 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. |
// +----------------------------------------------------------------------+
// | Author: Alan Knowles <alan@akbkhome.com>
// +----------------------------------------------------------------------+
//
/**
* The html Body only filter
*
* @abstract
* a Simple filter to remove the everything thats not in the body!
*
* @package HTML_Template_Flexy
*
*/
class HTML_Template_Flexy_Compiler_Regex_BodyOnly
{
/**
* Standard Set Engine
*
*
* @param object HTML_Template_Flexy the main engine
* @access private
*/
function _set_engine(&$engine)
{
}
/**
* Strip everything before and including the BODY tag
*
* @param string The template
* @access public
*/
function strip_body_head ($input)
{
if (!preg_match("/^(.*)<body/si", $input)) {
return $input;
}
$input = preg_replace("/^(.*)<body/si", "",$input);
$input = preg_replace("/^([^>]*)>/si", "",$input);
return $input;
}
/**
* Strip everything after and including the end BODY tag
*
* @param string The template
* @access public
*/
function strip_body_foot ($input)
{
if (!preg_match("/<\/body>.*/si", $input)) {
return $input;
}
$input = preg_replace("/<\/body>.*/si", "",$input);
return $input;
}
}
?>

View file

@ -0,0 +1,57 @@
<?php
//
// +----------------------------------------------------------------------+
// | PHP Version 4 |
// +----------------------------------------------------------------------+
// | Copyright (c) 1997-2003 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. |
// +----------------------------------------------------------------------+
// | Author: Alan Knowles <alan@akbkhome.com>
// +----------------------------------------------------------------------+
//
/**
* The Mail filter template (sorts out cr removal in php)
*
*
* @package HTML_Template_Flexy
*
*
*
*/
class HTML_Template_Flexy_Compiler_Regex_Mail {
/**
* Standard Set Engine
*
*
* @param object HTML_Template_Flexy the main engine
* @access private
*/
function _set_engine(&$engine)
{
}
/*
* add an extra cr to the end php tag, so it show correctly in Emails
*
* @param string The template
* @access public
*/
function post_fix_php_cr ($input)
{
$input = str_replace("?>\n","?>\n\n",$input);
return str_replace("?>\r\n","?>\r\n\r\n",$input);
}
}
?>

View file

@ -0,0 +1,74 @@
<?php
//
// +----------------------------------------------------------------------+
// | PHP Version 4 |
// +----------------------------------------------------------------------+
// | Copyright (c) 1997-2003 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. |
// +----------------------------------------------------------------------+
// | Author: Alan Knowles <alan@akbkhome.com>
// +----------------------------------------------------------------------+
//
/**
* A Math Filter
*
* enable simple maths to be done in the template
*
* TODO: add an {if:t.xxx%2} type syntax..
*
* @package HTML_Template_Flexy
*
*/
class HTML_Template_Flexy_Compiler_Regex_Math {
/*
* @var string $start the start tag for the template (escaped for regex)
*/
var $start = '\{';
/*
* @var string $stop the stopt tag for the template (escaped for regex)
*/
var $stop = '\}'; //ending template tag
/**
* Standard Set Engine
*
*
* @param object HTML_Template_Flexy the main engine
* @access private
*/
function _set_engine(&$engine) {
}
/*
* allow simple add multiply, divide and subtraction
*
* eg.
* {(12+t.somevar)*2} maps to =(12+$t->somevar)*2
*
* @param string The template
* @access public
*/
function variables ($input) {
$input = preg_replace(
"/".$this->start."([0-9\(\)+*\/-]*)([a-z0-9]+)([0-9\(\)+*\/-]*)".$this->stop."/ie",
"'<?=\\1($'.str_replace('.','->','\\2').')\\3?>'",
$input);
return $input;
}
}
?>

View file

@ -0,0 +1,59 @@
<?php
//
// +----------------------------------------------------------------------+
// | PHP Version 4 |
// +----------------------------------------------------------------------+
// | Copyright (c) 1997-2003 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. |
// +----------------------------------------------------------------------+
// | Author: Alan Knowles <alan@akbkhome.com>
// +----------------------------------------------------------------------+
//
/**
* Remove PHP tags and replace them with echo '< ? '
*
* should be the first filter if you use it
*
*
*
* @package HTML_Template_Flexy
*
*/
class HTML_Template_Flexy_Compiler_Regex_Php
{
/**
* Standard Set Engine
*
*
* @param object HTML_Template_Flexy the main engine
* @access private
*/
function _set_engine(&$engine)
{
}
/*
* replace the php tags
*
* @param string The template
* @access public
*/
function pre_strip_php ($input)
{
$input = str_replace("<?","__{<__?}__",$input);
$input = str_replace("?>","<?php echo '?'.'>'; ?>",$input);
return str_replace("__{<__?}__","<?php echo '<'.'>'; ?>",$input);
}
}
?>

View file

@ -0,0 +1,50 @@
<?php
//
// +----------------------------------------------------------------------+
// | PHP Version 4 |
// +----------------------------------------------------------------------+
// | Copyright (c) 1997-2003 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. |
// +----------------------------------------------------------------------+
// | Author: Alan Knowles <alan@akbkhome.com>
// +----------------------------------------------------------------------+
//
/**
* The rtf SimpleTags filter
*
* really an extension of simple tags with \\\{ and \\\\} as the tag delimiters
* can parse an RTF template and generate a file.
*
* usually best used with callback ouput buffering to reduce memory loads.
*
* @package HTML_Template_Flexy
*
*/
require_once "HTML/Template/Flexy/Filter/SimpleTags.php";
class HTML_Template_Flexy_Compiler_Regex_RtfSimpleTags extends HTML_Template_Flexy_Compiler_Regex_simpletags
{
/*
* @var string $start the start tag for the template (escaped for regex)
*/
var $start = '\\\{';
/*
* @var string $stop the stopt tag for the template (escaped for regex)
*/
var $stop= '\\\}';
}
?>

View file

@ -0,0 +1,391 @@
<?php
//
// +----------------------------------------------------------------------+
// | PHP Version 4 |
// +----------------------------------------------------------------------+
// | Copyright (c) 1997-2003 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. |
// +----------------------------------------------------------------------+
// | Author: Alan Knowles <alan@akbkhome.com>
// +----------------------------------------------------------------------+
//
/**
* The Standard Tag filter
*
* @abstract
* does all the clever stuff...
*
* Security Notes:
* Templates should not originate from untrusted sources,
* - the method(#.....#) could be regarded as insecure.
* - there is no attempt to protect your from <script / <?php in templates.
*
* @package HTML_Template_Flexy
*
*/
class HTML_Template_Flexy_Compiler_Regex_SimpleTags
{
/*
* @var object HTML_Template_Flexy the main engine
*/
var $engine; // the engine (with options)
/*
* @var string $start the start tag for the template (escaped for regex)
*/
var $start = '\{';
/*
* @var string $stop the stopt tag for the template (escaped for regex)
*/
var $stop = '\}';
/*
* @var string $error show/hide the PHP error messages on/off in templates
*/
var $error = "@"; // change to blank to debug errors.
/**
* Standard Set Engine
*
*
* @param object HTML_Template_Flexy the main engine
* @access private
*/
function _set_engine(&$engine) {
$this->engine = &$engine;
if ($this->engine->options['debug']) {
$this->error = "";
}
}
/**
* Standard Variable replacement
*
*
* Maps variables
* {i.xyz} maps to <?php echo htmlspecialchars($i->xyz)?>
* {i.xyz:h} maps to <?php echo $i->xyz?>
* {i.xyz:u} maps to <?php echo urlencode($i->xyz)?>
* {i.xyz:ru} maps to <?php echo rawurlencode($i->xyz)?>
*
* {i.xyz:r} maps to <PRE><?php echo print_r($i->xyz)?></PRE>
* {i.xyz:n} maps to <?php echo nl2br(htmlspecialchars($i->xyz))?>
*
*
* @param string $input the template
* @return string the result of the filtering
* @access public
*/
function variables ($input) {
$input = preg_replace(
"/".$this->start."([a-z0-9_.]+)".$this->stop."/ie",
"'<?php echo htmlspecialchars(".$this->error."$'.str_replace('.','->','\\1').')?>'",
$input);
$input = preg_replace(
"/".$this->start."([a-z0-9_.]+):h".$this->stop."/ie",
"'<?php echo ".$this->error."$'.str_replace('.','->','\\1').'?>'",
$input);
$input = preg_replace(
"/".$this->start."([a-z0-9_.]+):u".$this->stop."/ie",
"'<?php echo urlencode(".$this->error."$'.str_replace('.','->','\\1').')?>'",
$input);
$input = preg_replace(
"/".$this->start."([a-z0-9_.]+):ru".$this->stop."/ie",
"'<?php echo rawurlencode(".$this->error."$'.str_replace('.','->','\\1').')?>'",
$input);
$input = preg_replace(
"/".$this->start."([a-z0-9_.]+):r".$this->stop."/ie",
"'<PRE><?php echo print_r($'.str_replace('.','->','\\1').')?></PRE>'",
$input);
$input = preg_replace(
"/".$this->start."([a-z0-9_.]+):n".$this->stop."/ie",
"'<?php echo nl2br(htmlspecialchars(".$this->error."$'.str_replace('.','->','\\1').'))?>'",
$input);
return $input;
}
/**
* Urlencoded Variable replacement
*
* Often when you use a WYSISYG editor, it replaces { in
* the href="{somevar}" with the urlencoded version, this bit fixes it.
*
* Maps variables
* %??i.xyz%?? maps to <?php echo htmlspecialchars($i->xyz)?>
* %??i.xyz:h%?? maps to <?php echo $i->xyz?>
* %??i.xyz:u%?? maps to <?php echo urlencode($i->xyz)?>
* %??i.xyz:ru%?? maps to <?php echo urlencode($i->xyz)?>
* THIS IS PROBABLY THE ONE TO USE!
*
* %??i.xyz:uu%?? maps to <?php echo urlencode(urlencode($i->xyz))?>
*
*
* @param string $input the template
* @return string the result of the filtering
* @access public
*/
function urlencoded_variables ($input) {
$input = preg_replace(
"/".urlencode(stripslashes($this->start))."([a-z0-9_.]+)".urlencode(stripslashes($this->stop))."/ie",
"'<?php echo htmlspecialchars(".$this->error."$'.str_replace('.','->','\\1').')?>'",
$input);
$input = preg_replace(
"/".urlencode(stripslashes($this->start))."([a-z0-9_.]+):h".urlencode(stripslashes($this->stop))."/ie",
"'<?php echo ".$this->error."$'.str_replace('.','->','\\1').'?>'",
$input);
$input = preg_replace(
"/".urlencode(stripslashes($this->start))."([a-z0-9_.]+):u".urlencode(stripslashes($this->stop))."/ie",
"'<?php echo urlencode(".$this->error."$'.str_replace('.','->','\\1').')?>'",
$input);
$input = preg_replace(
"/".urlencode(stripslashes($this->start))."([a-z0-9_.]+):uu".urlencode(stripslashes($this->stop))."/ie",
"'<?php echo urlencode(urlencode(".$this->error."$'.str_replace('.','->','\\1').'))?>'",
$input);
return $input;
}
/**
* Calling Methods
*
* This allows you to call methods of your application
*
* Maps Methods
* {t.xxxx_xxxx()} maps to <?php echo htmlspecialchars($t->xxxx_xxxx())?>
* {t.xxxx_xxxx():h} maps to <?php echo $t->xxxx_xxxx()?>
*
* {t.xxxx_xxxx(sssss.dddd)} maps to <?php echo htmlspecialchars($t->xxxx_xxxx($ssss->dddd))?>
* {t.xxxx_xxxx(sssss.dddd):h} maps to <?php echo $t->xxxx_xxxx($ssss->dddd)?>
* {t.xxxx_xxxx(sssss.dddd):s} maps to <?php highlight_string($t->xxxx_xxxx($ssss->dddd))?>
*
* {t.xxxx_xxxx(#XXXXX#)} maps to <?php echo htmlspecialchars($t->xxxx_xxxx('XXXXXX'))?>
* {t.xxxx_xxxx(#XXXXX#):h} maps to <?php echo $t->xxxx_xxxx('XXXXXX')?>
*
* {t.xxxx_xxxx(sss.ddd,sss.ddd)} maps to <?php echo htmlspecialchars($t->xxxx_xxxx($sss->ddd,$sss->ddd))?>
* {t.xxxx_xxxx(#aaaa#,sss.ddd)} maps to <?php echo htmlspecialchars($t->xxxx_xxxx("aaaa",$sss->ddd))?>
* {t.xxxx_xxxx(sss.ddd,#aaaa#)} maps to <?php echo htmlspecialchars($t->xxxx_xxxx($sss->ddd,"aaaa"))?>
*
*
*
* @param string $input the template
* @return string the result of the filtering
* @access public
*/
function methods($input) {
/* no vars */
$input = preg_replace(
"/".$this->start."([a-z0-9_.]+)\(\)".$this->stop."/ie",
"'<?php echo htmlspecialchars(".$this->error."$'.str_replace('.','->','\\1').'())?>'",
$input);
$input = preg_replace(
"/".$this->start."([a-z0-9_.]+)\(\):h".$this->stop."/ie",
"'<?php echo ".$this->error."$'.str_replace('.','->','\\1').'()?>'",
$input);
/* single vars */
$input = preg_replace(
"/".$this->start."([a-z0-9_.]+)\(([a-z0-9_.]+)\)".$this->stop."/ie",
"'<?php echo htmlspecialchars(".$this->error."$'.str_replace('.','->','\\1').'($' . str_replace('.','->','\\2') . '))?>'",
$input);
$input = preg_replace(
"/".$this->start."([a-z0-9_.]+)\(([a-z0-9_.]+)\):h".$this->stop."/ie",
"'<?php echo ".$this->error."$'.str_replace('.','->','\\1').'($' . str_replace('.','->','\\2') . ')?>'",
$input);
$input = preg_replace(
"/".$this->start."([a-z0-9_.]+)\(([a-z0-9_.]+)\):s".$this->stop."/ie",
"'<?php highlight_string($'.str_replace('.','->','\\1').'($' . str_replace('.','->','\\2') . '));?>'",
$input);
/* double vars */
$input = preg_replace(
"/".$this->start."([a-z0-9_.]+)\(([a-z0-9_.]+),([a-z0-9_.]+)\)".$this->stop."/ie",
"'<?php echo htmlspecialchars(".$this->error."$'.str_replace('.','->','\\1').'($' . str_replace('.','->','\\2') . ',$' . str_replace('.','->','\\3') . '))?>'",
$input);
/* double vars:: # #'d ,var */
$input = preg_replace(
"/".$this->start."([a-z0-9_.]+)\(\#([^\#]+)\#,([a-z0-9_.]+)\)".$this->stop."/ie",
"'<?php echo htmlspecialchars(".$this->error."$'.str_replace('.','->','\\1').'(\''. str_replace(\"'\",\"\\\'\",'\\2') . '\',$' . str_replace('.','->','\\3') . '))?>'",
$input);
/* double vars:: var , # #'d */
$input = preg_replace(
"/".$this->start."([a-z0-9_.]+)\(([a-z0-9_.]+),\#([^\#]+)\#\)".$this->stop."/ie",
"'<?php echo htmlspecialchars(".$this->error."$'.str_replace('.','->','\\1').'($' . str_replace('.','->','\\2') . ',\''. str_replace(\"'\",\"\\\'\",'\\3') . '\'))?>'",
$input);
/*strings or integers */
$input = preg_replace(
"/".$this->start."([a-z0-9_.]+)\(\#([^\#]+)\#\)".$this->stop."/ie",
"'<?php echo htmlspecialchars(\$'.str_replace('.','->','\\1') . '(\''. str_replace(\"'\",\"\\\'\",'\\2') . '\'))?>'",
$input);
$input = preg_replace(
"/".$this->start."([a-z0-9_.]+)\(\#([^\#]+)\#\):h".$this->stop."/ie",
"'<?php echo ".$this->error."$'.str_replace('.','->','\\1').'(\"' . str_replace(\"'\",\"\\\'\",'\\2') . '\")?>'",
$input);
return $input;
}
/**
* Looping
*
* This allows you to do loops on variables (eg. nested/ repeated blocks!)
*
* Maps Methods
* {foreach:t.xyz,zzz} maps to <?php if ($i->xyz) foreach ($t->xyz as $zzz) { ?>
* {foreach:t.xyz,xxx,zzz} maps to <?php if ($i->xyz) foreach ($t->xyz as $xxx=>$zzz) { ?>
* {end:} maps to <?php }?>
* {else:} maps to <?php }else{?>
*
*
*
* @param string $input the template
* @return string the result of the filtering
* @access public
*/
function looping($input) {
$input = preg_replace(
"/".$this->start."foreach:([a-z0-9_.]+),([a-z0-9_.]+)".$this->stop."/ie",
"'<?php if (".$this->error."$' . str_replace('.','->','\\1') . ') foreach( $' . str_replace('.','->','\\1') . ' as $' . str_replace('.','->','\\2') . ') { ?>'",
$input);
$input = preg_replace(
"/".$this->start."foreach:([a-z0-9_.]+),([a-z0-9_.]+),([a-z0-9_.]+)".$this->stop."/ie",
"'<?php if (".$this->error."$' . str_replace('.','->','\\1') . ') foreach( $' . str_replace('.','->','\\1') . ' as $' . str_replace('.','->','\\2') . '=>$' . str_replace('.','->','\\3') .') { ?>'",
$input);
$input = str_replace(stripslashes($this->start)."else:".stripslashes($this->stop),'<?php }else{?>', $input);
$input = str_replace(stripslashes($this->start)."end:".stripslashes($this->stop),'<?php }?>', $input);
return $input;
}
/**
* Conditional inclusion
*
* This allows you to do conditional inclusion (eg. blocks!)
*
* Maps conditions
*
* {if:t.xxxx} => <?php if ($t->xxxx) { ?>
* {if:t.x_xxx()} => <?php if ($t->x_xxx()) { ?>
*
* @param string $input the template
* @return string the result of the filtering
* @access public
*/
function conditionals($input) {
$input = preg_replace(
"/".$this->start."if:([a-z0-9_.]+)".$this->stop."/ie",
"'<?php if (".$this->error."$' . str_replace('.','->','\\1') . ') { ?>'",
$input);
$input = preg_replace(
"/".$this->start."if:([a-z0-9_.]+)\(\)".$this->stop."/ie",
"'<?php if (".$this->error."$' . str_replace('.','->','\\1') . '()) { ?>'",
$input);
return $input;
}
/**
* sub template inclusion
*
* This allows you to do include other files (either flat or generated templates.).
*
* {include:t.abcdef} maps to <?php
* if($t->abcdef && file_exists($compileDir . "/". $t->abcdef . "en.php"))
* include($compileDir . "/". $t->abcdef . ".en.php");
* ?>
*
* include abcdef.en.php (Eg. hard coded compiled template
* {include:#abcdef#} => <?php
* if(file_exists($compileDir . "/abcdef.en.php"))
* include($compileDir . "/abcdef.en.php");
* ?>
*
* include raw
* {t_include:#abcdef.html#} => <?php
* if(file_exists($templateDir . "/abcdef.html"))
* include($compileDir . "/abcdef.html");
* ?>
* Compile and include
* {q_include:#abcdef.html#} => <?php
* HTML_Template_Flexy::staticQuickTemplate('abcedef.html',$t);
* ?>
*
*
* @param string $input the template
* @return string the result of the filtering
* @access public
*/
function include_template($input) {
$input = preg_replace(
"/".$this->start."include:([a-z0-9_.]+)".$this->stop."/ie",
"'<?php
if ((".$this->error."$' . str_replace('.','->','\\1') . ') &&
file_exists(\"" . $this->engine->options['compileDir'] .
"/\{$' . str_replace('.','->','\\1') . '}.en.php\"))
include(\"" . $this->engine->options['compileDir'] .
"/\{$' . str_replace('.','->','\\1') . '}.en.php\");?>'",
$input);
$input = preg_replace(
"/".$this->start."include:#([a-z0-9_.]+)#".$this->stop."/ie",
"'<?php if (file_exists(\"" . $this->engine->options['compileDir'] . "/\\1.en.php\")) include(\"" .
$this->engine->options['compileDir'] . "/\\1.en.php\");?>'",
$input);
$input = preg_replace(
"/".$this->start."t_include:#([a-z0-9_.]+)#".$this->stop."/ie",
"'<?php if (file_exists(\"" . $this->engine->options['templateDir'] .
"/\\1\")) include(\"" . $this->engine->options['templateDir'] . "/\\1\");?>'",
$input);
$input = preg_replace(
"/".$this->start."q_include:#([a-z0-9_.]+)#".$this->stop."/ie",
"'<?php HTML_Template_Flexy::staticQuickTemplate(\"\\1\",\$t); ?>'",
$input);
return $input;
}
}
?>

View file

@ -0,0 +1,58 @@
<?php
//
// +----------------------------------------------------------------------+
// | PHP Version 4 |
// +----------------------------------------------------------------------+
// | Copyright (c) 1997-2003 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. |
// +----------------------------------------------------------------------+
// | Author: Alan Knowles <alan@akbkhome.com>
// +----------------------------------------------------------------------+
//
/**
* Replace XML tags with echo '<' .'?xml';
*
* @package HTML_Template_Flexy
*
*/
class HTML_Template_Flexy_Compiler_Regex_Xml
{
/**
* Standard Set Engine
*
*
* @param object HTML_Template_Flexy the main engine
* @access private
*/
function _set_engine(&$engine)
{
}
/*
* replace the xml tags
*
* @param string The template
* @access public
*/
function pre_replace_xml ($input)
{
$input = str_replace("?>","<?php echo '?'.'>'; ?>\n",$input);
$input = str_replace("<?xml","<?php echo '<'.'?xml'; ?>",$input);
return $input;
}
}
?>

View file

@ -0,0 +1,335 @@
<?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: SmartyConvertor.php,v 1.3 2004/07/03 03:46:43 alan_k Exp $
//
// Smarty Conversion compiler
// takes a smarty template, and converts it to a flexy one.
// then does a standard flexy compile.
//
// anything that is not supported gets changed to HTML comments
/* Usage:
a simple script: 'convertsmarty.php'
#!/usr/bin/php
$file = $_SERVER['argv'][1];
$x = new HTML_Template_Flexy(array(
'compileDir' => dirname(__FILE__) , // where do you want to write to..
'templateDir' => $dir , // where are your templates
'locale' => 'en', // works with gettext
'forceCompile' => true, // only suggested for debugging
'debug' => false, // prints a few errors
'nonHTML' => false, // dont parse HTML tags (eg. email templates)
'allowPHP' => false, // allow PHP in template
'compiler' => 'SmartyConvertor', // which compiler to use.
'compileToString' => true, // returns the converted template (rather than actually
// converting to PHP.
'filters' => array(), // used by regex compiler..
'numberFormat' => ",2,'.',','", // default number format = eg. 1,200.00 ( {xxx:n} )
'flexyIgnore' => 0 // turn on/off the tag to element code
));
echo $x->compile(basename($file));
then run it at the command line:
php convertsmarty.php /path/to/a/smarty/template.tpl > /path/to/the/flexy/templates.html
*/
require_once 'HTML/Template/Flexy/Compiler.php';
/**
* The Smarty Converter implementation.
* designed primarily to be used as above, to convert from one to another.
* however it could be used inline to convert simple smarty templates into
* flexy ones - then compile them on the fly.
*
* @version $Id: SmartyConvertor.php,v 1.3 2004/07/03 03:46:43 alan_k Exp $
*/
class HTML_Template_Flexy_Compiler_SmartyConvertor extends HTML_Template_Flexy_Compiler {
/**
* compile implementation
*
* see HTML_Template_Flexy_Compiler::compile()
*
* @param object The core flexy object.
* @param string optionally a string to compile.
*
* @return true | string string when compiling to String.
* @access public
*/
function compile(&$flexy,$string=false)
{
$data = $string;
if ($string === false) {
$data = file_get_contents($flexy->currentTemplate);
}
$data = $this->convertToFlexy($data);
if ($flexy->options['compileToString']) {
return $data;
}
require_once 'HTML/Template/Flexy/Compiler/Standard.php';
$flexyCompiler = new HTML_Template_Flexy_Compiler_Standard;
$flexyCompiler->compile($flexy,$data);
return true;
}
/**
* The core work of parsing a smarty template and converting it into flexy.
*
* @param string the contents of the smarty template
*
* @return string the flexy version of the template.
* @access public|private
* @see see also methods.....
*/
function convertToFlexy($data)
{
$leftq = preg_quote('{', '!');
$rightq = preg_quote('}', '!');
preg_match_all("!" . $leftq . "\s*(.*?)\s*" . $rightq . "!s", $data, $matches);
$tags = $matches[1];
// find all the tags/text...
$text = preg_split("!" . $leftq . ".*?" . $rightq . "!s", $data);
$max_text = count($text);
$max_tags = count($tags);
for ($i = 0 ; $i < $max_tags ; $i++) {
$compiled_tags[] = $this->_compileTag($tags[$i]);
}
// error handling for closing tags.
$data = '';
for ($i = 0; $i < $max_tags; $i++) {
$data .= $text[$i].$compiled_tags[$i];
}
$data .= $text[$i];
return $data;
}
/**
* stack for conditional and closers.
*
* @var array
* @access public
*/
var $stack = array(
'if' => 0,
);
/**
* compile a smarty { tag } into a flexy one.
*
* @param string the tag
*
* @return string the converted version
* @access private
*/
function _compileTag($str)
{
// skip comments
if (($str{0} == '*') && (substr($str,-1,1) == '*')) {
return '';
}
switch($str{0}) {
case '$':
// its a var
return $this->_convertVar($str);
case '#':
// its a config var
return $this->_convertConfigVar($str);
case '%':
// wtf does this do
return "<!-- what is this? $str -->";
}
// this is where it gets messy
// this is very slow - but what the hell
// - its only done once
// - its alot more readable than a long regext.
// - it doesnt infringe on copyright...
switch(true) {
case (preg_match('/^config_load\s/', $str)):
// convert to $t->TemplateConfigLoad()
$args = $this->convertAttributesToKeyVal(substr($str,strpos( $str,' ')));
return '{plugin(#smartyConfigLoad#,#'.$args['file'].'#,#'.$args['section'].'#)}';
case (preg_match('/^include\s/', $str)):
// convert to $t->TemplateConfigLoad()
$args = $this->convertAttributesToKeyVal(substr($str,strpos( $str,' ')));
return '{plugin(#smartyInclude#,#'.$args['file'].'#)}';
case ($str == 'ldelim'):
return '{';
case ($str == 'rdelim'):
return '}';
case (preg_match('/^if \$(\S+)$/', $str,$matches)):
case (preg_match('/^if \$(\S+)\seq\s""$/', $str,$matches)):
// simple if variable..
// convert to : {if:sssssss}
$this->stack['if']++;
$var = $this->_convertVar('$'.$matches[1]);
return '{if:'.substr($var,1);
case (preg_match('/^if #(\S+)#$/', $str,$matches)):
case (preg_match('/^if #(\S+)#\sne\s""$/', $str,$matches)):
// simple if variable..
// convert to : {if:sssssss}
$this->stack['if']++;
$var = $this->_convertConfigVar('#'.$matches[1].'#');
return '{if:'.substr($var,1);
// negative matches
case (preg_match('/^if\s!\s\$(\S+)$/', $str,$matches)):
case (preg_match('/^if \$(\S+)\seq\s""$/', $str,$matches)):
// simple if variable..
// convert to : {if:sssssss}
$this->stack['if']++;
$var = $this->_convertVar('$'.$matches[1]);
return '{if:!'.substr($var,1);
case ($str == 'else'):
if (!$this->stack['if']) {
break;
}
return '{else:}';
case ($str == '/if'):
if (!$this->stack['if']) {
break;
}
$this->stack['if']--;
return '{end:}';
}
return "<!-- UNSUPPORTED TAG: $str FOUND -->";
}
/**
* convert a smarty var into a flexy one.
*
* @param string the inside of the smart tag
*
* @return string a flexy version of it.
* @access private
*/
function _convertVar($str)
{
// look for modfiers first.
$mods = explode('|', $str);
$var = array_shift($mods);
$var = substr($var,1); // strip $
// various formats :
// aaaa.bbbb.cccc => aaaa[bbbb][cccc]
// aaaa[bbbb] => aaa[bbbb]
// aaaa->bbbb => aaaa.bbbb
$bits = explode('.',$var);
$var = array_shift($bits);
foreach($bits as $k) {
$var.= '['.$k .']';
}
$bits = explode('->',$var);
$var = implode('.',$bits);
$mods = implode('|',$mods);
if (strlen($mods)) {
return '{plugin(#smartyModifiers#,'.$var.',#'.$mods.'#):h}';
}
return '{'.$var .'}' . $mods;
}
/**
* convert a smarty key="value" string into a key value array
* cheap and cheerfull - doesnt handle spaces inside the strings...
*
* @param string the key value part of the tag..
*
* @return array key value array
* @access private
*/
function convertAttributesToKeyVal($str)
{
$atts = explode(' ', $str);
$ret = array();
foreach($atts as $bit) {
$bits = explode('=',$bit);
// loose stuff!!!
if (count($bits) != 2) {
continue;
}
$ret[$bits[0]] = ($bits[1]{0} == '"') ? substr($bits[1],1,-1) : $bits[1];
}
return $ret;
}
/**
* convert a smarty config var into a flexy one.
*
* @param string the inside of the smart tag
*
* @return string a flexy version of it.
* @access private
*/
function _convertConfigVar($str)
{
$mods = explode('|', $str);
$var = array_shift($mods);
$var = substr($var,1,-1); // strip #'s
$mods = implode('|',$mods);
if (strlen($mods)) {
$mods = "<!-- UNSUPPORTED MODIFIERS: $mods -->";
}
return '{configVars.'.$var .'}' . $mods;
}
}

View file

@ -0,0 +1,910 @@
<?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,v 1.43 2005/02/08 05:35:27 alan_k Exp $
//
// 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
{
/**
* 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;
$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 (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->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 (is_a($res,'PEAR_Error')) {
return $res;
}
// turn tokens into Template..
$data = $res->compile($this);
if (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::raiseError('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 (is_a($add,'PEAR_Error')) {
return $add;
}
$ret .= $add;
if ($element->close) {
$add = $element->close->compile($this);
if (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 (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 (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 (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 (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 (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 (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->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;
}
/**
* translateString - a gettextWrapper
*
* tries to do gettext or falls back on File_Gettext
* This has !!!NO!!! error handling - if it fails you just get english..
* no questions asked!!!
*
* @param string string to translate
*
* @return string translated string..
* @access public
*/
function translateString($string)
{
if (is_a($this->options['Translation2'],'Translation2')) {
$result = $this->options['Translation2']->get($string);
if (!empty($result)) {
return $result;
}
return $string;
}
// note this stuff may have been broken by removing the \n replacement code
// since i dont have a test for it... it may remain broken..
// use Translation2 - it has gettext backend support
// and should sort out the mess that \n etc. entail.
$prefix = basename($GLOBALS['_HTML_TEMPLATE_FLEXY']['filename']).':';
if (@$this->options['debug']) {
echo __CLASS__.":TRANSLATING $string<BR>";
}
if (function_exists('gettext') && !$this->options['textdomain']) {
if (@$this->options['debug']) {
echo __CLASS__.":USING GETTEXT?<BR>";
}
$t = gettext($string);
if ($t != $string) {
return $t;
}
$tt = gettext($prefix.$string);
if ($tt != $prefix.$string) {
return $tt;
}
// give up it's not translated anywhere...
return $t;
}
if (!$this->options['textdomain'] || !$this->options['textdomainDir']) {
// text domain is not set..
if (@$this->options['debug']) {
echo __CLASS__.":MISSING textdomain settings<BR>";
}
return $string;
}
$pofile = $this->options['textdomainDir'] .
'/' . $this->options['locale'] .
'/LC_MESSAGES/' . $this->options['textdomain'] . '.po';
// did we try to load it already..
if (@$GLOBALS['_'.__CLASS__]['PO'][$pofile] === false) {
if (@$this->options['debug']) {
echo __CLASS__.":LOAD failed (Cached):<BR>";
}
return $string;
}
if (!@$GLOBALS['_'.__CLASS__]['PO'][$pofile]) {
// default - cant load it..
$GLOBALS['_'.__CLASS__]['PO'][$pofile] = false;
if (!file_exists($pofile)) {
if (@$this->options['debug']) {
echo __CLASS__.":LOAD failed: {$pofile}<BR>";
}
return $string;
}
if (!@include_once 'File/Gettext.php') {
if (@$this->options['debug']) {
echo __CLASS__.":LOAD no File_gettext:<BR>";
}
return $string;
}
$GLOBALS['_'.__CLASS__]['PO'][$pofile] = File_Gettext::factory('PO',$pofile);
$GLOBALS['_'.__CLASS__]['PO'][$pofile]->load();
//echo '<PRE>'.htmlspecialchars(print_r($GLOBALS['_'.__CLASS__]['PO'][$pofile]->strings,true));
}
$po = &$GLOBALS['_'.__CLASS__]['PO'][$pofile];
// we should have it loaded now...
// this is odd - data is a bit messed up with CR's
$string = str_replace('\n',"\n",$string);
if (isset($po->strings[$prefix.$string])) {
return $po->strings[$prefix.$string];
}
if (!isset($po->strings[$string])) {
if (@$this->options['debug']) {
echo __CLASS__.":no match:<BR>";
}
return $string;
}
if (@$this->options['debug']) {
echo __CLASS__.":MATCHED: {$po->strings[$string]}<BR>";
}
// finally we have a match!!!
return $po->strings[$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::raiseError('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);
}
}

View file

@ -0,0 +1,218 @@
<?php
/* vim: set expandtab tabstop=4 shiftwidth=4: */
// +----------------------------------------------------------------------+
// | PHP Version 4 |
// +----------------------------------------------------------------------+
// | Copyright (c) 1997-2003 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@akkbhome.com> |
// +----------------------------------------------------------------------+
//
// $Id: Flexy.php,v 1.15 2004/06/24 06:12:06 alan_k Exp $
//
// Handler code for the <flexy: namespace
//
/**
* the <flexy:XXXX namespace
*
*
* at present it handles
* <flexy:toJavascript flexy:prefix="Javascript_prefix" javscriptName="PHPvar" .....>
* <flexy:include src="xxx.htm">
*
*
*
* @version $Id: Flexy.php,v 1.15 2004/06/24 06:12:06 alan_k Exp $
*/
class HTML_Template_Flexy_Compiler_Standard_Flexy {
/**
* Parent Compiler for
*
* @var object HTML_Template_Flexy_Compiler
*
* @access public
*/
var $compiler;
/**
* The current element to parse..
*
* @var object
* @access public
*/
var $element;
/**
* toString - display tag, attributes, postfix and any code in attributes.
* Relays into namspace::method to get results..
*
*
* @see parent::toString()
*/
function toString($element)
{
list($namespace,$method) = explode(':',$element->oTag);
if (!strlen($method)) {
return '';
}
// things we dont handle...
if (!method_exists($this,$method.'ToString')) {
return '';
}
return $this->{$method.'ToString'}($element);
}
/**
* toJavascript handler
* <flexy:toJavascript flexy:prefix="some_prefix_" javascriptval="php.val" ....>
*
* @see parent::toString()
*/
function toJavascriptToString($element)
{
$ret = $this->compiler->appendPhp( "require_once 'HTML/Javascript/Convert.php';");
$ret .= $this->compiler->appendHTML("\n<script type='text/javascript'>\n");
$prefix = ''. $element->getAttribute('FLEXY:PREFIX');
foreach ($element->attributes as $k=>$v) {
// skip directives..
if (strpos($k,':')) {
continue;
}
if ($k == '/') {
continue;
}
$v = substr($v,1,-1);
$ret .= $this->compiler->appendPhp(
'$__tmp = HTML_Javascript_Convert::convertVar('.$element->toVar($v) .',\''.$prefix . $k.'\',true);'.
'echo (is_a($__tmp,"PEAR_Error")) ? ("<pre>".print_r($__tmp,true)."</pre>") : $__tmp;');
$ret .= $this->compiler->appendHTML("\n");
}
$ret .= $this->compiler->appendHTML("</script>");
return $ret;
}
/**
* include handler
* <flexy:include src="test.html">
*
* @see parent::toString()
*/
function includeToString($element)
{
// this is disabled by default...
// we ignore modifier pre/suffix
$arg = $element->getAttribute('SRC');
if (!$arg) {
return $this->compiler->appendHTML("<B>Flexy:Include without a src=filename</B>");
}
// ideally it would be nice to embed the results of one template into another.
// however that would involve some complex test which would have to stat
// the child templates anyway..
// compile the child template....
// output... include $this->options['compiled_templates'] . $arg . $this->options['locale'] . '.php'
return $this->compiler->appendPHP( "\n".
"\$x = new HTML_Template_Flexy(\$this->options);\n".
"\$x->compile('{$arg}');\n".
"\$x->outputObject(\$t);\n"
);
}
/**
* Convert flexy tokens to HTML_Template_Flexy_Elements.
*
* @param object token to convert into a element.
* @return object HTML_Template_Flexy_Element
* @access public
*/
function toElement($element)
{
return '';
}
/**
* Handler for User defined functions in templates..
* <flexy:function name="xxxxx">.... </flexy:block> // equivilant to function xxxxx() {
* <flexy:function call="{xxxxx}">.... </flexy:block> // equivilant to function {$xxxxx}() {
* <flexy:function call="xxxxx">.... </flexy:block> // equivilant to function {$xxxxx}() {
*
* This will not handle nested blocks initially!! (and may cause even more problems with
* if /foreach stuff..!!
*
* @param object token to convert into a element.
* @access public
*/
function functionToString($element)
{
if ($arg = $element->getAttribute('NAME')) {
// this is a really kludgy way of doing this!!!
// hopefully the new Template Package will have a sweeter method..
$GLOBALS['_HTML_TEMPLATE_FLEXY']['prefixOutput'] .=
$this->compiler->appendPHP(
"\nfunction _html_template_flexy_compiler_standard_flexy_{$arg}(\$t,\$this) {\n").
$element->compileChildren($this->compiler) .
$this->compiler->appendPHP( "\n}\n");
return '';
}
if (!isset($element->ucAttributes['CALL'])) {
return HTML_Template_Flexy::raiseError(
' tag flexy:function needs an argument call or name'.
" Error on Line {$element->line} &lt;{$element->tag}&gt;",
null, HTML_TEMPLATE_FLEXY_ERROR_DIE);
}
// call is a stirng : nice and simple..
if (is_string($element->ucAttributes['CALL'])) {
$arg = $element->getAttribute('CALL');
return $this->compiler->appendPHP(
"if (function_exists('_html_template_flexy_compiler_standard_flexy_'.{$arg})) " .
" _html_template_flexy_compiler_standard_flexy_{$arg}(\$t,\$this);");
}
// we make a big assumption here.. - it should really be error checked..
// that the {xxx} element is item 1 in the list...
$e=$element->ucAttributes['CALL'][1];
$add = $e->toVar($e->value);
if (is_a($add,'PEAR_Error')) {
return $add;
}
return $this->compiler->appendPHP(
"if (function_exists('_html_template_flexy_compiler_standard_flexy_'.{$add})) ".
"call_user_func_array('_html_template_flexy_compiler_standard_flexy_'.{$add},array(\$t,\$this));");
}
}

View file

@ -0,0 +1,893 @@
<?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> |
// +----------------------------------------------------------------------+
//
// $Id: Tag.php,v 1.50 2004/07/29 04:26:24 alan_k Exp $
/* FC/BC compatibility with php5 */
if ( (substr(phpversion(),0,1) < 5) && !function_exists('clone')) {
eval('function clone($t) { return $t; }');
}
/**
* Compiler That deals with standard HTML Tag output.
* Since it's pretty complex it has it's own class.
* I guess this class should deal with the main namespace
* and the parent (standard compiler can redirect other namespaces to other classes.
*
* one instance of these exists for each namespace.
*
*
* @version $Id: Tag.php,v 1.50 2004/07/29 04:26:24 alan_k Exp $
*/
class HTML_Template_Flexy_Compiler_Standard_Tag {
/**
* Parent Compiler for
*
* @var object HTML_Template_Flexy_Compiler
*
* @access public
*/
var $compiler;
/**
*
* Factory method to create Tag Handlers
*
* $type = namespace eg. <flexy:toJavascript loads Flexy.php
* the default is this... (eg. Tag)
*
*
* @param string Namespace handler for element.
* @param object HTML_Template_Flexy_Compiler
*
*
* @return object tag compiler
* @access public
*/
function &factory($type,&$compiler) {
if (!$type) {
$type = 'Tag';
}
// if we dont have a handler - just use the basic handler.
if (!file_exists(dirname(__FILE__) . '/'. ucfirst(strtolower($type)) . '.php')) {
$type = 'Tag';
}
include_once 'HTML/Template/Flexy/Compiler/Standard/' . ucfirst(strtolower($type)) . '.php';
$class = 'HTML_Template_Flexy_Compiler_Standard_' . $type;
if (!class_exists($class)) {
return false;
}
$ret = new $class;
$ret->compiler = &$compiler;
return $ret;
}
/**
* The current element to parse..
*
* @var object
* @access public
*/
var $element;
/**
* Flag to indicate has attribute flexy:foreach (so you cant mix it with flexy:if!)
*
* @var boolean
* @access public
*/
var $hasForeach = false;
/**
* toString - display tag, attributes, postfix and any code in attributes.
* Note first thing it does is call any parseTag Method that exists..
*
*
* @see parent::toString()
*/
function toString($element)
{
global $_HTML_TEMPLATE_FLEXY_TOKEN;
global $_HTML_TEMPLATE_FLEXY;
// store the element in a variable
$this->element = $element;
// echo "toString: Line {$this->element->line} &lt;{$this->element->tag}&gt;\n";
// if the FLEXYSTARTCHILDREN flag was set, only do children
// normally set in BODY tag.
// this will probably be superseeded by the Class compiler.
if (isset($element->ucAttributes['FLEXY:STARTCHILDREN'])) {
return $element->compileChildren($this->compiler);
}
$flexyignore = $this->parseAttributeIgnore();
// rewriting should be done with a tag.../flag.
$this->reWriteURL("HREF");
$this->reWriteURL("SRC");
// handle elements
if (($ret =$this->_parseTags()) !== false) {
return $ret;
}
// these add to the close tag..
$ret = $this->parseAttributeForeach();
$ret .= $this->parseAttributeIf();
// spit ou the tag and attributes.
if ($element->oTag{0} == '?') {
$ret .= '<?php echo "<"; ?>';
} else {
$ret .= "<";
}
$ret .= $element->oTag;
foreach ($element->attributes as $k=>$v) {
// if it's a flexy tag ignore it.
if (strtoupper($k) == 'FLEXY:RAW') {
if (!is_array($v) || !isset($v[1]) || !is_object($v[1])) {
return HTML_Template_Flexy::raiseError(
'flexy:raw only accepts a variable or method call as an argument, eg.'.
' flexy:raw="{somevalue}" you provided something else.' .
" Error on Line {$this->element->line} &lt;{$this->element->tag}&gt;",
null, HTML_TEMPLATE_FLEXY_ERROR_DIE);
}
$add = $v[1]->compile($this->compiler);
if (is_a($add,'PEAR_Error')) {
return $add;
}
$ret .= ' ' . $add;
continue;
}
if (strtoupper(substr($k,0,6)) == 'FLEXY:') {
continue;
}
// true == an attribute without a ="xxx"
if ($v === true) {
$ret .= " $k";
continue;
}
// if it's a string just dump it.
if (is_string($v)) {
$ret .= " {$k}={$v}";
continue;
}
// normally the value is an array of string, however
// if it is an object - then it's a conditional key.
// eg. if (something) echo ' SELECTED';
// the object is responsible for adding it's space..
if (is_object($v)) {
$add = $v->compile($this->compiler);
if (is_a($add,'PEAR_Error')) {
return $add;
}
$ret .= $add;
continue;
}
// otherwise its a key="sometext{andsomevars}"
$ret .= " {$k}=";
foreach($v as $item) {
if (is_string($item)) {
$ret .= $item;
continue;
}
$add = $item->compile($this->compiler);
if (is_a($add,'PEAR_Error')) {
return $add;
}
$ret .= $add;
}
}
$ret .= ">";
// post stuff this is probably in the wrong place...
if ($element->postfix) {
foreach ($element->postfix as $e) {
$add = $e->compile($this->compiler);
if (is_a($add,'PEAR_Error')) {
return $add;
}
$ret .= $add;
}
} else if ($this->element->postfix) { // if postfixed by self..
foreach ($this->element->postfix as $e) {
$add = $e->compile($this->compiler);
if (is_a($add,'PEAR_Error')) {
return $add;
}
$ret .= $add;
}
}
// dump contents of script raw - to prevent gettext additions..
// print_r($element);
if ($element->tag == 'SCRIPT') {
foreach($element->children as $c) {
//print_R($c);
if (!$c) {
continue;
}
if ($c->token == 'Text') {
$ret .= $c->value;
continue;
}
// techically we shouldnt have anything else inside of script tags.
// as the tokeinzer is supposted to ignore it..
}
} else {
$add = $element->compileChildren($this->compiler);
if (is_a($add,'PEAR_Error')) {
return $add;
}
$ret .= $add;
}
// output the closing tag.
if ($element->close) {
$add = $element->close->compile($this->compiler);
if (is_a($add,'PEAR_Error')) {
return $add;
}
$ret .= $add;
}
// reset flexyignore
$_HTML_TEMPLATE_FLEXY_TOKEN['flexyIgnore'] = $flexyignore;
if (isset($_HTML_TEMPLATE_FLEXY['currentOptions']['output.block']) &&
($_HTML_TEMPLATE_FLEXY['currentOptions']['output.block'] == $element->getAttribute('ID'))) {
// echo $_HTML_TEMPLATE_FLEXY['compiledTemplate'];
$fh = fopen($_HTML_TEMPLATE_FLEXY['compiledTemplate'],'w');
fwrite($fh,$ret);
fclose($fh);
}
return $ret;
}
/**
* Reads an flexy:foreach attribute -
*
*
* @return string to add to output.
* @access public
*/
function parseAttributeIgnore()
{
global $_HTML_TEMPLATE_FLEXY_TOKEN;
$flexyignore = $_HTML_TEMPLATE_FLEXY_TOKEN['flexyIgnore'];
if ($this->element->getAttribute('FLEXY:IGNORE') !== false) {
$_HTML_TEMPLATE_FLEXY_TOKEN['flexyIgnore'] = true;
$this->element->clearAttribute('FLEXY:IGNORE');
}
return $flexyignore;
}
/**
* Reads an flexy:foreach attribute -
*
*
* @return string to add to output.
* @access public
*/
function parseAttributeForeach()
{
$foreach = $this->element->getAttribute('FLEXY:FOREACH');
if ($foreach === false) {
return '';
}
//var_dump($foreach);
$this->element->hasForeach = true;
// create a foreach element to wrap this with.
$foreachObj = $this->element->factory('Foreach',
explode(',',$foreach),
$this->element->line);
// failed = probably not enough variables..
if ($foreachObj === false) {
return HTML_Template_Flexy::raiseError(
"Missing Arguments: An flexy:foreach attribute was foundon Line {$this->element->line}
in tag &lt;{$this->element->tag} flexy:foreach=&quot;$foreach&quot; .....&gt;<BR>
the syntax is &lt;sometag flexy:foreach=&quot;onarray,withvariable[,withanothervar] &gt;<BR>",
null, HTML_TEMPLATE_FLEXY_ERROR_DIE);
}
// does it have a closetag?
if (!$this->element->close) {
if ($this->element->getAttribute('/') === false) {
return HTML_Template_Flexy::raiseError(
"A flexy:foreach attribute was found in &lt;{$this->element->name} tag without a corresponding &lt;/{$this->element->tag}
tag on Line {$this->element->line} &lt;{$this->element->tag}&gt;",
null, HTML_TEMPLATE_FLEXY_ERROR_DIE);
}
// it's an xhtml tag!
$this->element->postfix = array($this->element->factory("End", '', $this->element->line));
} else {
$this->element->close->postfix = array($this->element->factory("End", '', $this->element->line));
}
$this->element->clearAttribute('FLEXY:FOREACH');
return $foreachObj->compile($this->compiler);
}
/**
* Reads an flexy:if attribute -
*
*
* @return string to add to output.
* @access public
*/
function parseAttributeIf()
{
// dont use the together, if is depreciated..
$if = $this->element->getAttribute('FLEXY:IF');
if ($if === false) {
return '';
}
if (isset($this->element->hasForeach)) {
return HTML_Template_Flexy::raiseError(
"You may not use FOREACH and IF tags in the same tag on Line {$this->element->line} &lt;{$this->element->tag}&gt;",
null, HTML_TEMPLATE_FLEXY_ERROR_DIE);
}
// allow if="!somevar"
$ifnegative = '';
if ($if{0} == '!') {
$ifnegative = '!';
$if = substr($if,1);
}
// if="xxxxx"
// if="xxxx.xxxx()" - should create a method prefixed with 'if:'
// these checks should really be in the if/method class..!!!
if (!preg_match('/^[_A-Z][A-Z0-9_]*(\[[0-9]+\])?((\[|%5B)[A-Z0-9_]+(\]|%5D))*'.
'(\.[_A-Z][A-Z0-9_]*((\[|%5B)[A-Z0-9_]+(\]|%5D))*)*(\\([^)]*\))?$/i',$if)) {
return HTML_Template_Flexy::raiseError(
"IF tags only accept simple object.variable or object.method() values on
Line {$this->element->line} &lt;{$this->element->tag}&gt;
{$if}",
null, HTML_TEMPLATE_FLEXY_ERROR_DIE);
}
if (substr($if,-1) == ')') {
// grab args..
$args = substr($if,strpos($if,'(')+1,-1);
// simple explode ...
$args = strlen(trim($args)) ? explode(',',$args) : array();
//print_R($args);
// this is nasty... - we need to check for quotes = eg. # at beg. & end..
$args_clean = array();
for ($i=0; $i<count($args); $i++) {
if ($args[$i]{0} != '#') {
$args_clean[] = $args[$i];
continue;
}
// single # - so , must be inside..
if ((strlen($args[$i]) > 1) && ($args[$i]{strlen($args[$i])-1}=='#')) {
$args_clean[] = $args[$i];
continue;
}
$args[$i] .=',' . $args[$i+1];
// remove args+1..
array_splice($args,$i+1,1);
$i--;
// reparse..
}
$ifObj = $this->element->factory('Method',
array('if:'.$ifnegative.substr($if,0,strpos($if,'(')), $args_clean),
$this->element->line);
} else {
$ifObj = $this->element->factory('If', $ifnegative.$if, $this->element->line);
}
// does it have a closetag? - you must have one - so you will have to hack in <span flexy:if=..><img></span> on tags
// that do not have close tags - it's done this way to try and avoid mistakes.
if (!$this->element->close) {
//echo "<PRE>";print_R($this->element);
if ($this->element->getAttribute('/') !== false) {
$this->element->postfix = array($this->element->factory("End",'', $this->element->line));
} else {
return HTML_Template_Flexy::raiseError(
"An flexy:if attribute was found in &lt;{$this->element->name} tag without a corresponding &lt;/{$this->element->name}
tag on Line {$this->element->line} &lt;{$this->element->tag}&gt;",
null, HTML_TEMPLATE_FLEXY_ERROR_DIE);
}
} else {
$this->element->close->postfix = array($this->element->factory("End",'', $this->element->line));
}
$this->element->clearAttribute('FLEXY:IF');
return $ifObj->compile($this->compiler);
}
/**
* Reads Tags - and relays to parseTagXXXXXXX
*
*
* @return string | false = html output or ignore (just output the tag)
* @access private
*/
function _parseTags()
{
global $_HTML_TEMPLATE_FLEXY_TOKEN;
// doesnt really need strtolower etc. as php functions are not case sensitive!
if ($this->element->getAttribute('FLEXY:DYNAMIC')) {
return $this->compiler->appendPhp(
$this->getElementPhp( $this->element->getAttribute('ID') )
);
}
if ($this->element->getAttribute('FLEXY:IGNOREONLY') !== false) {
return false;
}
if ($_HTML_TEMPLATE_FLEXY_TOKEN['flexyIgnore']) {
return false;
}
$tag = $this->element->tag;
if (strpos($tag,':') !== false) {
$bits = explode(':',$tag);
$tag = $bits[1];
}
$method = 'parseTag'.$tag;
if (!method_exists($this,$method)) {
return false;
}
// do any of the attributes use flexy data...
foreach ($this->element->attributes as $k=>$v) {
if (is_array($v)) {
return false;
}
}
//echo "call $method" . serialize($this->element->attributes). "\n";
return $this->$method();
// allow the parse methods to return output.
}
/**
* produces the code for dynamic elements
*
* @return string | false = html output or ignore (just output the tag)
* @access public
*/
function getElementPhp($id,$mergeWithName=false) {
global $_HTML_TEMPLATE_FLEXY;
static $tmpId=0;
if (!$id) {
return HTML_Template_Flexy::raiseError(
"Error:{$_HTML_TEMPLATE_FLEXY['filename']} on Line {$this->element->line} &lt;{$this->element->tag}&gt;: " .
" Dynamic tags require an ID value",
null, HTML_TEMPLATE_FLEXY_ERROR_DIE);
}
// dont mix and match..
if (($this->element->getAttribute('FLEXY:IF') !== false) ||
($this->element->getAttribute('FLEXY:FOREACH') !== false) )
{
return HTML_Template_Flexy::raiseError(
"Error:{$_HTML_TEMPLATE_FLEXY['filename']} on Line {$this->element->line} &lt;{$this->element->tag}&gt;: " .
" You can not mix flexy:if= or flexy:foreach= with dynamic form elements " .
" (turn off tag to element code with flexyIgnore=0, use flexy:ignore=&quot;yes&quot; in the tag" .
" or put the conditional outside in a span tag",
null, HTML_TEMPLATE_FLEXY_ERROR_DIE);
}
if ((strtolower($this->element->getAttribute('type')) == 'checkbox' ) &&
(substr($this->element->getAttribute('name'),-2) == '[]')) {
if ($this->element->getAttribute('id') === false) {
$id = 'tmpId'. (++$tmpId);
$this->element->attributes['id'] = $id;
$this->element->ucAttributes['ID'] = $id;
}
$mergeWithName = true;
}
if (isset($_HTML_TEMPLATE_FLEXY['elements'][$id])) {
// echo "<PRE>";print_r($this);print_r($_HTML_TEMPLATE_FLEXY['elements']);echo "</PRE>";
return HTML_Template_Flexy::raiseError(
"Error:{$_HTML_TEMPLATE_FLEXY['filename']} on Line {$this->element->line} in Tag &lt;{$this->element->tag}&gt;:<BR> " .
"The Dynamic tag Name '$id' has already been used previously by tag &lt;{$_HTML_TEMPLATE_FLEXY['elements'][$id]->tag}&gt;",
null,HTML_TEMPLATE_FLEXY_ERROR_DIE);
}
// this is for a case where you can use a sprintf as the name, and overlay it with a variable element..
$_HTML_TEMPLATE_FLEXY['elements'][$id] = $this->toElement($this->element);
if ($var = $this->element->getAttribute('FLEXY:NAMEUSES')) {
$var = 'sprintf(\''.$id .'\','.$this->element->toVar($var) .')';
return
'if (!isset($this->elements['.$var.'])) $this->elements['.$var.']= $this->elements[\''.$id.'\'];
$this->elements['.$var.'] = $this->mergeElement($this->elements[\''.$id.'\'],$this->elements['.$var.']);
$this->elements['.$var.']->attributes[\'name\'] = '.$var. ';
echo $this->elements['.$var.']->toHtml();';
} elseif ($mergeWithName) {
$name = $this->element->getAttribute('NAME');
return
'$element = $this->elements[\''.$id.'\'];
$element = $this->mergeElement($element,$this->elements[\''.$name.'\']);
echo $element->toHtml();';
} else {
return 'echo $this->elements[\''.$id.'\']->toHtml();';
}
}
/**
* Reads an Script tag - check if PHP is allowed.
*
* @return false|PEAR_Error
* @access public
*/
function parseTagScript() {
$lang = $this->element->getAttribute('LANGUAGE');
if (!$lang) {
return false;
}
$lang = strtoupper($lang);
if ($GLOBALS['_HTML_TEMPLATE_FLEXY']['currentOptions']['allowPHP']) {
return false;
}
if ($lang == "PHP") {
return HTML_Template_Flexy::raiseError('PHP code found in script',
HTML_TEMPLATE_FLEXY_ERROR_SYNTAX,HTML_TEMPLATE_FLEXY_ERROR_RETURN
);
}
return false;
}
/**
* Reads an Input tag - build a element object for it
*
*
* @return string | false = html output or ignore (just output the tag)
* @access public
*/
function parseTagInput()
{
global $_HTML_TEMPLATE_FLEXY;
if (in_array(strtoupper($this->element->getAttribute('TYPE')), array('SUBMIT','BUTTON','INPUT',''))) {
$this->compiler->addStringToGettext($this->element->getAttribute('VALUE'));
}
// form elements : format:
//value - fill out as PHP CODE
// as a general rule, this uses name, rather than ID except on
// radio
$mergeWithName = false;
$id = $this->element->getAttribute('NAME');
// checkboxes need more work.. - at the momemnt assume one with the same value...
if (in_array(strtoupper($this->element->getAttribute('TYPE')), array('RADIO'))) {
if (!isset($_HTML_TEMPLATE_FLEXY['elements'][$id])) {
// register it.. - so we dont overwrite it...
$_HTML_TEMPLATE_FLEXY['elements'][$id] = false;
} else if ($_HTML_TEMPLATE_FLEXY['elements'][$id] != false) {
return HTML_Template_Flexy::raiseError(
"Error:{$_HTML_TEMPLATE_FLEXY['filename']} on Line {$this->element->line} ".
"in Tag &lt;{$this->element->tag}&gt;:<BR>".
"The Dynamic tag Name '$id' has already been used previously by ".
"tag &lt;{$_HTML_TEMPLATE_FLEXY['elements'][$id]->tag}&gt;",
null, HTML_TEMPLATE_FLEXY_ERROR_DIE
);
}
$id = $this->element->getAttribute('ID');
if (!$id) {
return HTML_Template_Flexy::raiseError("Error in {$_HTML_TEMPLATE_FLEXY['filename']} on Line {$this->element->line} &lt;{$this->element->tag}&gt:
Radio Input's require an ID tag..",
null, HTML_TEMPLATE_FLEXY_ERROR_DIE);
}
$mergeWithName = true;
}
if (!$id) {
return false;
}
return $this->compiler->appendPhp($this->getElementPhp( $id,$mergeWithName));
}
/**
* Deal with a TextArea tag - build a element object for it
*
* @return string | false = html output or ignore (just output the tag)
* @access public
*/
function parseTagTextArea()
{
return $this->compiler->appendPhp(
$this->getElementPhp( $this->element->getAttribute('NAME')));
}
/**
* Deal with Selects - build a element object for it (unless flexyignore is set)
*
*
* @return string | false = html output or ignore (just output the tag)
* @access public
*/
function parseTagSelect()
{
return $this->compiler->appendPhp(
$this->getElementPhp( $this->element->getAttribute('NAME')));
}
/**
* Reads an Form tag - and set up the element object header etc.
*
* @return string | false = html output or ignore (just output the tag)
* @access public
*/
function parseTagForm()
{
global $_HTML_TEMPLATE_FLEXY;
$copy = clone($this->element);
$copy->children = array();
$id = $this->element->getAttribute('NAME');
if (!$id) {
$id = 'form';
}
// this adds the element to the elements array.
$old = clone($this->element);
$this->element = $copy;
$this->getElementPhp($id);
$this->element= $old;
return
$this->compiler->appendPhp('echo $this->elements[\''.$id.'\']->toHtmlnoClose();') .
$this->element->compileChildren($this->compiler) .
$this->compiler->appendHtml( "</{$copy->oTag}>");
}
/**
* reWriteURL - can using the config option 'url_rewrite'
* format "from:to,from:to"
* only handle left rewrite.
* so
* "/images:/myroot/images"
* would change
* /images/xyz.gif to /myroot/images/xyz.gif
* /images/stylesheet/imagestyles.css to /myroot/images/stylesheet/imagestyles.css
* note /imagestyles did not get altered.
* will only work on strings (forget about doing /images/{someimage}
*
*
* @param string attribute to rewrite
* @return none
* @access public
*/
function reWriteURL($which)
{
global $_HTML_TEMPLATE_FLEXY;
if (!is_string($original = $this->element->getAttribute($which))) {
return;
}
if ($original == '') {
return;
}
if (empty($_HTML_TEMPLATE_FLEXY['currentOptions']['url_rewrite'])) {
return;
}
$bits = explode(",",$_HTML_TEMPLATE_FLEXY['currentOptions']['url_rewrite']);
$new = $original;
foreach ($bits as $bit) {
if (!strlen(trim($bit))) {
continue;
}
$parts = explode (':', $bit);
if (!isset($parts[1])) {
return HTML_Template_Flexy::raiseError('HTML_Template_Flexy: url_rewrite syntax incorrect'.
print_r(array($bits,$bits),true),null,HTML_TEMPLATE_FLEXY_ERROR_DIE);
}
$new = preg_replace('#^'.$parts[0].'#',$parts[1], $new);
}
if ($original == $new) {
return;
}
$this->element->ucAttributes[$which] = '"'. $new . '"';
}
/**
* Convert flexy tokens to HTML_Template_Flexy_Elements.
*
* @param object token to convert into a element.
* @return object HTML_Template_Flexy_Element
* @access public
*/
function toElement($element) {
require_once 'HTML/Template/Flexy/Element.php';
$ret = new HTML_Template_Flexy_Element;
if (strtolower(get_class($element)) != 'html_template_flexy_token_tag') {
$this->compiler->addStringToGettext($element->value);
return $element->value;
}
$ret->tag = strtolower($element->tag);
$ats = $element->getAttributes();
if (isset($element->attributes['flexy:xhtml'])) {
$ats['flexy:xhtml'] = true;
}
foreach(array_keys($ats) as $a) {
$ret->attributes[$a] = $this->unHtmlEntities($ats[$a]);
}
//print_r($ats);
if (!$element->children) {
return $ret;
}
// children - normally to deal with <element>
//print_r($this->children);
foreach(array_keys($element->children) as $i) {
// not quite sure why this happens - but it does.
if (!is_object($element->children[$i])) {
continue;
}
$ret->children[] = $this->toElement($element->children[$i]);
}
return $ret;
}
/**
* do the reverse of htmlspecialchars on an attribute..
*
* copied from get-html-translation-table man page
*
* @param mixed from attribute values
*
* @return string return
* @access public
* @see see also methods.....
*/
function unHtmlEntities ($in)
{
if (!is_string($in)) {
return $in;
}
$trans_tbl = get_html_translation_table (HTML_ENTITIES);
$trans_tbl = array_flip ($trans_tbl);
$ret = strtr ($in, $trans_tbl);
return preg_replace('/&#(\d+);/me', "chr('\\1')",$ret);
}
}

Some files were not shown because too many files have changed in this diff Show more