Initial addition of the savant2 template engine and the egw-wrapper class.tplsavant2.inc.php Enjoy ;)

This commit is contained in:
Pim Snel 2005-05-26 19:38:09 +00:00
parent 266949f632
commit d9ec1f87e2
57 changed files with 8143 additions and 0 deletions

View File

@ -0,0 +1,201 @@
<?php
/**************************************************************************\
* eGroupWare API - Wrapper for the savant2 template engine *
* Written by Pim Snel <pim@lingewoud.nl> *
* *
* Wrapper for the savant2 template engine www.phpsavant.com *
* Copyright (C) 2005 Lingewoud BV and Pim Snel *
* -------------------------------------------------------------------------*
* This library is part of the eGroupWare API *
* http://www.egroupware.org *
* ------------------------------------------------------------------------ *
* This library is free software; you can redistribute it and/or modify it *
* under the terms of the GNU Lesser General Public License as published by *
* the Free Software Foundation; either version 2.1 of the License, *
* or any later version. *
* This library is distributed in the hope that it will be useful, but *
* WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. *
* See the GNU Lesser General Public License for more details. *
* You should have received a copy of the GNU Lesser General Public License *
* along with this library; if not, write to the Free Software Foundation, *
* Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA *
\**************************************************************************/
/* $Id$ */
if(is_file(EGW_INCLUDE_ROOT.'/phpgwapi/inc/savant2/Savant2.php'))
{
include_once(EGW_INCLUDE_ROOT.'/phpgwapi/inc/savant2/Savant2.php');
}
/*!
@class tplsavant2
@abstract wrapper class for the Savant2 template engine
*/
class tplsavant2 extends Savant2
{
/*!
@var $version
@abstract the version this wrapper is testet against
*/
var $version = '2.3.3';
/*!
@var $do_version_check
@abstract set this to true to halt when versions of this wrapper and savant2 itself differ
*/
var $do_version_check = false;
/*!
@function tplsavant2
@abstract constructor function which calls the constructor of Savant2 and sets necesary things for eGroupware
*/
function tplsavant2()
{
// run constructor of the Savant2 class
$this->Savant2();
if($this->do_version_check)
{
$this->version_check();
}
$this->set_tpl_path();
}
/**
@function version_check
@abstract check version of this wrapper with installed savant2 version and halts when version differs
@return void
*/
function version_check()
{
$Sav2Version = @file_get_contents(EGW_INCLUDE_ROOT.'/phpgwapi/inc/savant2/VERSION',"rb");
if(trim($Sav2Version) != trim($this->version))
{
$this->halt(lang('Savant2 version differs from Savant2 wrapper. <br/>This version: %1 <br/>Savants version: %2',$this->version, $Sav2Version));
}
}
/*!
@function set_tpl_path
@abstract sets the preferred and fallback template search paths
@return void
*/
function set_tpl_path()
{
$preferred_dir=$this->get_tpl_dir();
$fallback_dir=$this->get_tpl_dir(true);
if(!$preferred_dir && $fallback_dir)
{
$this->halt(lang('No Savant2 template directories were found in:'.EGW_APP_ROOT));
}
else
{
if($fallback_dir)
{
$this->addPath('template',$fallback_dir);
}
// add preferred tpl dir last because savant set the last added first in the search array
if($preferred_dir)
{
$this->addPath('template',$preferred_dir);
}
}
}
/*!
@function get_tpl_dir
@abstract get template dir of an application
@param $fallback if true the default fallback template dir is returned
@param $appname appication name optional can be derived from $GLOBALS['egw_info']['flags']['currentapp'];
*/
function get_tpl_dir($fallback=false,$appname = '')
{
if (! $appname)
{
$appname = $GLOBALS['egw_info']['flags']['currentapp'];
}
if ($appname == 'home' || $appname == 'logout' || $appname == 'login')
{
$appname = 'phpgwapi';
}
if (!isset($GLOBALS['egw_info']['server']['template_set']) && isset($GLOBALS['egw_info']['user']['preferences']['common']['template_set']))
{
$GLOBALS['egw_info']['server']['template_set'] = $GLOBALS['egw_info']['user']['preferences']['common']['template_set'];
}
// Setting this for display of template choices in user preferences
if ($GLOBALS['egw_info']['server']['template_set'] == 'user_choice')
{
$GLOBALS['egw_info']['server']['usrtplchoice'] = 'user_choice';
}
if (($GLOBALS['egw_info']['server']['template_set'] == 'user_choice' ||
!isset($GLOBALS['egw_info']['server']['template_set'])) &&
isset($GLOBALS['egw_info']['user']['preferences']['common']['template_set']))
{
$GLOBALS['egw_info']['server']['template_set'] = $GLOBALS['egw_info']['user']['preferences']['common']['template_set'];
}
elseif ($GLOBALS['egw_info']['server']['template_set'] == 'user_choice' ||
!isset($GLOBALS['egw_info']['server']['template_set']))
{
$GLOBALS['egw_info']['server']['template_set'] = 'default';
}
$tpldir = EGW_SERVER_ROOT . '/' . $appname . '/templatesSavant2/' . $GLOBALS['egw_info']['server']['template_set'];
$tpldir_default = EGW_SERVER_ROOT . '/' . $appname . '/templatesSavant2/default';
if (!$fallback && @is_dir($tpldir))
{
return $tpldir;
}
elseif (@is_dir($tpldir_default))
{
return $tpldir_default;
}
else
{
return False;
}
}
/***************************************************************************/
/* public: halt(string $msg)
* msg: error message to show.
*/
function halt($msg)
{
$this->last_error = $msg;
if ($this->halt_on_error != 'no')
{
$this->haltmsg($msg);
}
if ($this->halt_on_error == 'yes')
{
echo('<strong>Halted.</strong>');
}
$GLOBALS['phpgw']->common->phpgw_exit(True);
}
/* public, override: haltmsg($msg)
* msg: error message to show.
*/
function haltmsg($msg)
{
printf("<strong>Savant Template Error:</strong> %s<br/>\n", $msg);
echo "<strong>Backtrace</strong>: ".function_backtrace(2)."<br/>\n";
}
}

1488
phpgwapi/inc/savant2/Savant2.php Executable file

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,72 @@
<?php
/**
*
* Abstract Savant2_Compiler class.
*
* You have to extend this class for it to be useful; e.g., "class
* Savant2_Plugin_example extends Savant2_Plugin".
*
* $Id$
*
* @author Paul M. Jones <pmjones@ciaweb.net>
*
* @package Savant2
*
* @license http://www.gnu.org/copyleft/lesser.html LGPL
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as
* published by the Free Software Foundation; either version 2.1 of the
* License, or (at your option) any later version.
*
* This 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
* Lesser General Public License for more details.
*
*/
class Savant2_Compiler {
/**
*
* Reference to the "parent" Savant object.
*
*/
var $Savant = null;
/**
*
* Constructor.
*
* @access public
*
*/
function Savant2_Compiler($conf = array())
{
settype($conf, 'array');
foreach ($conf as $key => $val) {
$this->$key = $val;
}
}
/**
*
* Stub method for extended behaviors.
*
* @access public
*
* @return void
*
*/
function compile($tpl)
{
}
}
?>

View File

@ -0,0 +1,125 @@
<?php
/**
*
* Provides a simple error class for Savant.
*
* $Id$
*
* @author Paul M. Jones <pmjones@ciaweb.net>
*
* @package Savant2
*
* @license http://www.gnu.org/copyleft/lesser.html LGPL
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as
* published by the Free Software Foundation; either version 2.1 of the
* License, or (at your option) any later version.
*
* This 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
* Lesser General Public License for more details.
*
*/
class Savant2_Error {
/**
*
* The error code, typically a SAVANT_ERROR_* constant.
*
* @access public
*
* @var int
*
*/
var $code = null;
/**
*
* An array of error-specific information.
*
* @access public
*
* @var array
*
*/
var $info = array();
/**
*
* The error message text.
*
* @access public
*
* @var string
*
*/
var $text = null;
/**
*
* A debug backtrace for the error, if any.
*
* @access public
*
* @var array
*
*/
var $backtrace = null;
/**
*
* Constructor.
*
* @access public
*
* @param array $conf An associative array where the key is a
* Savant2_Error property and the value is the value for that
* property.
*
*/
function Savant2_Error($conf = array())
{
// set public properties
foreach ($conf as $key => $val) {
$this->$key = $val;
}
// generate a backtrace
if (function_exists('debug_backtrace')) {
$this->backtrace = debug_backtrace();
}
// extended behaviors
$this->error();
}
/**
*
* Stub method for extended behaviors.
*
* @access public
*
* @return void
*
*/
function error()
{
}
}
?>

View File

@ -0,0 +1,76 @@
<?php
/**
*
* Abstract Savant2_Filter class.
*
* You have to extend this class for it to be useful; e.g., "class
* Savant2_Filter_example extends Savant2_Filter".
*
* $Id$
*
* @author Paul M. Jones <pmjones@ciaweb.net>
*
* @package Savant2
*
* @license http://www.gnu.org/copyleft/lesser.html LGPL
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as
* published by the Free Software Foundation; either version 2.1 of the
* License, or (at your option) any later version.
*
* This 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
* Lesser General Public License for more details.
*
*/
class Savant2_Filter {
/**
*
* Optional reference to the calling Savant object.
*
* @var object
*
*/
var $Savant = null;
/**
*
* Constructor.
*
* @access public
*
*/
function Savant2_Filter($conf = array())
{
settype($conf, 'array');
foreach ($conf as $key => $val) {
$this->$key = $val;
}
}
/**
*
* Stub method for extended behaviors.
*
* @access public
*
* @param string &$text The text to filter.
*
* @return void
*
*/
function filter(&$text)
{
}
}
?>

View File

@ -0,0 +1,471 @@
<?php
/**
* A class for performing code analysis for php scripts
* It is designed to be the heart of a code limiting script
* to use with Savant {@link http://phpsavant.com}
*
* This code should be php4 compatiable but i've only run it in php5 and some of the Tokenizer constants have changed
*
* @author Joshua Eichorn <josh@bluga.net>
* @copyright Joshua Eichorn 2004
* @package PHPCodeAnalyzer
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as
* published by the Free Software Foundation; either version 2.1 of the
* License, or (at your option) any later version.
*
* This 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
* Lesser General Public License for more details.
*
* @license http://www.gnu.org/copyleft/lesser.html LGPL
*/
/**#@+
* compat tokeniezer defines
*/
if (! defined('T_OLD_FUNCTION')) {
define('T_OLD_FUNCTION', T_FUNCTION);
}
if (!defined('T_ML_COMMENT')) {
define('T_ML_COMMENT', T_COMMENT);
} else {
define('T_DOC_COMMENT', T_ML_COMMENT);
}
/**#@-*/
/**
* Code Analysis class
*
* Example Usage:
* <code>
* $analyzer = new PHPCodeAnalyzer();
* $analyzer->source = file_get_contents(__FILE__);
* $analyzer->analyze();
* print_r($analyzer->calledMethods);
* </code>
*
* @todo is it important to grab the details from creating new functions defines classes?
* @todo support php5 only stuff like interface
*
* @version 0.4
* @license http://www.gnu.org/copyleft/lesser.html LGPL
* @copyright Joshua Eichorn 2004
* @package PHPCodeAnalyzer
* @author Joshua Eichorn <josh@bluga.net>
*/
class PHPCodeAnalyzer
{
/**
* Source code to analyze
*/
var $source = "";
/**
* functions called
*/
var $calledFunctions = array();
/**
* Called constructs
*/
var $calledConstructs = array();
/**
* methods called
*/
var $calledMethods = array();
/**
* static methods called
*/
var $calledStaticMethods = array();
/**
* new classes instantiated
*/
var $classesInstantiated = array();
/**
* variables used
*/
var $usedVariables = array();
/**
* member variables used
*/
var $usedMemberVariables = array();
/**
* classes created
*/
var $createdClasses = array();
/**
* functions created
*/
var $createdFunctions = array();
/**
* Files includes or requried
*/
var $filesIncluded = array();
// private variables
/**#@+
* @access private
*/
var $currentString = null;
var $currentStrings = null;
var $currentVar = false;
var $staticClass = false;
var $inNew = false;
var $inInclude = false;
var $lineNumber = 1;
/**#@-*/
/**
* parse source filling informational arrays
*/
function analyze()
{
$tokens = token_get_all($this->source);
// mapping of token to method to call
$handleMap = array(
T_STRING => 'handleString',
T_CONSTANT_ENCAPSED_STRING => 'handleString',
T_ENCAPSED_AND_WHITESPACE => 'handleString',
T_CHARACTER => 'handleString',
T_NUM_STRING => 'handleString',
T_DNUMBER => 'handleString',
T_FUNC_C => 'handleString',
T_CLASS_C => 'handleString',
T_FILE => 'handleString',
T_LINE => 'handleString',
T_DOUBLE_ARROW => 'handleString',
T_DOUBLE_COLON => 'handleDoubleColon',
T_NEW => 'handleNew',
T_OBJECT_OPERATOR => 'handleObjectOperator',
T_VARIABLE => 'handleVariable',
T_FUNCTION => 'handleFunction',
T_OLD_FUNCTION => 'handleFunction',
T_CLASS => 'handleClass',
T_WHITESPACE => 'handleWhitespace',
T_INLINE_HTML => 'handleWhitespace',
T_OPEN_TAG => 'handleWhitespace',
T_CLOSE_TAG => 'handleWhitespace',
T_AS => 'handleAs',
T_ECHO => 'handleConstruct',
T_EVAL => 'handleConstruct',
T_UNSET => 'handleConstruct',
T_ISSET => 'handleConstruct',
T_PRINT => 'handleConstruct',
T_FOR => 'handleConstruct',
T_FOREACH=> 'handleConstruct',
T_EMPTY => 'handleConstruct',
T_EXIT => 'handleConstruct',
T_CASE => 'handleConstruct',
T_GLOBAL=> 'handleConstruct',
T_UNSET => 'handleConstruct',
T_WHILE => 'handleConstruct',
T_DO => 'handleConstruct',
T_IF => 'handleConstruct',
T_LIST => 'handleConstruct',
T_RETURN=> 'handleConstruct',
T_STATIC=> 'handleConstruct',
T_ENDFOR=> 'handleConstruct',
T_ENDFOREACH=> 'handleConstruct',
T_ENDIF=> 'handleConstruct',
T_ENDSWITCH=> 'handleConstruct',
T_ENDWHILE=> 'handleConstruct',
T_INCLUDE => 'handleInclude',
T_INCLUDE_ONCE => 'handleInclude',
T_REQUIRE => 'handleInclude',
T_REQUIRE_ONCE => 'handleInclude',
);
foreach($tokens as $token)
{
if (is_string($token))
{
// we have a simple 1-character token
$this->handleSimpleToken($token);
}
else
{
list($id, $text) = $token;
if (isseT($handleMap[$id]))
{
$call = $handleMap[$id];
$this->$call($id,$text);
}
/*else
{
echo token_name($id).": $text<br>\n";
}*/
}
}
}
/**
* Handle a 1 char token
* @access private
*/
function handleSimpleToken($token)
{
if ($token !== ";")
{
$this->currentStrings .= $token;
}
switch($token)
{
case "(":
// method is called
if ($this->staticClass !== false)
{
if (!isset($this->calledStaticMethods[$this->staticClass][$this->currentString]))
{
$this->calledStaticMethods[$this->staticClass][$this->currentString]
= array();
}
$this->calledStaticMethods[$this->staticClass][$this->currentString][]
= $this->lineNumber;
$this->staticClass = false;
}
else if ($this->currentVar !== false)
{
if (!isset($this->calledMethods[$this->currentVar][$this->currentString]))
{
$this->calledMethods[$this->currentVar][$this->currentString] = array();
}
$this->calledMethods[$this->currentVar][$this->currentString][] = $this->lineNumber;
$this->currentVar = false;
}
else if ($this->inNew !== false)
{
$this->classInstantiated();
}
else if ($this->currentString !== null)
{
$this->functionCalled();
}
//$this->currentString = null;
break;
case "=":
case ";":
if ($this->inNew !== false)
{
$this->classInstantiated();
}
else if ($this->inInclude !== false)
{
$this->fileIncluded();
}
else if ($this->currentVar !== false)
{
$this->useMemberVar();
}
$this->currentString = null;
$this->currentStrings = null;
break;
}
}
/**
* handle includes and requires
* @access private
*/
function handleInclude($id,$text)
{
$this->inInclude = true;
$this->handleConstruct($id,$text);
}
/**
* handle String tokens
* @access private
*/
function handleString($id,$text)
{
$this->currentString = $text;
$this->currentStrings .= $text;
}
/**
* handle variables
* @access private
*/
function handleVariable($id,$text)
{
$this->currentString = $text;
$this->currentStrings .= $text;
$this->useVariable();
}
/**
* handle Double Colon tokens
* @access private
*/
function handleDoubleColon($id,$text)
{
$this->staticClass = $this->currentString;
$this->currentString = null;
}
/**
* handle new keyword
* @access private
*/
function handleNew($id,$text)
{
$this->inNew = true;
}
/**
* handle function
* @access private
*/
function handleFunction($id,$text)
{
$this->createdFunctions[] = $this->lineNumber;
}
/**
* handle class
* @access private
*/
function handleClass($id,$text)
{
$this->createdClasses[] = $this->lineNumber;
}
/**
* Handle ->
* @access private
*/
function handleObjectOperator($id,$text)
{
$this->currentVar = $this->currentString;
$this->currentString = null;
$this->currentStrings .= $text;
}
/**
* handle whitespace to figure out line counts
* @access private
*/
function handleWhitespace($id,$text)
{
$this->lineNumber+=substr_count($text,"\n");
if ($id == T_CLOSE_TAG)
{
$this->handleSimpleToken(";");
}
}
/**
* as has been used we must have a var before it
*
* @access private
*/
function handleAs($id,$text)
{
$this->handleSimpleToken(";");
}
/**
* a language construct has been called record it
* @access private
*/
function handleConstruct($id,$construct)
{
if (!isset($this->calledConstructs[$construct]))
{
$this->calledConstructs[$construct] = array();
}
$this->calledConstructs[$construct][] = $this->lineNumber;
$this->currentString = null;
}
/**
* a class was Instantiated record it
* @access private
*/
function classInstantiated()
{
if (!isset($this->classesInstantiated[$this->currentString]))
{
$this->classesInstantiated[$this->currentString] = array();
}
$this->classesInstantiated[$this->currentString][] = $this->lineNumber;
$this->inNew = false;
}
/**
* a file was included record it
* @access private
*/
function fileIncluded()
{
if (!isset($this->filesIncluded[$this->currentStrings]))
{
$this->filesIncluded[$this->currentStrings] = array();
}
$this->filesIncluded[$this->currentStrings][] = $this->lineNumber;
$this->inInclude = false;
$this->currentString = null;
$this->currentStrings = "";
}
/**
* a function was called record it
* @access private
*/
function functionCalled($id = false)
{
if (!isset($this->calledFunctions[$this->currentString]))
{
$this->calledFunctions[$this->currentString] = array();
}
$this->calledFunctions[$this->currentString][] = $this->lineNumber;
$this->currentString = null;
}
/**
* we used a member variable record it
* @access private
*/
function useMemberVar()
{
if (!isset($this->usedMemberVariables[$this->currentVar][$this->currentString]))
{
$this->usedMemberVariables[$this->currentVar][$this->currentString] = array();
}
$this->usedMemberVariables[$this->currentVar][$this->currentString][] = $this->lineNumber;
$this->currentVar = false;
$this->currentString = null;
}
/**
* we used a variable record it
* @access private
*/
function useVariable()
{
if (!isset($this->usedVariables[$this->currentString]))
{
$this->usedVariables[$this->currentString] = array();
}
$this->usedVariables[$this->currentString][] = $this->lineNumber;
}
}
?>

View File

@ -0,0 +1,74 @@
<?php
/**
*
* Abstract Savant2_Plugin class.
*
* You have to extend this class for it to be useful; e.g., "class
* Savant2_Plugin_example extends Savant2_Plugin".
*
* $Id$
*
* @author Paul M. Jones <pmjones@ciaweb.net>
*
* @package Savant2
*
* @license http://www.gnu.org/copyleft/lesser.html LGPL
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as
* published by the Free Software Foundation; either version 2.1 of the
* License, or (at your option) any later version.
*
* This 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
* Lesser General Public License for more details.
*
*/
class Savant2_Plugin {
/**
*
* Optional reference to the calling Savant object.
*
* @var object
*
*/
var $Savant = null;
/**
*
* Constructor.
*
* @access public
*
*/
function Savant2_Plugin($conf = array())
{
settype($conf, 'array');
foreach ($conf as $key => $val) {
$this->$key = $val;
}
}
/**
*
* Stub method for extended behaviors.
*
* @access public
*
* @return void
*
*/
function plugin()
{
}
}
?>

View File

@ -0,0 +1,847 @@
<?php
/**
*
* Basic compiler for Savant2.
*
* This is a simple compiler provided as an example. It probably won't
* work with streams, but it does limit the template syntax in a
* relatively strict way. It's not perfect, but it's OK for many
* purposes. Basically, the compiler converts specialized instances of
* curly braces into PHP commands or Savant2 method calls. It will
* probably mess up embedded JavaScript unless you change the prefix
* and suffix to something else (e.g., '<!-- ' and ' -->', but then it
* will mess up your HTML comments ;-).
*
* When in "restrict" mode, ise of PHP commands not in the whitelists
* will cause the compiler to * fail. Use of various constructs and
* superglobals, likewise.
*
* Use {$var} or {$this->var} to print a variable.
*
* Use {: function-list} to print the results of function calls.
*
* Use {['pluginName', 'arg1', $arg2, $this->arg3]} to call plugins.
*
* Use these for looping:
* {foreach ():} ... {endforeach}
* {for ():} ... {endfor}
* {while ():} ... {endwhile}
*
* Use these for conditionals (normal PHP can go in the parens):
* {if (...):}
* {elseif (...):}
* {else:}
* {endif}
* {switch (...):}
* {case ...:}
* {default:}
* {endswitch}
*
* {break} and {continue} are supported as well.
*
* Use this to include a template:
* {tpl 'template.tpl.php'}
* {tpl $tplname}
* {tpl $this->tplname}
*
* $Id$
*
* @author Paul M. Jones <pmjones@ciaweb.net>
*
* @package Savant2
*
* @license http://www.gnu.org/copyleft/lesser.html LGPL
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as
* published by the Free Software Foundation; either version 2.1 of the
* License, or (at your option) any later version.
*
* This 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
* Lesser General Public License for more details.
*
*/
require_once 'Savant2/Compiler.php';
require_once 'Savant2/Error.php';
require_once 'Savant2/PHPCodeAnalyzer.php';
class Savant2_Compiler_basic extends Savant2_Compiler {
/**
*
* The template directive prefix.
*
* @access public
*
* @var array
*
*/
var $prefix = '{';
/**
*
* The template directive suffix.
*
* @access public
*
* @var array
*
*/
var $suffix = '}';
/**
*
* The conversion regular expressions.
*
* @access public
*
* @var array
*
*/
var $convert = array(
// branching
'(if\s*(.+):)' => '$1',
'(elseif\s*(.+):)' => '$1',
'(else\s*(.+):)' => '$1',
'(endif)' => '$1',
'(switch\s*(.+):)' => '$1',
'(case\s*(.+):)' => '$1',
'(default:)' => '$1',
'(endswitch)' => '$1',
'(break)' => '$1',
// looping
'(foreach\s*(.+):)' => '$1',
'(endforeach)' => '$1',
'(for\s*(.+):)' => '$1',
'(endfor)' => '$1',
'(while\s*(.+):)' => '$1',
'(endwhile)' => '$1',
'(continue)' => '$1',
// simple variable printing
'(\$(.+))' => 'print $1',
// extended printing
'(\:(.+))' => 'print ($2)',
// comments
'\*(.*)?\*' => '/**$1*/',
// template includes
'tpl (.*)' => 'include $this->findTemplate($1)',
// plugins
'\[\s*(.+)?\s*\]' => '$this->plugin($1)',
);
/**
*
* The list of allowed functions when in restricted mode.
*
* @access public
*
* @var array
*
*/
var $allowedFunctions = array();
/**
*
* The list of allowed static methods when in restricted mode.
*
* @access public
*
* @var array
*
*/
var $allowedStatic = array();
/**
*
* The directory where compiled templates are saved.
*
* @access public
*
* @var string
*
*/
var $compileDir = null;
/**
*
* Whether or not to force every template to be compiled every time.
*
* @access public
*
* @var bool
*
*/
var $forceCompile = false;
/**
*
* Whether or not to strict-check the compiled template.
*
* Strict-checks are off by default until all problems with
* PhpCodeAnalyzer have been resolved.
*
* @access public
*
* @var bool
*
*/
var $strict = false;
/**
*
* Constructor.
*
*/
function Savant2_Compiler_basic($conf = array())
{
parent::Savant2_Compiler($conf);
$this->ca =& new PHPCodeAnalyzer();
$this->allowedFunctions = $this->allowedFunctions();
$this->allowedStatic = $this->allowedStatic();
}
/**
*
* Has the source template changed since it was last compiled?
*
* @access public
*
* @var string $tpl The source template file.
*
*/
function changed($tpl)
{
// the path for the compiled file
$file = $this->getPath($tpl);
// if the copmiled file does not exist, or if the mod-time of
// the source is later than that of the existing compiled file,
// then the source template file has changed.
if (! file_exists($file) ||
filemtime($tpl) > filemtime($file)) {
return true;
} else {
return false;
}
}
/**
*
* Saves the PHP compiled from template source.
*
* @access public
*
* @var string $tpl The source template file.
*
*/
function saveCompiled($tpl, $php)
{
$fp = fopen($this->getPath($tpl), 'w');
if (! $fp) {
return false;
} else {
$result = fwrite($fp, $php);
fclose($fp);
return $result;
}
}
/**
*
* Gets the path to the compiled PHP for a template source.
*
* @access public
*
* @var string $tpl The source template file.
*
*/
function getPath($tpl)
{
$dir = $this->compileDir;
if (substr($dir, -1) != DIRECTORY_SEPARATOR) {
$dir .= DIRECTORY_SEPARATOR;
}
return $dir . 'Savant2_' . md5($tpl);
}
/**
*
* Compiles a template source into PHP code for Savant.
*
* @access public
*
* @var string $tpl The source template file.
*
*/
function compile($tpl)
{
// create a end-tag so that text editors don't
// stop colorizing text
$end = '?' . '>';
// recompile only if we are forcing compiled, or
// if the template source has changed.
if ($this->forceCompile || $this->changed($tpl)) {
// get the template source text
$php = file_get_contents($tpl);
/**
* @todo Do we really care about PHP tags? The code analyzer
* will disallow any offending PHP regardless.
*/
// disallow PHP long tags
$php = str_replace('<?php', '&lt;?php', $php);
// disallow PHP short tags (if turned on)
if (ini_get('short_open_tag')) {
$php = str_replace('<?', '&lt;?', $php);
$php = str_replace('<?=', '&lt;?=', $php);
}
// disallow closing tags
$php = str_replace($end, '?&gt;', $php);
// convert each template command
foreach ($this->convert as $find => $replace) {
// allow whitespace around the command
$find = preg_quote($this->prefix) . '\s*' . $find .
'\s*' . preg_quote($this->suffix);
// actually do the find-and-replace
$php = preg_replace(
"/$find/U",
"<?php $replace $end",
$php
);
}
// +++ DEBUG
// $this->saveCompiled($tpl, $php);
// --- DEBUG
// are we doing strict checking?
if ($this->strict) {
// analyze the code for restriction violations.
$report = $this->analyze($php);
if (count($report) > 0) {
// there were violations, report them as a generic
// Savant error and return. Savant will wrap this
// generic rror with another error that will report
// properly to the customized error handler (if any).
return new Savant2_Error(
array(
'code' => SAVANT2_ERROR_COMPILE_FAIL,
'text' => $GLOBALS['_SAVANT2']['error'][SAVANT2_ERROR_COMPILE_FAIL],
'info' => $report
)
);
}
}
// otherwise, save the compiled template
$this->saveCompiled($tpl, $php);
}
// return the path to the compiled PHP script
return $this->getPath($tpl);
}
/**
*
* Analyze a compiled template for restriction violations.
*
* @access public
*
* @var string $php The compiled PHP code from a template source.
*
* @return array An array of restriction violations; if empty, then
* there were no violations discovered by analysis.
*
*/
function analyze(&$php)
{
// analyze the compiled code
$ca =& $this->ca;
$ca->source =& $php;
$ca->analyze();
// array of captured restriction violations
$report = array();
// -------------------------------------------------------------
//
// go through the list of called functions and make sure each
// one is allowed via the whitelist. if not, record each non-
// allowed function. this also restricts variable-functions
// such as $var().
//
foreach ($ca->calledFunctions as $func => $lines) {
if (! in_array($func, $this->allowedFunctions)) {
$report[$func] = $lines;
}
}
// -------------------------------------------------------------
//
// disallow use of various constructs (include is allowed, we
// need it for {tpl}).
//
$tmp = array(
'eval',
'global',
'include_once',
'require',
'require_once',
'parent',
'self'
);
foreach ($tmp as $val) {
if (isset($ca->calledConstructs[$val])) {
$report[$val] = $ca->calledConstructs[$val];
}
}
// -------------------------------------------------------------
//
// disallow instantiation of new classes
//
foreach ($ca->classesInstantiated as $key => $val) {
$report['new ' . $key] = $val;
}
// -------------------------------------------------------------
//
// disallow access to the various superglobals
// so that templates cannot manipulate them.
//
$tmp = array(
'$_COOKIE',
'$_ENV',
'$_FILES',
'$_GET',
'$_POST',
'$_REQUEST',
'$_SERVER',
'$_SESSION',
'$GLOBALS',
'$HTTP_COOKIE_VARS',
'$HTTP_ENV_VARS',
'$HTTP_GET_VARS',
'$HTTP_POST_FILES',
'$HTTP_POST_VARS',
'$HTTP_SERVER_VARS',
'$HTTP_SESSION_VARS'
);
foreach ($ca->usedVariables as $var => $lines) {
if (in_array(strtoupper($var), $tmp)) {
$report[$var] = $lines;
}
}
// -------------------------------------------------------------
//
// allow only certain $this methods
//
$tmp = array('plugin', 'splugin', 'findTemplate');
if (isset($ca->calledMethods['$this'])) {
foreach ($ca->calledMethods['$this'] as $method => $lines) {
if (! in_array($method, $tmp)) {
$report['$this->' . $method] = $lines;
}
}
}
// -------------------------------------------------------------
//
// disallow private and variable-variable $this properties
//
if (isset($ca->usedMemberVariables['$this'])) {
foreach ($ca->usedMemberVariables['$this'] as $prop => $lines) {
$char = substr($prop, 0, 1);
if ($char == '_' || $char == '$') {
$report['$this->' . $prop] = $lines;
}
}
}
// -------------------------------------------------------------
//
// allow only certain static method calls
//
foreach ($ca->calledStaticMethods as $class => $methods) {
foreach ($methods as $method => $lines) {
if (! array_key_exists($class, $this->allowedStatic)) {
// the class itself is not allowed
$report["$class::$method"] = $lines;
} elseif (! in_array('*', $this->allowedStatic[$class]) &&
! in_array($method, $this->allowedStatic[$class])){
// the specific method is not allowed,
// and there is no wildcard for the class methods.
$report["$class::$method"] = $lines;
}
}
}
// -------------------------------------------------------------
//
// only allow includes via $this->findTemplate(*)
//
foreach ($ca->filesIncluded as $text => $lines) {
// in each include statment, look for $this->findTemplate.
preg_match(
'/(.*)?\$this->findTemplate\((.*)?\)(.*)/i',
$text,
$matches
);
if (! empty($matches[1]) || ! empty($matches[3]) ||
empty($matches[2])) {
// there is something before or after the findTemplate call,
// or it's a direct include (which is not allowed)
$report["include $text"] = $lines;
}
}
// -------------------------------------------------------------
//
// do not allow the use of "$this" by itself;
// it must be always be followed by "->" or another
// valid variable-name character (a-z, 0-9, or _).
//
$regex = '/(.*)?\$this(?!(\-\>)|([a-z0-9_]))(.*)?/i';
preg_match_all($regex, $php, $matches, PREG_SET_ORDER);
foreach ($matches as $val) {
$report['\'$this\' without \'->\''][] = $val[0];
}
/** @todo disallow standalone variable-variables, $$var */
/** @todo disallow vars from static classes? class::$var */
// -------------------------------------------------------------
//
// done!
//
// +++ DEBUG
//echo "<pre>";
//print_r($ca);
//echo "</pre>";
// --- DEBUG
return $report;
}
/**
*
* A list of allowed static method calls for templates.
*
* The format is ...
*
* array(
* 'Class1' => array('method1', 'method2'),
* 'Class2' => array('methodA', 'methodB'),
* 'Class3' => '*'
* );
*
* If you want to allow all methods from the static class to be allowed,
* use a '*' in the method name list.
*
*/
function allowedStatic()
{
return array();
}
/**
*
* A list of allowed functions for templates.
*
*/
function allowedFunctions()
{
return array(
// arrays
'array_count_values',
'array_key_exists',
'array_keys',
'array_sum',
'array_values',
'compact',
'count',
'current',
'each',
'end',
'extract',
'in_array',
'key',
'list',
'next',
'pos',
'prev',
'reset',
'sizeof',
// calendar
'cal_days_in_month',
'cal_from_jd',
'cal_to_jd',
'easter_date',
'easter_days',
'FrenchToJD',
'GregorianToJD',
'JDDayOfWeek',
'JDMonthName',
'JDToFrench',
'JDToGregorian',
'jdtojewish',
'JDToJulian',
'jdtounix',
'JewishToJD',
'JulianToJD',
'unixtojd',
// date
'checkdate',
'date_sunrise',
'date_sunset',
'date',
'getdate',
'gettimeofday',
'gmdate',
'gmmktime',
'gmstrftime',
'idate',
'localtime',
'microtime',
'mktime',
'strftime',
'strptime',
'strtotime',
'time',
// gettext
'_',
'gettext',
'ngettext',
// math
'abs',
'acos',
'acosh',
'asin',
'asinh',
'atan2',
'atan',
'atanh',
'base_convert',
'bindec',
'ceil',
'cos',
'cosh',
'decbin',
'dechex',
'decoct',
'deg2rad',
'exp',
'expm1',
'floor',
'fmod',
'getrandmax',
'hexdec',
'hypot',
'is_finite',
'is_infinite',
'is_nan',
'lcg_value',
'log10',
'log1p',
'log',
'max',
'min',
'mt_getrandmax',
'mt_rand',
'mt_srand',
'octdec',
'pi',
'pow',
'rad2deg',
'rand',
'round',
'sin',
'sinh',
'sqrt',
'srand',
'tan',
'tanh',
// strings
'chop',
'count_chars',
'echo',
'explode',
'hebrev',
'hebrevc',
'html_entity_decode',
'htmlentities',
'htmlspecialchars',
'implode',
'join',
'localeconv',
'ltrim',
'money_format',
'nl_langinfo',
'nl2br',
'number_format',
'ord',
'print',
'printf',
'quoted_printable_decode',
'rtrim',
'sprintf',
'sscanf',
'str_pad',
'str_repeat',
'str_replace',
'str_rot13',
'str_shuffle',
'str_word_count',
'strcasecmp',
'strchr',
'strcmp',
'strcoll',
'strcspn',
'strip_tags',
'stripcslashes',
'stripos',
'stripslashes',
'stristr',
'strlen',
'strnatcasecmp',
'strnatcmp',
'strncasecmp',
'strncmp',
'strpbrk',
'strpos',
'strrchr',
'strrev',
'strripos',
'strrpos',
'strspn',
'strstr',
'strtok',
'strtolower',
'strtoupper',
'strtr',
'substr_compare',
'substr_count',
'substr_replace',
'substr',
'trim',
'ucfirst',
'ucwords',
'wordwrap',
// url
'base64_decode',
'base64_encode',
'rawurldecode',
'rawurlencode',
'urldecode',
'urlencode',
// variables
'empty',
'is_array',
'is_bool',
'is_double',
'is_float',
'is_int',
'is_integer',
'is_long',
'is_null',
'is_numeric',
'is_object',
'is_real',
'is_resource',
'is_scalar',
'is_string',
'isset',
'print_r',
'unset',
'var_dump',
);
}
}
?>

View File

@ -0,0 +1,53 @@
<?php
/**
* The base Savant2_Error class.
*/
require_once 'Savant2/Error.php';
/**
* A simple Savant2_Exception class.
*/
class Savant2_Exception extends Exception { };
/**
*
* Throws PHP5 exceptions for Savant.
*
* $Id$
*
* @author Paul M. Jones <pmjones@ciaweb.net>
*
* @package Savant2
*
* @license http://www.gnu.org/copyleft/lesser.html LGPL
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as
* published by the Free Software Foundation; either version 2.1 of the
* License, or (at your option) any later version.
*
* This 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
* Lesser General Public License for more details.
*
*/
class Savant2_Error_exception extends Savant2_Error {
/**
*
* Throws an Savant2_Exception in PHP5.
*
* @return void
*
*/
function error()
{
throw new Savant2_Exception($this->text, $this->code);
}
}
?>

View File

@ -0,0 +1,56 @@
<?php
/**
* The base Savant2_Error class.
*/
require_once 'Savant2/Error.php';
/**
* The PEAR_Error class.
*/
require_once 'PEAR.php';
/**
*
* Provides an interface to PEAR_ErrorStack class for Savant.
*
* $Id$
*
* @author Paul M. Jones <pmjones@ciaweb.net>
*
* @package Savant2
*
* @license http://www.gnu.org/copyleft/lesser.html LGPL
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as
* published by the Free Software Foundation; either version 2.1 of the
* License, or (at your option) any later version.
*
* This 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
* Lesser General Public License for more details.
*
*/
class Savant2_Error_pear extends Savant2_Error {
/**
*
* Extended behavior for PEAR_Error.
*
* @access public
*
* @return void
*
*/
function error()
{
// throw a PEAR_Error
PEAR::throwError($this->text, $this->code, $this->info);
}
}
?>

View File

@ -0,0 +1,60 @@
<?php
/**
* The base Savant2_Error class.
*/
require_once 'Savant2/Error.php';
/**
* The PEAR_ErrorStack class.
*/
require_once 'PEAR/ErrorStack.php';
/**
*
* Provides an interface to PEAR_ErrorStack class for Savant.
*
* $Id$
*
* @author Paul M. Jones <pmjones@ciaweb.net>
*
* @package Savant2
*
* @license http://www.gnu.org/copyleft/lesser.html LGPL
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as
* published by the Free Software Foundation; either version 2.1 of the
* License, or (at your option) any later version.
*
* This 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
* Lesser General Public License for more details.
*
*/
class Savant2_Error_stack extends Savant2_Error {
/**
*
* Pushes an error onto the PEAR_ErrorStack.
*
* @return void
*
*/
function error()
{
// push an error onto the stack
PEAR_ErrorStack::staticPush(
'Savant2', // package name
$this->code, // error code
null, // error level
$this->info, // user info
$this->text // error message
);
}
}
?>

View File

@ -0,0 +1,123 @@
<?php
/**
* Base filter class.
*/
require_once 'Savant2/Filter.php';
/**
*
* Colorizes all text between <code>...</code> tags.
*
* @author Paul M. Jones <pmjones@ciaweb.net>
*
* $Id$
*
* @author Paul M. Jones <pmjones@ciaweb.net>
*
* @package Savant2
*
* @license http://www.gnu.org/copyleft/lesser.html LGPL
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as
* published by the Free Software Foundation; either version 2.1 of the
* License, or (at your option) any later version.
*
* This 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
* Lesser General Public License for more details.
*
*/
class Savant2_Filter_colorizeCode extends Savant2_Filter {
/**
*
* Colorizes all text between <code>...</code> tags.
*
* Colorizes all text between <code>...</code> tags with PHP's
* highlight_string function. Additionally, this will convert HTML
* entities within <code> blocks, so you can demonstrate HTML tags
* without them being honored in the browser. Also converts tabs to four
* spaces.
*
* To mark the beginning of php code in a <code> block, use the custom
* tag <php>, and use </php> to mark the end. You can't use the normal
* php code tags because Savant2 will try to execute that code when the
* template runs.
*
* @access public
*
* @param string &$text The source text to be filtered.
*
* @return void
*
*/
function filter(&$text)
{
// break the source into blocks by the beginning <code> tag.
// this will remove the text "<code>" from the block, so
// we'll need to add it in again later.
$blocks = explode('<code>', $text);
// loop through each block and convert text within
// <code></code> tags.
foreach ($blocks as $key => $val) {
// now find then the ending </code> within the block
$pos = strpos($val, '</code>');
if ($pos === false) {
// there was no </code> tag -- do nothing
} else {
// change all <php> and </php> tags
$val = str_replace('<php>', '<?php', $val);
$val = str_replace('</php>', '?>', $val); // <?php
// $tmp[0] will be the part before </code>, and
// thus the part we want to modify.
//
// $tmp[1] will be the part after the
// <code></code> block, which we will leave
// alone.
//
// this will remove the text "</code>" from the
// text, so we'll need to add it in again when modifying
// the text.
$tmp = explode('</code>', $val);
// set entities by highlighting the string. we do the
// output buffering ob() thing because the native
// highlight_string() dumps the output to the screen
// instead of returning to a variable (before PHP
// 4.2.2).
$tmp[0] = trim($tmp[0]);
ob_start();
highlight_string($tmp[0]);
$tmp[0] = ob_get_contents();
ob_end_clean();
// remove break tags from the highlighted text
$tmp[0] = str_replace("<br />", "\n", $tmp[0]);
// convert tabs to 4-spaces and then
// re-surround with <code> tags
$tmp[0] = str_replace("\t", ' ', $tmp[0]);
// save the modified text in the block
$blocks[$key] = $tmp[0] . $tmp[1];
}
}
// reassemble the blocks
$text = implode('', $blocks);
}
}

View File

@ -0,0 +1,104 @@
<?php
/**
* Base filter class.
*/
require_once 'Savant2/Filter.php';
/**
*
* Remove extra white space within the text.
*
* $Id$
*
* @author Monte Ohrt <monte@ispi.net>
*
* @author Contributions from Lars Noschinski <lars@usenet.noschinski.de>
*
* @author Converted to a Savant2 filter by Paul M. Jones
* <pmjones@ciaweb.net>
*
* @license http://www.gnu.org/copyleft/lesser.html LGPL
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as
* published by the Free Software Foundation; either version 2.1 of the
* License, or (at your option) any later version.
*
* This 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
* Lesser General Public License for more details.
*
*/
class Savant2_Filter_trimwhitespace extends Savant2_Filter {
/**
*
* Removes extra white space within the text.
*
* Trim leading white space and blank lines from template source after it
* gets interpreted, cleaning up code and saving bandwidth. Does not
* affect <PRE>></PRE> and <SCRIPT></SCRIPT> blocks.<br>
*
* @access public
*
* @param string &$source The source text to be filtered.
*
*/
function filter(&$source)
{
// Pull out the script blocks
preg_match_all("!<script[^>]+>.*?</script>!is", $source, $match);
$_script_blocks = $match[0];
$source = preg_replace("!<script[^>]+>.*?</script>!is",
'@@@SAVANT:TRIM:SCRIPT@@@', $source);
// Pull out the pre blocks
preg_match_all("!<pre[^>]+>.*?</pre>!is", $source, $match);
$_pre_blocks = $match[0];
$source = preg_replace("!<pre[^>]+>.*?</pre>!is",
'@@@SAVANT:TRIM:PRE@@@', $source);
// Pull out the textarea blocks
preg_match_all("!<textarea[^>]+>.*?</textarea>!is", $source, $match);
$_textarea_blocks = $match[0];
$source = preg_replace("!<textarea[^>]+>.*?</textarea>!is",
'@@@SAVANT:TRIM:TEXTAREA@@@', $source);
// remove all leading spaces, tabs and carriage returns NOT
// preceeded by a php close tag.
$source = trim(preg_replace('/((?<!\?>)\n)[\s]+/m', '\1', $source));
// replace script blocks
Savant2_Filter_trimwhitespace::_replace(
"@@@SAVANT:TRIM:SCRIPT@@@",$_script_blocks, $source);
// replace pre blocks
Savant2_Filter_trimwhitespace::_replace(
"@@@SAVANT:TRIM:PRE@@@",$_pre_blocks, $source);
// replace textarea blocks
Savant2_Filter_trimwhitespace::_replace(
"@@@SAVANT:TRIM:TEXTAREA@@@",$_textarea_blocks, $source);
return $source;
}
function _replace($search_str, $replace, &$subject)
{
$_len = strlen($search_str);
$_pos = 0;
for ($_i=0, $_count=count($replace); $_i<$_count; $_i++) {
if (($_pos=strpos($subject, $search_str, $_pos))!==false) {
$subject = substr_replace($subject, $replace[$_i], $_pos, $_len);
} else {
break;
}
}
}
}
?>

View File

@ -0,0 +1,114 @@
<?php
/**
* Base plugin class.
*/
require_once 'Savant2/Plugin.php';
/**
*
* Outputs an HTML <a href="">...</a> tag.
*
* $Id$
*
* @author Paul M. Jones <pmjones@ciaweb.net>
*
* @package Savant2
*
* @license http://www.gnu.org/copyleft/lesser.html LGPL
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as
* published by the Free Software Foundation; either version 2.1 of the
* License, or (at your option) any later version.
*
* This 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
* Lesser General Public License for more details.
*
*/
class Savant2_Plugin_ahref extends Savant2_Plugin {
/**
*
* Output an HTML <a href="">...</a> tag.
*
* @access public
*
* @param string|array $href A string URL for the resulting tag. May
* also be an array with any combination of the keys 'scheme',
* 'host', 'path', 'query', and 'fragment' (c.f. PHP's native
* parse_url() function).
*
* @param string $text The displayed text of the link.
*
* @param string|array $attr Any extra attributes for the <a> tag.
*
* @return string The <a href="">...</a> tag.
*
*/
function plugin($href, $text, $attr = null)
{
$html = '<a href="';
if (is_array($href)) {
// add the HREF from an array
$tmp = '';
if (isset($href['scheme'])) {
$tmp .= $href['scheme'] . ':';
if (strtolower($href['scheme']) != 'mailto') {
$tmp .= '//';
}
}
if (isset($href['host'])) {
$tmp .= $href['host'];
}
if (isset($href['path'])) {
$tmp .= $href['path'];
}
if (isset($href['query'])) {
$tmp .= '?' . $href['query'];
}
if (isset($href['fragment'])) {
$tmp .= '#' . $href['fragment'];
}
$html .= htmlspecialchars($tmp);
} else {
// add the HREF from a scalar
$html .= htmlspecialchars($href);
}
$html .= '"';
// add attributes
if (is_array($attr)) {
// from array
foreach ($attr as $key => $val) {
$key = htmlspecialchars($key);
$val = htmlspecialchars($val);
$html .= " $key=\"$val\"";
}
} elseif (! is_null($attr)) {
// from scalar
$html .= " $attr";
}
// set the link text, close the tag, and return
$html .= '>' . htmlspecialchars($text) . '</a>';
return $html;
}
}
?>

View File

@ -0,0 +1,103 @@
<?php
/**
* Base plugin class.
*/
require_once 'Savant2/Plugin.php';
/**
*
* Outputs a single checkbox <input> element.
*
* $Id$
*
* @author Paul M. Jones <pmjones@ciaweb.net>
*
* @package Savant2
*
* @license http://www.gnu.org/copyleft/lesser.html LGPL
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as
* published by the Free Software Foundation; either version 2.1 of the
* License, or (at your option) any later version.
*
* This 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
* Lesser General Public License for more details.
*
*/
class Savant2_Plugin_checkbox extends Savant2_Plugin {
/**
*
* Outputs a single checkbox <input> element.
*
* @access public
*
* @param string $name The HTML "name=" value for the checkbox.
*
* @param string $value The value of the checkbox when checked.
*
* @param array $checked If $value is in this array of values,
* mark the checkbox as checked.
*
* @param array $default The value to return if the checkbox is not
* checked.
*
* @param string|array $attr Any extra HTML attributes to place
* within the checkbox element.
*
* @return string
*
*/
function plugin(
$name,
$value = '1',
$checked = null,
$default = null,
$attr = null)
{
$html = '';
// define the hidden default value (if any) when not checked
if (! is_null($default)) {
$html .= '<input type="hidden"';
$html .= ' name="' . htmlspecialchars($name) . '"';
$html .= ' value="' .htmlspecialchars($default) . '" />';
$html .= "\n";
}
// start the checkbox tag with name and value
$html .= '<input type="checkbox"';
$html .= ' name="' . htmlspecialchars($name) . '"';
$html .= ' value="' . htmlspecialchars($value) . '"';
// is the checkbox checked?
settype($checked, 'array');
if (in_array($value, $checked)) {
$html .= ' checked="checked"';
}
// add extra attributes
if (is_array($attr)) {
// add from array
foreach ($attr as $key => $val) {
$key = htmlspecialchars($key);
$val = htmlspecialchars($val);
$html .= " $key=\"$val\"";
}
} elseif (! is_null($attr)) {
// add from scalar
$html .= " $attr";
}
// close the checkbox tag and return
$html .= ' />';
return $html;
}
}
?>

View File

@ -0,0 +1,97 @@
<?php
/**
* Base plugin class.
*/
require_once 'Savant2/Plugin.php';
/**
*
* Cycles through a series of values.
*
* $Id$
*
* @author Paul M. Jones <pmjones@ciaweb.net>
*
* @package Savant2
*
* @license http://www.gnu.org/copyleft/lesser.html LGPL
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as
* published by the Free Software Foundation; either version 2.1 of the
* License, or (at your option) any later version.
*
* This 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
* Lesser General Public License for more details.
*
*/
class Savant2_Plugin_cycle extends Savant2_Plugin {
/**
*
* An associative array of predefined cycle value sets.
*
* You can preset cycle values via Savant::loadPlugin().
*
* $conf = array(
* 'values' => array(
* 'lightdark' => array('light', 'dark'),
* 'threesome' => array('one', 'two', 'three')
* )
* );
*
* $Savant->loadPlugin('cycle', $conf);
*
* ... and in your template you can call:
*
* $this->plugin('cycle', 'lightdark', $iteration);
*
* @access public
*
* @var array
*
*/
var $values = array();
/**
*
* Cycles through a series of values.
*
* @access public
*
* @param string|array $cycle If a string, the preset cycle value key to use
* from $this->cycles; if an array, use the array as the cycle values.
*
* @param int $iteration The iteration number for the cycle.
*
* @param int $repeat The number of times to repeat each cycle value.
*
* @return mixed The value of the cycle iteration.
*
*/
function plugin($cycle, $iteration, $repeat = 1)
{
// get the proper value set as an array
if (is_string($cycle) && isset($this->values[$cycle])) {
$values = (array) $this->values[$cycle];
} else {
$values = (array) $cycle;
}
// prevent divide-by-zero errors
if ($repeat == 0) {
$repeat = 1;
}
// return the perper value for iteration and repetition
return $values[($iteration / $repeat) % count($values)];
}
}
?>

View File

@ -0,0 +1,136 @@
<?php
/**
* Base plugin class.
*/
require_once 'Savant2/Plugin.php';
/**
*
* Outputs a formatted date using strftime() conventions.
*
* $Id$
*
* @author Paul M. Jones <pmjones@ciaweb.net>
*
* @package Savant2
*
* @license http://www.gnu.org/copyleft/lesser.html LGPL
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as
* published by the Free Software Foundation; either version 2.1 of the
* License, or (at your option) any later version.
*
* This 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
* Lesser General Public License for more details.
*
*/
class Savant2_Plugin_dateformat extends Savant2_Plugin {
/**
*
* The default strftime() format string to use for dates.
*
* You can preset the default format string via Savant::loadPlugin().
*
* $conf = array(
* 'format' => '%Y-%m-%d %H:%M:%S'
* );
*
* $Savant->loadPlugin('dateformat', $conf);
*
* ... and in your template, to use the default format string:
*
* $this->plugin('date', $datestring);
*
* ... or, to use a custom string at call-time:
*
* $this->plugin('date', $datestring, '%b');
*
* @access public
*
* @var string
*
*/
var $format = '%c';
/**
*
* The default strftime() format string to use for dates.
*
* You can preset the custom format strings via Savant::loadPlugin().
*
* $conf = array(
* 'custom' => array(
* 'mydate' => '%Y-%m-%d',
* 'mytime' => '%R'
* )
* );
*
* $Savant->loadPlugin('dateformat', $conf);
*
* ... and in your template, to use a preset custom string by name:
*
* $this->plugin('date', $datestring, 'mydate');
*
* @access public
*
* @var array
*
*/
var $custom = array(
'date' => '%Y-%m-%d',
'time' => '%H:%M:%S'
);
/**
*
* Outputs a formatted date using strftime() conventions.
*
* @access public
*
* @param string $datestring Any date-time string suitable for
* strtotime().
*
* @param string $format The strftime() formatting string, or a named
* custom string key from $this->custom.
*
* @return string
*
*/
function plugin($datestring, $format = null)
{
settype($format, 'string');
// does the format string have a % sign in it?
if (strpos($format, '%') === false) {
// no, look for a custom format string
if (isset($this->custom[$format])) {
// found a custom format string
$format = $this->custom[$format];
} else {
// did not find the custom format, revert to default
$format = $this->format;
}
}
// convert the date string to the specified format
if (trim($datestring != '')) {
return strftime($format, strtotime($datestring));
} else {
// no datestring, return VOID
return;
}
}
}
?>

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,220 @@
<?php
/**
* Base plugin class.
*/
require_once 'Savant2/Plugin.php';
/**
*
* Outputs an <image ... /> tag.
*
* Support for alpha transparency of PNG files in Microsoft IE added by
* Edward Ritter; thanks, Edward.
*
* $Id$
*
* @author Paul M. Jones <pmjones@ciaweb.net>
*
* @author Edward Ritter <esritter@gmail.com>
*
* @package Savant2
*
* @license http://www.gnu.org/copyleft/lesser.html LGPL
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as
* published by the Free Software Foundation; either version 2.1 of the
* License, or (at your option) any later version.
*
* This 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
* Lesser General Public License for more details.
*
*/
class Savant2_Plugin_image extends Savant2_Plugin {
/**
*
* The document root.
*
* @access public
*
* @var string
*
*/
var $documentRoot = null;
/**
*
* The base directory for images within the document root.
*
* @access public
*
* @var string
*
*/
var $imageDir = null;
/**
*
* Outputs an <img ... /> tag.
*
* Microsoft IE alpha PNG support added by Edward Ritter.
*
* @access public
*
* @param string $file The path to the image on the local file system
* relative to $this->imageDir.
*
* @param string $alt Alternative descriptive text for the image;
* defaults to the filename of the image.
*
* @param int $border The border width for the image; defaults to zero.
*
* @param int $width The displayed image width in pixels; defaults to
* the width of the image.
*
* @param int $height The displayed image height in pixels; defaults to
* the height of the image.
*
*/
function plugin($file, $alt = null, $height = null, $width = null,
$attr = null)
{
// is the document root set?
if (is_null($this->documentRoot)) {
// no, so set it
$this->documentRoot = $_SERVER['DOCUMENT_ROOT'];
}
// the image file type code (PNG = 3)
$type = null;
// get the file information
$info = false;
if (strpos($file, '://') === false) {
// no "://" in the file, so it's local
$file = $this->imageDir . $file;
$info = @getimagesize($this->documentRoot . $file);
} else {
// get the file size info as from a stream
$info = @getimagesize($file);
}
// did we find the file?
if (is_array($info)) {
// capture type info regardless
$type = $info[2];
// capture size info where both not specified
if (is_null($width) && is_null($height)) {
$width = $info[0];
$height = $info[1];
}
}
// clean up
unset($info);
// is the file a PNG? if so, check user agent, we will need to
// make special allowances for Microsoft IE.
if (stristr($_SERVER['HTTP_USER_AGENT'], 'MSIE') && $type === 3) {
// support alpha transparency for PNG files in MSIE
$html = '<span style="position: relative;';
if ($height) {
$html .= ' height: ' . $height . 'px;';
}
if ($width) {
$html .= ' width: ' . $width . 'px;';
}
$html .= ' filter:progid:DXImageTransform.Microsoft.AlphaImageLoader';
$html .= "(src='$file',sizingMethod='scale');\"";
$html .= ' title="' . htmlspecialchars($alt) . '"';
$html .= $this->_attr($attr);
// done
$html .= '></span>';
} else {
// not IE, so build a normal image tag.
$html = '<img';
$html .= ' src="' . htmlspecialchars($file) . '"';
// add the alt attribute
if (is_null($alt)) {
$alt = basename($file);
}
$html .= ' alt="' . htmlspecialchars($alt) . '"';
// add the height attribute
if ($height) {
$html .= ' height="' . htmlspecialchars($height) . '"';
}
// add the width attribute
if ($width) {
$html .= ' width="' . htmlspecialchars($width) . '"';
}
$html .= $this->_attr($attr);
// done
$html .= ' />';
}
// done!
return $html;
}
/**
*
* Create additional HTML attributes.
*
* @access private
*
* @param array|string $attr An array or string of attributes.
*
* @return string A string of attributes.
*
*/
function _attr($attr = null)
{
$html = '';
// add other attributes
if (is_array($attr)) {
// from array
foreach ($attr as $key => $val) {
$key = htmlspecialchars($key);
$val = htmlspecialchars($val);
$html .= " $key=\"$val\"";
}
} elseif (! is_null($attr)) {
// from scalar
$html .= " $attr";
}
return $html;
}
}
?>

View File

@ -0,0 +1,82 @@
<?php
/**
* Base plugin class.
*/
require_once 'Savant2/Plugin.php';
/**
*
* Outputs a single <input> element.
*
* $Id$
*
* @author Paul M. Jones <pmjones@ciaweb.net>
*
* @package Savant2
*
* @license http://www.gnu.org/copyleft/lesser.html LGPL
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as
* published by the Free Software Foundation; either version 2.1 of the
* License, or (at your option) any later version.
*
* This 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
* Lesser General Public License for more details.
*
*/
class Savant2_Plugin_input extends Savant2_Plugin {
/**
*
* Outputs a single <input> element.
*
* @access public
*
* @param string $type The HTML "type=" value (e.g., 'text',
* 'hidden', 'password').
*
* @param string $name The HTML "name=" value.
*
* @param mixed $value The initial value of the input element.
*
* @param string $attr Any extra HTML attributes to place within the
* input element.
*
* @return string
*
*/
function plugin($type, $name, $value = '', $attr = null)
{
$type = htmlspecialchars($type);
$name = htmlspecialchars($name);
$value = htmlspecialchars($value);
// start the tag
$html = "<input type=\"$type\" name=\"$name\" value=\"$value\"";
// add extra attributes
if (is_array($attr)) {
// add from array
foreach ($attr as $key => $val) {
$key = htmlspecialchars($key);
$val = htmlspecialchars($val);
$html .= " $key=\"$val\"";
}
} elseif (! is_null($attr)) {
// add from scalar
$html .= " $attr";
}
// end the tag and return
$html .= ' />';
return $html;
}
}
?>

View File

@ -0,0 +1,54 @@
<?php
/**
* Base plugin class.
*/
require_once 'Savant2/Plugin.php';
/**
*
* Output a <script></script> link to a JavaScript file.
*
* $Id$
*
* @author Paul M. Jones <pmjones@ciaweb.net>
*
* @package Savant2
*
* @license http://www.gnu.org/copyleft/lesser.html LGPL
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as
* published by the Free Software Foundation; either version 2.1 of the
* License, or (at your option) any later version.
*
* This 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
* Lesser General Public License for more details.
*
*/
class Savant2_Plugin_javascript extends Savant2_Plugin {
/**
*
* Output a <script></script> link to a JavaScript file.
*
* @access public
*
* @param string $href The HREF leading to the JavaScript source
* file.
*
* @return string
*
*/
function plugin($href)
{
return '<script language="javascript" type="text/javascript" src="' .
htmlspecialchars($href) . '"></script>';
}
}
?>

View File

@ -0,0 +1,82 @@
<?php
/**
* Base plugin class.
*/
require_once 'Savant2/Plugin.php';
/**
*
* Modifies a value with a series of functions.
*
* $Id$
*
* @author Paul M. Jones <pmjones@ciaweb.net>
*
* @package Savant2
*
* @license http://www.gnu.org/copyleft/lesser.html LGPL
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as
* published by the Free Software Foundation; either version 2.1 of the
* License, or (at your option) any later version.
*
* This 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
* Lesser General Public License for more details.
*
*/
class Savant2_Plugin_modify extends Savant2_Plugin {
/**
*
* Modifies a value with a series of functions.
*
* Allows you to pass a space-separated list of value-manipulation
* functions so that the value is "massaged" before output. For
* example, if you want to strip slashes, force to lower case, and
* convert to HTML entities (as for an input text box), you might do
* this:
*
* $this->modify($value, 'stripslashes strtolower htmlentities');
*
* @param object &$savant A reference to the calling Savant2 object.
*
* @access public
*
* @param string $value The value to be printed.
*
* @param string $functions A space-separated list of
* single-parameter functions to be applied to the $value before
* printing.
*
* @return string
*
*/
function plugin($value, $functions = null)
{
// is there a space-delimited function list?
if (is_string($functions)) {
// yes. split into an array of the
// functions to be called.
$list = explode(' ', $functions);
// loop through the function list and
// apply to the output in sequence.
foreach ($list as $func) {
if (function_exists($func)) {
$value = $func($value);
}
}
}
return $value;
}
}
?>

View File

@ -0,0 +1,107 @@
<?php
/**
* Base plugin class.
*/
require_once 'Savant2/Plugin.php';
/**
*
* Outputs a series of HTML <option>s.
*
* $Id$
*
* @author Paul M. Jones <pmjones@ciaweb.net>
*
* @package Savant2
*
* @license http://www.gnu.org/copyleft/lesser.html LGPL
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as
* published by the Free Software Foundation; either version 2.1 of the
* License, or (at your option) any later version.
*
* This 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
* Lesser General Public License for more details.
*
*/
class Savant2_Plugin_options extends Savant2_Plugin {
/**
*
* Outputs a series of HTML <option>s.
*
* Outputs a series of HTML <option>s based on an associative array
* where the key is the option value and the value is the option
* label. You can pass a "selected" value as well to tell the
* function which option value(s) should be marked as selected.
*
* @access public
*
* @param array $options An associative array of key-value pairs; the
* key is the option value, the value is the option label.
*
* @param string|array $selected A string or array that matches one
* or more option values, to tell the function what options should be
* marked as selected. Defaults to an empty array.
*
* @param string|array $attr Extra attributes to apply to the option
* tag. If a string, they are added as-is; if an array, the key is
* the attribute name and the value is the attribute value.
*
* @return string A set of HTML <option> tags.
*
*/
function plugin($options, $selected = array(), $attr = null,
$labelIsValue = false)
{
$html = '';
// force $selected to be an array. this allows multi-selects to
// have multiple selected options.
settype($selected, 'array');
settype($options, 'array');
// loop through the options array
foreach ($options as $value => $label) {
// is the label being used as the value?
if ($labelIsValue) {
$value = $label;
}
// set the value and label in the tag
$html .= '<option value="' . htmlspecialchars($value) . '"';
$html .= ' label="' . htmlspecialchars($label) . '"';
// is the option one of the selected values?
if (in_array($value, $selected)) {
$html .= ' selected="selected"';
}
// are we adding extra attributes?
if (is_array($attr)) {
// yes, from an array
foreach ($attr as $key => $val) {
$val = htmlspecialchars($val);
$html .= " $key=\"$val\"";
}
} elseif (! is_null($attr)) {
// yes, from a string
$html .= ' ' . $attr;
}
// add the label and close the tag
$html .= '>' . htmlspecialchars($label) . "</option>\n";
}
return $html;
}
}
?>

View File

@ -0,0 +1,130 @@
<?php
/**
* Base plugin class.
*/
require_once 'Savant2/Plugin.php';
/**
*
* Outputs a set of radio <input>s with the same name.
*
* $Id$
*
* @author Paul M. Jones <pmjones@ciaweb.net>
*
* @package Savant2
*
* @license http://www.gnu.org/copyleft/lesser.html LGPL
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as
* published by the Free Software Foundation; either version 2.1 of the
* License, or (at your option) any later version.
*
* This 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
* Lesser General Public License for more details.
*
*/
class Savant2_Plugin_radios extends Savant2_Plugin {
/**
*
* Outputs a set of radio <input>s with the same name.
*
* @access public
*
* @param string $name The HTML "name=" value of all the radio <input>s.
*
* @param array $radios An array of key-value pairs where the key is the
* radio button value and the value is the radio button label.
*
* @param string $checked A comparison string; if any of the $option
* element values and $checked are the same, that radio button will
* be marked as "checked" (otherwise not).
*
* @param array $default The value to return if no radio buttons are
* checked.
*
* @param string|array $attr Any extra HTML attributes to place
* within the checkbox element.
*
* @param string $sep The HTML text to place between every radio
* button in the set.
*
* @return string
*
*/
function plugin(
$name,
$radios,
$checked = null,
$default = null,
$sep = "<br />\n",
$attr = null,
$labelIsValue = false
)
{
settype($radios, 'array');
$html = '';
// define the hidden default value (if any) when no buttons are checked
if (! is_null($default)) {
$html .= '<input type="hidden"';
$html .= ' name="' . htmlspecialchars($name) . '"';
$html .= ' value="' . htmlspecialchars($default) . '" />';
$html .= "\n";
}
// the array of individual radio buttons
$radio = array();
// build the full set of radio buttons
foreach ($radios as $value => $label) {
// reset to blank HTML for this radio button
$tmp = '';
// is the label being used as the value?
if ($labelIsValue) {
$value = $label;
}
// start the radio button tag
$tmp .= '<input type="radio"';
$tmp .= ' name="' . htmlspecialchars($name) . '"';
$tmp .= ' value="' . htmlspecialchars($value) . '"';
// is the radio button selected?
if ($value == $checked) {
$tmp .= ' checked="checked"';
}
// add extra attributes
if (is_array($attr)) {
// add from array
foreach ($attr as $key => $val) {
$key = htmlspecialchars($key);
$val = htmlspecialchars($val);
$tmp .= " $key=\"$val\"";
}
} elseif (! is_null($attr)) {
// add from scalar
$tmp .= " $attr";
}
// add the label and save the button in the array
$tmp .= ' />' . htmlspecialchars($label);
$radio[] = $tmp;
}
// return the radio buttons with separators
return $html . implode($sep, $radio);
}
}
?>

View File

@ -0,0 +1,56 @@
<?php
/**
* Base plugin class.
*/
require_once 'Savant2/Plugin.php';
/**
*
* Outputs a <link ... /> to a CSS stylesheet.
*
* $Id$
*
* @author Paul M. Jones <pmjones@ciaweb.net>
*
* @package Savant2
*
* @license http://www.gnu.org/copyleft/lesser.html LGPL
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as
* published by the Free Software Foundation; either version 2.1 of the
* License, or (at your option) any later version.
*
* This 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
* Lesser General Public License for more details.
*
*/
class Savant2_Plugin_stylesheet extends Savant2_Plugin {
/**
*
* Output a <link ... /> to a CSS stylesheet.
*
* @access public
*
* @param object &$savant A reference to the calling Savant2 object.
*
* @param string $href The HREF leading to the stylesheet file.
*
* @return string
*
*/
function plugin($href)
{
return '<link rel="stylesheet" type="text/css" href="' .
htmlspecialchars($href) . '" />';
}
}
?>

View File

@ -0,0 +1,81 @@
<?php
/**
* Base plugin class.
*/
require_once 'Savant2/Plugin.php';
/**
*
* Outputs a single <textarea> element.
*
* $Id$
*
* @author Paul M. Jones <pmjones@ciaweb.net>
*
* @package Savant2
*
* @license http://www.gnu.org/copyleft/lesser.html LGPL
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as
* published by the Free Software Foundation; either version 2.1 of the
* License, or (at your option) any later version.
*
* This 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
* Lesser General Public License for more details.
*
*/
class Savant2_Plugin_textarea extends Savant2_Plugin {
/**
*
* Outputs a single <textarea> element.
*
* @access public
*
* @param string $name The HTML "name=" value.
*
* @param string $text The initial value of the textarea element.
*
* @param int $rows How many rows tall should the area be?
*
* @param int $cols The many columns wide should the area be?
*
* @param string $attr Any "extra" HTML code to place within the
* checkbox element.
*
* @return string
*
*/
function plugin($name, $text = '', $rows = 24, $cols = 80, $attr = null)
{
// start the tag
$html = '<textarea name="' . htmlspecialchars($name) . '"';
$html .= ' rows="' . htmlspecialchars($rows) . '"';
$html .= ' cols="' . htmlspecialchars($cols) . '"';
// add extra attributes
if (is_array($attr)) {
// add from array
foreach ($attr as $key => $val) {
$key = htmlspecialchars($key);
$val = htmlspecialchars($val);
$html .= " $key=\"$val\"";
}
} elseif (! is_null($attr)) {
// add from scalar
$html .= " $attr";
}
// add the default text, close the tag, and return
$html .= '>' . htmlspecialchars($text) . '</textarea>';
return $html;
}
}
?>

View File

@ -0,0 +1,141 @@
<?php
/**
*
* Tests assign() issues
*
* @version $Id$
*
*/
error_reporting(E_ALL);
require_once 'Savant2.php';
$savant =& new Savant2(array('template_path' => 'templates'));
echo "<h1>assign 0 (string, null)</h1>";
$val = null;
$result = $savant->assign('nullvar', $val);
echo "result: <pre>";
print_r($result);
echo "</pre>";
echo "properties: <pre>";
print_r(get_object_vars($savant));
echo "</pre>";
echo "<h1>assign 1 (string, mixed)</h1>";
$result = $savant->assign('variable', 'variable_value');
echo "result: <pre>";
print_r($result);
echo "</pre>";
echo "properties: <pre>";
print_r(get_object_vars($savant));
echo "</pre>";
echo "<h1>assign 2 (array)</h1>";
$result = $savant->assign(array('array1' => 'value1', 'array2' => 'value2'));
echo "result: <pre>";
print_r($result);
echo "</pre>";
echo "properties: <pre>";
print_r(get_object_vars($savant));
echo "</pre>";
echo "<h1>assign 3 (object)</h1>";
$object = new StdClass();
$object->obj1 = 'this';
$object->obj2 = 'that';
$object->obj3 = 'other';
$result = $savant->assign($object);
echo "result: <pre>";
print_r($result);
echo "</pre>";
echo "properties: <pre>";
print_r(get_object_vars($savant));
echo "</pre>";
echo "<h1>assignRef</h1>";
$reference = 'reference_value';
$result = $savant->assignRef('reference', $reference);
echo "result: <pre>";
print_r($result);
echo "</pre>";
echo "properties: <pre>";
print_r(get_object_vars($savant));
echo "</pre>";
/*
echo "<h1>assignObject</h1>";
$object = new stdClass();
$result = $savant->assignObject('object', $object);
echo "result: <pre>";
print_r($result);
echo "</pre>";
echo "properties: <pre>";
print_r(get_object_vars($savant));
echo "</pre>";
*/
echo "<h1>Assign variable without value</h1>";
$result = $savant->assign('variable_without_value');
echo "result: <pre>";
print_r($result);
echo "</pre>";
echo "properties: <pre>";
print_r(get_object_vars($savant));
echo "</pre>";
echo "<h1>Assign reference without value</h1>";
$result = $savant->assignRef('reference_without_value');
echo "result: <pre>";
print_r($result);
echo "</pre>";
echo "properties: <pre>";
print_r(get_object_vars($savant));
echo "</pre>";
/*
echo "<h1>Assign object when value is not object</h1>";
$reference3 = 'failed!';
$result = $savant->assignObject('object2', $reference3);
echo "result: <pre>";
print_r($result);
echo "</pre>";
echo "properties: <pre>";
print_r(get_object_vars($savant));
echo "</pre>";
*/
echo "<h1>Change reference values from logic</h1>";
$reference = 'CHANGED VALUE FROM LOGIC';
echo "properties: <pre>";
print_r(get_object_vars($savant));
echo "</pre>";
echo "<h1>getVars</h1>";
echo "<p>All</p><pre>";
print_r($savant->getVars());
echo "</pre>";
echo "<p>Some</p><pre>";
print_r($savant->getVars(array('obj1', 'obj2', 'obj3')));
echo "</pre>";
echo "<p>One</p><pre>";
print_r($savant->getVars('variable'));
echo "</pre>";
echo "<p>Nonexistent</p><pre>";
var_dump($savant->getVars('nosuchvar'));
echo "</pre>";
$savant->display('assign.tpl.php');
echo "<p>After: $reference</p>";
?>

View File

@ -0,0 +1,72 @@
<?php
/**
*
* Tests display() issues
*
* @version $Id$
*
*/
error_reporting(E_ALL);
require_once 'Savant2.php';
$conf = array(
'template_path' => 'templates',
'resource_path' => 'resources'
);
$savant =& new Savant2($conf);
$array = array(
'key0' => 'val0',
'key1' => 'val1',
'key2' => 'val2',
);
$var1 = 'variable1';
$var2 = 'variable2';
$var3 = 'variable3';
$ref1 = 'reference1';
$ref2 = 'reference2';
$ref3 = 'reference3';
// assign vars
$savant->assign($var1, $var1);
$savant->assign($var2, $var2);
$savant->assign($var3, $var3);
// assigns $array to a variable $set
$savant->assign('set', $array);
// assigns the keys and values of array
$savant->assign($array);
// assign references
$savant->assignRef($ref1, $ref1);
$savant->assignRef($ref2, $ref2);
$savant->assignRef($ref3, $ref3);
echo "<h1>Display non-existent template</h1>";
$result = $savant->display('no_such_template.tpl.php');
echo "result: <pre>";
print_r($result);
echo "</pre>";
echo "<h1>Storage</h1>";
echo "properties: <pre>";
print_r(get_object_vars($savant));
echo "</pre>";
echo "<h1>Display existing template</h1>";
$result = $savant->display('test.tpl.php');
echo "result: <pre>";
var_dump($result);
echo "</pre>";
?>

View File

@ -0,0 +1,71 @@
<?php
/**
*
* Tests fetch() issues
*
* @version $Id$
*
*/
error_reporting(E_ALL);
require_once 'Savant2.php';
$conf = array(
'template_path' => 'templates',
'resource_path' => 'resources'
);
$savant =& new Savant2($conf);
$array = array(
'key0' => 'val0',
'key1' => 'val1',
'key2' => 'val2',
);
$var1 = 'variable1';
$var2 = 'variable2';
$var3 = 'variable3';
$ref1 = 'reference1';
$ref2 = 'reference2';
$ref3 = 'reference3';
// assign vars
$savant->assign($var1, $var1);
$savant->assign($var2, $var2);
$savant->assign($var3, $var3);
// assigns $array to a variable $set
$savant->assign('set', $array);
// assigns the keys and values of array
$savant->assign($array);
// assign references
$savant->assignRef($ref1, $ref1);
$savant->assignRef($ref2, $ref2);
$savant->assignRef($ref3, $ref3);
echo "<h1>Fetch non-existent template</h1>";
$result = $savant->fetch('no_such_template.tpl.php');
echo "result: <pre>";
print_r($result);
echo "</pre>";
echo "<h1>Storage</h1>";
echo "properties: <pre>";
print_r(get_object_vars($savant));
echo "</pre>";
echo "<h1>Fetch existing template</h1>";
$result = $savant->fetch('test.tpl.php');
echo "fetched this code: <pre>";
print_r(htmlentities($result));
echo "</pre>";
?>

View File

@ -0,0 +1,85 @@
<?php
/**
*
* Tests default plugins
*
* @version $Id$
*
*/
error_reporting(E_ALL);
require_once 'Savant2.php';
$conf = array(
'template_path' => 'templates',
'resource_path' => 'resources'
);
$savant =& new Savant2($conf);
$array = array(
'key0' => 'val0',
'key1' => 'val1',
'key2' => 'val2',
);
$var1 = 'variable1';
$var2 = 'variable2';
$var3 = 'variable3';
$ref1 = 'reference1';
$ref2 = 'reference2';
$ref3 = 'reference3';
// assign vars
$savant->assign($var1, $var1);
$savant->assign($var2, $var2);
$savant->assign($var3, $var3);
// assigns $array to a variable $set
$savant->assign('set', $array);
// assigns the keys and values of array
$savant->assign($array);
// assign references
$savant->assignRef($ref1, $ref1);
$savant->assignRef($ref2, $ref2);
$savant->assignRef($ref3, $ref3);
// load the cycle plugin with preset cycle values
$savant->loadPlugin(
'cycle',
array(
'values' => array(
'lightdark' => array('light', 'dark')
)
)
);
// preload the image plugin
$savant->loadPlugin('image',
array(
'imageDir' => 'resources/'
)
);
// preload the dateformat plugin
$savant->loadPlugin('dateformat',
array(
'custom' => array(
'mydate' => '%d/%m/%Y'
)
)
);
// preload a custom plugin
$savant->loadPlugin('fester', null, true);
// run through the template
$savant->display('plugins.tpl.php');
// done!
?>

View File

@ -0,0 +1,42 @@
<?php
/**
*
* Tests filters and plugins
*
* @version $Id$
*
*/
error_reporting(E_ALL);
require_once 'Savant2.php';
$conf = array(
'template_path' => 'templates',
'resource_path' => 'resources'
);
$savant =& new Savant2($conf);
// set up filters
$savant->loadFilter('colorizeCode');
$savant->loadFilter('trimwhitespace');
$savant->loadFilter('fester', null, true);
// run through the template
$savant->display('filters.tpl.php');
// do it again to test object persistence
$savant->display('filters.tpl.php');
// do it again to test object persistence
$savant->display('filters.tpl.php');
echo "<hr />\n";
echo "<pre>";
print_r($savant);
echo "</pre>";
?>

View File

@ -0,0 +1,52 @@
<?php
/**
*
* Tests multiple-path directory searches
*
* @version $Id$
*
*/
function preprint($val)
{
echo "<pre>\n";
print_r($val);
echo "</pre>\n";
}
error_reporting(E_ALL);
require_once 'Savant2.php';
$conf = array(
'template_path' => 'templates',
'resource_path' => 'resources'
);
$savant =& new Savant2($conf);
echo "<h1>Paths to begin with</h1>\n";
preprint($savant->getPath('resource'));
preprint($savant->getPath('template'));
echo "<h1>Add a path</h1>\n";
$savant->addPath('resource', 'no/such/path');
preprint($savant->getPath('resource'));
echo "<h1>Find an existing resource (non-default)</h1>\n";
$file = $savant->findFile('resource', 'Savant2_Plugin_cycle.php');
preprint($file);
echo "<h1>Find an existing resource (default)</h1>\n";
$file = $savant->findFile('resource', 'Savant2_Plugin_input.php');
preprint($file);
echo "<h1>Find a non-existent template</h1>\n";
$file = $savant->findFile('template', 'no_such_template.tpl.php');
if ($file) {
preprint($file);
} else {
preprint("false or null");
}
?>

View File

@ -0,0 +1,65 @@
<?php
/**
*
* Tests default plugins
*
* @version $Id$
*
*/
error_reporting(E_ALL);
require_once 'Savant2.php';
$conf = array(
'template_path' => 'templates',
'resource_path' => 'resources'
);
$savant =& new Savant2($conf);
$array = array(
'key0' => 'val0',
'key1' => 'val1',
'key2' => 'val2',
);
$var1 = 'variable1';
$var2 = 'variable2';
$var3 = 'variable3';
$ref1 = 'reference1';
$ref2 = 'reference2';
$ref3 = 'reference3';
// assign vars
$savant->assign($var1, $var1);
$savant->assign($var2, $var2);
$savant->assign($var3, $var3);
// assigns $array to a variable $set
$savant->assign('set', $array);
// assigns the keys and values of array
$savant->assign($array);
// assign references
$savant->assignRef($ref1, $ref1);
$savant->assignRef($ref2, $ref2);
$savant->assignRef($ref3, $ref3);
// load the cycle plugin with preset cycle values
$savant->loadPlugin(
'cycle',
array(
'values' => array(
'lightdark' => array('light', 'dark')
)
)
);
// run through the template
$savant->display('main.tpl.php');
?>

View File

@ -0,0 +1,24 @@
<?php
/**
*
* Tests default plugins
*
* @version $Id$
*
*/
error_reporting(E_ALL);
require_once 'Savant2.php';
$conf = array(
'template_path' => 'templates',
'resource_path' => 'resources'
);
$savant =& new Savant2($conf);
$savant->display('extend.tpl.php');
?>

View File

@ -0,0 +1,46 @@
<?php
/**
*
* Tests default plugins
*
* @version $Id$
*
*/
error_reporting(E_ALL);
require_once 'Savant2.php';
$savant =& new Savant2();
require_once 'PEAR.php';
PEAR::setErrorHandling(PEAR_ERROR_PRINT);
echo "<h1>PEAR_Error</h1>\n";
$savant->setError('pear');
$result = $savant->loadPlugin('nosuchthing');
echo "<pre>\n";
print_r($result);
echo "</pre>\n\n";
echo "<h1>PEAR_ErrorStack</h1>\n";
$savant->setError('stack');
$result = $savant->loadPlugin('nosuchthing');
echo "<pre>\n";
print_r($result);
echo "</pre>\n\n";
echo "<pre>\n";
print_r(print_r($GLOBALS['_PEAR_ERRORSTACK_SINGLETON']));
echo "</pre>\n\n";
echo "<h1>Exception</h1>\n";
$savant->setError('exception');
$result = $savant->loadPlugin('nosuchthing');
echo "<pre>\n";
print_r($result);
echo "</pre>\n\n";
?>

View File

@ -0,0 +1,80 @@
<?php
/**
*
* Tests the basic compiler
*
* @version $Id$
*
*/
function preprint($val)
{
echo "<pre>\n";
print_r($val);
echo "</pre>\n";
}
error_reporting(E_ALL);
// instantiate Savant
require_once 'Savant2.php';
$conf = array(
'template_path' => 'templates',
'resource_path' => 'resources',
'restrict' => true // adding path restrictions!
);
$savant =& new Savant2($conf);
// instantiate a compiler...
require_once 'Savant2/Savant2_Compiler_basic.php';
$compiler =& new Savant2_Compiler_basic();
$compiler->compileDir = '/tmp/';
$compiler->forceCompile = true;
// and tell Savant to use it.
$savant->setCompiler($compiler);
// set up vars
$array = array(
'key0' => 'val0',
'key1' => 'val1',
'key2' => 'val2',
);
$var1 = 'variable1';
$var2 = 'variable2';
$var3 = 'variable3';
$ref1 = 'reference1';
$ref2 = 'reference2';
$ref3 = 'reference3';
// assign vars
$savant->assign($var1, $var1);
$savant->assign($var2, $var2);
$savant->assign($var3, $var3);
// assigns $array to a variable $set
$savant->assign('set', $array);
// assigns the keys and values of array
$savant->assign($array);
// assign references
$savant->assignRef($ref1, $ref1);
$savant->assignRef($ref2, $ref2);
$savant->assignRef($ref3, $ref3);
echo "<h1>The 'good' template</h1>";
$compiler->strict = false;
$result = $savant->display('compile.tpl.php');
preprint($result);
echo "<h1>The 'bad' template</h1>";
$compiler->strict = true;
$result = $savant->display('compile_bad.tpl.php');
preprint($result);
?>

View File

@ -0,0 +1,49 @@
<?php
error_reporting(E_ALL);
require_once 'Savant2.php';
$Savant2 =& new Savant2();
$Savant2->addPath('template', 'templates/');
$Savant2->addPath('resource', 'resources/');
$defaults = array(
'hideme' => null,
'mytext' => null,
'xbox' => null,
'picker' => null,
'picker2' => null,
'chooser' => null,
'myarea' => null
);
$values = array_merge($defaults, $_POST);
$tmp = array();
if ($values['mytext'] == '') {
// required
$tmp[] = 'required';
}
if (strlen($values['mytext']) > 5) {
// max 5 chars
$tmp[] = 'maxlen';
}
if (preg_match('/[0-9]+/', $values['mytext'])) {
// no digits
$tmp[] = 'no_digits';
}
if (count($tmp) == 0) {
$valid = array('mytext' => true);
} else {
$valid = array('mytext' => $tmp);
}
$Savant2->assign('opts', array('one', 'two', 'three', 'four', 'five'));
$Savant2->assign($values);
$Savant2->assign('valid', $valid);
$Savant2->display('form.tpl.php');
?>

View File

@ -0,0 +1,49 @@
<?php
error_reporting(E_ALL);
require_once 'Savant2.php';
$Savant2 =& new Savant2();
$Savant2->addPath('template', 'templates/');
$Savant2->addPath('resource', 'resources/');
$defaults = array(
'hideme' => null,
'mytext' => null,
'xbox' => null,
'picker' => null,
'picker2' => null,
'chooser' => null,
'myarea' => null
);
$values = array_merge($defaults, $_POST);
$tmp = array();
if ($values['mytext'] == '') {
// required
$tmp[] = 'required';
}
if (strlen($values['mytext']) > 5) {
// max 5 chars
$tmp[] = 'maxlen';
}
if (preg_match('/[0-9]+/', $values['mytext'])) {
// no digits
$tmp[] = 'no_digits';
}
if (count($tmp) == 0) {
$valid = array('mytext' => true);
} else {
$valid = array('mytext' => $tmp);
}
$Savant2->assign('opts', array('one', 'two', 'three', 'four', 'five'));
$Savant2->assign($values);
$Savant2->assign('valid', $valid);
$Savant2->display('form2.tpl.php');
?>

View File

@ -0,0 +1,18 @@
<?php
require_once 'Savant2/Filter.php';
class Savant2_Filter_fester extends Savant2_Filter {
var $count = 0;
function filter(&$text)
{
$text .= "<br />Fester has a light bulb in his mouth (" .
$this->count ++ . ")\n";
$text .= "<br />Fester has a light bulb in his mouth again (" .
$this->count ++ . ")\n";
}
}
?>

View File

@ -0,0 +1,19 @@
<?php
/**
*
* Example plugin for unit testing.
*
* @version $Id$
*
*/
require_once 'Savant2/Plugin.php';
class Savant2_Plugin_cycle extends Savant2_Plugin {
function plugin()
{
return "REPLACES DEFAULT CYCLE";
}
}
?>

View File

@ -0,0 +1,22 @@
<?php
/**
*
* Example plugin for unit testing.
*
* @version $Id$
*
*/
require_once 'Savant2/Plugin.php';
class Savant2_Plugin_example extends Savant2_Plugin {
var $msg = "Example: ";
function plugin()
{
echo $this->msg . "this is an example!";
}
}
?>

View File

@ -0,0 +1,18 @@
<?php
/**
*
* Example plugin for unit testing.
*
* @version $Id$
*
*/
$this->loadPlugin('example');
class Savant2_Plugin_example_extend extends Savant2_Plugin_example {
var $msg = "Extended Example! ";
}
?>

View File

@ -0,0 +1,31 @@
<?php
/**
*
* Example plugin for unit testing.
*
* @version $Id$
*
*/
require_once 'Savant2/Plugin.php';
class Savant2_Plugin_fester extends Savant2_Plugin {
var $message = "Fester";
var $count = 0;
function Savant2_Plugin_fester()
{
// do some other constructor stuff
$this->message .= " is printing this: ";
}
function plugin(&$text)
{
$output = $this->message . $text . " ({$this->count})";
$this->count++;
return $output;
}
}
?>

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.0 KiB

View File

@ -0,0 +1,12 @@
<?php
/**
*
* Template for testing token references.
*
* @version $Id$
*
*/
?>
<h1>Change reference values from template</h1>
<p>Before: <?php echo $this->reference; $this->reference = "Changed Value From Template!" ?></p>

View File

@ -0,0 +1,31 @@
{* Savant2_Compiler_basic : compile.tpl.php *}
{tpl 'header.tpl.php'}
<p>{$this->variable1}</p>
<p>{$this->variable2}</p>
<p>{$this->variable3}</p>
<p>{$this->key0}</p>
<p>{$this->key1}</p>
<p>{$this->key2}</p>
<p>{$this->reference1}</p>
<p>{$this->reference2}</p>
<p>{$this->reference3}</p>
<p>{$this->variable1}</p>
<p>Extended printing: {: $this->variable1 . ' ' . $this->variable2}</p>
<ul>
{foreach ($this->set as $key => $val):}
<li>{$key} = {$val} ({$this->set[$key]})</li>
{endforeach}
</ul>
{['form', 'start']}
{['form', 'text', 'example', 'default value', 'label:']}
{['form', 'end']}
<p style="clear: both;"><?php echo "PHP Tags" ?>
{tpl 'footer.tpl.php'}

View File

@ -0,0 +1,35 @@
{* Savant2_Compiler_basic *}
{tpl 'header.tpl.php'}
<p>{$varivari; $this->$varivari}</p>
<p>{$this->variable1; global $_SERVER;}</p>
<p>{$this->variable2; $obj =& new StdClass;}</p>
<p>{$this->variable3; eval("echo 'bad guy!';")}</p>
<p>{$this->key0; print_r($this->_compiler);}</p>
<p>{$this->key1; File::read('/etc/passwd');}</p>
<p>{$this->key2; include "/etc/passwd";}</p>
<p>{$this->reference1; include $this->findTemplate('template.tpl.php') . '../../etc/passwd';}</p>
<p>{$this->reference2; $newvar = $this; $newvar =& $this; $newvar = & $this; $newvar
=
&
$this;
$newvar = array(&$this); }</p>
<p>{$this->reference3; $thisIsOk; $thisIs_OK; $function(); }</p>
<p>{$this->variable1; echo parent::findTemplate('template.tpl.php')}</p>
<ul>
{foreach ($this->set as $key => $val): $this->$key; $this->$val(); }
<li>{$key} = {$val} ({$this->set[$key]})</li>
{endforeach; echo htmlspecialchars(file_get_contents('/etc/httpd/php.ini')); }
</ul>
{['form', 'start']}
{['form', 'text', 'example', 'default value', 'My Text Field:']}
{['form', 'end']}
<p style="clear: both;"><?php echo "PHP Tags" ?>
{tpl 'footer.tpl.php'}

View File

@ -0,0 +1,11 @@
<?php
/**
*
* Template for testing token assignment.
*
* @version $Id$
*
*/
?>
<p><?php $result = $this->plugin('example'); var_dump($result); ?></p>
<p><?php $result = $this->plugin('example_extend'); var_dump($result); ?></p>

View File

@ -0,0 +1,44 @@
<?php
/**
*
* Tests the default and example filters for Savant.
*
* @version $Id$
*
*/
?>
<h1>Filters</h1>
<p>This and that</p>
<p>And the other</p>
<pre><code>
<php>
// this is a test of PHP colorizing
echo "some text";
highlight_string("something");
$variable = 'value';
function fester()
{
// does nothing
}
</php>
</code></pre>
<!-- end -->

View File

@ -0,0 +1,2 @@
</body>
</html>

View File

@ -0,0 +1,140 @@
<html>
<head>
<title>Form Test</title>
<style>
body, table, tr, th, td {
font-family: Verdana;
font-size: 9pt;
background-color: aliceblue;
}
div.Savant-Form {
margin: 8px;
}
fieldset.Savant-Form {
margin: 8px;
border-top: 1px solid silver;
border-left: 1px solid silver;
border-bottom: 1px solid gray;
border-right: 1px solid gray;
padding: 4px;
}
legend.Savant-Form{
padding: 2px 4px;
color: #036;
font-weight: bold;
font-size: 120%;
}
table.Savant-Form {
border-spacing: 0px;
margin: 0px;
spacing: 0px;
padding: 0px;
}
tr.Savant-Form {
}
th.Savant-Form {
padding: 4px;
spacing: 0px;
border: 0px;
text-align: right;
vertical-align: top;
}
td.Savant-Form {
padding: 4px;
spacing: 0px;
border: 0px;
text-align: left;
vertical-align: top;
}
label.Savant-Form {
font-weight: bold;
}
input[type="text"] {
font-family: monospace;
font-size: 9pt;
}
textarea {
font-family: monospace;
font-size: 9pt;
}
</style>
</head>
<body>
<?php
// start a form and set a property
$this->plugin('form', 'start');
$this->plugin('form', 'set', 'class', 'Savant-Form');
// add a hidden value before the layout
$this->plugin('form', 'hidden', 'hideme', 'hidden & valued');
// NEW BLOCK
$this->plugin('form', 'block', 'start', "First Section", 'row');
// text field
$this->plugin('form', 'text', 'mytext', $this->mytext, 'Enter some text here:', null);
// messages for the text field
$this->plugin('form', 'note', null, null, $this->valid['mytext'],
array('required' => 'This field is required.', 'maxlen' => 'No more than 5 letters.', 'no_digits' => 'No digits allowed.'));
$this->plugin('form', 'block', 'split');
// checkbox with default value (array(checked, not-checked))
$this->plugin('form', 'checkbox', 'xbox', $this->xbox, 'Check this:', array(1,0), 'style="text-align: center;"');
// single select
$this->plugin('form', 'select', 'picker', $this->picker, 'Pick one:', $this->opts);
// END THE BLOCK and put in some custom stuff.
$this->plugin('form', 'block', 'end');
?>
<!-- the "clear: both;" is very important when you have floating elements -->
<h1 style="clear: both; background-color: silver; border: 1px solid black; margin: 4px; padding: 4px;">Custom HTML Between Fieldset Blocks</h1>
<?php
// NEW BLOCK
$this->plugin('form', 'block', 'start', "Second Section", 'col');
// multi-select with note
$this->plugin('form', 'group', 'start', 'Pick many:');
$this->plugin('form', 'select', 'picker2[]', $this->picker2, 'Pick many:', $this->opts, 'multiple="multiple"');
$this->plugin('form', 'note', "<br />Pick as many as you like; use the Ctrl key on Windows, or the Cmd key on Macintosh.");
$this->plugin('form', 'group', 'end');
// radio buttons
$this->plugin('form', 'radio', 'chooser', $this->chooser, 'Choose one:', $this->opts);
// NEW BLOCK
$this->plugin('form', 'block', 'start', null, 'row');
// text area
$this->plugin('form', 'textarea', 'myarea', $this->myarea, 'Long text:', array('rows'=>12,'cols'=>40));
// NEW BLOCK (clears floats)
$this->plugin('form', 'block', 'start', null, 'row', null, 'both');
$this->plugin('form', 'submit', 'op', 'Save');
$this->plugin('form', 'reset', 'op', 'Reset');
$this->plugin('form', 'button', '', 'Click Me!', null, array('onClick' => 'return alert("hello!")'));
// end the form
$this->plugin('form', 'end');
?>
</body>
</html>

View File

@ -0,0 +1,140 @@
<html>
<head>
<title>Form Test</title>
<style>
body, table, tr, th, td {
font-family: Verdana;
font-size: 9pt;
background-color: aliceblue;
}
div.Savant-Form {
margin: 8px;
}
fieldset.Savant-Form {
margin: 8px;
border-top: 1px solid silver;
border-left: 1px solid silver;
border-bottom: 1px solid gray;
border-right: 1px solid gray;
padding: 4px;
}
legend.Savant-Form{
padding: 2px 4px;
color: #036;
font-weight: bold;
font-size: 120%;
}
table.Savant-Form {
border-spacing: 0px;
margin: 0px;
spacing: 0px;
padding: 0px;
}
tr.Savant-Form {
}
th.Savant-Form {
padding: 4px;
spacing: 0px;
border: 0px;
text-align: right;
vertical-align: top;
}
td.Savant-Form {
padding: 4px;
spacing: 0px;
border: 0px;
text-align: left;
vertical-align: top;
}
label.Savant-Form {
font-weight: bold;
}
input[type="text"] {
font-family: monospace;
font-size: 9pt;
}
textarea {
font-family: monospace;
font-size: 9pt;
}
</style>
</head>
<body>
<?php
// start a form and set a property
$this->form('start');
$this->form('set', 'class', 'Savant-Form');
// add a hidden value before the layout
$this->form('hidden', 'hideme', 'hidden & valued');
// NEW BLOCK
$this->form('block', 'start', "First Section", 'row');
// text field
$this->form('text', 'mytext', $this->mytext, 'Enter some text here:', null);
// messages for the text field
$this->form('note', null, null, $this->valid['mytext'],
array('required' => 'This field is required.', 'maxlen' => 'No more than 5 letters.', 'no_digits' => 'No digits allowed.'));
$this->form('block', 'split');
// checkbox with default value (array(checked, not-checked))
$this->form('checkbox', 'xbox', $this->xbox, 'Check this:', array(1,0), 'style="text-align: center;"');
// single select
$this->form('select', 'picker', $this->picker, 'Pick one:', $this->opts);
// END THE BLOCK and put in some custom stuff.
$this->form('block', 'end');
?>
<!-- the "clear: both;" is very important when you have floating elements -->
<h1 style="clear: both; background-color: silver; border: 1px solid black; margin: 4px; padding: 4px;">Custom HTML Between Fieldset Blocks</h1>
<?php
// NEW BLOCK
$this->form('block', 'start', "Second Section", 'col');
// multi-select with note
$this->form('group', 'start', 'Pick many:');
$this->form('select', 'picker2[]', $this->picker2, 'Pick many:', $this->opts, 'multiple="multiple"');
$this->form('note', "<br />Pick as many as you like; use the Ctrl key on Windows, or the Cmd key on Macintosh.");
$this->form('group', 'end');
// radio buttons
$this->form('radio', 'chooser', $this->chooser, 'Choose one:', $this->opts);
// NEW BLOCK
$this->form('block', 'start', null, 'row');
// text area
$this->form('textarea', 'myarea', $this->myarea, 'Long text:', array('rows'=>12,'cols'=>40));
// NEW BLOCK (clears floats)
$this->form('block', 'start', null, 'row', null, 'both');
$this->form('submit', 'op', 'Save');
$this->form('reset', 'op', 'Reset');
$this->form('button', '', 'Click Me!', null, array('onClick' => 'return alert("hello!")'));
// end the form
$this->form('end');
?>
</body>
</html>

View File

@ -0,0 +1,7 @@
<html>
<head>
<title>Savant2 Testing</title>
</head>
<body>

View File

@ -0,0 +1,15 @@
<?php
/**
*
* Test includes and loadTemplate()
*
* @version $Id$
*
*/
?>
<?php include $this->loadTemplate('header.tpl.php') ?>
<?php include $this->loadTemplate('plugins.tpl.php') ?>
<?php include $this->loadTemplate('footer.tpl.php') ?>

View File

@ -0,0 +1,192 @@
<?php
/**
*
* Tests the default and example plugins for Savant.
*
* @version $Id$
*
*/
?>
<h1>ahref</h1>
<h2>from strings</h2>
<pre>
<?php
$result = $this->splugin('ahref', 'http://example.com/index.html?this=this&that=that#something', 'Example Link', 'target="_blank"');
echo '<p>' . $this->splugin('modify', $result, 'htmlentities nl2br') . '</p>';
echo "<p>$result</p>";
?>
</pre>
<h2>from arrays</h2>
<pre>
<?php
$result = $this->splugin(
'ahref',
parse_url('http://example.com/index.html?this=this&that=that#something'),
'Example Link',
array('target' => "_blank")
);
echo '<p>' . $this->splugin('modify', $result, 'htmlentities nl2br') . '</p>';
echo "<p>$result</p>";
?>
</pre>
<h1>checkbox</h1>
<pre>
<?php
$result = '';
foreach ($this->set as $key => $val) {
$result .= $this->splugin(
'checkbox', // plugin
"xboxen[$key]", // checkbox name
$key, // checkbox value
'key1', // pre-checked
'', // default value when not checked
'dumb="dumber"' // attributes
);
$result .= $val . "<br /><br />\n";
}
$this->plugin('modify', $result, 'htmlentities nl2br');
?>
</pre>
<form><?php echo $result ?></form>
<h1>cycle</h1>
<h2>repeat 1 on array</h2>
<pre>
<?php for ($i = 0; $i < 9; $i++): ?>
<?php $this->plugin('cycle', array('a', 'b', 'c'), $i) ?><br />
<?php endfor; ?>
</pre>
<h2>repeat 3 on preset</h2>
<pre>
<?php for ($i = 0; $i < 12; $i++): ?>
<?php $this->plugin('cycle', 'lightdark', $i, 3) ?><br />
<?php endfor; ?>
</pre>
<h1>dateformat</h1>
<p><?php $this->plugin('dateformat', "Aug 8, 1970") ?></p>
<p><?php $this->plugin('dateformat', "Aug 8, 1970", 'mydate') ?></p>
<h1>javascript</h1>
<pre><?php echo htmlentities($this->splugin('javascript', 'path/to/file.js')) ?></pre>
<h1>image</h1>
<h2>local</h2>
<pre><?php echo htmlentities($this->splugin('image', 'savant.gif')) ?></pre>
<?php $this->plugin('image', 'savant.gif') ?>
<h2>nonexistent</h2>
<pre><?php echo htmlentities($this->splugin('image', 'savantx.gif', 'image does not exist')) ?></pre>
<?php $this->plugin('image', 'savantx.gif', 'image does not exist') ?>
<h2>stream</h2>
<pre><?php echo htmlentities($this->splugin('image', 'http://phpsavant.com/etc/fester.jpg')) ?></pre>
<?php $this->plugin('image', 'http://phpsavant.com/etc/fester.jpg') ?>
<h1>options</h1>
<h2>assoc</h2>
<pre>
<?php
$result = $this->splugin('options', $this->set, 'key1', 'dumb="dumber"');
$this->plugin('modify', $result, 'htmlentities nl2br');
?>
</pre>
<form><select name="test"><?php echo $result ?></select></form>
<h2>seq</h2>
<pre>
<?php
$result = $this->splugin('options', $this->set, 'val2', array('attrib' => 'this & that'), true);
$this->plugin('modify', $result, 'htmlentities nl2br');
?>
</pre>
<form><select name="test"><?php echo $result ?></select></form>
<h1>radios</h1>
<h2>assoc</h2>
<pre>
<?php
$result = $this->splugin('radios', 'das_radio', $this->set, 'key1', 'nil', "<br /><br />\n", 'dumb="dumber"');
$this->plugin('modify', $result, 'htmlentities nl2br');
?>
</pre>
<form><?php echo $result ?></form>
<h2>seq</h2>
<pre>
<?php
$result = $this->splugin('radios', 'das_radio', $this->set, 'val2', 'nil', "<br /><br />\n", 'dumb="dumber"', true);
$this->plugin('modify', $result, 'htmlentities nl2br');
?>
</pre>
<form><?php echo $result ?></form>
<h1>stylesheet</h1>
<pre><?php echo htmlentities($this->splugin('stylesheet', 'path/to/styles.css')) ?></pre>
<h1>textarea</h1>
<pre>
<?php
$result = $this->splugin('textarea', 'longtext', "some really long text");
$this->plugin('modify', $result, 'htmlentities nl2br');
?>
</pre>
<?php
// tests the plugin path and a call-by-instance plugin
?>
<h1>fester</h1>
<?php $this->plugin('fester', 'Gomez') ?><br />
<?php $this->plugin('fester', 'Morticia') ?><br />
<?php $this->plugin('fester', 'Cara Mia!') ?><br />
<h1>Plugin Objects</h1>
_resource[plugin]: <pre><?php print_r($this->_resource['plugin']) ?></pre>
<!-- end -->

View File

@ -0,0 +1,21 @@
<?php
/**
*
* Template for testing token assignment.
*
* @version $Id$
*
*/
?>
<p><?php echo $this->variable1 ?></p>
<p><?php echo $this->variable2 ?></p>
<p><?php echo $this->variable3 ?></p>
<p><?php echo $this->key0 ?></p>
<p><?php echo $this->key1 ?></p>
<p><?php echo $this->key2 ?></p>
<p><?php echo $this->reference1 ?></p>
<p><?php echo $this->reference2 ?></p>
<p><?php echo $this->reference3 ?></p>
<ul>
<?php foreach ($this->set as $key => $val) echo "<li>$key = $val</li>\n" ?>
</ul>

View File

@ -0,0 +1 @@
2.3.3