+ *
+ * $Savant2 =& new Savant2();
+ *
+ * // assign directly
+ * $Savant2->var1 = 'something';
+ * $Savant2->var2 = 'else';
+ *
+ * // assign by name and value
+ * $Savant2->assign('var1', 'something');
+ * $Savant2->assign('var2', 'else');
+ *
+ * // assign by assoc-array
+ * $ary = array('var1' => 'something', 'var2' => 'else');
+ * $Savant2->assign($obj);
+ *
+ * // assign by object
+ * $obj = new stdClass;
+ * $obj->var1 = 'something';
+ * $obj->var2 = 'else';
+ * $Savant2->assign($obj);
+ *
+ *
+ *
+ * Greg Beaver came up with the idea of assigning to public class
+ * properties.
+ *
+ * @access public
+ *
+ * @return void
+ *
+ * @throws object An error object with a SAVANT2_ERROR_ASSIGN code.
+ *
+ */
+
+ function assign()
+ {
+ // this method is overloaded.
+ $arg = func_get_args();
+
+ // must have at least one argument. no error, just do nothing.
+ if (! isset($arg[0])) {
+ return;
+ }
+
+ // assign by object
+ if (is_object($arg[0])) {
+ // assign public properties
+ foreach (get_object_vars($arg[0]) as $key => $val) {
+ if (substr($key, 0, 1) != '_') {
+ $this->$key = $val;
+ }
+ }
+ return;
+ }
+
+ // assign by associative array
+ if (is_array($arg[0])) {
+ foreach ($arg[0] as $key => $val) {
+ if (substr($key, 0, 1) != '_') {
+ $this->$key = $val;
+ }
+ }
+ return;
+ }
+
+ // assign by string name and mixed value.
+ //
+ // we use array_key_exists() instead of isset() becuase isset()
+ // fails if the value is set to null.
+ if (is_string($arg[0]) &&
+ substr($arg[0], 0, 1) != '_' &&
+ array_key_exists(1, $arg)) {
+ $this->$arg[0] = $arg[1];
+ } else {
+ return $this->error(SAVANT2_ERROR_ASSIGN, $arg);
+ }
+ }
+
+
+ /**
+ *
+ * Sets references for the template.
+ *
+ * // assign by name and value
+ * $Savant2->assignRef('ref', $reference);
+ *
+ * // assign directly
+ * $Savant2->ref =& $reference;
+ *
+ * Greg Beaver came up with the idea of assigning to public class
+ * properties.
+ *
+ * @access public
+ *
+ * @param string $key The name for the reference in the template.
+ *
+ * @param mixed &$val The referenced variable.
+ *
+ * @return void
+ *
+ * @throws object An error object with a SAVANT2_ERROR_ASSIGNREF code.
+ *
+ */
+
+ function assignRef($key, &$val)
+ {
+ if (is_string($key) && substr($key, 0, 1) != '_') {
+ $this->$key =& $val;
+ } else {
+ return $this->error(
+ SAVANT2_ERROR_ASSIGNREF,
+ array('key' => $key, 'val' => $val)
+ );
+ }
+ }
+
+
+ /**
+ *
+ * Unsets assigned variables and references.
+ *
+ * @access public
+ *
+ * @param mixed $var If null, clears all variables; if a string, clears
+ * the one variable named by the string; if a sequential array, clears
+ * the variables names in that array.
+ *
+ * @return void
+ *
+ */
+
+ function clear($var = null)
+ {
+ if (is_null($var)) {
+ // clear all variables
+ $var = array_keys(get_object_vars($this));
+ } else {
+ // clear specific variables
+ settype($var, 'array');
+ }
+
+ // clear out the selected variables
+ foreach ($var as $name) {
+ if (substr($name, 0, 1) != '_' && isset($this->$name)) {
+ unset($this->$name);
+ }
+ }
+ }
+
+
+ /**
+ *
+ * Gets the current value of one, many, or all assigned variables.
+ *
+ * Never returns variables starting with an underscore; these are
+ * reserved for internal Savant2 use.
+ *
+ * @access public
+ *
+ * @param mixed $key If null, returns a copy of all variables and
+ * their values; if an array, returns an only those variables named
+ * in the array; if a string, returns only that variable.
+ *
+ * @return mixed If multiple variables were reqested, returns an
+ * associative array where the key is the variable name and the
+ * value is the variable value; if one variable was requested,
+ * returns the variable value only.
+ *
+ */
+
+ function getVars($key = null)
+ {
+ if (is_null($key)) {
+ $key = array_keys(get_object_vars($this));
+ }
+
+ if (is_array($key)) {
+ // return a series of vars
+ $tmp = array();
+ foreach ($key as $var) {
+ if (substr($var, 0, 1) != '_' && isset($this->$var)) {
+ $tmp[$var] = $this->$var;
+ }
+ }
+ return $tmp;
+ } else {
+ // return a single var
+ if (substr($key, 0, 1) != '_' && isset($this->$key)) {
+ return $this->$key;
+ }
+ }
+ }
+
+
+ // -----------------------------------------------------------------
+ //
+ // Template processing
+ //
+ // -----------------------------------------------------------------
+
+
+ /**
+ *
+ * Loads a template script for execution (does not execute the script).
+ *
+ * This will optionally compile the template source into a PHP script
+ * if a compiler object has been passed into Savant2.
+ *
+ * Also good for including templates from the template paths within
+ * another template, like so:
+ *
+ * include $this->loadTemplate('template.tpl.php');
+ *
+ * @access public
+ *
+ * @param string $tpl The template source name to look for.
+ *
+ * @param bool $setScript Default false; if true, sets the $this->_script
+ * property to the resulting script path (or null on error). Normally,
+ * only $this->fetch() will need to set this to true.
+ *
+ * @return string The full path to the compiled template script.
+ *
+ * @throws object An error object with a SAVANT2_ERROR_NOTEMPLATE code.
+ *
+ */
+
+ function loadTemplate($tpl = null, $setScript = false)
+ {
+ // set to default template if none specified.
+ if (is_null($tpl)) {
+ $tpl = $this->_template;
+ }
+
+ // find the template source.
+ $file = $this->findFile('template', $tpl);
+ if (! $file) {
+ return $this->error(
+ SAVANT2_ERROR_NOTEMPLATE,
+ array('template' => $tpl)
+ );
+ }
+
+ // are we compiling source into a script?
+ if (is_object($this->_compiler)) {
+ // compile the template source and get the path to the
+ // compiled script (will be returned instead of the
+ // source path)
+ $result = $this->_compiler->compile($file);
+ } else {
+ // no compiling requested, return the source path
+ $result = $file;
+ }
+
+ // is there a script from the compiler?
+ if (! $result || $this->isError($result)) {
+
+ if ($setScript) {
+ $this->_script = null;
+ }
+
+ // return an error, along with any error info
+ // generated by the compiler.
+ return $this->error(
+ SAVANT2_ERROR_NOSCRIPT,
+ array(
+ 'template' => $tpl,
+ 'compiler' => $result
+ )
+ );
+
+ } else {
+
+ if ($setScript) {
+ $this->_script = $result;
+ }
+
+ return $result;
+
+ }
+ }
+
+
+ /**
+ *
+ * This is a an alias to loadTemplate() that cannot set the script.
+ *
+ * @access public
+ *
+ * @param string $tpl The template source name to look for.
+ *
+ * @return string The full path to the compiled template script.
+ *
+ * @throws object An error object with a SAVANT2_ERROR_NOTEMPLATE code.
+ *
+ */
+
+ function findTemplate($tpl = null)
+ {
+ return $this->loadTemplate($tpl, false);
+ }
+
+
+ /**
+ *
+ * Executes a template script and returns the results as a string.
+ *
+ * @param string $_tpl The name of the template source file ...
+ * automatically searches the template paths and compiles as needed.
+ *
+ * @return string The output of the the template script.
+ *
+ * @throws object An error object with a SAVANT2_ERROR_NOSCRIPT code.
+ *
+ */
+
+ function fetch($_tpl = null)
+ {
+ // clear prior output
+ $this->_output = null;
+
+ // load the template script
+ $_result = $this->loadTemplate($_tpl, true);
+
+ // is there a template script to be processed?
+ if ($this->isError($_result)) {
+ return $_result;
+ }
+
+ // unset so as not to introduce into template scope
+ unset($_tpl);
+ unset($_result);
+
+ // never allow a 'this' property
+ if (isset($this->this)) {
+ unset($this->this);
+ }
+
+ // are we extracting variables into local scope?
+ if ($this->_extract) {
+ // extract references to this object's public properties.
+ // this allows variables assigned by-reference to refer all
+ // the way back to the model logic. variables assigned
+ // by-copy only refer back to the property.
+ foreach (array_keys(get_object_vars($this)) as $_prop) {
+ if (substr($_prop, 0, 1) != '_') {
+ // set a variable-variable to an object property
+ // reference
+ $$_prop =& $this->$_prop;
+ }
+ }
+
+ // unset private loop vars
+ unset($_prop);
+ }
+
+ // start capturing output into a buffer
+ ob_start();
+
+ // include the requested template filename in the local scope
+ // (this will execute the view logic).
+ include $this->_script;
+
+ // done with the requested template; get the buffer and
+ // clear it.
+ $this->_output = ob_get_contents();
+ ob_end_clean();
+
+ // done!
+ return $this->applyFilters();
+ }
+
+
+ /**
+ *
+ * Execute and display a template script.
+ *
+ * @param string $tpl The name of the template file to parse;
+ * automatically searches through the template paths.
+ *
+ * @return void
+ *
+ * @throws object An error object with a SAVANT2_ERROR_NOSCRIPT code.
+ *
+ * @see fetch()
+ *
+ */
+
+ function display($tpl = null)
+ {
+ $result = $this->fetch($tpl);
+ if ($this->isError($result)) {
+ return $result;
+ } else {
+ echo $result;
+ }
+ }
+
+
+ // -----------------------------------------------------------------
+ //
+ // Plugins
+ //
+ // -----------------------------------------------------------------
+
+
+ /**
+ *
+ * Loads a plugin class and instantiates it within Savant2.
+ *
+ * @access public
+ *
+ * @param string $name The plugin name (not including Savant2_Plugin_
+ * prefix).
+ *
+ * @param array $conf An associative array of plugin configuration
+ * options.
+ *
+ * @param bool $savantRef Default false. When true, sets the $Savant
+ * property of the filter to a reference to this Savant object.
+ *
+ * @return void
+ *
+ * @throws object An error object with a SAVANT2_ERROR_NOPLUGIN code.
+ *
+ */
+
+ function loadPlugin($name, $conf = array(), $savantRef = null)
+ {
+ // if no $savantRef is provided, use the default.
+ if (is_null($savantRef)) {
+ $savantRef = $this->_reference;
+ }
+
+ // some basic information
+ $class = "Savant2_Plugin_$name";
+ $file = "$class.php";
+
+ // is it loaded?
+ if (! class_exists($class)) {
+
+ $result = $this->findFile('resource', $file);
+ if (! $result) {
+ return $this->error(
+ SAVANT2_ERROR_NOPLUGIN,
+ array('plugin' => $name)
+ );
+ } else {
+ include_once $result;
+ }
+ }
+
+ // is it instantiated?
+ if (! isset($this->_resource['plugin'][$name]) ||
+ ! is_object($this->_resource['plugin'][$name]) ||
+ ! is_a($this->_resource['plugin'][$name], $class)) {
+
+ // instantiate it
+ $this->_resource['plugin'][$name] =& new $class($conf);
+
+ // add a Savant reference if requested
+ if ($savantRef) {
+ $this->_resource['plugin'][$name]->Savant =& $this;
+ }
+
+ }
+ }
+
+
+ /**
+ *
+ * Unloads one or more plugins from Savant2.
+ *
+ * @access public
+ *
+ * @param string|array $name The plugin name (not including Savant2_Plugin_
+ * prefix). If null, unloads all plugins; if a string, unloads that one
+ * plugin; if an array, unloads all plugins named as values in the array.
+ *
+ * @return void
+ *
+ */
+
+ function unloadPlugin($name = null)
+ {
+ if (is_null($name)) {
+ $this->_resource['plugin'] = array();
+ } else {
+ settype($name, 'array');
+ foreach ($name as $key) {
+ if (isset($this->_resource['plugin'][$key])) {
+ unset($this->_resource['plugin'][$key]);
+ }
+ }
+ }
+ }
+
+
+ /**
+ *
+ * Executes a plugin with arbitrary parameters and returns the
+ * result.
+ *
+ * @access public
+ *
+ * @param string $name The plugin name (not including Savant2_Plugin_
+ * prefix).
+ *
+ * @return mixed The plugin results.
+ *
+ * @throws object An error object with a SAVANT2_ERROR_NOPLUGIN code.
+ *
+ * @see loadPlugin()
+ *
+ */
+
+ function splugin($name)
+ {
+ // attempt to load the plugin
+ $result = $this->loadPlugin($name);
+ if ($this->isError($result)) {
+ return $result;
+ }
+
+ // call the plugin's "plugin()" method with arguments,
+ // dropping the first argument (the plugin name)
+ $args = func_get_args();
+ array_shift($args);
+ return call_user_func_array(
+ array(&$this->_resource['plugin'][$name], 'plugin'), $args
+ );
+ }
+
+
+ /**
+ *
+ * Executes a plugin with arbitrary parameters and displays the
+ * result.
+ *
+ * @access public
+ *
+ * @param string $name The plugin name (not including Savant2_Plugin_
+ * prefix).
+ *
+ * @return void
+ *
+ * @throws object An error object with a SAVANT2_ERROR_NOPLUGIN code.
+ *
+ */
+
+ function plugin($name)
+ {
+ $args = func_get_args();
+
+ $result = call_user_func_array(
+ array(&$this, 'splugin'),
+ $args
+ );
+
+ if ($this->isError($result)) {
+ return $result;
+ } else {
+ echo $result;
+ }
+ }
+
+
+ /**
+ *
+ * PHP5 ONLY: Magic method alias to plugin().
+ *
+ * E.g., instead of $this->plugin('form', ...) you would use
+ * $this->form(...). You can set this to use any other Savant2 method
+ * by issuing, for example, setCall('splugin') to use splugin() ... which
+ * is really the only other sensible choice.
+ *
+ * @access public
+ *
+ * @param string $func The plugin name.
+ *
+ * @param array $args Arguments passed to the plugin.
+ *
+ * @return void
+ *
+ * @throws object An error object with a SAVANT2_ERROR_NOPLUGIN code.
+ *
+ */
+
+ function __call($func, $args)
+ {
+ // add the plugin name to the args
+ array_unshift($args, $func);
+
+ // call the plugin() method
+ return call_user_func_array(
+ array(&$this, $this->_call),
+ $args
+ );
+ }
+
+
+ // -----------------------------------------------------------------
+ //
+ // Filters
+ //
+ // -----------------------------------------------------------------
+
+
+ /**
+ *
+ * Loads a filter class and instantiates it within Savant2.
+ *
+ * @access public
+ *
+ * @param string $name The filter name (not including Savant2_Filter_
+ * prefix).
+ *
+ * @param array $conf An associative array of filter configuration
+ * options.
+ *
+ * @param bool $savantRef Default false. When true, sets the $Savant
+ * property of the filter to a reference to this Savant object.
+ *
+ * @return void
+ *
+ * @throws object An error object with a SAVANT2_ERROR_NOFILTER code.
+ *
+ */
+
+ function loadFilter($name, $conf = array(), $savantRef = null)
+ {
+ // if no $savantRef is provided, use the default.
+ if (is_null($savantRef)) {
+ $savantRef = $this->_reference;
+ }
+
+ // some basic information
+ $class = "Savant2_Filter_$name";
+ $file = "$class.php";
+
+ // is it loaded?
+ if (! class_exists($class)) {
+
+ $result = $this->findFile('resource', $file);
+ if (! $result) {
+ return $this->error(
+ SAVANT2_ERROR_NOFILTER,
+ array('filter' => $name)
+ );
+ } else {
+ include_once $result;
+ }
+ }
+
+ // is it instantiated?
+ if (! isset($this->_resource['filter'][$name]) ||
+ ! is_object($this->_resource['filter'][$name]) ||
+ ! is_a($this->_resource['filter'][$name], $class)) {
+
+ // instantiate it
+ $this->_resource['filter'][$name] =& new $class($conf);
+
+ // add a Savant reference if requested
+ if ($savantRef) {
+ $this->_resource['filter'][$name]->Savant =& $this;
+ }
+
+ }
+ }
+
+
+ /**
+ *
+ * Unloads one or more filters from Savant2.
+ *
+ * @access public
+ *
+ * @param string|array $name The filter name (not including Savant2_Filter_
+ * prefix). If null, unloads all filters; if a string, unloads that one
+ * filter; if an array, unloads all filters named as values in the array.
+ *
+ * @return void
+ *
+ */
+
+ function unloadFilter($name = null)
+ {
+ if (is_null($name)) {
+ $this->_resource['filter'] = array();
+ } else {
+ settype($name, 'array');
+ foreach ($name as $key) {
+ if (isset($this->_resource['filter'][$key])) {
+ unset($this->_resource['filter'][$key]);
+ }
+ }
+ }
+ }
+
+
+ /**
+ *
+ * Apply all loaded filters, in order, to text.
+ *
+ * @access public
+ *
+ * @param string $text The text to which filters should be applied.
+ * If null, sets the text to $this->_output.
+ *
+ * @return string The text after being passed through all loded
+ * filters.
+ *
+ */
+
+ function applyFilters($text = null)
+ {
+ // set to output text if no text specified
+ if (is_null($text)) {
+ $text = $this->_output;
+ }
+
+ // get the list of filter names...
+ $filter = array_keys($this->_resource['filter']);
+
+ // ... and apply them each in turn.
+ foreach ($filter as $name) {
+ $this->_resource['filter'][$name]->filter($text);
+ }
+
+ // done
+ return $text;
+ }
+
+
+ // -----------------------------------------------------------------
+ //
+ // Error handling
+ //
+ // -----------------------------------------------------------------
+
+
+ /**
+ *
+ * Returns an error object.
+ *
+ * @access public
+ *
+ * @param int $code A SAVANT2_ERROR_* constant.
+ *
+ * @param array $info An array of error-specific information.
+ *
+ * @return object An error object of the type specified by
+ * $this->_error.
+ *
+ */
+
+ function &error($code, $info = array())
+ {
+ // the error config array
+ $conf = array(
+ 'code' => $code,
+ 'text' => 'Savant2: ',
+ 'info' => (array) $info
+ );
+
+ // set an error message from the globals
+ if (isset($GLOBALS['_SAVANT2']['error'][$code])) {
+ $conf['text'] .= $GLOBALS['_SAVANT2']['error'][$code];
+ } else {
+ $conf['text'] .= '???';
+ }
+
+ // set up the error class name
+ if ($this->_error) {
+ $class = 'Savant2_Error_' . $this->_error;
+ } else {
+ $class = 'Savant2_Error';
+ }
+
+ // set up the error class file name
+ $file = $class . '.php';
+
+ // is it loaded?
+ if (! class_exists($class)) {
+
+ // find the error class
+ $result = $this->findFile('resource', $file);
+ if (! $result) {
+ // could not find the custom error class, revert to
+ // Savant_Error base class.
+ $class = 'Savant2_Error';
+ $result = dirname(__FILE__) . '/Savant2/Error.php';
+ }
+
+ // include the error class
+ include_once $result;
+ }
+
+ // instantiate and return the error class
+ $err =& new $class($conf);
+ return $err;
+ }
+
+
+ /**
+ *
+ * Tests if an object is of the Savant2_Error class.
+ *
+ * @access public
+ *
+ * @param object &$obj The object to be tested.
+ *
+ * @return boolean True if $obj is an error object of the type
+ * Savant2_Error, or is a subclass that Savant2_Error. False if not.
+ *
+ */
+
+ function isError(&$obj)
+ {
+ if (is_object($obj)) {
+ if (is_a($obj, 'Savant2_Error') ||
+ is_subclass_of($obj, 'Savant2_Error')) {
+ return true;
+ }
+ }
+
+ return false;
+ }
+}
+?>
diff --git a/phpgwapi/inc/savant2/Savant2/Compiler.php b/phpgwapi/inc/savant2/Savant2/Compiler.php
new file mode 100755
index 0000000000..ad02271072
--- /dev/null
+++ b/phpgwapi/inc/savant2/Savant2/Compiler.php
@@ -0,0 +1,72 @@
+
+*
+* @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)
+ {
+ }
+}
+?>
\ No newline at end of file
diff --git a/phpgwapi/inc/savant2/Savant2/Error.php b/phpgwapi/inc/savant2/Savant2/Error.php
new file mode 100755
index 0000000000..0d2051e953
--- /dev/null
+++ b/phpgwapi/inc/savant2/Savant2/Error.php
@@ -0,0 +1,125 @@
+
+*
+* @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()
+ {
+ }
+}
+?>
\ No newline at end of file
diff --git a/phpgwapi/inc/savant2/Savant2/Filter.php b/phpgwapi/inc/savant2/Savant2/Filter.php
new file mode 100755
index 0000000000..632f5b7d86
--- /dev/null
+++ b/phpgwapi/inc/savant2/Savant2/Filter.php
@@ -0,0 +1,76 @@
+
+*
+* @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)
+ {
+ }
+}
+?>
\ No newline at end of file
diff --git a/phpgwapi/inc/savant2/Savant2/PHPCodeAnalyzer.php b/phpgwapi/inc/savant2/Savant2/PHPCodeAnalyzer.php
new file mode 100755
index 0000000000..9f9d56eb54
--- /dev/null
+++ b/phpgwapi/inc/savant2/Savant2/PHPCodeAnalyzer.php
@@ -0,0 +1,471 @@
+
+* @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:
+*
+* $analyzer = new PHPCodeAnalyzer();
+* $analyzer->source = file_get_contents(__FILE__);
+* $analyzer->analyze();
+* print_r($analyzer->calledMethods);
+*
+*
+* @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 "; + //print_r($ca); + //echo ""; + // --- 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', + ); + } +} + + + +?> \ No newline at end of file diff --git a/phpgwapi/inc/savant2/Savant2/Savant2_Error_exception.php b/phpgwapi/inc/savant2/Savant2/Savant2_Error_exception.php new file mode 100755 index 0000000000..61a7106e0e --- /dev/null +++ b/phpgwapi/inc/savant2/Savant2/Savant2_Error_exception.php @@ -0,0 +1,53 @@ + +* +* @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); + } +} +?> \ No newline at end of file diff --git a/phpgwapi/inc/savant2/Savant2/Savant2_Error_pear.php b/phpgwapi/inc/savant2/Savant2/Savant2_Error_pear.php new file mode 100755 index 0000000000..f7e62d3b81 --- /dev/null +++ b/phpgwapi/inc/savant2/Savant2/Savant2_Error_pear.php @@ -0,0 +1,56 @@ + +* +* @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); + } +} +?> \ No newline at end of file diff --git a/phpgwapi/inc/savant2/Savant2/Savant2_Error_stack.php b/phpgwapi/inc/savant2/Savant2/Savant2_Error_stack.php new file mode 100755 index 0000000000..32a783fd9e --- /dev/null +++ b/phpgwapi/inc/savant2/Savant2/Savant2_Error_stack.php @@ -0,0 +1,60 @@ + +* +* @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 + ); + } +} +?> \ No newline at end of file diff --git a/phpgwapi/inc/savant2/Savant2/Savant2_Filter_colorizeCode.php b/phpgwapi/inc/savant2/Savant2/Savant2_Filter_colorizeCode.php new file mode 100755 index 0000000000..0a5d287454 --- /dev/null +++ b/phpgwapi/inc/savant2/Savant2/Savant2_Filter_colorizeCode.php @@ -0,0 +1,123 @@ +... tags. +* +* @author Paul M. Jones
...
tags.
+ *
+ * Colorizes all text between ...
tags with PHP's
+ * highlight_string function. Additionally, this will convert HTML
+ * entities within 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 block, use the custom
+ * tag , and use 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 tag.
+ // this will remove the text "" from the block, so
+ // we'll need to add it in again later.
+ $blocks = explode('', $text);
+
+ // loop through each block and convert text within
+ //
tags.
+ foreach ($blocks as $key => $val) {
+
+ // now find then the ending
within the block
+ $pos = strpos($val, '
');
+
+ if ($pos === false) {
+
+ // there was no
tag -- do nothing
+
+ } else {
+
+ // change all and tags
+ $val = str_replace('', '', '?>', $val); // , and
+ // thus the part we want to modify.
+ //
+ // $tmp[1] will be the part after the
+ //
block, which we will leave
+ // alone.
+ //
+ // this will remove the text "
" from the
+ // text, so we'll need to add it in again when modifying
+ // the text.
+ $tmp = explode('
', $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(" 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);
+ }
+}
\ No newline at end of file
diff --git a/phpgwapi/inc/savant2/Savant2/Savant2_Filter_trimwhitespace.php b/phpgwapi/inc/savant2/Savant2/Savant2_Filter_trimwhitespace.php
new file mode 100755
index 0000000000..aebe0b9b7c
--- /dev/null
+++ b/phpgwapi/inc/savant2/Savant2/Savant2_Filter_trimwhitespace.php
@@ -0,0 +1,104 @@
+
+*
+* @author Contributions from Lars Noschinski
+*
+* @author Converted to a Savant2 filter by Paul M. Jones
+*
+*
+* @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 >
and blocks.
+ *
+ * @access public
+ *
+ * @param string &$source The source text to be filtered.
+ *
+ */
+
+ function filter(&$source)
+ {
+ // Pull out the script blocks
+ preg_match_all("!!is", $source, $match);
+ $_script_blocks = $match[0];
+ $source = preg_replace("!!is",
+ '@@@SAVANT:TRIM:SCRIPT@@@', $source);
+
+ // Pull out the pre blocks
+ preg_match_all("!]+>.*?
!is", $source, $match);
+ $_pre_blocks = $match[0];
+ $source = preg_replace("!]+>.*?
!is",
+ '@@@SAVANT:TRIM:PRE@@@', $source);
+
+ // Pull out the textarea blocks
+ preg_match_all("!!is", $source, $match);
+ $_textarea_blocks = $match[0];
+ $source = preg_replace("!!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;
+ }
+ }
+ }
+
+}
+?>
\ No newline at end of file
diff --git a/phpgwapi/inc/savant2/Savant2/Savant2_Plugin_ahref.php b/phpgwapi/inc/savant2/Savant2/Savant2_Plugin_ahref.php
new file mode 100755
index 0000000000..14b9a2abe5
--- /dev/null
+++ b/phpgwapi/inc/savant2/Savant2/Savant2_Plugin_ahref.php
@@ -0,0 +1,114 @@
+... tag.
+*
+* $Id$
+*
+* @author Paul M. Jones
+*
+* @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 ... 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 tag.
+ *
+ * @return string The ... tag.
+ *
+ */
+
+ function plugin($href, $text, $attr = null)
+ {
+ $html = ' $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) . '';
+ return $html;
+ }
+}
+?>
\ No newline at end of file
diff --git a/phpgwapi/inc/savant2/Savant2/Savant2_Plugin_checkbox.php b/phpgwapi/inc/savant2/Savant2/Savant2_Plugin_checkbox.php
new file mode 100755
index 0000000000..d84a3f20bf
--- /dev/null
+++ b/phpgwapi/inc/savant2/Savant2/Savant2_Plugin_checkbox.php
@@ -0,0 +1,103 @@
+ element.
+*
+* $Id$
+*
+* @author Paul M. Jones
+*
+* @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 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 .= '';
+ $html .= "\n";
+ }
+
+ // start the checkbox tag with name and value
+ $html .= ' $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;
+ }
+}
+?>
\ No newline at end of file
diff --git a/phpgwapi/inc/savant2/Savant2/Savant2_Plugin_cycle.php b/phpgwapi/inc/savant2/Savant2/Savant2_Plugin_cycle.php
new file mode 100755
index 0000000000..a90c7233e5
--- /dev/null
+++ b/phpgwapi/inc/savant2/Savant2/Savant2_Plugin_cycle.php
@@ -0,0 +1,97 @@
+
+*
+* @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)];
+ }
+}
+?>
\ No newline at end of file
diff --git a/phpgwapi/inc/savant2/Savant2/Savant2_Plugin_dateformat.php b/phpgwapi/inc/savant2/Savant2/Savant2_Plugin_dateformat.php
new file mode 100755
index 0000000000..cc6fb09fc6
--- /dev/null
+++ b/phpgwapi/inc/savant2/Savant2/Savant2_Plugin_dateformat.php
@@ -0,0 +1,136 @@
+
+*
+* @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;
+ }
+ }
+
+}
+?>
\ No newline at end of file
diff --git a/phpgwapi/inc/savant2/Savant2/Savant2_Plugin_form.php b/phpgwapi/inc/savant2/Savant2/Savant2_Plugin_form.php
new file mode 100755
index 0000000000..a32f8f714c
--- /dev/null
+++ b/phpgwapi/inc/savant2/Savant2/Savant2_Plugin_form.php
@@ -0,0 +1,1596 @@
+
+*
+* @package Savant2
+*
+* @todo Add non-standard elements: date, time, hierselect, autocomplete
+*
+* @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_form extends Savant2_Plugin {
+
+
+ /**
+ *
+ * The CSS class to use when generating form layout.
+ *
+ * This class name will be applied to the following tags:
+ *
+ * - div
+ * - fieldset
+ * - legend
+ * - table
+ * - tr
+ * - th
+ * - td
+ * - label
+ *
+ * @access public
+ *
+ * @var array
+ *
+ */
+
+ var $class = '';
+
+
+ /**
+ *
+ * The default 'float' style for fieldset blocks.
+ *
+ * @access public
+ *
+ * @var string
+ *
+ */
+
+ var $float = '';
+
+
+ /**
+ *
+ * The default 'clear' style for fieldset blocks.
+ *
+ * @access public
+ *
+ * @var string
+ *
+ */
+
+ var $clear = '';
+
+
+ /**
+ *
+ * The sprintf() format for element notes in col-type blocks.
+ *
+ * @access public
+ *
+ * @var string
+ *
+ */
+
+ var $noteCol = '%s';
+
+
+ /**
+ *
+ * The sprintf() format for element notes in row-type blocks.
+ *
+ * @access public
+ *
+ * @var string
+ *
+ */
+
+ var $noteRow = '%s';
+
+
+ /**
+ *
+ * The text used to separate radio buttons in col-type blocks.
+ *
+ * @access public
+ *
+ * @var string
+ *
+ */
+
+ var $radioCol = '
';
+
+
+ /**
+ *
+ * The text used to separate radio buttons in row-type blocks.
+ *
+ * @access public
+ *
+ * @var string
+ *
+ */
+
+ var $radioRow = ' ';
+
+
+ /**
+ *
+ * The base number of tabs to use when tidying up the generated XHTML.
+ *
+ * @access public
+ *
+ * @var int
+ *
+ */
+
+ var $tabBase = 2;
+
+
+ /**
+ *
+ * The sprintf() format for validation messages in col-type blocks.
+ *
+ * @access public
+ *
+ * @var string
+ *
+ */
+
+ var $validCol = '
%s';
+
+
+ /**
+ *
+ * The sprintf() format for validation messages in col-type blocks.
+ *
+ * @access public
+ *
+ * @var string
+ *
+ */
+
+ var $validRow = '
%s';
+
+
+ /**
+ *
+ * Whether or not to automatically dispel magic quotes from values.
+ *
+ * @access public
+ *
+ * @var bool
+ *
+ */
+
+ var $unquote = true;
+
+
+ /**
+ *
+ * Whether or not to use automatic layout.
+ *
+ * @access public
+ *
+ * @var bool
+ *
+ */
+
+ var $layout = true;
+
+
+ /**
+ *
+ * The kind of fieldset block being generated ('col' or 'row').
+ *
+ * @access private
+ *
+ * @var bool
+ *
+ */
+
+ var $_blockType = null;
+
+
+ /**
+ *
+ * The legend for the fieldset block, if any.
+ *
+ * @access private
+ *
+ * @var string
+ *
+ */
+
+ var $_blockLabel = null;
+
+
+ /**
+ *
+ * Whether or not the form is generating elements within a fieldset block.
+ *
+ * @access private
+ *
+ * @var bool
+ *
+ */
+
+ var $_inBlock = false;
+
+
+ /**
+ *
+ * Whether or not the form is generating elements as a group.
+ *
+ * @access private
+ *
+ * @var bool
+ *
+ */
+
+ var $_inGroup = false;
+
+
+ /**
+ *
+ * The number of tabs to use before certain tags when tidying XHTML layout.
+ *
+ * @access private
+ *
+ * @var bool
+ *
+ */
+
+ var $_tabs = array(
+ 'form' => 0,
+ '/form' => 0,
+ 'div' => 1,
+ '/div' => 1,
+ 'fieldset' => 1,
+ '/fieldset' => 1,
+ 'legend' => 2,
+ 'table' => 2,
+ '/table' => 2,
+ 'tr' => 3,
+ '/tr' => 3,
+ 'th' => 4,
+ '/th' => 4,
+ 'td' => 4,
+ '/td' => 4,
+ 'label' => 5,
+ 'input type="button"' => 5,
+ 'input type="checkbox"' => 5,
+ 'input type="file"' => 5,
+ 'input type="hidden"' => 5,
+ 'input type="image"' => 5,
+ 'input type="password"' => 5,
+ 'input type="reset"' => 5,
+ 'input type="submit"' => 5,
+ 'input type="text"' => 5,
+ 'textarea' => 5,
+ 'select' => 5,
+ '/select' => 5,
+ 'option' => 6
+ );
+
+
+ /**
+ *
+ * Central switcher API for the the various public methods.
+ *
+ * @access public
+ *
+ * @param string $method The public method to call from this class; all
+ * additional parameters will be passed to the called method, and all
+ * returns from the mehtod will be tidied.
+ *
+ * @return string XHTML generated by the public method.
+ *
+ */
+
+ function plugin($method)
+ {
+ // only pass calls to public methods (i.e., no leading underscore)
+ if (substr($method, 0, 1) != '_' && method_exists($this, $method)) {
+
+ // get all arguments and drop the first one (the method name)
+ $args = func_get_args();
+ array_shift($args);
+
+ // call the method, then return the tidied-up XHTML results
+ $xhtml = call_user_func_array(array(&$this, $method), $args);
+ return $this->_tidy($xhtml);
+ }
+ }
+
+
+ /**
+ *
+ * Sets the value of a public property.
+ *
+ * @access public
+ *
+ * @param string $key The name of the property to set.
+ *
+ * @param mixed $val The new value for the property.
+ *
+ * @return void
+ *
+ */
+
+ function set($key, $val)
+ {
+ if (substr($key, 0, 1) != '_' && isset($this->$key)) {
+ $this->$key = $val;
+ }
+ }
+
+
+ // ---------------------------------------------------------------------
+ //
+ // Form methods
+ //
+ // ---------------------------------------------------------------------
+
+
+ /**
+ *
+ * Starts the form.
+ *
+ * The form defaults to 'action="$_SERVER['REQUEST_URI']"' and
+ * 'method="post"', but you can override those, and add any other
+ * attributes you like.
+ *
+ * @access public
+ *
+ * @param array|string $attr Attributes to add to the form tag.
+ *
+ * @return A tag.
+ *
+ */
+
+ function end()
+ {
+ $xhtml = '';
+ $xhtml .= $this->group('end');
+ $xhtml .= $this->block('end');
+ return $xhtml . '';
+ }
+
+
+ // ---------------------------------------------------------------------
+ //
+ // Element methods
+ //
+ // ---------------------------------------------------------------------
+
+
+ /**
+ *
+ * Generates a 'button' element.
+ *
+ * @access public
+ *
+ * @param string $name The element name.
+ *
+ * @param mixed $value The element value.
+ *
+ * @param string $label The element label.
+ *
+ * @param array|string $attr Attributes for the element tag.
+ *
+ * @param mixed $validCode A validation code. If exactly boolean
+ * true, or exactly null, no validation message will be displayed.
+ * If any other integer, string, or array value, the element is
+ * treated as not-valid and will display the corresponding message.
+ *
+ * @param mixed array|string $validMsg A validation message. If an
+ * array, the $validCode value is used as a key for this array to
+ * determine which message(s) should be displayed.
+ *
+ * @return string The element XHTML.
+ *
+ */
+
+ function button($name, $value = null, $label = null, $attr = null,
+ $validCode = null, $validMsg = null)
+ {
+ $xhtml = $this->_input('button', $name, $value, $attr);
+ return $this->_element($label, $xhtml, $validCode, $validMsg);
+ }
+
+
+ /**
+ *
+ * Generates a 'checkbox' element.
+ *
+ * @access public
+ *
+ * @param string $name The element name.
+ *
+ * @param mixed $value The element value.
+ *
+ * @param string $label The element label.
+ *
+ * @param mixed $options If a scalar (single value), then value of the
+ * checkbox when checked; if an array, element 0 is the value when
+ * checked, and element 1 is the value when not-checked.
+ *
+ * @param array|string $attr Attributes for the element tag.
+ *
+ * @param mixed $validCode A validation code. If exactly boolean
+ * true, or exactly null, no validation message will be displayed.
+ * If any other integer, string, or array value, the element is
+ * treated as not-valid and will display the corresponding message.
+ *
+ * @param mixed array|string $validMsg A validation message. If an
+ * array, the $validCode value is used as a key for this array to
+ * determine which message(s) should be displayed.
+ *
+ * @return string The element XHTML.
+ *
+ */
+
+ function checkbox($name, $value = null, $label = null, $options = null,
+ $attr = null, $validCode = null, $validMsg = null)
+ {
+ if (is_null($options)) {
+ $options = array(1, 0);
+ } else {
+ settype($options, 'array');
+ }
+
+ $options = $this->_unquote($options);
+
+ if (isset($options[1])) {
+ $xhtml = $this->_input('hidden', $name, $options[1]);
+ } else {
+ $xhtml = '';
+ }
+
+ $xhtml .= '_attr($attr);
+ $xhtml .= ' />';
+ return $this->_element($label, $xhtml, $validCode, $validMsg);
+ }
+
+
+ /**
+ *
+ * Generates a 'file' element.
+ *
+ * @access public
+ *
+ * @param string $name The element name.
+ *
+ * @param mixed $value The element value.
+ *
+ * @param string $label The element label.
+ *
+ * @param array|string $attr Attributes for the element tag.
+ *
+ * @param mixed $validCode A validation code. If exactly boolean
+ * true, or exactly null, no validation message will be displayed.
+ * If any other integer, string, or array value, the element is
+ * treated as not-valid and will display the corresponding message.
+ *
+ * @param mixed array|string $validMsg A validation message. If an
+ * array, the $validCode value is used as a key for this array to
+ * determine which message(s) should be displayed.
+ *
+ * @return string The element XHTML.
+ *
+ */
+
+ function file($name, $value = null, $label = null, $attr = null,
+ $validCode = null, $validMsg = null)
+ {
+ $xhtml = $this->_input('file', $name, $value, $attr);
+ return $this->_element($label, $xhtml, $validCode, $validMsg);
+ }
+
+
+ /**
+ *
+ * Generates a 'hidden' element (no layout is generated).
+ *
+ * @access public
+ *
+ * @param string $name The element name.
+ *
+ * @param mixed $value The element value.
+ *
+ * @param array|string $attr Attributes for the element tag.
+ *
+ * @return string The element XHTML.
+ *
+ */
+
+ function hidden($name, $value = null, $attr = null)
+ {
+ return $this->_input('hidden', $name, $value, $attr);
+ }
+
+
+ /**
+ *
+ * Generates an 'image' element.
+ *
+ * @access public
+ *
+ * @param string $name The element name.
+ *
+ * @param mixed $src The image HREF source.
+ *
+ * @param string $label The element label.
+ *
+ * @param array|string $attr Attributes for the element tag.
+ *
+ * @param mixed $validCode A validation code. If exactly boolean
+ * true, or exactly null, no validation message will be displayed.
+ * If any other integer, string, or array value, the element is
+ * treated as not-valid and will display the corresponding message.
+ *
+ * @param mixed array|string $validMsg A validation message. If an
+ * array, the $validCode value is used as a key for this array to
+ * determine which message(s) should be displayed.
+ *
+ * @return string The element XHTML.
+ *
+ */
+
+ function image($name, $src, $label = null, $attr = null, $validCode = null,
+ $validMsg = null)
+ {
+ $xhtml = '_attr($attr);
+ $xhtml .= ' />';
+ return $this->_element($label, $xhtml, $validCode, $validMsg);
+ }
+
+
+ /**
+ *
+ * Generates a 'password' element.
+ *
+ * @access public
+ *
+ * @param string $name The element name.
+ *
+ * @param mixed $value The element value.
+ *
+ * @param string $label The element label.
+ *
+ * @param array|string $attr Attributes for the element tag.
+ *
+ * @param mixed $validCode A validation code. If exactly boolean
+ * true, or exactly null, no validation message will be displayed.
+ * If any other integer, string, or array value, the element is
+ * treated as not-valid and will display the corresponding message.
+ *
+ * @param mixed array|string $validMsg A validation message. If an
+ * array, the $validCode value is used as a key for this array to
+ * determine which message(s) should be displayed.
+ *
+ * @return string The element XHTML.
+ *
+ */
+
+ function password($name, $value = null, $label = null, $attr = null,
+ $validCode = null, $validMsg = null)
+ {
+ $xhtml = $this->_input('password', $name, $value, $attr);
+ return $this->_element($label, $xhtml, $validCode, $validMsg);
+ }
+
+
+ /**
+ *
+ * Generates a set of radio button elements.
+ *
+ * @access public
+ *
+ * @param string $name The element name.
+ *
+ * @param mixed $value The radio value to mark as 'checked'.
+ *
+ * @param string $label The element label.
+ *
+ * @param array $options An array of key-value pairs where the array
+ * key is the radio value, and the array value is the radio text.
+ *
+ * @param array|string $attr Attributes added to each radio.
+ *
+ * @param mixed $validCode A validation code. If exactly boolean
+ * true, or exactly null, no validation message will be displayed.
+ * If any other integer, string, or array value, the element is
+ * treated as not-valid and will display the corresponding message.
+ *
+ * @param mixed array|string $validMsg A validation message. If an
+ * array, the $validCode value is used as a key for this array to
+ * determine which message(s) should be displayed.
+ *
+ * @return string The radio buttons XHTML.
+ *
+ */
+
+ function radio($name, $value = null, $label = null, $options = null,
+ $attr = null, $validCode = null, $validMsg = null)
+ {
+ settype($options, 'array');
+ $value = $this->_unquote($value);
+
+ $list = array();
+ foreach ($options as $optval => $optlabel) {
+ $radio = '';
+ }
+ $xhtml .= '';
+ $xhtml .= $this->_tag('td');
+ }
+
+ // build a 'row' group?
+ if ($this->_blockType == 'row') {
+ $xhtml .= $this->_tag('td');
+ if (! is_null($label)) {
+ $xhtml .= $this->_tag('label');
+ $xhtml .= htmlspecialchars($label);
+ $xhtml .= '
';
+ }
+ }
+
+ // we're in a group now
+ $this->_inGroup = true;
+
+ }
+
+ // are we ending a current group?
+ if ($type == 'end' && $this->_inGroup) {
+
+ // we're out of the group now
+ $this->_inGroup = false;
+
+ if ($this->_blockType == 'col') {
+ $xhtml .= '';
+ }
+
+ if ($this->_blockType == 'row') {
+ $xhtml .= '';
+ }
+ }
+
+ // done!
+ return $xhtml;
+ }
+
+
+ // ---------------------------------------------------------------------
+ //
+ // Private support methods
+ //
+ // ---------------------------------------------------------------------
+
+
+ /**
+ *
+ * Builds an attribute string for a tag.
+ *
+ * @access private
+ *
+ * @param array|string $attr The attributes to add to a tag; if an array,
+ * the key is the attribute name and the value is the attribute value; if a
+ * string, adds the literal string to the tag.
+ *
+ * @return string A string of tag attributes.
+ *
+ */
+
+ function _attr($attr = null)
+ {
+ if (is_array($attr)) {
+ // add from array
+ $xhtml = '';
+ foreach ($attr as $key => $val) {
+ $key = htmlspecialchars($key);
+ $val = htmlspecialchars($val);
+ $xhtml .= " $key=\"$val\"";
+ }
+ } elseif (! is_null($attr)) {
+ // add from scalar
+ $xhtml = " $attr";
+ } else {
+ $xhtml = null;
+ }
+
+ return $xhtml;
+ }
+
+
+ /**
+ *
+ * Builds an XHTML opening tag with class and attributes.
+ *
+ * @access private
+ *
+ * @param string $type The tag type ('td', 'th', 'div', etc).
+ *
+ * @param array|string $attr Additional attributes for the tag.
+ *
+ * @return string The opening tag XHTML.
+ *
+ */
+
+ function _tag($type, $attr = null)
+ {
+ // open the tag
+ $xhtml = '<' . $type;
+
+ // add a CSS class attribute
+ if ($this->class) {
+ $xhtml .= ' class="' . $this->class . '"';
+ }
+
+ // add other attributes
+ $xhtml .= $this->_attr($attr);
+
+ // done!
+ return $xhtml . ">";
+ }
+
+
+ /**
+ *
+ * Adds an element to the table layout; auto-starts a block as needed.
+ *
+ * @access private
+ *
+ * @param string $label The label for the element.
+ *
+ * @param string $fieldXhtml The XHTML for the element field.
+ *
+ * @param mixed $validCode A validation code. If exactly boolean
+ * true, or exactly null, no validation message will be displayed.
+ * If any other integer, string, or array value, the element is
+ * treated as not-valid and will display the corresponding message.
+ *
+ * @param mixed array|string $validMsg A validation message. If an
+ * array, the $validCode value is used as a key for this array to
+ * determine which message(s) should be displayed.
+ *
+ * @return string The element layout XHTML.
+ *
+ */
+
+ function _element($label, $fieldXhtml, $validCode = null, $validMsg = null)
+ {
+ // the XHTML to return
+ $xhtml = '';
+
+ // if we're starting an element without having started
+ // a block first, forcibly start a default block
+ if (! $this->_inBlock) {
+
+ // is there a label for the element?
+ if (is_null($label)) {
+ // not in a block, and no label specified. this is most
+ // likely a hidden element above the form itself. just
+ // return the XHTML as it is, no layout at all.
+ return $fieldXhtml;
+ } else {
+ // start a block and continue
+ $xhtml .= $this->block();
+ }
+ }
+
+ // are we checking validation and adding validation messages?
+ if ($validCode === null || $validCode === true) {
+
+ // do nothing
+
+ } else {
+
+ // force to arrays so we can have multiple messages.
+ settype($validCode, 'array');
+ settype($validMsg, 'array');
+
+ // pick the format
+ if ($this->_inBlock && $this->_blockType == 'row') {
+ $format = $this->validRow;
+ } else {
+ $format = $this->validCol;
+ }
+
+ // add the validation messages
+ foreach ($validCode as $code) {
+ if (isset($validMsg[$code])) {
+ // print the message
+ $fieldXhtml .= sprintf(
+ $format,
+ $validMsg[$code]
+ );
+ } else {
+ // print the code
+ $fieldXhtml .= sprintf(
+ $format,
+ $code
+ );
+ }
+ }
+ }
+
+ // are we in a group?
+ if (! $this->_inGroup) {
+ // no, put the element in a group by itself
+ $xhtml .= $this->group('start', $label);
+ $xhtml .= $fieldXhtml;
+ $xhtml .= $this->group('end');
+ } else {
+ // yes, just add the element to the current group.
+ // elements in groups do not get their own labels,
+ // the group has already set the label.
+ $xhtml .= $fieldXhtml;
+ }
+
+ // done!
+ return $xhtml;
+ }
+
+
+ /**
+ *
+ * Recursively removes magic quotes from values and arrays.
+ *
+ * @access private
+ *
+ * @param mixed $value The value from which to remove magic quotes.
+ *
+ * @return mixed The un-quoted value.
+ *
+ */
+
+ function _unquote($value)
+ {
+ if (! $this->unquote) {
+ return $value;
+ }
+
+ static $mq;
+ if (! isset($mq)) {
+ $mq = get_magic_quotes_gpc() || get_magic_quotes_runtime();
+ }
+
+ if ($mq) {
+ if (is_array($value)) {
+ foreach ($value as $k => $v) {
+ $value[$k] = $this->_unquote($v);
+ }
+ } else {
+ $value = stripslashes($value);
+ }
+ }
+
+ return $value;
+ }
+
+
+ /**
+ *
+ * Builds an 'input' element.
+ *
+ * @access private
+ *
+ * @param string $type The input type ('text', 'hidden', etc).
+ *
+ * @param string $name The element name.
+ *
+ * @param mixed $value The element value.
+ *
+ * @param array|string $attr Attributes for the element tag.
+ *
+ * @return The 'input' tag XHTML.
+ *
+ */
+
+ function _input($type, $name, $value = null, $attr = null)
+ {
+ $value = $this->_unquote($value);
+ $xhtml = '_attr($attr);
+ $xhtml .= ' />';
+ return $xhtml;
+ }
+
+
+ /**
+ *
+ * Puts in newlines and tabs to make the source code readable.
+ *
+ * @access private
+ *
+ * @param string $xhtml The XHTML to tidy up.
+ *
+ * @return string The tidied XHTML.
+ *
+ */
+
+ function _tidy($xhtml)
+ {
+ // only tidy up if layout is turned on
+ if ($this->layout) {
+ foreach ($this->_tabs as $key => $val) {
+ $key = '<' . $key;
+ $pad = str_pad('', $val + $this->tabBase, "\t");
+ $xhtml = str_replace($key, "\n$pad$key", $xhtml);
+ }
+ }
+ return $xhtml;
+ }
+
+
+ /**
+ *
+ * Generates XHTML to start a fieldset block.
+ *
+ * @access private
+ *
+ * @param string $label The fieldset legend. If an empty string,
+ * builds a fieldset with no legend; if null, builds a div (not a
+ * fieldset).
+ *
+ * @param string $type The layout type to use, 'col' or 'row'. The
+ * 'col' layout uses a left-column for element labels and a
+ * right-column for the elements; the 'row' layout shows the elements
+ * left-to-right, with the element label over the element, all in a
+ * single row.
+ *
+ * @param string $float Whether the block should float 'left' or
+ * 'right' (set to an empty string if you don't want floating).
+ * Defaults to the value of $this->float.
+ *
+ * @param string $float Whether the block should be cleared of 'left'
+ * or 'right' floating blocks (set to an empty string if you don't
+ * want to clear). Defaults to the value of $this->clear.
+ *
+ * @return string The XHTML to start a block.
+ *
+ */
+
+ function _blockStart($label = null, $type = 'col', $float = null,
+ $clear = null)
+ {
+ // the XHTML text to return.
+ $xhtml = '';
+
+ // if not using automated layout, stop now.
+ if (! $this->layout) {
+ return $xhtml;
+ }
+
+ // are we already in a block? if so, end the current one
+ // so we can start a new one.
+ if ($this->_inBlock) {
+ $xhtml .= $this->block('end');
+ }
+
+ // set the new block type and label
+ $this->_inBlock = true;
+ $this->_blockType = $type;
+ $this->_blockLabel = $label;
+
+ // build up the "style" attribute for the new block
+ $style = '';
+
+ if ($float) {
+ $style .= " float: $float;";
+ }
+
+ if ($clear) {
+ $style .= " clear: $clear;";
+ }
+
+ if (! empty($style)) {
+ $attr = 'style="' . trim($style) . '"';
+ } else {
+ $attr = null;
+ }
+
+ // build the block opening XHTML itself; use a fieldset when a label
+ // is specifed, or a div when the label is not specified
+ if (is_string($this->_blockLabel)) {
+
+ // has a label, use a fieldset with e style attribute
+ $xhtml .= $this->_tag('fieldset', $attr);
+
+ // add the label as a legend, if it exists
+ if (! empty($this->_blockLabel)) {
+ $xhtml .= $this->_tag('legend');
+ $xhtml .= htmlspecialchars($this->_blockLabel);
+ $xhtml .= '';
+ }
+
+ } else {
+ // no label, use a div with the style attribute
+ $xhtml .= $this->_tag('div', $attr);
+ }
+
+ // start a table for the block elements
+ $xhtml .= $this->_tag('table');
+
+ // if the block is row-based, start a row
+ if ($this->_blockType == 'row') {
+ $xhtml .= $this->_tag('tr');
+ }
+
+ // done!
+ return $xhtml;
+ }
+
+
+ /**
+ *
+ * Generates the XHTML to end a block.
+ *
+ * @access public
+ *
+ * @return string The XHTML to end a block.
+ *
+ */
+
+ function _blockEnd()
+ {
+ // the XHTML to return
+ $xhtml = '';
+
+ // if not using automated layout, stop now.
+ if (! $this->layout) {
+ return $xhtml;
+ }
+
+ // if not in a block, return right away
+ if (! $this->_inBlock) {
+ return;
+ }
+
+ // are we in a group? if so, end it.
+ if ($this->_inGroup) {
+ $xhtml .= $this->group('end');
+ }
+
+ // end the block layout proper
+ if ($this->_blockType == 'row') {
+ // previous block was type 'row'
+ $xhtml .= '';
+ } else {
+ // previous block was type 'col'
+ $xhtml .= '';
+ }
+
+ // end the fieldset or div tag for the block
+ if (is_string($this->_blockLabel)) {
+ // there was a label, so the block used fieldset
+ $xhtml .= '';
+ } else {
+ // there was no label, so the block used div
+ $xhtml .= '';
+ }
+
+ // reset tracking properties
+ $this->_inBlock = false;
+ $this->_blockType = null;
+ $this->_blockLabel = null;
+
+ // done!
+ return $xhtml;
+ }
+
+
+ /**
+ *
+ * Generates the layout to split the layout within a block.
+ *
+ * @access public
+ *
+ * @return string The XHTML to split the layout with in a block.
+ *
+ */
+
+ function _blockSplit()
+ {
+ // the XHTML to return
+ $xhtml = '';
+
+ // if not using automated layout, stop now.
+ if (! $this->layout) {
+ return $xhtml;
+ }
+
+ // not already in a block, so don't bother.
+ if (! $this->_inBlock) {
+ return;
+ }
+
+ // end any group we might already be in
+ if ($this->_inGroup) {
+ $xhtml .= $this->group('end');
+ }
+
+ // end the current block and start a new one
+ switch ($this->_blockType) {
+
+ case 'row':
+ $xhtml .= '';
+ $xhtml .= $this->_tag('tr');
+ break;
+
+ case 'col':
+ $xhtml .= '';
+ $xhtml .= $this->_tag('table');
+ break;
+ }
+
+ // done!
+ return $xhtml;
+ }
+}
+
+?>
\ No newline at end of file
diff --git a/phpgwapi/inc/savant2/Savant2/Savant2_Plugin_image.php b/phpgwapi/inc/savant2/Savant2/Savant2_Plugin_image.php
new file mode 100755
index 0000000000..1060d06b13
--- /dev/null
+++ b/phpgwapi/inc/savant2/Savant2/Savant2_Plugin_image.php
@@ -0,0 +1,220 @@
+ tag.
+*
+* Support for alpha transparency of PNG files in Microsoft IE added by
+* Edward Ritter; thanks, Edward.
+*
+* $Id$
+*
+* @author Paul M. Jones
+*
+* @author Edward Ritter
+*
+* @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 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 = '_attr($attr);
+
+ // done
+ $html .= '>';
+
+ } else {
+
+ // not IE, so build a normal image tag.
+ $html = '_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;
+ }
+}
+
+?>
\ No newline at end of file
diff --git a/phpgwapi/inc/savant2/Savant2/Savant2_Plugin_input.php b/phpgwapi/inc/savant2/Savant2/Savant2_Plugin_input.php
new file mode 100755
index 0000000000..265fbb101a
--- /dev/null
+++ b/phpgwapi/inc/savant2/Savant2/Savant2_Plugin_input.php
@@ -0,0 +1,82 @@
+ element.
+*
+* $Id$
+*
+* @author Paul M. Jones
+*
+* @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 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 = " $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;
+ }
+}
+
+?>
\ No newline at end of file
diff --git a/phpgwapi/inc/savant2/Savant2/Savant2_Plugin_javascript.php b/phpgwapi/inc/savant2/Savant2/Savant2_Plugin_javascript.php
new file mode 100755
index 0000000000..2bd0a54268
--- /dev/null
+++ b/phpgwapi/inc/savant2/Savant2/Savant2_Plugin_javascript.php
@@ -0,0 +1,54 @@
+ link to a JavaScript file.
+*
+* $Id$
+*
+* @author Paul M. Jones
+*
+* @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 link to a JavaScript file.
+ *
+ * @access public
+ *
+ * @param string $href The HREF leading to the JavaScript source
+ * file.
+ *
+ * @return string
+ *
+ */
+
+ function plugin($href)
+ {
+ return '';
+ }
+
+}
+?>
\ No newline at end of file
diff --git a/phpgwapi/inc/savant2/Savant2/Savant2_Plugin_modify.php b/phpgwapi/inc/savant2/Savant2/Savant2_Plugin_modify.php
new file mode 100755
index 0000000000..191af341aa
--- /dev/null
+++ b/phpgwapi/inc/savant2/Savant2/Savant2_Plugin_modify.php
@@ -0,0 +1,82 @@
+
+*
+* @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;
+ }
+
+}
+?>
\ No newline at end of file
diff --git a/phpgwapi/inc/savant2/Savant2/Savant2_Plugin_options.php b/phpgwapi/inc/savant2/Savant2/Savant2_Plugin_options.php
new file mode 100755
index 0000000000..3960d92200
--- /dev/null
+++ b/phpgwapi/inc/savant2/Savant2/Savant2_Plugin_options.php
@@ -0,0 +1,107 @@
+s.
+*
+* $Id$
+*
+* @author Paul M. Jones
+*
+* @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 \n";
+ }
+
+ return $html;
+ }
+}
+?>
\ No newline at end of file
diff --git a/phpgwapi/inc/savant2/Savant2/Savant2_Plugin_radios.php b/phpgwapi/inc/savant2/Savant2/Savant2_Plugin_radios.php
new file mode 100755
index 0000000000..516d8bba39
--- /dev/null
+++ b/phpgwapi/inc/savant2/Savant2/Savant2_Plugin_radios.php
@@ -0,0 +1,130 @@
+s with the same name.
+*
+* $Id$
+*
+* @author Paul M. Jones
+*
+* @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 s with the same name.
+ *
+ * @access public
+ *
+ * @param string $name The HTML "name=" value of all the radio 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 = "
\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 .= '';
+ $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 .= ' $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);
+ }
+}
+?>
\ No newline at end of file
diff --git a/phpgwapi/inc/savant2/Savant2/Savant2_Plugin_stylesheet.php b/phpgwapi/inc/savant2/Savant2/Savant2_Plugin_stylesheet.php
new file mode 100755
index 0000000000..ace96bda61
--- /dev/null
+++ b/phpgwapi/inc/savant2/Savant2/Savant2_Plugin_stylesheet.php
@@ -0,0 +1,56 @@
+ to a CSS stylesheet.
+*
+* $Id$
+*
+* @author Paul M. Jones
+*
+* @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 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 '';
+ }
+
+}
+
+?>
\ No newline at end of file
diff --git a/phpgwapi/inc/savant2/Savant2/Savant2_Plugin_textarea.php b/phpgwapi/inc/savant2/Savant2/Savant2_Plugin_textarea.php
new file mode 100755
index 0000000000..b81ded5f84
--- /dev/null
+++ b/phpgwapi/inc/savant2/Savant2/Savant2_Plugin_textarea.php
@@ -0,0 +1,81 @@
+ element.
+*
+* $Id$
+*
+* @author Paul M. Jones
+*
+* @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