Actualización

This commit is contained in:
Xes
2025-04-10 12:49:05 +02:00
parent 4aff98e77b
commit 1cdd00920f
9151 changed files with 1800913 additions and 0 deletions

View File

@@ -0,0 +1,388 @@
<?php
/* vim: set expandtab tabstop=4 shiftwidth=4 foldmethod=marker: */
/**
* PEAR_Exception
*
* PHP version 5
*
* @category pear
* @package PEAR_Exception
* @author Tomas V. V. Cox <cox@idecnet.com>
* @author Hans Lellelid <hans@velum.net>
* @author Bertrand Mansion <bmansion@mamasam.com>
* @author Greg Beaver <cellog@php.net>
* @copyright 1997-2009 The Authors
* @license http://opensource.org/licenses/bsd-license.php New BSD License
* @link http://pear.php.net/package/PEAR_Exception
* @since File available since Release 1.0.0
*/
/**
* Base PEAR_Exception Class
*
* 1) Features:
*
* - Nestable exceptions (throw new PEAR_Exception($msg, $prev_exception))
* - Definable triggers, shot when exceptions occur
* - Pretty and informative error messages
* - Added more context info available (like class, method or cause)
* - cause can be a PEAR_Exception or an array of mixed
* PEAR_Exceptions/PEAR_ErrorStack warnings
* - callbacks for specific exception classes and their children
*
* 2) Ideas:
*
* - Maybe a way to define a 'template' for the output
*
* 3) Inherited properties from PHP Exception Class:
*
* protected $message
* protected $code
* protected $line
* protected $file
* private $trace
*
* 4) Inherited methods from PHP Exception Class:
*
* __clone
* __construct
* getMessage
* getCode
* getFile
* getLine
* getTraceSafe
* getTraceSafeAsString
* __toString
*
* 5) Usage example
*
* <code>
* require_once 'PEAR/Exception.php';
*
* class Test {
* function foo() {
* throw new PEAR_Exception('Error Message', ERROR_CODE);
* }
* }
*
* function myLogger($pear_exception) {
* echo $pear_exception->getMessage();
* }
* // each time a exception is thrown the 'myLogger' will be called
* // (its use is completely optional)
* PEAR_Exception::addObserver('myLogger');
* $test = new Test;
* try {
* $test->foo();
* } catch (PEAR_Exception $e) {
* print $e;
* }
* </code>
*
* @category pear
* @package PEAR_Exception
* @author Tomas V.V.Cox <cox@idecnet.com>
* @author Hans Lellelid <hans@velum.net>
* @author Bertrand Mansion <bmansion@mamasam.com>
* @author Greg Beaver <cellog@php.net>
* @copyright 1997-2009 The Authors
* @license http://opensource.org/licenses/bsd-license.php New BSD License
* @version Release: @package_version@
* @link http://pear.php.net/package/PEAR_Exception
* @since Class available since Release 1.0.0
*
*/
class PEAR_Exception extends Exception
{
const OBSERVER_PRINT = -2;
const OBSERVER_TRIGGER = -4;
const OBSERVER_DIE = -8;
protected $cause;
private static $_observers = array();
private static $_uniqueid = 0;
private $_trace;
/**
* Supported signatures:
* - PEAR_Exception(string $message);
* - PEAR_Exception(string $message, int $code);
* - PEAR_Exception(string $message, Exception $cause);
* - PEAR_Exception(string $message, Exception $cause, int $code);
* - PEAR_Exception(string $message, PEAR_Error $cause);
* - PEAR_Exception(string $message, PEAR_Error $cause, int $code);
* - PEAR_Exception(string $message, array $causes);
* - PEAR_Exception(string $message, array $causes, int $code);
* @param string exception message
* @param int|Exception|PEAR_Error|array|null exception cause
* @param int|null exception code or null
*/
public function __construct($message, $p2 = null, $p3 = null)
{
if (is_int($p2)) {
$code = $p2;
$this->cause = null;
} elseif (is_object($p2) || is_array($p2)) {
// using is_object allows both Exception and PEAR_Error
if (is_object($p2) && !($p2 instanceof Exception)) {
if (!class_exists('PEAR_Error') || !($p2 instanceof PEAR_Error)) {
throw new PEAR_Exception('exception cause must be Exception, ' .
'array, or PEAR_Error');
}
}
$code = $p3;
if (is_array($p2) && isset($p2['message'])) {
// fix potential problem of passing in a single warning
$p2 = array($p2);
}
$this->cause = $p2;
} else {
$code = null;
$this->cause = null;
}
parent::__construct($message, $code);
$this->signal();
}
/**
* @param mixed $callback - A valid php callback, see php func is_callable()
* - A PEAR_Exception::OBSERVER_* constant
* - An array(const PEAR_Exception::OBSERVER_*,
* mixed $options)
* @param string $label The name of the observer. Use this if you want
* to remove it later with removeObserver()
*/
public static function addObserver($callback, $label = 'default')
{
self::$_observers[$label] = $callback;
}
public static function removeObserver($label = 'default')
{
unset(self::$_observers[$label]);
}
/**
* @return int unique identifier for an observer
*/
public static function getUniqueId()
{
return self::$_uniqueid++;
}
private function signal()
{
foreach (self::$_observers as $func) {
if (is_callable($func)) {
call_user_func($func, $this);
continue;
}
settype($func, 'array');
switch ($func[0]) {
case self::OBSERVER_PRINT :
$f = (isset($func[1])) ? $func[1] : '%s';
printf($f, $this->getMessage());
break;
case self::OBSERVER_TRIGGER :
$f = (isset($func[1])) ? $func[1] : E_USER_NOTICE;
trigger_error($this->getMessage(), $f);
break;
case self::OBSERVER_DIE :
$f = (isset($func[1])) ? $func[1] : '%s';
die(printf($f, $this->getMessage()));
break;
default:
trigger_error('invalid observer type', E_USER_WARNING);
}
}
}
/**
* Return specific error information that can be used for more detailed
* error messages or translation.
*
* This method may be overridden in child exception classes in order
* to add functionality not present in PEAR_Exception and is a placeholder
* to define API
*
* The returned array must be an associative array of parameter => value like so:
* <pre>
* array('name' => $name, 'context' => array(...))
* </pre>
* @return array
*/
public function getErrorData()
{
return array();
}
/**
* Returns the exception that caused this exception to be thrown
* @access public
* @return Exception|array The context of the exception
*/
public function getCause()
{
return $this->cause;
}
/**
* Function must be public to call on caused exceptions
* @param array
*/
public function getCauseMessage(&$causes)
{
$trace = $this->getTraceSafe();
$cause = array('class' => get_class($this),
'message' => $this->message,
'file' => 'unknown',
'line' => 'unknown');
if (isset($trace[0])) {
if (isset($trace[0]['file'])) {
$cause['file'] = $trace[0]['file'];
$cause['line'] = $trace[0]['line'];
}
}
$causes[] = $cause;
if ($this->cause instanceof PEAR_Exception) {
$this->cause->getCauseMessage($causes);
} elseif ($this->cause instanceof Exception) {
$causes[] = array('class' => get_class($this->cause),
'message' => $this->cause->getMessage(),
'file' => $this->cause->getFile(),
'line' => $this->cause->getLine());
} elseif (class_exists('PEAR_Error') && $this->cause instanceof PEAR_Error) {
$causes[] = array('class' => get_class($this->cause),
'message' => $this->cause->getMessage(),
'file' => 'unknown',
'line' => 'unknown');
} elseif (is_array($this->cause)) {
foreach ($this->cause as $cause) {
if ($cause instanceof PEAR_Exception) {
$cause->getCauseMessage($causes);
} elseif ($cause instanceof Exception) {
$causes[] = array('class' => get_class($cause),
'message' => $cause->getMessage(),
'file' => $cause->getFile(),
'line' => $cause->getLine());
} elseif (class_exists('PEAR_Error') && $cause instanceof PEAR_Error) {
$causes[] = array('class' => get_class($cause),
'message' => $cause->getMessage(),
'file' => 'unknown',
'line' => 'unknown');
} elseif (is_array($cause) && isset($cause['message'])) {
// PEAR_ErrorStack warning
$causes[] = array(
'class' => $cause['package'],
'message' => $cause['message'],
'file' => isset($cause['context']['file']) ?
$cause['context']['file'] :
'unknown',
'line' => isset($cause['context']['line']) ?
$cause['context']['line'] :
'unknown',
);
}
}
}
}
public function getTraceSafe()
{
if (!isset($this->_trace)) {
$this->_trace = $this->getTrace();
if (empty($this->_trace)) {
$backtrace = debug_backtrace();
$this->_trace = array($backtrace[count($backtrace)-1]);
}
}
return $this->_trace;
}
public function getErrorClass()
{
$trace = $this->getTraceSafe();
return $trace[0]['class'];
}
public function getErrorMethod()
{
$trace = $this->getTraceSafe();
return $trace[0]['function'];
}
public function __toString()
{
if (isset($_SERVER['REQUEST_URI'])) {
return $this->toHtml();
}
return $this->toText();
}
public function toHtml()
{
$trace = $this->getTraceSafe();
$causes = array();
$this->getCauseMessage($causes);
$html = '<table style="border: 1px" cellspacing="0">' . "\n";
foreach ($causes as $i => $cause) {
$html .= '<tr><td colspan="3" style="background: #ff9999">'
. str_repeat('-', $i) . ' <b>' . $cause['class'] . '</b>: '
. htmlspecialchars($cause['message']) . ' in <b>' . $cause['file'] . '</b> '
. 'on line <b>' . $cause['line'] . '</b>'
. "</td></tr>\n";
}
$html .= '<tr><td colspan="3" style="background-color: #aaaaaa; text-align: center; font-weight: bold;">Exception trace</td></tr>' . "\n"
. '<tr><td style="text-align: center; background: #cccccc; width:20px; font-weight: bold;">#</td>'
. '<td style="text-align: center; background: #cccccc; font-weight: bold;">Function</td>'
. '<td style="text-align: center; background: #cccccc; font-weight: bold;">Location</td></tr>' . "\n";
foreach ($trace as $k => $v) {
$html .= '<tr><td style="text-align: center;">' . $k . '</td>'
. '<td>';
if (!empty($v['class'])) {
$html .= $v['class'] . $v['type'];
}
$html .= $v['function'];
$args = array();
if (!empty($v['args'])) {
foreach ($v['args'] as $arg) {
if (is_null($arg)) $args[] = 'null';
elseif (is_array($arg)) $args[] = 'Array';
elseif (is_object($arg)) $args[] = 'Object('.get_class($arg).')';
elseif (is_bool($arg)) $args[] = $arg ? 'true' : 'false';
elseif (is_int($arg) || is_double($arg)) $args[] = $arg;
else {
$arg = (string)$arg;
$str = htmlspecialchars(substr($arg, 0, 16));
if (strlen($arg) > 16) $str .= '&hellip;';
$args[] = "'" . $str . "'";
}
}
}
$html .= '(' . implode(', ',$args) . ')'
. '</td>'
. '<td>' . (isset($v['file']) ? $v['file'] : 'unknown')
. ':' . (isset($v['line']) ? $v['line'] : 'unknown')
. '</td></tr>' . "\n";
}
$html .= '<tr><td style="text-align: center;">' . ($k+1) . '</td>'
. '<td>{main}</td>'
. '<td>&nbsp;</td></tr>' . "\n"
. '</table>';
return $html;
}
public function toText()
{
$causes = array();
$this->getCauseMessage($causes);
$causeMsg = '';
foreach ($causes as $i => $cause) {
$causeMsg .= str_repeat(' ', $i) . $cause['class'] . ': '
. $cause['message'] . ' in ' . $cause['file']
. ' on line ' . $cause['line'] . "\n";
}
return $causeMsg . $this->getTraceAsString();
}
}

View File

@@ -0,0 +1,468 @@
<?php
/* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4: */
/**
* Base class for all HTML classes
*
* PHP versions 4 and 5
*
* LICENSE: This source file is subject to version 3.01 of the PHP license
* that is available through the world-wide-web at the following URI:
* http://www.php.net/license/3_01.txt If you did not receive a copy of
* the PHP License and are unable to obtain it through the web, please
* send a note to license@php.net so we can mail you a copy immediately.
*
* @category HTML
* @package HTML_Common
* @author Adam Daniel <adaniel1@eesus.jnj.com>
* @copyright 2001-2009 The PHP Group
* @license http://www.php.net/license/3_01.txt PHP License 3.01
* @version CVS: $Id: Common.php,v 1.15 2009/04/03 15:26:22 avb Exp $
* @link http://pear.php.net/package/HTML_Common/
*/
/**
* Base class for all HTML classes
*
* @category HTML
* @package HTML_Common
* @author Adam Daniel <adaniel1@eesus.jnj.com>
* @version Release: 1.2.5
* @abstract
*/
class HTML_Common
{
/**
* Associative array of attributes
* @var array
* @access private
*/
var $_attributes = array();
/**
* Tab offset of the tag
* @var int
* @access private
*/
var $_tabOffset = 0;
/**
* Tab string
* @var string
* @since 1.7
* @access private
*/
var $_tab = "\11";
/**
* Contains the line end string
* @var string
* @since 1.7
* @access private
*/
var $_lineEnd = "\12";
/**
* HTML comment on the object
* @var string
* @since 1.5
* @access private
*/
var $_comment = '';
public $freezeSeeOnlySelected;
/**
* Class constructor
* @param mixed $attributes Associative array of table tag attributes
* or HTML attributes name="value" pairs
* @param int $tabOffset Indent offset in tabs
* @access public
*/
public function __construct($attributes = null, $tabOffset = 0)
{
$this->freezeSeeOnlySelected = false;
$this->setAttributes($attributes);
$this->setTabOffset($tabOffset);
} // end constructor
/**
* Returns the current API version
* @access public
* @returns double
*/
function apiVersion()
{
return 1.7;
} // end func apiVersion
/**
* Returns the lineEnd
*
* @since 1.7
* @access private
* @return string
*/
function _getLineEnd()
{
return $this->_lineEnd;
} // end func getLineEnd
/**
* Returns a string containing the unit for indenting HTML
*
* @since 1.7
* @access private
* @return string
*/
function _getTab()
{
return $this->_tab;
} // end func _getTab
/**
* Returns a string containing the offset for the whole HTML code
*
* @return string
* @access private
*/
function _getTabs()
{
return str_repeat($this->_getTab(), $this->_tabOffset);
}
/**
* Returns an HTML formatted attribute string
* @param array $attributes
* @return string
* @access private
*/
public function _getAttrString($attributes)
{
$strAttr = '';
if (is_array($attributes)) {
$charset = self::charset();
foreach ($attributes as $key => $value) {
if (is_array($value)) {
continue;
}
// Modified by Ivan Tcholakov, 16-MAR-2010
$value = @htmlspecialchars($value, ENT_COMPAT, $charset);
$strAttr .= ' ' . $key . '="' . $value. '"';
}
}
return $strAttr;
}
/**
* Returns a valid attributes array from either a string or array
* @param mixed $attributes Either a typical HTML attribute string or an associative array
* @access private
* @return array
*/
public function _parseAttributes($attributes)
{
if (is_array($attributes)) {
$ret = array();
foreach ($attributes as $key => $value) {
if (is_int($key)) {
$key = $value = strtolower($value);
} else {
$key = strtolower($key);
}
$ret[$key] = $value;
}
return $ret;
} elseif (is_string($attributes)) {
$preg = "/(([A-Za-z_:]|[^\\x00-\\x7F])([A-Za-z0-9_:.-]|[^\\x00-\\x7F])*)" .
"([ \\n\\t\\r]+)?(=([ \\n\\t\\r]+)?(\"[^\"]*\"|'[^']*'|[^ \\n\\t\\r]*))?/";
if (preg_match_all($preg, $attributes, $regs)) {
for ($counter=0; $counter<count($regs[1]); $counter++) {
$name = $regs[1][$counter];
$check = $regs[0][$counter];
$value = $regs[7][$counter];
if (trim($name) == trim($check)) {
$arrAttr[strtolower(trim($name))] = strtolower(trim($name));
} else {
if (substr($value, 0, 1) == "\"" || substr($value, 0, 1) == "'") {
$arrAttr[strtolower(trim($name))] = substr($value, 1, -1);
} else {
$arrAttr[strtolower(trim($name))] = trim($value);
}
}
}
return $arrAttr;
}
}
} // end func _parseAttributes
/**
* Returns the array key for the given non-name-value pair attribute
*
* @param string $attr Attribute
* @param array $attributes Array of attribute
* @since 1.0
* @access private
* @return bool
*/
function _getAttrKey($attr, $attributes)
{
if (isset($attributes[strtolower($attr)])) {
return true;
} else {
return null;
}
} //end func _getAttrKey
/**
* Updates the attributes in $attr1 with the values in $attr2 without changing the other existing attributes
* @param array $attr1 Original attributes array
* @param array $attr2 New attributes array
* @access private
*/
function _updateAttrArray(&$attr1, $attr2)
{
if (!is_array($attr2)) {
return false;
}
foreach ($attr2 as $key => $value) {
$attr1[$key] = $value;
}
} // end func _updateAtrrArray
/**
* Removes the given attribute from the given array
*
* @param string $attr Attribute name
* @param array $attributes Attribute array
* @since 1.4
* @access private
* @return void
*/
function _removeAttr($attr, &$attributes)
{
$attr = strtolower($attr);
if (isset($attributes[$attr])) {
unset($attributes[$attr]);
}
}
/**
* Returns the value of the given attribute
*
* @param string $attr Attribute name
* @since 1.5
* @access public
* @return string|null returns null if an attribute does not exist
*/
public function getAttribute($attr)
{
$attr = strtolower($attr);
if (isset($this->_attributes[$attr])) {
return $this->_attributes[$attr];
}
return null;
}
/**
* Sets the value of the attribute
*
* @param string Attribute name
* @param string Attribute value (will be set to $name if omitted)
* @access public
*/
function setAttribute($name, $value = null)
{
$name = strtolower($name);
if (is_null($value)) {
$value = $name;
}
$this->_attributes[$name] = $value;
} // end func setAttribute
/**
* Sets the HTML attributes
* @param mixed $attributes Either a typical HTML attribute string or an associative array
* @access public
*/
function setAttributes($attributes)
{
$this->_attributes = $this->_parseAttributes($attributes);
} // end func setAttributes
/**
* Returns the assoc array (default) or string of attributes
*
* @param bool Whether to return the attributes as string
* @since 1.6
* @access public
* @return mixed attributes
*/
function getAttributes($asString = false)
{
if ($asString) {
return $this->_getAttrString($this->_attributes);
} else {
return $this->_attributes;
}
} //end func getAttributes
/**
* Updates the passed attributes without changing the other existing attributes
* @param mixed $attributes Either a typical HTML attribute string or an associative array
* @access public
*/
function updateAttributes($attributes)
{
$this->_updateAttrArray($this->_attributes, $this->_parseAttributes($attributes));
} // end func updateAttributes
/**
* Removes an attribute
*
* @param string $attr Attribute name
* @since 1.4
* @access public
* @return void
*/
function removeAttribute($attr)
{
$this->_removeAttr($attr, $this->_attributes);
} //end func removeAttribute
/**
* Sets the line end style to Windows, Mac, Unix or a custom string.
*
* @param string $style "win", "mac", "unix" or custom string.
* @since 1.7
* @access public
* @return void
*/
function setLineEnd($style)
{
switch ($style) {
case 'win':
$this->_lineEnd = "\15\12";
break;
case 'unix':
$this->_lineEnd = "\12";
break;
case 'mac':
$this->_lineEnd = "\15";
break;
default:
$this->_lineEnd = $style;
}
} // end func setLineEnd
/**
* Sets the tab offset
*
* @param int $offset
* @access public
*/
function setTabOffset($offset)
{
$this->_tabOffset = $offset;
} // end func setTabOffset
/**
* Returns the tabOffset
*
* @since 1.5
* @access public
* @return int
*/
function getTabOffset()
{
return $this->_tabOffset;
} //end func getTabOffset
/**
* Sets the string used to indent HTML
*
* @since 1.7
* @param string $string String used to indent ("\11", "\t", ' ', etc.).
* @access public
* @return void
*/
function setTab($string)
{
$this->_tab = $string;
} // end func setTab
/**
* Sets the HTML comment to be displayed at the beginning of the HTML string
*
* @param string
* @since 1.4
* @access public
* @return void
*/
function setComment($comment)
{
$this->_comment = $comment;
} // end func setHtmlComment
/**
* Returns the HTML comment
*
* @since 1.5
* @access public
* @return string
*/
function getComment()
{
return $this->_comment;
} //end func getComment
/**
* Abstract method. Must be extended to return the objects HTML
*
* @access public
* @return string
* @abstract
*/
function toHtml()
{
return '';
} // end func toHtml
/**
* Displays the HTML to the screen
*
* @access public
*/
function display()
{
print $this->toHtml();
} // end func display
/**
* Sets the charset to use by htmlspecialchars() function
*
* Since this parameter is expected to be global, the function is designed
* to be called statically:
* <code>
* HTML_Common::charset('utf-8');
* </code>
* or
* <code>
* $charset = HTML_Common::charset();
* </code>
*
* @param string New charset to use. Omit if just getting the
* current value. Consult the htmlspecialchars() docs
* for a list of supported character sets.
* @return string Current charset
* @access public
* @static
*/
function charset($newCharset = null)
{
return 'UTF-8';
}
}

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,55 @@
<?php
/* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4: */
/**
* Class representing an action to perform on HTTP request.
*
* PHP versions 4 and 5
*
* LICENSE: This source file is subject to version 3.01 of the PHP license
* that is available through the world-wide-web at the following URI:
* http://www.php.net/license/3_01.txt If you did not receive a copy of
* the PHP License and are unable to obtain it through the web, please
* send a note to license@php.net so we can mail you a copy immediately.
*
* @category HTML
* @package HTML_QuickForm_Controller
* @author Alexey Borzov <avb@php.net>
* @copyright 2003-2009 The PHP Group
* @license http://www.php.net/license/3_01.txt PHP License 3.01
* @version SVN: $Id: Action.php 289084 2009-10-02 06:53:09Z avb $
* @link http://pear.php.net/package/HTML_QuickForm_Controller
*/
/**
* Class representing an action to perform on HTTP request.
*
* The Controller will select the appropriate Action to call on the request and
* call its perform() method. The subclasses of this class should implement all
* the necessary business logic.
*
* @category HTML
* @package HTML_QuickForm_Controller
* @author Alexey Borzov <avb@php.net>
* @version Release: 1.0.10
* @abstract
*/
class HTML_QuickForm_Action
{
/**
* Processes the request. This method should be overriden by child classes to
* provide the necessary logic.
*
* @access public
* @param HTML_QuickForm_Page The current form-page
* @param string Current action name, as one Action object
* can serve multiple actions
* @throws PEAR_Error
* @abstract
*/
function perform(&$page, $actionName)
{
}
}
?>

View File

@@ -0,0 +1,65 @@
<?php
/* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4: */
/**
* The action for a 'back' button of wizard-type multipage form.
*
* PHP versions 4 and 5
*
* LICENSE: This source file is subject to version 3.01 of the PHP license
* that is available through the world-wide-web at the following URI:
* http://www.php.net/license/3_01.txt If you did not receive a copy of
* the PHP License and are unable to obtain it through the web, please
* send a note to license@php.net so we can mail you a copy immediately.
*
* @category HTML
* @package HTML_QuickForm_Controller
* @author Alexey Borzov <avb@php.net>
* @copyright 2003-2009 The PHP Group
* @license http://www.php.net/license/3_01.txt PHP License 3.01
* @version SVN: $Id: Back.php 289084 2009-10-02 06:53:09Z avb $
* @link http://pear.php.net/package/HTML_QuickForm_Controller
*/
/**
* The action for a 'back' button of wizard-type multipage form.
*
* @category HTML
* @package HTML_QuickForm_Controller
* @author Alexey Borzov <avb@php.net>
* @version Release: 1.0.10
*/
class HTML_QuickForm_Action_Back extends HTML_QuickForm_Action
{
function perform(&$page, $actionName)
{
// save the form values and validation status to the session
$page->isFormBuilt() or $page->buildForm();
$pageName = $page->getAttribute('id');
$data =& $page->controller->container();
$data['values'][$pageName] = $page->exportValues();
if (!$page->controller->isModal()) {
if (PEAR::isError($valid = $page->validate())) {
return $valid;
}
$data['valid'][$pageName] = $valid;
}
// get the previous page and go to it
// we don't check validation status here, 'jump' handler should
if (null === ($prevName = $page->controller->getPrevName($pageName))) {
// Modified by Chamilo team, 16-MAR-2010.
//$page->handle('jump');
return $page->handle('jump');
//
} else {
$prev =& $page->controller->getPage($prevName);
// Modified by Chamilo team, 16-MAR-2010.
//$prev->handle('jump');
return $prev->handle('jump');
//
}
}
}
?>

View File

@@ -0,0 +1,57 @@
<?php
/* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4: */
/**
* This action allows to go to a specific page of a multipage form.
*
* PHP versions 4 and 5
*
* LICENSE: This source file is subject to version 3.01 of the PHP license
* that is available through the world-wide-web at the following URI:
* http://www.php.net/license/3_01.txt If you did not receive a copy of
* the PHP License and are unable to obtain it through the web, please
* send a note to license@php.net so we can mail you a copy immediately.
*
* @category HTML
* @package HTML_QuickForm_Controller
* @author Alexey Borzov <avb@php.net>
* @copyright 2003-2009 The PHP Group
* @license http://www.php.net/license/3_01.txt PHP License 3.01
* @version SVN: $Id: Direct.php 289084 2009-10-02 06:53:09Z avb $
* @link http://pear.php.net/package/HTML_QuickForm_Controller
*/
/**
* This action allows to go to a specific page of a multipage form.
*
* Please note that the name for this action in addAction() should NOT be
* 'direct', but the name of the page you wish to go to.
*
* @category HTML
* @package HTML_QuickForm_Controller
* @author Alexey Borzov <avb@php.net>
* @version Release: 1.0.10
*/
class HTML_QuickForm_Action_Direct extends HTML_QuickForm_Action
{
function perform(&$page, $actionName)
{
// save the form values and validation status to the session
$page->isFormBuilt() or $page->buildForm();
$pageName = $page->getAttribute('id');
$data =& $page->controller->container();
$data['values'][$pageName] = $page->exportValues();
if (PEAR::isError($valid = $page->validate())) {
return $valid;
}
$data['valid'][$pageName] = $valid;
$target =& $page->controller->getPage($actionName);
if (PEAR::isError($target)) {
return $target;
} else {
return $target->handle('jump');
}
}
}
?>

View File

@@ -0,0 +1,90 @@
<?php
/* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4: */
/**
* This action handles output of the form.
*
* PHP versions 4 and 5
*
* LICENSE: This source file is subject to version 3.01 of the PHP license
* that is available through the world-wide-web at the following URI:
* http://www.php.net/license/3_01.txt If you did not receive a copy of
* the PHP License and are unable to obtain it through the web, please
* send a note to license@php.net so we can mail you a copy immediately.
*
* @category HTML
* @package HTML_QuickForm_Controller
* @author Alexey Borzov <avb@php.net>
* @copyright 2003-2009 The PHP Group
* @license http://www.php.net/license/3_01.txt PHP License 3.01
* @version SVN: $Id: Display.php 289084 2009-10-02 06:53:09Z avb $
* @link http://pear.php.net/package/HTML_QuickForm_Controller
*/
/**
* This action handles output of the form.
*
* If you want to customize the form display, subclass this class and
* override the _renderForm() method, you don't need to change the perform()
* method itself.
*
* @category HTML
* @package HTML_QuickForm_Controller
* @author Alexey Borzov <avb@php.net>
* @version Release: 1.0.10
*/
class HTML_QuickForm_Action_Display extends HTML_QuickForm_Action
{
function perform(&$page, $actionName)
{
$pageName = $page->getAttribute('id');
// If the original action was 'display' and we have values in container then we load them
// BTW, if the page was invalid, we should later call validate() to get the errors
list(, $oldName) = $page->controller->getActionName();
if ('display' == $oldName) {
// If the controller is "modal" we should not allow direct access to a page
// unless all previous pages are valid (see also bug #2323)
if ($page->controller->isModal() && !$page->controller->isValid($page->getAttribute('id'))) {
$target =& $page->controller->getPage($page->controller->findInvalid());
// Modified by Chamilo team, 16-MAR-2010.
//$target->handle('jump');
return $target->handle('jump');
//
}
$data =& $page->controller->container();
if (!empty($data['values'][$pageName])) {
$page->loadValues($data['values'][$pageName]);
$validate = false === $data['valid'][$pageName];
}
}
// set "common" defaults and constants
$page->controller->applyDefaults($pageName);
$page->isFormBuilt() or $page->buildForm();
// if we had errors we should show them again
if (isset($validate) && $validate) {
if (PEAR::isError($err = $page->validate())) {
return $err;
}
}
// Modified by Chamilo team, 16-MAR-2010.
//$this->_renderForm($page);
return $this->_renderForm($page);
//
}
/**
* Actually outputs the form.
*
* If you want to customize the form's appearance (you most certainly will),
* then you should override this method. There is no need to override perform()
*
* @access private
* @param HTML_QuickForm_Page the page being processed
*/
function _renderForm(&$page)
{
$page->display();
}
}
?>

View File

@@ -0,0 +1,157 @@
<?php
/* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4: */
/**
* This action performs HTTP redirect to a specific page.
*
* PHP versions 4 and 5
*
* LICENSE: This source file is subject to version 3.01 of the PHP license
* that is available through the world-wide-web at the following URI:
* http://www.php.net/license/3_01.txt If you did not receive a copy of
* the PHP License and are unable to obtain it through the web, please
* send a note to license@php.net so we can mail you a copy immediately.
*
* @category HTML
* @package HTML_QuickForm_Controller
* @author Alexey Borzov <avb@php.net>
* @copyright 2003-2009 The PHP Group
* @license http://www.php.net/license/3_01.txt PHP License 3.01
* @version SVN: $Id: Jump.php 289084 2009-10-02 06:53:09Z avb $
* @link http://pear.php.net/package/HTML_QuickForm_Controller
*/
/**
* This action performs HTTP redirect to a specific page.
*
* @category HTML
* @package HTML_QuickForm_Controller
* @author Alexey Borzov <avb@php.net>
* @version Release: 1.0.10
*/
class HTML_QuickForm_Action_Jump extends HTML_QuickForm_Action
{
/**
* Splits (part of) the URI into path and query components
*
* @param string String of the form 'foo?bar'
* @return array Array of the form array('foo', '?bar)
* @access private
*/
function _splitUri($uri)
{
if (false === ($qm = strpos($uri, '?'))) {
return array($uri, '');
} else {
return array(substr($uri, 0, $qm), substr($uri, $qm));
}
}
/**
* Removes the '..' and '.' segments from the path component
*
* @param string Path component of the URL, possibly with '.' and '..' segments
* @return string Path component of the URL with '.' and '..' segments removed
* @access private
*/
function _normalizePath($path)
{
$pathAry = explode('/', $path);
$i = 1;
do {
if ('.' == $pathAry[$i]) {
if ($i < count($pathAry) - 1) {
array_splice($pathAry, $i, 1);
} else {
$pathAry[$i] = '';
$i++;
}
} elseif ('..' == $pathAry[$i] && $i > 1 && '..' != $pathAry[$i - 1]) {
if ($i < count($pathAry) -1) {
array_splice($pathAry, $i - 1, 2);
$i--;
} else {
array_splice($pathAry, $i - 1, 2, '');
}
} else {
$i++;
}
} while ($i < count($pathAry));
return implode('/', $pathAry);
}
/**
* Resolves relative URL using current page's URL as base
*
* The method follows procedure described in section 4 of RFC 1808 and
* passes the examples provided in section 5 of said RFC. Values from
* $_SERVER array are used for calculation of "current URL"
*
* @param string Relative URL, probably from form's action attribute
* @return string Absolute URL
* @access private
*/
function _resolveRelativeURL($url)
{
$https = !empty($_SERVER['HTTPS']) && ('off' != strtolower($_SERVER['HTTPS']));
$scheme = ($https? 'https:': 'http:');
if ('//' == substr($url, 0, 2)) {
return $scheme . $url;
} else {
$host = $scheme . '//' . $_SERVER['SERVER_NAME'] .
(($https && 443 == $_SERVER['SERVER_PORT'] ||
!$https && 80 == $_SERVER['SERVER_PORT'])? '': ':' . $_SERVER['SERVER_PORT']);
if ('' == $url) {
return $host . $_SERVER['REQUEST_URI'];
} elseif ('/' == $url[0]) {
return $host . $url;
} else {
list($basePath, $baseQuery) = $this->_splitUri($_SERVER['REQUEST_URI']);
list($actPath, $actQuery) = $this->_splitUri($url);
if ('' == $actPath) {
return $host . $basePath . $actQuery;
} else {
$path = substr($basePath, 0, strrpos($basePath, '/') + 1) . $actPath;
return $host . $this->_normalizePath($path) . $actQuery;
}
}
}
}
function perform(&$page, $actionName)
{
// check whether the page is valid before trying to go to it
if ($page->controller->isModal()) {
// we check whether *all* pages up to current are valid
// if there is an invalid page we go to it, instead of the
// requested one
$pageName = $page->getAttribute('id');
if (!$page->controller->isValid($pageName)) {
$pageName = $page->controller->findInvalid();
}
$current =& $page->controller->getPage($pageName);
} else {
$current =& $page;
}
// generate the URL for the page 'display' event and redirect to it
$action = $current->getAttribute('action');
// Bug #13087: RFC 2616 requires an absolute URI in Location header
if (!preg_match('!^https?://!i', $action)) {
$action = $this->_resolveRelativeURL($action);
}
$url = $action . (false === strpos($action, '?')? '?': '&') .
$current->getButtonName('display') . '=true' .
((!defined('SID') || '' == SID || ini_get('session.use_only_cookies'))? '': '&' . SID);
header('Location: ' . $url);
exit;
}
}
?>

View File

@@ -0,0 +1,80 @@
<?php
/* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4: */
/**
* The action for a 'next' button of wizard-type multipage form.
*
* PHP versions 4 and 5
*
* LICENSE: This source file is subject to version 3.01 of the PHP license
* that is available through the world-wide-web at the following URI:
* http://www.php.net/license/3_01.txt If you did not receive a copy of
* the PHP License and are unable to obtain it through the web, please
* send a note to license@php.net so we can mail you a copy immediately.
*
* @category HTML
* @package HTML_QuickForm_Controller
* @author Alexey Borzov <avb@php.net>
* @copyright 2003-2009 The PHP Group
* @license http://www.php.net/license/3_01.txt PHP License 3.01
* @version SVN: $Id: Next.php 289084 2009-10-02 06:53:09Z avb $
* @link http://pear.php.net/package/HTML_QuickForm_Controller
*/
/**
* The action for a 'next' button of wizard-type multipage form.
*
* @category HTML
* @package HTML_QuickForm_Controller
* @author Alexey Borzov <avb@php.net>
* @version Release: 1.0.10
*/
class HTML_QuickForm_Action_Next extends HTML_QuickForm_Action
{
function perform(&$page, $actionName)
{
// save the form values and validation status to the session
$page->isFormBuilt() or $page->buildForm();
$pageName = $page->getAttribute('id');
$data =& $page->controller->container();
$data['values'][$pageName] = $page->exportValues();
if (PEAR::isError($valid = $page->validate())) {
return $valid;
}
$data['valid'][$pageName] = $valid;
// Modal form and page is invalid: don't go further
if ($page->controller->isModal() && !$data['valid'][$pageName]) {
return $page->handle('display');
}
// More pages?
if (null !== ($nextName = $page->controller->getNextName($pageName))) {
$next =& $page->controller->getPage($nextName);
// Modified by Chamilo team, 16-MAR-2010.
//$next->handle('jump');
return $next->handle('jump');
//
// Consider this a 'finish' button, if there is no explicit one
} elseif($page->controller->isModal()) {
if ($page->controller->isValid()) {
// Modified by Chamilo team, 16-MAR-2010.
//$page->handle('process');
return $page->handle('process');
//
} else {
// this should redirect to the first invalid page
// Modified by Chamilo team, 16-MAR-2010.
//$page->handle('jump');
return $page->handle('jump');
//
}
} else {
// Modified by Chamilo team, 16-MAR-2010.
//$page->handle('display');
return $page->handle('display');
//
}
}
}
?>

View File

@@ -0,0 +1,71 @@
<?php
/* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4: */
/**
* The action for a 'submit' button.
*
* PHP versions 4 and 5
*
* LICENSE: This source file is subject to version 3.01 of the PHP license
* that is available through the world-wide-web at the following URI:
* http://www.php.net/license/3_01.txt If you did not receive a copy of
* the PHP License and are unable to obtain it through the web, please
* send a note to license@php.net so we can mail you a copy immediately.
*
* @category HTML
* @package HTML_QuickForm_Controller
* @author Alexey Borzov <avb@php.net>
* @copyright 2003-2009 The PHP Group
* @license http://www.php.net/license/3_01.txt PHP License 3.01
* @version SVN: $Id: Submit.php 289084 2009-10-02 06:53:09Z avb $
* @link http://pear.php.net/package/HTML_QuickForm_Controller
*/
/**
* The action for a 'submit' button.
*
* @category HTML
* @package HTML_QuickForm_Controller
* @author Alexey Borzov <avb@php.net>
* @version Release: 1.0.10
*/
class HTML_QuickForm_Action_Submit extends HTML_QuickForm_Action
{
function perform(&$page, $actionName)
{
// save the form values and validation status to the session
$page->isFormBuilt() or $page->buildForm();
$pageName = $page->getAttribute('id');
$data =& $page->controller->container();
$data['values'][$pageName] = $page->exportValues();
if (PEAR::isError($valid = $page->validate())) {
return $valid;
}
$data['valid'][$pageName] = $valid;
// All pages are valid, process
if ($page->controller->isValid()) {
// Modified by Chamilo team, 16-MAR-2010.
//$page->handle('process');
return $page->handle('process');
//
// Current page is invalid, display it
} elseif (!$data['valid'][$pageName]) {
// Modified by Chamilo team, 16-MAR-2010.
//$page->handle('display');
return $page->handle('display');
//
// Some other page is invalid, redirect to it
} else {
$target =& $page->controller->getPage($page->controller->findInvalid());
// Modified by Chamilo team, 16-MAR-2010.
//$target->handle('jump');
return $target->handle('jump');
//
}
}
}
?>

View File

@@ -0,0 +1,6 @@
<html>
<head>
</head>
<body>
</body>
</html>

View File

@@ -0,0 +1,258 @@
<?php
/* vim: set expandtab tabstop=4 shiftwidth=4: */
/**
* Common class for HTML_QuickForm elements to display a CAPTCHA
*
* The HTML_QuickForm_CAPTCHA package adds an element to the
* HTML_QuickForm package to display a CAPTCHA question (image, riddle, etc...)
*
* This package requires the use of a PHP session ($_SESSION).
*
* PHP versions 4 and 5
*
* LICENSE:
*
* Copyright (c) 2006-2008, Philippe Jausions / 11abacus
*
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* - Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* - Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* - Neither the name of 11abacus nor the names of its contributors may
* be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* @category HTML
* @package HTML_QuickForm_CAPTCHA
* @author Philippe Jausions <Philippe.Jausions@11abacus.com>
* @copyright 2006-2008 by Philippe Jausions / 11abacus
* @license http://www.opensource.org/licenses/bsd-license.php New BSD
* @version CVS: $Id: CAPTCHA.php,v 1.1 2008/04/26 23:27:28 jausions Exp $
* @link http://pear.php.net/package/HTML_QuickForm_CAPTCHA
*/
/**
* Common class for HTML_QuickForm elements to display a CAPTCHA
*
* The HTML_QuickForm_CAPTCHA package adds an element to the
* HTML_QuickForm package to display a CAPTCHA question (image, riddle, etc...)
*
* This package requires the use of a PHP session ($_SESSION).
*
* Because the CAPTCHA element is serialized in the PHP session,
* you need to include the class declaration BEFORE the session starts.
* So BEWARE if you have php.ini session.auto_start enabled, you won't be
* able to use this element, unless you're also using PHP 5's __autoload()
* or php.ini's unserialize_callback_func setting
*
* @category HTML
* @package HTML_QuickForm_CAPTCHA
* @author Philippe Jausions <Philippe.Jausions@11abacus.com>
* @copyright 2006-2008 by Philippe Jausions / 11abacus
* @license http://www.opensource.org/licenses/bsd-license.php New BSD
* @version Release: 0.3.0
* @link http://pear.php.net/package/HTML_QuickForm_CAPTCHA
* @abstract
*/
class HTML_QuickForm_CAPTCHA extends HTML_QuickForm_input
{
/**
* Default options
*
* @var array
* @access protected
*/
var $_options = array(
'sessionVar' => '_HTML_QuickForm_CAPTCHA',
'phrase' => null,
);
/**
* CAPTCHA driver
*
* @var string
* @access protected
*/
var $_CAPTCHA_driver;
/**
* Class constructor
*
* @param string $elementName Name
* @param mixed $elementLabel Label for the CAPTCHA
* @param array $options Options for the Text_CAPTCHA package
* <ul>
* <li>'sessionVar' (string) name of session variable containing
* the Text_CAPTCHA instance (defaults to
* _HTML_QuickForm_CAPTCHA.)</li>
* <li>Other options depend on the driver used</li>
* </ul>
* @param mixed $attributes HTML Attributes for the <a> tag surrounding
* the image. Can be a string or array.
*
* @access public
*/
public function __construct(
$elementName = null,
$elementLabel = null,
$options = null,
$attributes = null
) {
parent::__construct($elementName, $elementLabel, $attributes);
$this->setType('CAPTCHA_'.$this->_CAPTCHA_driver);
if (is_array($options)) {
$this->_options = array_merge($this->_options, $options);
}
}
/**
* Initializes the CAPTCHA instance (if needed)
*
* @return boolean TRUE or PEAR_Error on error
* @access protected
*/
function _initCAPTCHA()
{
$sessionVar = $this->_options['sessionVar'];
if (empty($_SESSION[$sessionVar])) {
$_SESSION[$sessionVar] = Text_CAPTCHA::factory($this->_CAPTCHA_driver);
if (PEAR::isError($_SESSION[$sessionVar])) {
return $_SESSION[$sessionVar];
}
$result = $_SESSION[$sessionVar]->init($this->_options);
if (PEAR::isError($result)) {
return $result;
}
}
return true;
}
/**
* Returns the answer/phrase of the CAPTCHA
*
* @param mixed &$values Ignored by this element
*
* @return string
* @access private
*/
function _findValue(&$values)
{
return $this->getValue();
}
/**
* Returns the answer/phrase of the CAPTCHA
*
* @return string
* @access public
*/
function getValue()
{
$sessionVar = $this->_options['sessionVar'];
return (!empty($_SESSION[$sessionVar]))
? $_SESSION[$sessionVar]->getPhrase()
: null;
}
/**
* Returns the answer/phrase of the CAPTCHA
*
* @param mixed &$submitValues Ignored by this element
* @param boolean $assoc Whether to return an array
*
* @return string
* @access public
*/
function exportValue(&$submitValues, $assoc = false)
{
return ($assoc)
? array($this->getName() => $this->getValue())
: $this->getValue();
}
/**
* Sets the CAPTCHA question/phrase
*
* Pass NULL or no argument for a random question/phrase to be generated
*
* @param string $phrase Value of the CAPTCHA to set
*
* @return void
* @access public
*/
function setPhrase($phrase = null)
{
$this->_options['phrase'] = $phrase;
if (!empty($_SESSION[$this->_options['sessionVar']])) {
$_SESSION[$this->_options['sessionVar']]->setPhrase($phrase);
}
}
/**
* Destroys the CAPTCHA instance to prevent reuse
*
* @return void
* @access public
*/
function destroy()
{
unset($_SESSION[$this->_options['sessionVar']]);
}
/**
* Returns the HTML for the CAPTCHA
*
* This can be overwritten by sub-classes for specific output behavior
* (for instance the Image CAPTCHA displays an image)
*
* @return string
* @access public
*/
function toHtml()
{
$result = $this->_initCAPTCHA();
if (PEAR::isError($result)) {
return $result;
}
$captcha = $_SESSION[$this->_options['sessionVar']]->getCAPTCHA();
$attr = $this->_attributes;
unset($attr['type']);
unset($attr['value']);
unset($attr['name']);
$html = $this->_getTabs()
. '<span' . $this->_getAttrString($attr) . '>'
. htmlspecialchars($captcha)
. '</span>';
return $html;
}
}

View File

@@ -0,0 +1,76 @@
<?php
/* vim: set expandtab tabstop=4 shiftwidth=4: */
/**
* Element for HTML_QuickForm to display a CAPTCHA equation
*
* The HTML_QuickForm_CAPTCHA package adds an element to the
* HTML_QuickForm package to display a CAPTCHA equation.
*
* This package requires the use of a PHP session.
*
* PHP versions 4 and 5
*
* @category HTML
* @package HTML_QuickForm_CAPTCHA
* @author Philippe Jausions <Philippe.Jausions@11abacus.com>
* @copyright 2006-2008 by Philippe Jausions / 11abacus
* @license http://www.opensource.org/licenses/bsd-license.php New BSD
* @version CVS: $Id: Equation.php,v 1.1 2008/04/26 23:27:30 jausions Exp $
* @link http://pear.php.net/package/HTML_QuickForm_CAPTCHA
*/
/**
* Element for HTML_QuickForm to display a CAPTCHA equation question
*
* The HTML_QuickForm_CAPTCHA package adds an element to the
* HTML_QuickForm package to display a CAPTCHA equation question.
*
* Options for the element
* <ul>
* <li>'min' (integer) Minimal number to use in an equation.</li>
* <li>'max' (integer) Maximal number to use in an equation.</li>
* <li>'severity' (integer) Complexity of the equation to resolve
* (1 = easy, 2 = harder)</li>
* <li>'numbersToText' (boolean) Whether to use the Numbers_Words
* package to convert numbers to text,</li>
* <li>'sessionVar' (string) name of session variable containing
* the Text_CAPTCHA instance (defaults to
* _HTML_QuickForm_CAPTCHA.)</li>
* </ul>
*
* This package requires the use of a PHP session.
*
* @category HTML
* @package HTML_QuickForm_CAPTCHA
* @author Philippe Jausions <Philippe.Jausions@11abacus.com>
* @copyright 2006-2008 by Philippe Jausions / 11abacus
* @license http://www.opensource.org/licenses/bsd-license.php New BSD
* @version Release: 0.3.0
* @link http://pear.php.net/package/HTML_QuickForm_CAPTCHA
* @see Text_CAPTCHA_Driver_Equation
*/
class HTML_QuickForm_CAPTCHA_Equation extends HTML_QuickForm_CAPTCHA
{
/**
* Default options
*
* @var array
* @access protected
*/
var $_options = array(
'sessionVar' => '_HTML_QuickForm_CAPTCHA',
'severity' => 1,
'numbersToText' => false,
'phrase' => null,
);
/**
* CAPTCHA driver
*
* @var string
* @access protected
*/
var $_CAPTCHA_driver = 'Equation';
}

View File

@@ -0,0 +1,109 @@
<?php
/* vim: set expandtab tabstop=4 shiftwidth=4: */
/**
* Element for HTML_QuickForm to display a CAPTCHA figlet
*
* The HTML_QuickForm_CAPTCHA package adds an element to the
* HTML_QuickForm package to display a CAPTCHA figlet.
*
* This package requires the use of a PHP session.
*
* PHP versions 4 and 5
*
* @category HTML
* @package HTML_QuickForm_CAPTCHA
* @author Philippe Jausions <Philippe.Jausions@11abacus.com>
* @copyright 2006-2008 by Philippe Jausions / 11abacus
* @license http://www.opensource.org/licenses/bsd-license.php New BSD
* @version CVS: $Id: Figlet.php,v 1.1 2008/04/26 23:27:30 jausions Exp $
* @link http://pear.php.net/package/HTML_QuickForm_CAPTCHA
*/
/**
* Element for HTML_QuickForm to display a CAPTCHA figlet
*
* The HTML_QuickForm_CAPTCHA package adds an element to the
* HTML_QuickForm package to display a CAPTCHA figlet
*
* Options for the element
* <ul>
* <li>'width' (integer) Width of figlet (default is 200px)</li>
* <li>'output' (string) Output format: "html", "text" or
* "javascript" (default is "html").</li>
* <li>'length' (integer) number of letters in the figlet
* (default is 6)</li>
* <li>'options' (array) only index supported is "font_file", which
* should either be one figlet font file path,
* or an array of figlet font file paths
* (one we be picked randomly)</li>
* <li>'sessionVar' (string) name of session variable containing
* the Text_CAPTCHA instance (defaults to
* _HTML_QuickForm_CAPTCHA.)</li>
* </ul>
*
* This package requires the use of a PHP session.
*
* @category HTML
* @package HTML_QuickForm_CAPTCHA
* @author Philippe Jausions <Philippe.Jausions@11abacus.com>
* @copyright 2006-2008 by Philippe Jausions / 11abacus
* @license http://www.opensource.org/licenses/bsd-license.php New BSD
* @version Release: 0.3.0
* @link http://pear.php.net/package/HTML_QuickForm_CAPTCHA
* @see Text_CAPTCHA_Driver_Figlet
*/
class HTML_QuickForm_CAPTCHA_Figlet extends HTML_QuickForm_CAPTCHA
{
/**
* Default options
*
* @var array
* @access protected
*/
var $_options = array(
'sessionVar' => '_HTML_QuickForm_CAPTCHA',
'output' => 'html',
'width' => 200,
'length' => 6,
'phrase' => null,
);
/**
* CAPTCHA driver
*
* @var string
* @access protected
*/
var $_CAPTCHA_driver = 'Figlet';
/**
* Returns the HTML for the CAPTCHA
*
* This can be overwritten by sub-classes for specific output behavior
* (for instance the Image CAPTCHA displays an image)
*
* @access public
* @return string
*/
function toHtml()
{
$result = $this->_initCAPTCHA();
if (PEAR::isError($result)) {
return $result;
}
$attr = $this->_attributes;
unset($attr['type']);
unset($attr['value']);
unset($attr['name']);
$html = $this->_getTabs()
. '<div' . $this->_getAttrString($attr) . '>'
. $_SESSION[$this->_options['sessionVar']]->getCAPTCHA()
. '</div>';
return $html;
}
}

View File

@@ -0,0 +1,221 @@
<?php
/* vim: set expandtab tabstop=4 shiftwidth=4: */
/**
* Element for HTML_QuickForm to display a CAPTCHA image
*
* The HTML_QuickForm_CAPTCHA package adds an element to the
* HTML_QuickForm package to display a CAPTCHA image.
*
* This package requires the use of a PHP session.
*
* PHP versions 4 and 5
*
* @category HTML
* @package HTML_QuickForm_CAPTCHA
* @author Philippe Jausions <Philippe.Jausions@11abacus.com>
* @copyright 2006-2008 by Philippe Jausions / 11abacus
* @license http://www.opensource.org/licenses/bsd-license.php New BSD
* @version CVS: $Id: Image.php,v 1.1 2008/04/26 23:27:30 jausions Exp $
* @link http://pear.php.net/package/HTML_QuickForm_CAPTCHA
*/
/**
* Element for HTML_QuickForm to display a CAPTCHA image
*
* The HTML_QuickForm_CAPTCHA package adds an element to the
* HTML_QuickForm package to display a CAPTCHA image.
*
* Options for the element
* <ul>
* <li>'width' (integer) width of the image,</li>
* <li>'height' (integer) height of the image,</li>
* <li>'imageOptions' (array) options passed to the Image_Text
* constructor,</li>
* <li>'callback' (string) URL of callback script that will generate
* and output the image itself,</li>
* <li>'alt' (string) the alt text for the image,</li>
* <li>'sessionVar' (string) name of session variable containing
* the Text_CAPTCHA instance (defaults to
* _HTML_QuickForm_CAPTCHA.)</li>
* </ul>
*
* This package requires the use of a PHP session.
*
* @category HTML
* @package HTML_QuickForm_CAPTCHA
* @author Philippe Jausions <Philippe.Jausions@11abacus.com>
* @copyright 2006-2008 by Philippe Jausions / 11abacus
* @license http://www.opensource.org/licenses/bsd-license.php New BSD
* @version Release: 0.3.0
* @link http://pear.php.net/package/HTML_QuickForm_CAPTCHA
* @see Text_CAPTCHA_Driver_Image
*/
class HTML_QuickForm_CAPTCHA_Image extends HTML_QuickForm_CAPTCHA
{
public function __construct(
$elementName = null,
$elementLabel = null,
$options = null,
$attributes = null
) {
return parent::__construct(
$elementName,
$elementLabel,
$options,
$attributes
);
}
/**
* Default options
*
* @var array
* @access protected
*/
var $_options = array(
'sessionVar' => '_HTML_QuickForm_CAPTCHA',
'width' => '200',
'height' => '80',
'alt' => 'Click to view another image',
'callback' => '',
'imageOptions' => null,
'phrase' => null,
);
/**
* CAPTCHA driver
*
* @var string
* @access protected
*/
var $_CAPTCHA_driver = 'Image';
/**
* Code based in HTML_QuickForm_text::getTemplate()
* In order to render correctly the captcha in different layouts
* @param string $layout
*
* @return string
*/
public static function getTemplate($layout)
{
$size = 8;
switch ($layout) {
case FormValidator::LAYOUT_INLINE:
return '
<div class="form-group {error_class}">
<label {label-for} >
<!-- BEGIN required --><span class="form_required">*</span><!-- END required -->
{label}
</label>
{element}
</div>';
break;
case FormValidator::LAYOUT_HORIZONTAL:
return '
<div class="form-group {error_class}">
<label {label-for} class="col-sm-2 control-label" >
<!-- BEGIN required --><span class="form_required">*</span><!-- END required -->
{label}
</label>
<div class="col-sm-'.$size.'">
{icon}
{element}
<!-- BEGIN label_2 -->
<p class="help-block">{label_2}</p>
<!-- END label_2 -->
<!-- BEGIN error -->
<span class="help-inline help-block">{error}</span>
<!-- END error -->
</div>
<div class="col-sm-2">
<!-- BEGIN label_3 -->
{label_3}
<!-- END label_3 -->
</div>
</div>';
break;
case FormValidator::LAYOUT_BOX_NO_LABEL:
return '
<div class="input-group">
{icon}
{element}
</div>';
break;
}
}
/**
* Returns the HTML for the CAPTCHA image
*
* @return string
* @access public
*/
public function toHtml()
{
if ($this->_flagFrozen) {
return '';
}
$result = parent::_initCAPTCHA();
if (PEAR::isError($result)) {
return $result;
}
$html = '';
$tabs = $this->_getTabs();
$inputName = $this->getName();
$imgName = 'QF_CAPTCHA_'.$inputName;
if ($this->getComment() != '') {
$html .= $tabs.'<!-- '.$this->getComment().' // -->';
}
$attr = $this->_attributes;
unset($attr['type']);
unset($attr['value']);
unset($attr['name']);
$html = $tabs.'<a href="'.$this->_options['callback']
.'" target="_blank" '
.$this->_getAttrString($attr)
.' onclick="var cancelClick = false; '
.$this->getOnclickJs($imgName)
.' return !cancelClick;"><img src="'
.$this->_options['callback'].'" name="'.$imgName
.'" id="'.$imgName.'" width="'.$this->_options['width']
.'" height="'.$this->_options['height'].'" title="'
.htmlspecialchars($this->_options['alt']).'" /></a>';
return $html;
}
/**
* Creates the javascript for the onclick event which will
* reload a new CAPTCHA image
*
* @param string $imageName The image name/id
*
* @return string
* @access public
*/
function getOnclickJs($imageName)
{
$onclickJs = ''
.'if (document.images) {'
.' var img = new Image();'
.' var d = new Date();'
.' img.src = this.href + ((this.href.indexOf(\'?\') == -1) '
.'? \'?\' : \'&\') + d.getTime();'
.' document.images[\''.addslashes($imageName).'\'].src = img.src;'
.' cancelClick = true;'
.'}';
return $onclickJs;
}
}

View File

@@ -0,0 +1,74 @@
<?php
/* vim: set expandtab tabstop=4 shiftwidth=4: */
/**
* Element for HTML_QuickForm to display a CAPTCHA "Word"
*
* The HTML_QuickForm_CAPTCHA package adds an element to the
* HTML_QuickForm package to display a CAPTCHA "word".
*
* This package requires the use of a PHP session.
*
* PHP versions 4 and 5
*
* @category HTML
* @package HTML_QuickForm_CAPTCHA
* @author Philippe Jausions <Philippe.Jausions@11abacus.com>
* @copyright 2006-2008 by Philippe Jausions / 11abacus
* @license http://www.opensource.org/licenses/bsd-license.php New BSD
* @version CVS: $Id: Word.php,v 1.1 2008/04/26 23:27:30 jausions Exp $
* @link http://pear.php.net/package/HTML_QuickForm_CAPTCHA
*/
/**
* Element for HTML_QuickForm to display a CAPTCHA "word" question
*
* The HTML_QuickForm_CAPTCHA package adds an element to the
* HTML_QuickForm package to display a CAPTCHA "word" question.
*
* Options for the element
* <ul>
* <li>'length' (integer) the length of the Word.</li>
* <li>'mode' (string) 'single' for separated words.</li>
* <li>'locale' (string) locale for Numbers_Words package</li>
* <li>'sessionVar' (string) name of session variable containing
* the Text_CAPTCHA instance (defaults to
* _HTML_QuickForm_CAPTCHA.)</li>
* </ul>
*
* This package requires the use of a PHP session.
*
* @category HTML
* @package HTML_QuickForm_CAPTCHA
* @author Philippe Jausions <Philippe.Jausions@11abacus.com>
* @copyright 2006-2008 by Philippe Jausions / 11abacus
* @license http://www.opensource.org/licenses/bsd-license.php New BSD
* @version Release: 0.3.0
* @link http://pear.php.net/package/HTML_QuickForm_CAPTCHA
* @see Text_CAPTCHA_Driver_Equation
*/
class HTML_QuickForm_CAPTCHA_Word extends HTML_QuickForm_CAPTCHA
{
/**
* Default options
*
* @var array
* @access protected
*/
var $_options = array(
'sessionVar' => '_HTML_QuickForm_CAPTCHA',
'length' => 4,
'mode' => 'single',
'locale' => 'en_US',
'phrase' => null,
);
/**
* CAPTCHA driver
*
* @var string
* @access protected
*/
var $_CAPTCHA_driver = 'Word';
}

View File

@@ -0,0 +1,516 @@
<?php
/* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4: */
/**
* The class representing a Controller of MVC design pattern.
*
* PHP versions 4 and 5
*
* LICENSE: This source file is subject to version 3.01 of the PHP license
* that is available through the world-wide-web at the following URI:
* http://www.php.net/license/3_01.txt If you did not receive a copy of
* the PHP License and are unable to obtain it through the web, please
* send a note to license@php.net so we can mail you a copy immediately.
*
* @category HTML
* @package HTML_QuickForm_Controller
* @author Alexey Borzov <avb@php.net>
* @author Bertrand Mansion <bmansion@mamasam.com>
* @copyright 2003-2009 The PHP Group
* @license http://www.php.net/license/3_01.txt PHP License 3.01
* @version SVN: $Id: Controller.php 289084 2009-10-02 06:53:09Z avb $
* @link http://pear.php.net/package/HTML_QuickForm_Controller
*/
/**
* The class representing a Controller of MVC design pattern.
*
* This class keeps track of pages and (default) action handlers for the form,
* it manages keeping the form values in session, setting defaults and
* constants for the form as a whole and getting its submit values.
*
* Generally you don't need to subclass this.
*
* @category HTML
* @package HTML_QuickForm_Controller
* @author Alexey Borzov <avb@php.net>
* @author Bertrand Mansion <bmansion@mamasam.com>
* @version Release: 1.0.10
*/
class HTML_QuickForm_Controller
{
/**
* Contains the pages (HTML_QuickForm_Page objects) of the miultipage form
* @var array
*/
var $_pages = array();
/**
* Contains the mapping of actions to corresponding HTML_QuickForm_Action objects
* @var array
*/
var $_actions = array();
/**
* Name of the form, used to store the values in session
* @var string
*/
var $_name;
/**
* Whether the form is modal
* @var bool
*/
var $_modal = true;
/**
* The action extracted from HTTP request: array('page', 'action')
* @var array
*/
var $_actionName = null;
/**
* Class constructor.
*
* Sets the form name and modal/non-modal behaviuor. Different multipage
* forms should have different names, as they are used to store form
* values in session. Modal forms allow passing to the next page only when
* all of the previous pages are valid.
*
* @access public
* @param string form name
* @param bool whether the form is modal
*/
function HTML_QuickForm_Controller($name, $modal = true)
{
$this->_name = $name;
$this->_modal = $modal;
}
/**
* Returns a reference to a session variable containing the form-page
* values and pages' validation status.
*
* This is a "low-level" method, use exportValues() if you want just to
* get the form's values.
*
* @access public
* @param bool If true, then reset the container: clear all default, constant and submitted values
* @return array
*/
function &container($reset = false)
{
$name = '_' . $this->_name . '_container';
if (!isset($_SESSION[$name]) || $reset) {
$_SESSION[$name] = array(
'defaults' => array(),
'constants' => array(),
'values' => array(),
'valid' => array()
);
}
foreach (array_keys($this->_pages) as $pageName) {
if (!isset($_SESSION[$name]['values'][$pageName])) {
$_SESSION[$name]['values'][$pageName] = array();
$_SESSION[$name]['valid'][$pageName] = null;
}
}
return $_SESSION[$name];
}
/**
* Processes the request.
*
* This finds the current page, the current action and passes the action
* to the page's handle() method.
*
* @access public
* @throws PEAR_Error
*/
function run()
{
// the names of the action and page should be saved
list($page, $action) = $this->_actionName = $this->getActionName();
return $this->_pages[$page]->handle($action);
}
/**
* Registers a handler for a specific action.
*
* @access public
* @param string name of the action
* @param HTML_QuickForm_Action the handler for the action
*/
function addAction($actionName, &$action)
{
$this->_actions[$actionName] =& $action;
}
/**
* Adds a new page to the form
*
* @access public
* @param HTML_QuickForm_Page
*/
function addPage(&$page)
{
$page->controller =& $this;
$this->_pages[$page->getAttribute('id')] =& $page;
}
/**
* Returns a page
*
* @access public
* @param string Name of a page
* @return HTML_QuickForm_Page A reference to the page
* @throws PEAR_Error
*/
function &getPage($pageName)
{
if (!isset($this->_pages[$pageName])) {
throw new \Exception('HTML_QuickForm_Controller: Unknown page "' . $pageName . '"');
}
return $this->_pages[$pageName];
}
/**
* Handles an action.
*
* This will be called if the page itself does not have a handler
* to a specific action. The method also loads and uses default handlers
* for common actions, if specific ones were not added.
*
* @access public
* @param HTML_QuickForm_Page The page that failed to handle the action
* @param string Name of the action
* @throws PEAR_Error
*/
function handle(&$page, $actionName)
{
if (isset($this->_actions[$actionName])) {
return $this->_actions[$actionName]->perform($page, $actionName);
}
switch ($actionName) {
case 'next':
case 'back':
case 'submit':
case 'display':
case 'jump':
include_once 'HTML/QuickForm/Action/' . ucfirst($actionName) . '.php';
$className = 'HTML_QuickForm_Action_' . $actionName;
$this->_actions[$actionName] =& new $className();
return $this->_actions[$actionName]->perform($page, $actionName);
break;
default:
throw new \Exception('HTML_QuickForm_Controller: Unhandled action "' . $actionName . '" in page "' . $page->getAttribute('id') . '"');
} // switch
}
/**
* Checks whether the form is modal.
*
* @access public
* @return bool
*/
function isModal()
{
return $this->_modal;
}
/**
* Checks whether the pages of the controller are valid
*
* @access public
* @param string If set, check only the pages before (not including) that page
* @return bool
* @throws PEAR_Error
*/
function isValid($pageName = null)
{
$data =& $this->container();
foreach (array_keys($this->_pages) as $key) {
if (isset($pageName) && $pageName == $key) {
return true;
} elseif (!$data['valid'][$key]) {
// We should handle the possible situation when the user has never
// seen a page of a non-modal multipage form
if (!$this->isModal() && null === $data['valid'][$key]) {
$page =& $this->_pages[$key];
// Fix for bug #8687: the unseen page was considered
// submitted, so defaults for checkboxes and multiselects
// were not used. Shouldn't break anything since this flag
// will be reset right below in loadValues().
$page->_flagSubmitted = false;
// Use controller's defaults and constants, if present
$this->applyDefaults($key);
$page->isFormBuilt() or $page->BuildForm();
// We use defaults and constants as if they were submitted
$data['values'][$key] = $page->exportValues();
$page->loadValues($data['values'][$key]);
// Is the page now valid?
if (PEAR::isError($valid = $page->validate())) {
return $valid;
}
$data['valid'][$key] = $valid;
if (true === $valid) {
continue;
}
}
return false;
}
}
return true;
}
/**
* Returns the name of the page before the given.
*
* @access public
* @param string
* @return string
*/
function getPrevName($pageName)
{
$prev = null;
foreach (array_keys($this->_pages) as $key) {
if ($key == $pageName) {
return $prev;
}
$prev = $key;
}
}
/**
* Returns the name of the page after the given.
*
* @access public
* @param string
* @return string
*/
function getNextName($pageName)
{
$prev = null;
foreach (array_keys($this->_pages) as $key) {
if ($prev == $pageName) {
return $key;
}
$prev = $key;
}
return null;
}
/**
* Finds the (first) invalid page
*
* @access public
* @return string Name of an invalid page
*/
function findInvalid()
{
$data =& $this->container();
foreach (array_keys($this->_pages) as $key) {
if (!$data['valid'][$key]) {
return $key;
}
}
return null;
}
/**
* Extracts the names of the current page and the current action from
* HTTP request data.
*
* @access public
* @return array first element is page name, second is action name
*/
function getActionName()
{
if (is_array($this->_actionName)) {
return $this->_actionName;
}
$names = array_map('preg_quote', array_keys($this->_pages));
$regex = '/^_qf_(' . implode('|', $names) . ')_(.+?)(_x)?$/';
foreach (array_keys($_REQUEST) as $key) {
if (preg_match($regex, $key, $matches)) {
return array($matches[1], $matches[2]);
}
}
if (isset($_REQUEST['_qf_default'])) {
$matches = explode(':', $_REQUEST['_qf_default'], 2);
if (isset($this->_pages[$matches[0]])) {
return $matches;
}
}
reset($this->_pages);
return array(key($this->_pages), 'display');
}
/**
* Initializes default form values.
*
* @access public
* @param array default values
* @param mixed filter(s) to apply to default values
* @throws PEAR_Error
*/
function setDefaults($defaultValues = null, $filter = null)
{
if (is_array($defaultValues)) {
$data =& $this->container();
return $this->_setDefaultsOrConstants($data['defaults'], $defaultValues, $filter);
}
}
/**
* Initializes constant form values.
* These values won't get overridden by POST or GET vars
*
* @access public
* @param array constant values
* @param mixed filter(s) to apply to constant values
* @throws PEAR_Error
*/
function setConstants($constantValues = null, $filter = null)
{
if (is_array($constantValues)) {
$data =& $this->container();
return $this->_setDefaultsOrConstants($data['constants'], $constantValues, $filter);
}
}
/**
* Adds new values to defaults or constants array
*
* @access private
* @param array array to add values to (either defaults or constants)
* @param array values to add
* @param mixed filters to apply to new values
* @throws PEAR_Error
*/
function _setDefaultsOrConstants(&$values, $newValues, $filter = null)
{
if (isset($filter)) {
if (is_array($filter) && (2 != count($filter) || !is_callable($filter))) {
foreach ($filter as $val) {
if (!is_callable($val)) {
throw new \Exception("Callback function does not exist in QuickForm_Controller::_setDefaultsOrConstants()");
} else {
$newValues = $this->_arrayMapRecursive($val, $newValues);
}
}
} elseif (!is_callable($filter)) {
throw new \Exception("Callback function does not exist in QuickForm_Controller::_setDefaultsOrConstants()");
} else {
$newValues = $this->_arrayMapRecursive($val, $newValues);
}
}
$values = HTML_QuickForm::arrayMerge($values, $newValues);
}
/**
* Recursively applies the callback function to the value
*
* @param mixed Callback function
* @param mixed Value to process
* @access private
* @return mixed Processed values
*/
function _arrayMapRecursive($callback, $value)
{
if (!is_array($value)) {
return call_user_func($callback, $value);
} else {
$map = array();
foreach ($value as $k => $v) {
$map[$k] = $this->_arrayMapRecursive($callback, $v);
}
return $map;
}
}
/**
* Sets the default values for the given page
*
* @access public
* @param string Name of a page
*/
function applyDefaults($pageName)
{
$data =& $this->container();
if (!empty($data['defaults'])) {
$this->_pages[$pageName]->setDefaults($data['defaults']);
}
if (!empty($data['constants'])) {
$this->_pages[$pageName]->setConstants($data['constants']);
}
}
/**
* Returns the form's values
*
* @access public
* @param string name of the page, if not set then returns values for all pages
* @return array
*/
function exportValues($pageName = null)
{
$data =& $this->container();
$values = array();
if (isset($pageName)) {
$pages = array($pageName);
} else {
$pages = array_keys($data['values']);
}
foreach ($pages as $page) {
// skip elements representing actions
foreach ($data['values'][$page] as $key => $value) {
if (0 !== strpos($key, '_qf_')) {
if (isset($values[$key]) && is_array($value)) {
$values[$key] = HTML_QuickForm::arrayMerge($values[$key], $value);
} else {
$values[$key] = $value;
}
}
}
}
return $values;
}
/**
* Returns the element's value
*
* @access public
* @param string name of the page
* @param string name of the element in the page
* @return mixed value for the element
*/
function exportValue($pageName, $elementName)
{
$data =& $this->container();
return isset($data['values'][$pageName][$elementName])? $data['values'][$pageName][$elementName]: null;
}
}
?>

View File

@@ -0,0 +1,210 @@
<?php
/**
* Class representing a page of a multipage form.
*
* PHP versions 4 and 5
*
* LICENSE: This source file is subject to version 3.01 of the PHP license
* that is available through the world-wide-web at the following URI:
* http://www.php.net/license/3_01.txt If you did not receive a copy of
* the PHP License and are unable to obtain it through the web, please
* send a note to license@php.net so we can mail you a copy immediately.
*
* @category HTML
* @package HTML_QuickForm_Controller
* @author Alexey Borzov <avb@php.net>
* @author Bertrand Mansion <bmansion@mamasam.com>
* @copyright 2003-2009 The PHP Group
* @license http://www.php.net/license/3_01.txt PHP License 3.01
* @version SVN: $Id: Page.php 289084 2009-10-02 06:53:09Z avb $
* @link http://pear.php.net/package/HTML_QuickForm_Controller
*/
/**
* Class representing a page of a multipage form.
*
* Generally you'll need to subclass this and define your buildForm()
* method that will build the form. While it is also possible to instantiate
* this class and build the form manually, this is not the recommended way.
*
* @category HTML
* @package HTML_QuickForm_Controller
* @author Alexey Borzov <avb@php.net>
* @author Bertrand Mansion <bmansion@mamasam.com>
* @version Release: 1.0.10
*/
class HTML_QuickForm_Page extends HTML_QuickForm
{
/**
* Contains the mapping of actions to corresponding HTML_QuickForm_Action objects
* @var array
*/
var $_actions = array();
/**
* Contains a reference to a Controller object containing this page
* @var HTML_QuickForm_Controller
* @access public
*/
var $controller = null;
/**
* Should be set to true on first call to buildForm()
* @var bool
*/
var $_formBuilt = false;
/**
* Class constructor
*
* @access public
*/
function HTML_QuickForm_Page($formName, $method = 'post', $target = '', $attributes = null)
{
$this->HTML_QuickForm($formName, $method, '', $target, $attributes);
}
/**
* Registers a handler for a specific action.
*
* @access public
*
* @param string name of the action
* @param HTML_QuickForm_Action the handler for the action
*/
function addAction($actionName, &$action)
{
$this->_actions[$actionName] =& $action;
}
/**
* Handles an action.
*
* If an Action object was not registered here, controller's handle()
* method will be called.
*
* @access public
*
* @param string Name of the action
*
* @throws PEAR_Error
*/
function handle($actionName)
{
if (isset($this->_actions[$actionName])) {
return $this->_actions[$actionName]->perform($this, $actionName);
} else {
return $this->controller->handle($this, $actionName);
}
}
/**
* Returns a name for a submit button that will invoke a specific action.
*
* @access public
*
* @param string Name of the action
*
* @return string "name" attribute for a submit button
*/
function getButtonName($actionName)
{
return '_qf_'.$this->getAttribute('id').'_'.$actionName;
}
/**
* Loads the submit values from the array.
*
* The method is NOT intended for general usage.
*
* @param array 'submit' values
*
* @access public
*/
function loadValues($values)
{
$this->_flagSubmitted = true;
$this->_submitValues = $values;
foreach (array_keys($this->_elements) as $key) {
$this->_elements[$key]->onQuickFormEvent('updateValue', null, $this);
}
}
/**
* Builds a form.
*
* You should override this method when you subclass HTML_QuickForm_Page,
* it should contain all the necessary addElement(), applyFilter(), addRule()
* and possibly setDefaults() and setConstants() calls. The method will be
* called on demand, so please be sure to set $_formBuilt property to true to
* assure that the method works only once.
*
* @access public
* @abstract
*/
function buildForm()
{
$this->_formBuilt = true;
}
/**
* Checks whether the form was already built.
*
* @access public
* @return bool
*/
function isFormBuilt()
{
return $this->_formBuilt;
}
/**
* Sets the default action invoked on page-form submit
*
* This is necessary as the user may just press Enter instead of
* clicking one of the named submit buttons and then no action name will
* be passed to the script.
*
* @access public
*
* @param string default action name
*/
function setDefaultAction($actionName)
{
if ($this->elementExists('_qf_default')) {
$element =& $this->getElement('_qf_default');
$element->setValue($this->getAttribute('id').':'.$actionName);
} else {
$this->addElement('hidden', '_qf_default', $this->getAttribute('id').':'.$actionName);
}
}
/**
* Returns 'safe' elements' values
*
* @param mixed Array/string of element names, whose values we want. If not set then return all elements.
* @param bool Whether to remove internal (_qf_...) values from the resultant array
*/
function exportValues($elementList = null, $filterInternal = false)
{
$values = parent::exportValues($elementList);
if ($filterInternal) {
foreach (array_keys($values) as $key) {
if (0 === strpos($key, '_qf_')) {
unset($values[$key]);
}
}
}
return $values;
}
}
?>

View File

@@ -0,0 +1,156 @@
<?php
/**
* An abstract base class for QuickForm renderers
*
* PHP versions 4 and 5
*
* LICENSE: This source file is subject to version 3.01 of the PHP license
* that is available through the world-wide-web at the following URI:
* http://www.php.net/license/3_01.txt If you did not receive a copy of
* the PHP License and are unable to obtain it through the web, please
* send a note to license@php.net so we can mail you a copy immediately.
*
* @category HTML
* @package HTML_QuickForm
* @author Alexey Borzov <avb@php.net>
* @copyright 2001-2009 The PHP Group
* @license http://www.php.net/license/3_01.txt PHP License 3.01
* @version CVS: $Id$
* @link http://pear.php.net/package/HTML_QuickForm
*/
/**
* An abstract base class for QuickForm renderers
*
* The class implements a Visitor design pattern
*
* @category HTML
* @package HTML_QuickForm
* @author Alexey Borzov <avb@php.net>
* @version Release: 3.2.11
* @since 3.0
* @abstract
*/
class HTML_QuickForm_Renderer
{
/**
* Constructor
*
* @access public
*/
public function __construct()
{
}
/**
* Called when visiting a form, before processing any form elements
*
* @param HTML_QuickForm a form being visited
* @access public
* @return void
* @abstract
*/
function startForm(&$form)
{
return;
}
/**
* Called when visiting a form, after processing all form elements
*
* @param HTML_QuickForm a form being visited
* @access public
* @return void
* @abstract
*/
function finishForm(&$form)
{
return;
} // end func finishForm
/**
* Called when visiting a header element
*
* @param HTML_QuickForm_header a header element being visited
* @access public
* @return void
* @abstract
*/
function renderHeader(&$header)
{
return;
} // end func renderHeader
/**
* Called when visiting an element
*
* @param HTML_QuickForm_element form element being visited
* @param bool Whether an element is required
* @param string An error message associated with an element
* @access public
* @return void
* @abstract
*/
function renderElement(&$element, $required, $error)
{
return;
}
/**
* Called when visiting a hidden element
*
* @param HTML_QuickForm_element a hidden element being visited
* @access public
* @return void
* @abstract
*/
function renderHidden(&$element)
{
return;
}
/**
* Called when visiting a raw HTML/text pseudo-element
*
* Only implemented in Default renderer. Usage of 'html' elements is
* discouraged, templates should be used instead.
*
* @param HTML_QuickForm_html a 'raw html' element being visited
* @access public
* @return void
* @abstract
*/
function renderHtml(&$data)
{
return;
} // end func renderHtml
/**
* Called when visiting a group, before processing any group elements
*
* @param HTML_QuickForm_group A group being visited
* @param bool Whether a group is required
* @param string An error message associated with a group
* @access public
* @return void
* @abstract
*/
function startGroup(&$group, $required, $error)
{
return;
} // end func startGroup
/**
* Called when visiting a group, after processing all group elements
*
* @param HTML_QuickForm_group A group being visited
* @access public
* @return void
* @abstract
*/
function finishGroup(&$group)
{
return;
}
}

View File

@@ -0,0 +1,335 @@
<?php
/* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4: */
/**
* A concrete renderer for HTML_QuickForm, makes an array of form contents
*
* PHP versions 4 and 5
*
* LICENSE: This source file is subject to version 3.01 of the PHP license
* that is available through the world-wide-web at the following URI:
* http://www.php.net/license/3_01.txt If you did not receive a copy of
* the PHP License and are unable to obtain it through the web, please
* send a note to license@php.net so we can mail you a copy immediately.
*
* @category HTML
* @package HTML_QuickForm
* @author Alexey Borzov <avb@php.net>
* @author Adam Daniel <adaniel1@eesus.jnj.com>
* @author Bertrand Mansion <bmansion@mamasam.com>
* @author Thomas Schulz <ths@4bconsult.de>
* @copyright 2001-2009 The PHP Group
* @license http://www.php.net/license/3_01.txt PHP License 3.01
* @version CVS: $Id: Array.php,v 1.11 2009/04/04 21:34:04 avb Exp $
* @link http://pear.php.net/package/HTML_QuickForm
*/
/**
* A concrete renderer for HTML_QuickForm, makes an array of form contents
*
* Based on old HTML_QuickForm::toArray() code.
*
* The form array structure is the following:
* <pre>
* array(
* 'frozen' => 'whether the form is frozen',
* 'javascript' => 'javascript for client-side validation',
* 'attributes' => 'attributes for <form> tag',
* 'requirednote => 'note about the required elements',
* // if we set the option to collect hidden elements
* 'hidden' => 'collected html of all hidden elements',
* // if there were some validation errors:
* 'errors' => array(
* '1st element name' => 'Error for the 1st element',
* ...
* 'nth element name' => 'Error for the nth element'
* ),
* // if there are no headers in the form:
* 'elements' => array(
* element_1,
* ...
* element_N
* )
* // if there are headers in the form:
* 'sections' => array(
* array(
* 'header' => 'Header text for the first header',
* 'name' => 'Header name for the first header',
* 'elements' => array(
* element_1,
* ...
* element_K1
* )
* ),
* ...
* array(
* 'header' => 'Header text for the Mth header',
* 'name' => 'Header name for the Mth header',
* 'elements' => array(
* element_1,
* ...
* element_KM
* )
* )
* )
* );
* </pre>
*
* where element_i is an array of the form:
* <pre>
* array(
* 'name' => 'element name',
* 'value' => 'element value',
* 'type' => 'type of the element',
* 'frozen' => 'whether element is frozen',
* 'label' => 'label for the element',
* 'required' => 'whether element is required',
* 'error' => 'error associated with the element',
* 'style' => 'some information about element style (e.g. for Smarty)',
* // if element is not a group
* 'html' => 'HTML for the element'
* // if element is a group
* 'separator' => 'separator for group elements',
* 'elements' => array(
* element_1,
* ...
* element_N
* )
* );
* </pre>
*
* @category HTML
* @package HTML_QuickForm
* @author Alexey Borzov <avb@php.net>
* @author Adam Daniel <adaniel1@eesus.jnj.com>
* @author Bertrand Mansion <bmansion@mamasam.com>
* @author Thomas Schulz <ths@4bconsult.de>
* @version Release: 3.2.11
* @since 3.0
*/
class HTML_QuickForm_Renderer_Array extends HTML_QuickForm_Renderer
{
/**#@+
* @access private
*/
/**
* An array being generated
* @var array
*/
var $_ary;
/**
* Number of sections in the form (i.e. number of headers in it)
* @var integer
*/
var $_sectionCount;
/**
* Current section number
* @var integer
*/
var $_currentSection;
/**
* Array representing current group
* @var array
*/
var $_currentGroup = null;
/**
* Additional style information for different elements
* @var array
*/
var $_elementStyles = array();
/**
* true: collect all hidden elements into string; false: process them as usual form elements
* @var bool
*/
var $_collectHidden = false;
/**
* true: render an array of labels to many labels, $key 0 named 'label', the rest "label_$key"
* false: leave labels as defined
* @var bool
*/
var $_staticLabels = false;
/**#@-*/
/**
* Constructor
*
* @param bool true: collect all hidden elements into string; false: process them as usual form elements
* @param bool true: render an array of labels to many labels, $key 0 to 'label' and the oterh to "label_$key"
* @access public
*/
function HTML_QuickForm_Renderer_Array($collectHidden = false, $staticLabels = false)
{
$this->HTML_QuickForm_Renderer();
$this->_collectHidden = $collectHidden;
$this->_staticLabels = $staticLabels;
} // end constructor
/**
* Returns the resultant array
*
* @access public
* @return array
*/
function toArray()
{
return $this->_ary;
}
function startForm(&$form)
{
$this->_ary = array(
'frozen' => $form->isFrozen(),
'javascript' => $form->getValidationScript(),
'attributes' => $form->getAttributes(true),
'requirednote' => $form->getRequiredNote(),
'errors' => array()
);
if ($this->_collectHidden) {
$this->_ary['hidden'] = '';
}
$this->_elementIdx = 1;
$this->_currentSection = null;
$this->_sectionCount = 0;
} // end func startForm
function renderHeader(&$header)
{
$this->_ary['sections'][$this->_sectionCount] = array(
'header' => $header->toHtml(),
'name' => $header->getName()
);
$this->_currentSection = $this->_sectionCount++;
} // end func renderHeader
function renderElement(&$element, $required, $error)
{
$elAry = $this->_elementToArray($element, $required, $error);
if (!empty($error)) {
$this->_ary['errors'][$elAry['name']] = $error;
}
$this->_storeArray($elAry);
} // end func renderElement
function renderHidden(&$element)
{
if ($this->_collectHidden) {
$this->_ary['hidden'] .= $element->toHtml() . "\n";
} else {
$this->renderElement($element, false, null);
}
} // end func renderHidden
function startGroup(&$group, $required, $error)
{
$this->_currentGroup = $this->_elementToArray($group, $required, $error);
if (!empty($error)) {
$this->_ary['errors'][$this->_currentGroup['name']] = $error;
}
} // end func startGroup
function finishGroup(&$group)
{
$this->_storeArray($this->_currentGroup);
$this->_currentGroup = null;
} // end func finishGroup
/**
* Creates an array representing an element
*
* @access private
* @param HTML_QuickForm_element element being processed
* @param bool Whether an element is required
* @param string Error associated with the element
* @return array
*/
function _elementToArray(&$element, $required, $error)
{
$ret = array(
'name' => $element->getName(),
'value' => $element->getValue(),
'type' => $element->getType(),
'frozen' => $element->isFrozen(),
'required' => $required,
'error' => $error
);
// render label(s)
$labels = $element->getLabel();
if (is_array($labels) && $this->_staticLabels) {
foreach($labels as $key => $label) {
$key = is_int($key)? $key + 1: $key;
if (1 === $key) {
$ret['label'] = $label;
} else {
$ret['label_' . $key] = $label;
}
}
} else {
$ret['label'] = $labels;
}
// set the style for the element
if (isset($this->_elementStyles[$ret['name']])) {
$ret['style'] = $this->_elementStyles[$ret['name']];
}
if ('group' == $ret['type']) {
$ret['separator'] = $element->_separator;
$ret['elements'] = array();
} else {
$ret['html'] = $element->toHtml();
}
return $ret;
}
/**
* Stores an array representation of an element in the form array
*
* @access private
* @param array Array representation of an element
* @return void
*/
function _storeArray($elAry)
{
// where should we put this element...
if (is_array($this->_currentGroup) && ('group' != $elAry['type'])) {
$this->_currentGroup['elements'][] = $elAry;
} elseif (isset($this->_currentSection)) {
$this->_ary['sections'][$this->_currentSection]['elements'][] = $elAry;
} else {
$this->_ary['elements'][] = $elAry;
}
}
/**
* Sets a style to use for element rendering
*
* @param mixed element name or array ('element name' => 'style name')
* @param string style name if $elementName is not an array
* @access public
* @return void
*/
function setElementStyle($elementName, $styleName = null)
{
if (is_array($elementName)) {
$this->_elementStyles = array_merge($this->_elementStyles, $elementName);
} else {
$this->_elementStyles[$elementName] = $styleName;
}
}
}
?>

View File

@@ -0,0 +1,398 @@
<?php
/* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4: */
/**
* A static renderer for HTML_QuickForm, makes an array of form content
* useful for a Smarty template
*
* PHP versions 4 and 5
*
* LICENSE: This source file is subject to version 3.01 of the PHP license
* that is available through the world-wide-web at the following URI:
* http://www.php.net/license/3_01.txt If you did not receive a copy of
* the PHP License and are unable to obtain it through the web, please
* send a note to license@php.net so we can mail you a copy immediately.
*
* @category HTML
* @package HTML_QuickForm
* @author Alexey Borzov <avb@php.net>
* @author Bertrand Mansion <bmansion@mamasam.com>
* @author Thomas Schulz <ths@4bconsult.de>
* @copyright 2001-2009 The PHP Group
* @license http://www.php.net/license/3_01.txt PHP License 3.01
* @version CVS: $Id: ArraySmarty.php,v 1.14 2009/04/06 12:02:08 avb Exp $
* @link http://pear.php.net/package/HTML_QuickForm
*/
/**
* A static renderer for HTML_QuickForm, makes an array of form content
* useful for a Smarty template
*
* Based on old HTML_QuickForm::toArray() code and ITStatic renderer.
*
* The form array structure is the following:
* <pre>
* Array (
* [frozen] => whether the complete form is frozen'
* [javascript] => javascript for client-side validation
* [attributes] => attributes for <form> tag
* [hidden] => html of all hidden elements
* [requirednote] => note about the required elements
* [errors] => Array
* (
* [1st_element_name] => Error for the 1st element
* ...
* [nth_element_name] => Error for the nth element
* )
*
* [header] => Array
* (
* [1st_header_name] => Header text for the 1st header
* ...
* [nth_header_name] => Header text for the nth header
* )
*
* [1st_element_name] => Array for the 1st element
* ...
* [nth_element_name] => Array for the nth element
* </pre>
*
* where an element array has the form:
* <pre>
* (
* [name] => element name
* [value] => element value,
* [type] => type of the element
* [frozen] => whether element is frozen
* [label] => label for the element
* [required] => whether element is required
* // if element is not a group:
* [html] => HTML for the element
* // if element is a group:
* [separator] => separator for group elements
* [1st_gitem_name] => Array for the 1st element in group
* ...
* [nth_gitem_name] => Array for the nth element in group
* )
* )
* </pre>
*
* @category HTML
* @package HTML_QuickForm
* @author Alexey Borzov <avb@php.net>
* @author Bertrand Mansion <bmansion@mamasam.com>
* @author Thomas Schulz <ths@4bconsult.de>
* @version Release: 3.2.11
* @since 3.0
*/
class HTML_QuickForm_Renderer_ArraySmarty extends HTML_QuickForm_Renderer_Array
{
/**#@+
* @access private
*/
/**
* The Smarty template engine instance
* @var object
*/
var $_tpl = null;
/**
* Current element index
* @var integer
*/
var $_elementIdx = 0;
/**
* The current element index inside a group
* @var integer
*/
var $_groupElementIdx = 0;
/**
* How to handle the required tag for required fields
* @var string
* @see setRequiredTemplate()
*/
var $_required = '';
/**
* How to handle error messages in form validation
* @var string
* @see setErrorTemplate()
*/
var $_error = '';
/**#@-*/
/**
* Constructor
*
* @param Smarty reference to the Smarty template engine instance
* @param bool true: render an array of labels to many labels, $key 0 to 'label' and the oterh to "label_$key"
* @param bool true: collect all hidden elements into string; false: process them as usual form elements
* @access public
*/
function HTML_QuickForm_Renderer_ArraySmarty(&$tpl, $staticLabels = false, $collectHidden = true)
{
$this->HTML_QuickForm_Renderer_Array($collectHidden, $staticLabels);
$this->_tpl =& $tpl;
} // end constructor
/**
* Called when visiting a header element
*
* @param HTML_QuickForm_header header element being visited
* @access public
* @return void
*/
function renderHeader(&$header)
{
if ($name = $header->getName()) {
$this->_ary['header'][$name] = $header->toHtml();
} else {
$this->_ary['header'][$this->_sectionCount] = $header->toHtml();
}
$this->_currentSection = $this->_sectionCount++;
} // end func renderHeader
/**
* Called when visiting a group, before processing any group elements
*
* @param HTML_QuickForm_group group being visited
* @param bool Whether a group is required
* @param string An error message associated with a group
* @access public
* @return void
*/
function startGroup(&$group, $required, $error)
{
parent::startGroup($group, $required, $error);
$this->_groupElementIdx = 1;
} // end func startGroup
/**
* Creates an array representing an element containing
* the key for storing this
*
* @access private
* @param HTML_QuickForm_element form element being visited
* @param bool Whether an element is required
* @param string Error associated with the element
* @return array
*/
function _elementToArray(&$element, $required, $error)
{
$ret = parent::_elementToArray($element, $required, $error);
if ('group' == $ret['type']) {
$ret['html'] = $element->toHtml();
// we don't need the elements, see the array structure
unset($ret['elements']);
}
if (($required || $error) && !empty($this->_required)){
$this->_renderRequired($ret['label'], $ret['html'], $required, $error);
}
if ($error && !empty($this->_error)) {
$this->_renderError($ret['label'], $ret['html'], $error);
$ret['error'] = $error;
}
// create keys for elements grouped by native group or name
if (strstr($ret['name'], '[') or $this->_currentGroup) {
// Fix for bug #8123: escape backslashes and quotes to prevent errors
// in eval(). The code below seems to handle the case where element
// name has unbalanced square brackets. Dunno whether we really
// need this after the fix for #8123, but I'm wary of making big
// changes to this code.
preg_match('/([^]]*)\\[([^]]*)\\]/', $ret['name'], $matches);
if (isset($matches[1])) {
$sKeysSub = substr_replace($ret['name'], '', 0, strlen($matches[1]));
$sKeysSub = str_replace(
array('\\', '\'', '[' , ']', '[\'\']'),
array('\\\\', '\\\'', '[\'', '\']', '[]' ),
$sKeysSub
);
$sKeys = '[\'' . str_replace(array('\\', '\''), array('\\\\', '\\\''), $matches[1]) . '\']' . $sKeysSub;
} else {
$sKeys = '[\'' . str_replace(array('\\', '\''), array('\\\\', '\\\''), $ret['name']) . '\']';
}
// special handling for elements in native groups
if ($this->_currentGroup) {
// skip unnamed group items unless radios: no name -> no static access
// identification: have the same key string as the parent group
if ($this->_currentGroup['keys'] == $sKeys and 'radio' != $ret['type']) {
return false;
}
// reduce string of keys by remove leading group keys
if (0 === strpos($sKeys, $this->_currentGroup['keys'])) {
$sKeys = substr_replace($sKeys, '', 0, strlen($this->_currentGroup['keys']));
}
}
// element without a name
} elseif ($ret['name'] == '') {
$sKeys = '[\'element_' . $this->_elementIdx . '\']';
// other elements
} else {
$sKeys = '[\'' . str_replace(array('\\', '\''), array('\\\\', '\\\''), $ret['name']) . '\']';
}
// for radios: add extra key from value
if ('radio' == $ret['type'] and substr($sKeys, -2) != '[]') {
$sKeys .= '[\'' . str_replace(array('\\', '\''), array('\\\\', '\\\''), $ret['value']) . '\']';
}
$this->_elementIdx++;
$ret['keys'] = $sKeys;
return $ret;
} // end func _elementToArray
/**
* Stores an array representation of an element in the form array
*
* @access private
* @param array Array representation of an element
* @return void
*/
function _storeArray($elAry)
{
if ($elAry) {
$sKeys = $elAry['keys'];
unset($elAry['keys']);
// where should we put this element...
if (is_array($this->_currentGroup) && ('group' != $elAry['type'])) {
$toEval = '$this->_currentGroup' . $sKeys . ' = $elAry;';
} else {
$toEval = '$this->_ary' . $sKeys . ' = $elAry;';
}
eval($toEval);
}
return;
}
/**
* Called when an element is required
*
* This method will add the required tag to the element label and/or the element html
* such as defined with the method setRequiredTemplate.
*
* @param string The element label
* @param string The element html rendering
* @param boolean The element required
* @param string The element error
* @see setRequiredTemplate()
* @access private
* @return void
*/
function _renderRequired(&$label, &$html, &$required, &$error)
{
$this->_tpl->assign(array(
'label' => $label,
'html' => $html,
'required' => $required,
'error' => $error
));
if (!empty($label) && strpos($this->_required, $this->_tpl->left_delimiter . '$label') !== false) {
$label = $this->_tplFetch($this->_required);
}
if (!empty($html) && strpos($this->_required, $this->_tpl->left_delimiter . '$html') !== false) {
$html = $this->_tplFetch($this->_required);
}
$this->_tpl->clear_assign(array('label', 'html', 'required'));
} // end func _renderRequired
/**
* Called when an element has a validation error
*
* This method will add the error message to the element label or the element html
* such as defined with the method setErrorTemplate. If the error placeholder is not found
* in the template, the error will be displayed in the form error block.
*
* @param string The element label
* @param string The element html rendering
* @param string The element error
* @see setErrorTemplate()
* @access private
* @return void
*/
function _renderError(&$label, &$html, &$error)
{
$this->_tpl->assign(array('label' => '', 'html' => '', 'error' => $error));
$error = $this->_tplFetch($this->_error);
$this->_tpl->assign(array('label' => $label, 'html' => $html));
if (!empty($label) && strpos($this->_error, $this->_tpl->left_delimiter . '$label') !== false) {
$label = $this->_tplFetch($this->_error);
} elseif (!empty($html) && strpos($this->_error, $this->_tpl->left_delimiter . '$html') !== false) {
$html = $this->_tplFetch($this->_error);
}
$this->_tpl->clear_assign(array('label', 'html', 'error'));
} // end func _renderError
/**
* Process an template sourced in a string with Smarty
*
* Smarty has no core function to render a template given as a string.
* So we use the smarty eval plugin function to do this.
*
* @param string The template source
* @access private
* @return void
*/
function _tplFetch($tplSource)
{
if (!function_exists('smarty_function_eval')) {
require SMARTY_DIR . '/plugins/function.eval.php';
}
return smarty_function_eval(array('var' => $tplSource), $this->_tpl);
}// end func _tplFetch
/**
* Sets the way required elements are rendered
*
* You can use {$label} or {$html} placeholders to let the renderer know where
* where the element label or the element html are positionned according to the
* required tag. They will be replaced accordingly with the right value. You
* can use the full smarty syntax here, especially a custom modifier for I18N.
* For example:
* {if $required}<span style="color: red;">*</span>{/if}{$label|translate}
* will put a red star in front of the label if the element is required and
* translate the label.
*
*
* @param string The required element template
* @access public
* @return void
*/
function setRequiredTemplate($template)
{
$this->_required = $template;
} // end func setRequiredTemplate
/**
* Sets the way elements with validation errors are rendered
*
* You can use {$label} or {$html} placeholders to let the renderer know where
* where the element label or the element html are positionned according to the
* error message. They will be replaced accordingly with the right value.
* The error message will replace the {$error} placeholder.
* For example:
* {if $error}<span style="color: red;">{$error}</span>{/if}<br />{$html}
* will put the error message in red on top of the element html.
*
* If you want all error messages to be output in the main error block, use
* the {$form.errors} part of the rendered array that collects all raw error
* messages.
*
* If you want to place all error messages manually, do not specify {$html}
* nor {$label}.
*
* Groups can have special layouts. With this kind of groups, you have to
* place the formated error message manually. In this case, use {$form.group.error}
* where you want the formated error message to appear in the form.
*
* @param string The element error template
* @access public
* @return void
*/
function setErrorTemplate($template)
{
$this->_error = $template;
} // end func setErrorTemplate
}
?>

View File

@@ -0,0 +1,566 @@
<?php
/* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4: */
/**
* A concrete renderer for HTML_QuickForm, based on QuickForm 2.x built-in one
*
* PHP versions 4 and 5
*
* LICENSE: This source file is subject to version 3.01 of the PHP license
* that is available through the world-wide-web at the following URI:
* http://www.php.net/license/3_01.txt If you did not receive a copy of
* the PHP License and are unable to obtain it through the web, please
* send a note to license@php.net so we can mail you a copy immediately.
*
* @category HTML
* @package HTML_QuickForm
* @author Alexey Borzov <avb@php.net>
* @author Adam Daniel <adaniel1@eesus.jnj.com>
* @author Bertrand Mansion <bmansion@mamasam.com>
* @copyright 2001-2009 The PHP Group
* @license http://www.php.net/license/3_01.txt PHP License 3.01
* @version CVS: $Id$
* @link http://pear.php.net/package/HTML_QuickForm
*/
/**
* A concrete renderer for HTML_QuickForm, based on QuickForm 2.x built-in one
*
* @category HTML
* @package HTML_QuickForm
* @author Alexey Borzov <avb@php.net>
* @author Adam Daniel <adaniel1@eesus.jnj.com>
* @author Bertrand Mansion <bmansion@mamasam.com>
* @version Release: 3.2.11
* @since 3.0
*/
class HTML_QuickForm_Renderer_Default extends HTML_QuickForm_Renderer
{
private $form;
private $customElementTemplate;
/**
* @return mixed
*/
public function getCustomElementTemplate()
{
return $this->customElementTemplate;
}
/**
* This template will be taken instead of the default templates by element
* @param string $customElementTemplate
*/
public function setCustomElementTemplate($customElementTemplate)
{
$this->customElementTemplate = $customElementTemplate;
}
/**
* The HTML of the form
* @var string
* @access private
*/
var $_html;
/**
* Header Template string
* @var string
* @access private
*/
var $_headerTemplate =
"\n\t<tr>\n\t\t<td style=\"white-space: nowrap; background-color: #CCCCCC;\" align=\"left\" valign=\"top\" colspan=\"2\"><b>{header}</b></td>\n\t</tr>";
/**
* Element template string
* @var string
* @access private
*/
var $_elementTemplate =
"\n\t<tr>\n\t\t<td align=\"right\" valign=\"top\"><!-- BEGIN required --><span style=\"color: #ff0000\">*</span><!-- END required --><b>{label}</b></td>\n\t\t<td valign=\"top\" align=\"left\"><!-- BEGIN error --><span style=\"color: #ff0000\">{error}</span><br /><!-- END error -->\t{element}</td>\n\t</tr>";
/**
* Form template string
* @var string
* @access private
*/
var $_formTemplate =
"\n<form{attributes}>\n<div>\n{hidden}<table border=\"0\">\n{content}\n</table>\n</div>\n</form>";
/**
* Required Note template string
* @var string
* @access private
*/
var $_requiredNoteTemplate =
"\n\t<tr>\n\t\t<td></td>\n\t<td align=\"left\" valign=\"top\">{requiredNote}</td>\n\t</tr>";
/**
* Array containing the templates for customised elements
* @var array
* @access private
*/
var $_templates = array();
/**
* Array containing the templates for group wraps.
*
* These templates are wrapped around group elements and groups' own
* templates wrap around them. This is set by setGroupTemplate().
*
* @var array
* @access private
*/
var $_groupWraps = array();
/**
* Array containing the templates for elements within groups
* @var array
* @access private
*/
var $_groupTemplates = array();
/**
* True if we are inside a group
* @var bool
* @access private
*/
var $_inGroup = false;
/**
* Array with HTML generated for group elements
* @var array
* @access private
*/
var $_groupElements = array();
/**
* Template for an element inside a group
* @var string
* @access private
*/
var $_groupElementTemplate = '';
/**
* HTML that wraps around the group elements
* @var string
* @access private
*/
var $_groupWrap = '';
/**
* HTML for the current group
* @var string
* @access private
*/
var $_groupTemplate = '';
/**
* Collected HTML of the hidden fields
* @var string
* @access private
*/
var $_hiddenHtml = '';
/**
* Constructor
*
* @access public
*/
public function __construct()
{
parent::__construct();
} // end constructor
/**
* returns the HTML generated for the form
*
* @access public
* @return string
*/
public function toHtml()
{
// _hiddenHtml is cleared in finishForm(), so this only matters when
// finishForm() was not called (e.g. group::toHtml(), bug #3511)
return $this->_hiddenHtml . $this->_html;
} // end func toHtml
/**
* Called when visiting a form, before processing any form elements
*
* @param HTML_QuickForm form object being visited
* @access public
* @return void
*/
function startForm(&$form)
{
$this->setForm($form);
$this->_html = '';
$this->_hiddenHtml = '';
}
/**
* @return FormValidator
*/
public function getForm()
{
return $this->form;
}
/**
* @param mixed $form
*/
public function setForm($form)
{
$this->form = $form;
} // end func startForm
/**
* Called when visiting a form, after processing all form elements
* Adds required note, form attributes, validation javascript and form content.
*
* @param HTML_QuickForm form object being visited
* @access public
* @return void
*/
public function finishForm(&$form)
{
// add a required note, if one is needed
if (!empty($form->_required) && !$form->_freezeAll) {
$this->_html .= str_replace('{requiredNote}', $form->getRequiredNote(), $this->_requiredNoteTemplate);
}
// add form attributes and content
$html = str_replace('{attributes}', $form->getAttributes(true), $this->_formTemplate);
if (strpos($this->_formTemplate, '{hidden}')) {
$html = str_replace('{hidden}', $this->_hiddenHtml, $html);
} else {
$this->_html .= $this->_hiddenHtml;
}
$this->_hiddenHtml = '';
$this->_html = str_replace('{content}', $this->_html, $html);
// add a validation script
if ('' != ($script = $form->getValidationScript())) {
$this->_html = $script . "\n" . $this->_html;
}
} // end func finishForm
/**
* Called when visiting a header element
*
* @param HTML_QuickForm_header header element being visited
* @access public
* @return void
*/
function renderHeader(&$header)
{
$name = $header->getName();
if (!empty($name) && isset($this->_templates[$name])) {
$this->_html .= str_replace('{header}', $header->toHtml(), $this->_templates[$name]);
} else {
$this->_html .= str_replace('{header}', $header->toHtml(), $this->_headerTemplate);
}
} // end func renderHeader
/**
* Helper method for renderElement
*
* @param HTML_QuickForm_element $element
* @param bool Whether an element is required
* @param string $required Error message associated with the element
* @param string $error Label for ID
* @access private
* @see renderElement()
* @return string Html for element
*/
private function _prepareTemplate(HTML_QuickForm_element $element, $required, $error)
{
$name = $element->getName();
$label = $element->getLabel();
$labelForId = $element->getAttribute('id');
$extraLabelClass = $element->getAttribute('extra_label_class');
$icon = $element->getIconToHtml();
if (is_array($label)) {
$nameLabel = array_shift($label);
// In some cases, label (coming from display_text) might be a
// double-level array. In this case, take the first item of the
// sub-array as label
if (is_array($nameLabel)) {
$nameLabel = $nameLabel[0];
}
} else {
$nameLabel = $label;
}
$labelFor = !empty($labelForId) ? 'for="' . $labelForId . '"' : 'for="' . $element->getName() . '"';
if (isset($this->_templates[$name])) {
// Custom template
$html = str_replace('{label}', $nameLabel, $this->_templates[$name]);
} else {
$customElementTemplate = $this->getCustomElementTemplate();
if (empty($customElementTemplate)) {
if (method_exists($element, 'getTemplate')) {
$template = $element->getTemplate(
$this->getForm()->getLayout()
);
if ($element->isFrozen()) {
$customFrozentemplate = $element->getCustomFrozenTemplate();
if (!empty($customFrozentemplate)) {
$template = $customFrozentemplate;
}
}
} else {
$template = $this->getForm()->getDefaultElementTemplate();
}
} else {
$template = $customElementTemplate;
}
$html = str_replace('{label}', $nameLabel, $template);
}
$html = str_replace('{label-for}', $labelFor, $html);
$html = str_replace('{icon}', $icon, $html);
$html = str_replace('{extra_label_class}', $extraLabelClass, $html);
if ($required) {
$html = str_replace('<!-- BEGIN required -->', '', $html);
$html = str_replace('<!-- END required -->', '', $html);
} else {
$html = preg_replace("/([ \t\n\r]*)?<!-- BEGIN required -->.*<!-- END required -->([ \t\n\r]*)?/isU", '', $html);
}
if (isset($error)) {
$html = str_replace('{error}', $error, $html);
$html = str_replace('{error_class}', 'error has-error', $html);
$html = str_replace('<!-- BEGIN error -->', '', $html);
$html = str_replace('<!-- END error -->', '', $html);
} else {
$html = str_replace('{error_class}', '', $html);
$html = preg_replace("/([ \t\n\r]*)?<!-- BEGIN error -->.*<!-- END error -->([ \t\n\r]*)?/isU", '', $html);
}
if (is_array($label)) {
foreach ($label as $key => $text) {
$key = is_int($key)? $key + 2: $key;
$html = str_replace("{label_{$key}}", $text, $html);
$html = str_replace("<!-- BEGIN label_{$key} -->", '', $html);
$html = str_replace("<!-- END label_{$key} -->", '', $html);
}
}
if (strpos($html, '{label_')) {
$html = preg_replace('/\s*<!-- BEGIN label_(\S+) -->.*<!-- END label_\1 -->\s*/is', '', $html);
}
return $html;
}
/**
* Renders an element Html
* Called when visiting an element
*
* @param HTML_QuickForm_element form element being visited
* @param bool Whether an element is required
* @param string An error message associated with an element
* @access public
* @return void
*/
public function renderElement(&$element, $required, $error)
{
if (!$this->_inGroup) {
$html = $this->_prepareTemplate(
$element,
$required,
$error
);
$this->_html .= str_replace('{element}', $element->toHtml(), $html);
} elseif (!empty($this->_groupElementTemplate)) {
$html = str_replace('{label}', $element->getLabel(), $this->_groupElementTemplate);
$html = str_replace('{label-for}', $element->getLabelFor(), $this->_groupElementTemplate);
if ($required) {
$html = str_replace('<!-- BEGIN required -->', '', $html);
$html = str_replace('<!-- END required -->', '', $html);
} else {
$html = preg_replace("/([ \t\n\r]*)?<!-- BEGIN required -->.*<!-- END required -->([ \t\n\r]*)?/isU", '', $html);
}
$this->_groupElements[] = str_replace('{element}', $element->toHtml(), $html);
} else {
$this->_groupElements[] = $element->toHtml();
}
} // end func renderElement
/**
* Renders an hidden element
* Called when visiting a hidden element
*
* @param HTML_QuickForm_element form element being visited
* @access public
* @return void
*/
function renderHidden(&$element)
{
$this->_hiddenHtml .= $element->toHtml() . "\n";
} // end func renderHidden
/**
* Called when visiting a raw HTML/text pseudo-element
*
* @param HTML_QuickForm_html element being visited
* @access public
* @return void
*/
function renderHtml(&$data)
{
$this->_html .= $data->toHtml();
} // end func renderHtml
/**
* Called when visiting a group, before processing any group elements
*
* @param HTML_QuickForm_group group being visited
* @param bool Whether a group is required
* @param string An error message associated with a group
* @access public
* @return void
*/
function startGroup(&$group, $required, $error)
{
$name = $group->getName();
$this->_groupTemplate = $this->_prepareTemplate($group, $required, $error);
$this->_groupElementTemplate = empty($this->_groupTemplates[$name])? '': $this->_groupTemplates[$name];
$this->_groupWrap = empty($this->_groupWraps[$name])? '': $this->_groupWraps[$name];
$this->_groupElements = array();
$this->_inGroup = true;
} // end func startGroup
/**
* Called when visiting a group, after processing all group elements
*
* @param HTML_QuickForm_group group being visited
* @access public
* @return void
*/
function finishGroup(&$group)
{
$separator = $group->_separator;
if (is_array($separator)) {
$count = count($separator);
$html = '';
for ($i = 0; $i < count($this->_groupElements); $i++) {
$html .= (0 == $i? '': $separator[($i - 1) % $count]) . $this->_groupElements[$i];
}
} else {
if (is_null($separator)) {
$separator = '&nbsp;';
}
$html = implode((string)$separator, $this->_groupElements);
}
if (!empty($this->_groupWrap)) {
$html = str_replace('{content}', $html, $this->_groupWrap);
}
$this->_html .= str_replace('{element}', $html, $this->_groupTemplate);
$this->_inGroup = false;
} // end func finishGroup
/**
* Sets element template
*
* @param string The HTML surrounding an element
* @param string (optional) Name of the element to apply template for
* @access public
* @return void
*/
function setElementTemplate($html, $element = null)
{
if (is_null($element)) {
$this->_elementTemplate = $html;
} else {
$this->_templates[$element] = $html;
}
} // end func setElementTemplate
/**
* Sets template for a group wrapper
*
* This template is contained within a group-as-element template
* set via setTemplate() and contains group's element templates, set
* via setGroupElementTemplate()
*
* @param string The HTML surrounding group elements
* @param string Name of the group to apply template for
* @access public
* @return void
*/
function setGroupTemplate($html, $group)
{
$this->_groupWraps[$group] = $html;
} // end func setGroupTemplate
/**
* Sets element template for elements within a group
*
* @param string The HTML surrounding an element
* @param string Name of the group to apply template for
* @access public
* @return void
*/
function setGroupElementTemplate($html, $group)
{
$this->_groupTemplates[$group] = $html;
} // end func setGroupElementTemplate
/**
* Sets header template
*
* @param string The HTML surrounding the header
* @access public
* @return void
*/
function setHeaderTemplate($html)
{
$this->_headerTemplate = $html;
} // end func setHeaderTemplate
/**
* Sets form template
*
* @param string The HTML surrounding the form tags
* @access public
* @return void
*/
function setFormTemplate($html) {
$this->_formTemplate = $html;
} // end func setFormTemplate
/**
* Sets the note indicating required fields template
*
* @param string The HTML surrounding the required note
* @access public
* @return void
*/
function setRequiredNoteTemplate($html)
{
$this->_requiredNoteTemplate = $html;
} // end func setRequiredNoteTemplate
/**
* Clears all the HTML out of the templates that surround notes, elements, etc.
* Useful when you want to use addData() to create a completely custom form look
*
* @access public
* @return void
*/
function clearAllTemplates()
{
$this->setElementTemplate('{element}');
$this->setFormTemplate("\n\t<form{attributes}>{content}\n\t</form>\n");
$this->setRequiredNoteTemplate('');
$this->_templates = array();
} // end func clearAllTemplates
} // end class HTML_QuickForm_Renderer_Default

View File

@@ -0,0 +1,295 @@
<?php
/* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4: */
/**
* A concrete renderer for HTML_QuickForm, using Integrated Templates.
*
* PHP versions 4 and 5
*
* LICENSE: This source file is subject to version 3.01 of the PHP license
* that is available through the world-wide-web at the following URI:
* http://www.php.net/license/3_01.txt If you did not receive a copy of
* the PHP License and are unable to obtain it through the web, please
* send a note to license@php.net so we can mail you a copy immediately.
*
* @category HTML
* @package HTML_QuickForm
* @author Alexey Borzov <avb@php.net>
* @copyright 2001-2009 The PHP Group
* @license http://www.php.net/license/3_01.txt PHP License 3.01
* @version CVS: $Id: ITDynamic.php,v 1.7 2009/04/04 21:34:04 avb Exp $
* @link http://pear.php.net/package/HTML_QuickForm
*/
/**
* A concrete renderer for HTML_QuickForm, using Integrated Templates.
*
* This is a "dynamic" renderer, which means that concrete form look
* is defined at runtime. This also means that you can define
* <b>one</b> template file for <b>all</b> your forms. That template
* should contain a block for every element 'look' appearing in your
* forms and also some special blocks (consult the examples). If a
* special block is not set for an element, the renderer falls back to
* a default one.
*
* @category HTML
* @package HTML_QuickForm
* @author Alexey Borzov <avb@php.net>
* @version Release: 3.2.11
* @since 3.0
*/
class HTML_QuickForm_Renderer_ITDynamic extends HTML_QuickForm_Renderer
{
/**#@+
* @access private
*/
/**
* A template class (HTML_Template_ITX or HTML_Template_Sigma) instance
* @var HTML_Template_ITX|HTML_Template_Sigma
*/
var $_tpl = null;
/**
* The errors that were not shown near concrete fields go here
* @var array
*/
var $_errors = array();
/**
* Show the block with required note?
* @var bool
*/
var $_showRequired = false;
/**
* A separator for group elements
* @var mixed
*/
var $_groupSeparator = null;
/**
* The current element index inside a group
* @var integer
*/
var $_groupElementIdx = 0;
/**
* Blocks to use for different elements
* @var array
*/
var $_elementBlocks = array();
/**
* Block to use for headers
* @var string
*/
var $_headerBlock = null;
/**#@-*/
/**
* Constructor
*
* @param HTML_Template_ITX|HTML_Template_Sigma Template object to use
*/
function HTML_QuickForm_Renderer_ITDynamic(&$tpl)
{
$this->HTML_QuickForm_Renderer();
$this->_tpl =& $tpl;
$this->_tpl->setCurrentBlock('qf_main_loop');
}
function finishForm(&$form)
{
// display errors above form
if (!empty($this->_errors) && $this->_tpl->blockExists('qf_error_loop')) {
foreach ($this->_errors as $error) {
$this->_tpl->setVariable('qf_error', $error);
$this->_tpl->parse('qf_error_loop');
}
}
// show required note
if ($this->_showRequired) {
$this->_tpl->setVariable('qf_required_note', $form->getRequiredNote());
}
// assign form attributes
$this->_tpl->setVariable('qf_attributes', $form->getAttributes(true));
// assign javascript validation rules
$this->_tpl->setVariable('qf_javascript', $form->getValidationScript());
}
function renderHeader(&$header)
{
$blockName = $this->_matchBlock($header);
if ('qf_header' == $blockName && isset($this->_headerBlock)) {
$blockName = $this->_headerBlock;
}
$this->_tpl->setVariable('qf_header', $header->toHtml());
$this->_tpl->parse($blockName);
$this->_tpl->parse('qf_main_loop');
}
function renderElement(&$element, $required, $error)
{
$blockName = $this->_matchBlock($element);
// are we inside a group?
if ('qf_main_loop' != $this->_tpl->currentBlock) {
if (0 != $this->_groupElementIdx && $this->_tpl->placeholderExists('qf_separator', $blockName)) {
if (is_array($this->_groupSeparator)) {
$this->_tpl->setVariable('qf_separator', $this->_groupSeparator[($this->_groupElementIdx - 1) % count($this->_groupSeparator)]);
} else {
$this->_tpl->setVariable('qf_separator', (string)$this->_groupSeparator);
}
}
$this->_groupElementIdx++;
} elseif(!empty($error)) {
// show the error message or keep it for later use
if ($this->_tpl->blockExists($blockName . '_error')) {
$this->_tpl->setVariable('qf_error', $error);
} else {
$this->_errors[] = $error;
}
}
// show an '*' near the required element
if ($required) {
$this->_showRequired = true;
if ($this->_tpl->blockExists($blockName . '_required')) {
$this->_tpl->touchBlock($blockName . '_required');
}
}
// Prepare multiple labels
$labels = $element->getLabel();
if (is_array($labels)) {
$mainLabel = array_shift($labels);
} else {
$mainLabel = $labels;
}
// render the element itself with its main label
$this->_tpl->setVariable('qf_element', $element->toHtml());
if ($this->_tpl->placeholderExists('qf_label', $blockName)) {
$this->_tpl->setVariable('qf_label', $mainLabel);
}
// render extra labels, if any
if (is_array($labels)) {
foreach($labels as $key => $label) {
$key = is_int($key)? $key + 2: $key;
if ($this->_tpl->blockExists($blockName . '_label_' . $key)) {
$this->_tpl->setVariable('qf_label_' . $key, $label);
}
}
}
$this->_tpl->parse($blockName);
$this->_tpl->parseCurrentBlock();
}
function renderHidden(&$element)
{
$this->_tpl->setVariable('qf_hidden', $element->toHtml());
$this->_tpl->parse('qf_hidden_loop');
}
function startGroup(&$group, $required, $error)
{
$blockName = $this->_matchBlock($group);
$this->_tpl->setCurrentBlock($blockName . '_loop');
$this->_groupElementIdx = 0;
$this->_groupSeparator = is_null($group->_separator)? '&nbsp;': $group->_separator;
// show an '*' near the required element
if ($required) {
$this->_showRequired = true;
if ($this->_tpl->blockExists($blockName . '_required')) {
$this->_tpl->touchBlock($blockName . '_required');
}
}
// show the error message or keep it for later use
if (!empty($error)) {
if ($this->_tpl->blockExists($blockName . '_error')) {
$this->_tpl->setVariable('qf_error', $error);
} else {
$this->_errors[] = $error;
}
}
$this->_tpl->setVariable('qf_group_label', $group->getLabel());
}
function finishGroup(&$group)
{
$this->_tpl->parse($this->_matchBlock($group));
$this->_tpl->setCurrentBlock('qf_main_loop');
$this->_tpl->parseCurrentBlock();
}
/**
* Returns the name of a block to use for element rendering
*
* If a name was not explicitly set via setElementBlock(), it tries
* the names '{prefix}_{element type}' and '{prefix}_{element}', where
* prefix is either 'qf' or the name of the current group's block
*
* @param HTML_QuickForm_element form element being rendered
* @access private
* @return string block name
*/
function _matchBlock(&$element)
{
$name = $element->getName();
$type = $element->getType();
if (isset($this->_elementBlocks[$name]) && $this->_tpl->blockExists($this->_elementBlocks[$name])) {
if (('group' == $type) || ($this->_elementBlocks[$name] . '_loop' != $this->_tpl->currentBlock)) {
return $this->_elementBlocks[$name];
}
}
if ('group' != $type && 'qf_main_loop' != $this->_tpl->currentBlock) {
$prefix = substr($this->_tpl->currentBlock, 0, -5); // omit '_loop' postfix
} else {
$prefix = 'qf';
}
if ($this->_tpl->blockExists($prefix . '_' . $type)) {
return $prefix . '_' . $type;
} elseif ($this->_tpl->blockExists($prefix . '_' . $name)) {
return $prefix . '_' . $name;
} else {
return $prefix . '_element';
}
}
/**
* Sets the block to use for element rendering
*
* @param mixed element name or array ('element name' => 'block name')
* @param string block name if $elementName is not an array
* @access public
* @return void
*/
function setElementBlock($elementName, $blockName = null)
{
if (is_array($elementName)) {
$this->_elementBlocks = array_merge($this->_elementBlocks, $elementName);
} else {
$this->_elementBlocks[$elementName] = $blockName;
}
}
/**
* Sets the name of a block to use for header rendering
*
* @param string block name
* @access public
* @return void
*/
function setHeaderBlock($blockName)
{
$this->_headerBlock = $blockName;
}
}
?>

View File

@@ -0,0 +1,499 @@
<?php
/* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4: */
/**
* A static renderer for HTML_QuickForm compatible
* with HTML_Template_IT and HTML_Template_Sigma.
*
* PHP versions 4 and 5
*
* LICENSE: This source file is subject to version 3.01 of the PHP license
* that is available through the world-wide-web at the following URI:
* http://www.php.net/license/3_01.txt If you did not receive a copy of
* the PHP License and are unable to obtain it through the web, please
* send a note to license@php.net so we can mail you a copy immediately.
*
* @category HTML
* @package HTML_QuickForm
* @author Bertrand Mansion <bmansion@mamasam.com>
* @copyright 2001-2009 The PHP Group
* @license http://www.php.net/license/3_01.txt PHP License 3.01
* @version CVS: $Id: ITStatic.php,v 1.9 2009/04/04 21:34:04 avb Exp $
* @link http://pear.php.net/package/HTML_QuickForm
*/
/**
* A static renderer for HTML_QuickForm compatible
* with HTML_Template_IT and HTML_Template_Sigma.
*
* As opposed to the dynamic renderer, this renderer needs
* every elements and labels in the form to be specified by
* placeholders at the position you want them to be displayed.
*
* @category HTML
* @package HTML_QuickForm
* @author Bertrand Mansion <bmansion@mamasam.com>
* @version Release: 3.2.11
* @since 3.0
*/
class HTML_QuickForm_Renderer_ITStatic extends HTML_QuickForm_Renderer
{
/**#@+
* @access private
*/
/**
* An HTML_Template_IT or some other API compatible Template instance
* @var object
*/
var $_tpl = null;
/**
* Rendered form name
* @var string
*/
var $_formName = 'form';
/**
* The errors that were not shown near concrete fields go here
* @var array
*/
var $_errors = array();
/**
* Show the block with required note?
* @var bool
*/
var $_showRequired = false;
/**
* Which group are we currently parsing ?
* @var string
*/
var $_inGroup;
/**
* Index of the element in its group
* @var int
*/
var $_elementIndex = 0;
/**
* If elements have been added with the same name
* @var array
*/
var $_duplicateElements = array();
/**
* How to handle the required tag for required fields
* @var string
*/
var $_required = '{label}<font size="1" color="red">*</font>';
/**
* How to handle error messages in form validation
* @var string
*/
var $_error = '<font color="red">{error}</font><br />{html}';
/**
* Collected HTML for hidden elements, if needed
* @var string
*/
var $_hidden = '';
/**#@-*/
/**
* Constructor
*
* @param HTML_Template_IT|HTML_Template_Sigma Template object to use
*/
function HTML_QuickForm_Renderer_ITStatic(&$tpl)
{
$this->HTML_QuickForm_Renderer();
$this->_tpl =& $tpl;
} // end constructor
/**
* Called when visiting a form, before processing any form elements
*
* @param HTML_QuickForm form object being visited
* @access public
* @return void
*/
function startForm(&$form)
{
$this->_formName = $form->getAttribute('id');
if (count($form->_duplicateIndex) > 0) {
// Take care of duplicate elements
foreach ($form->_duplicateIndex as $elementName => $indexes) {
$this->_duplicateElements[$elementName] = 0;
}
}
} // end func startForm
/**
* Called when visiting a form, after processing all form elements
*
* @param HTML_QuickForm form object being visited
* @access public
* @return void
*/
function finishForm(&$form)
{
// display errors above form
if (!empty($this->_errors) && $this->_tpl->blockExists($this->_formName.'_error_loop')) {
foreach ($this->_errors as $error) {
$this->_tpl->setVariable($this->_formName.'_error', $error);
$this->_tpl->parse($this->_formName.'_error_loop');
}
}
// show required note
if ($this->_showRequired) {
$this->_tpl->setVariable($this->_formName.'_required_note', $form->getRequiredNote());
}
// add hidden elements, if collected
if (!empty($this->_hidden)) {
$this->_tpl->setVariable($this->_formName . '_hidden', $this->_hidden);
}
// assign form attributes
$this->_tpl->setVariable($this->_formName.'_attributes', $form->getAttributes(true));
// assign javascript validation rules
$this->_tpl->setVariable($this->_formName.'_javascript', $form->getValidationScript());
} // end func finishForm
/**
* Called when visiting a header element
*
* @param HTML_QuickForm_header header element being visited
* @access public
* @return void
*/
function renderHeader(&$header)
{
$name = $header->getName();
$varName = $this->_formName.'_header';
// Find placeHolder
if (!empty($name) && $this->_tpl->placeHolderExists($this->_formName.'_header_'.$name)) {
$varName = $this->_formName.'_header_'.$name;
}
$this->_tpl->setVariable($varName, $header->toHtml());
} // end func renderHeader
/**
* Called when visiting an element
*
* @param HTML_QuickForm_element form element being visited
* @param bool Whether an element is required
* @param string An error message associated with an element
* @access public
* @return void
*/
function renderElement(&$element, $required, $error)
{
$name = $element->getName();
// are we inside a group?
if (!empty($this->_inGroup)) {
$varName = $this->_formName.'_'.str_replace(array('[', ']'), '_', $name);
if (substr($varName, -2) == '__') {
// element name is of type : group[]
$varName = $this->_inGroup.'_'.$this->_elementIndex.'_';
$this->_elementIndex++;
}
if ($varName != $this->_inGroup) {
$varName .= '_' == substr($varName, -1)? '': '_';
// element name is of type : group[name]
$label = $element->getLabel();
$html = $element->toHtml();
if ($required && !$element->isFrozen()) {
$this->_renderRequired($label, $html);
$this->_showRequired = true;
}
if (!empty($label)) {
if (is_array($label)) {
foreach ($label as $key => $value) {
$this->_tpl->setVariable($varName.'label_'.$key, $value);
}
} else {
$this->_tpl->setVariable($varName.'label', $label);
}
}
$this->_tpl->setVariable($varName.'html', $html);
}
} else {
$name = str_replace(array('[', ']'), array('_', ''), $name);
if (isset($this->_duplicateElements[$name])) {
// Element is a duplicate
$varName = $this->_formName.'_'.$name.'_'.$this->_duplicateElements[$name];
$this->_duplicateElements[$name]++;
} else {
$varName = $this->_formName.'_'.$name;
}
$label = $element->getLabel();
$html = $element->toHtml();
if ($required) {
$this->_showRequired = true;
$this->_renderRequired($label, $html);
}
if (!empty($error)) {
$this->_renderError($label, $html, $error);
}
if (is_array($label)) {
foreach ($label as $key => $value) {
$this->_tpl->setVariable($varName.'_label_'.$key, $value);
}
} else {
$this->_tpl->setVariable($varName.'_label', $label);
}
$this->_tpl->setVariable($varName.'_html', $html);
}
} // end func renderElement
/**
* Called when visiting a hidden element
*
* @param HTML_QuickForm_element hidden element being visited
* @access public
* @return void
*/
function renderHidden(&$element)
{
if ($this->_tpl->placeholderExists($this->_formName . '_hidden')) {
$this->_hidden .= $element->toHtml();
} else {
$name = $element->getName();
$name = str_replace(array('[', ']'), array('_', ''), $name);
$this->_tpl->setVariable($this->_formName.'_'.$name.'_html', $element->toHtml());
}
} // end func renderHidden
/**
* Called when visiting a group, before processing any group elements
*
* @param HTML_QuickForm_group group being visited
* @param bool Whether a group is required
* @param string An error message associated with a group
* @access public
* @return void
*/
function startGroup(&$group, $required, $error)
{
$name = $group->getName();
$varName = $this->_formName.'_'.$name;
$this->_elementIndex = 0;
$html = $this->_tpl->placeholderExists($varName.'_html') ? $group->toHtml() : '';
$label = $group->getLabel();
if ($required) {
$this->_renderRequired($label, $html);
}
if (!empty($error)) {
$this->_renderError($label, $html, $error);
}
if (!empty($html)) {
$this->_tpl->setVariable($varName.'_html', $html);
} else {
// Uses error blocks to set the special groups layout error
// <!-- BEGIN form_group_error -->{form_group_error}<!-- END form_group_error -->
if (!empty($error)) {
if ($this->_tpl->placeholderExists($varName.'_error')) {
if ($this->_tpl->blockExists($this->_formName . '_error_block')) {
$this->_tpl->setVariable($this->_formName . '_error', $error);
$error = $this->_getTplBlock($this->_formName . '_error_block');
} elseif (strpos($this->_error, '{html}') !== false || strpos($this->_error, '{label}') !== false) {
$error = str_replace('{error}', $error, $this->_error);
}
}
$this->_tpl->setVariable($varName . '_error', $error);
array_pop($this->_errors);
}
}
if (is_array($label)) {
foreach ($label as $key => $value) {
$this->_tpl->setVariable($varName.'_label_'.$key, $value);
}
} else {
$this->_tpl->setVariable($varName.'_label', $label);
}
$this->_inGroup = $varName;
} // end func startGroup
/**
* Called when visiting a group, after processing all group elements
*
* @param HTML_QuickForm_group group being visited
* @access public
* @return void
*/
function finishGroup(&$group)
{
$this->_inGroup = '';
} // end func finishGroup
/**
* Sets the way required elements are rendered
*
* You can use {label} or {html} placeholders to let the renderer know where
* where the element label or the element html are positionned according to the
* required tag. They will be replaced accordingly with the right value.
* For example:
* <font color="red">*</font>{label}
* will put a red star in front of the label if the element is required.
*
* @param string The required element template
* @access public
* @return void
*/
function setRequiredTemplate($template)
{
$this->_required = $template;
} // end func setRequiredTemplate
/**
* Sets the way elements with validation errors are rendered
*
* You can use {label} or {html} placeholders to let the renderer know where
* where the element label or the element html are positionned according to the
* error message. They will be replaced accordingly with the right value.
* The error message will replace the {error} place holder.
* For example:
* <font color="red">{error}</font><br />{html}
* will put the error message in red on top of the element html.
*
* If you want all error messages to be output in the main error block, do not specify
* {html} nor {label}.
*
* Groups can have special layouts. With this kind of groups, the renderer will need
* to know where to place the error message. In this case, use error blocks like:
* <!-- BEGIN form_group_error -->{form_group_error}<!-- END form_group_error -->
* where you want the error message to appear in the form.
*
* @param string The element error template
* @access public
* @return void
*/
function setErrorTemplate($template)
{
$this->_error = $template;
} // end func setErrorTemplate
/**
* Called when an element is required
*
* This method will add the required tag to the element label and/or the element html
* such as defined with the method setRequiredTemplate
*
* @param string The element label
* @param string The element html rendering
* @see setRequiredTemplate()
* @access private
* @return void
*/
function _renderRequired(&$label, &$html)
{
if ($this->_tpl->blockExists($tplBlock = $this->_formName . '_required_block')) {
if (!empty($label) && $this->_tpl->placeholderExists($this->_formName . '_label', $tplBlock)) {
$this->_tpl->setVariable($this->_formName . '_label', is_array($label)? $label[0]: $label);
if (is_array($label)) {
$label[0] = $this->_getTplBlock($tplBlock);
} else {
$label = $this->_getTplBlock($tplBlock);
}
}
if (!empty($html) && $this->_tpl->placeholderExists($this->_formName . '_html', $tplBlock)) {
$this->_tpl->setVariable($this->_formName . '_html', $html);
$html = $this->_getTplBlock($tplBlock);
}
} else {
if (!empty($label) && strpos($this->_required, '{label}') !== false) {
if (is_array($label)) {
$label[0] = str_replace('{label}', $label[0], $this->_required);
} else {
$label = str_replace('{label}', $label, $this->_required);
}
}
if (!empty($html) && strpos($this->_required, '{html}') !== false) {
$html = str_replace('{html}', $html, $this->_required);
}
}
} // end func _renderRequired
/**
* Called when an element has a validation error
*
* This method will add the error message to the element label or the element html
* such as defined with the method setErrorTemplate. If the error placeholder is not found
* in the template, the error will be displayed in the form error block.
*
* @param string The element label
* @param string The element html rendering
* @param string The element error
* @see setErrorTemplate()
* @access private
* @return void
*/
function _renderError(&$label, &$html, $error)
{
if ($this->_tpl->blockExists($tplBlock = $this->_formName . '_error_block')) {
$this->_tpl->setVariable($this->_formName . '_error', $error);
if (!empty($label) && $this->_tpl->placeholderExists($this->_formName . '_label', $tplBlock)) {
$this->_tpl->setVariable($this->_formName . '_label', is_array($label)? $label[0]: $label);
if (is_array($label)) {
$label[0] = $this->_getTplBlock($tplBlock);
} else {
$label = $this->_getTplBlock($tplBlock);
}
} elseif (!empty($html) && $this->_tpl->placeholderExists($this->_formName . '_html', $tplBlock)) {
$this->_tpl->setVariable($this->_formName . '_html', $html);
$html = $this->_getTplBlock($tplBlock);
}
// clean up after ourselves
$this->_tpl->setVariable($this->_formName . '_error', null);
} elseif (!empty($label) && strpos($this->_error, '{label}') !== false) {
if (is_array($label)) {
$label[0] = str_replace(array('{label}', '{error}'), array($label[0], $error), $this->_error);
} else {
$label = str_replace(array('{label}', '{error}'), array($label, $error), $this->_error);
}
} elseif (!empty($html) && strpos($this->_error, '{html}') !== false) {
$html = str_replace(array('{html}', '{error}'), array($html, $error), $this->_error);
} else {
$this->_errors[] = $error;
}
}// end func _renderError
/**
* Returns the block's contents
*
* The method is needed because ITX and Sigma implement clearing
* the block contents on get() a bit differently
*
* @param string Block name
* @return string Block contents
*/
function _getTplBlock($block)
{
$this->_tpl->parse($block);
if (is_a($this->_tpl, 'html_template_sigma')) {
$ret = $this->_tpl->get($block, true);
} else {
$oldClear = $this->_tpl->clearCache;
$this->_tpl->clearCache = true;
$ret = $this->_tpl->get($block);
$this->_tpl->clearCache = $oldClear;
}
return $ret;
}
} // end class HTML_QuickForm_Renderer_ITStatic
?>

View File

@@ -0,0 +1,456 @@
<?php
/* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4: */
/**
* A concrete renderer for HTML_QuickForm, makes an object from form contents
*
* PHP versions 4 and 5
*
* LICENSE: This source file is subject to version 3.01 of the PHP license
* that is available through the world-wide-web at the following URI:
* http://www.php.net/license/3_01.txt If you did not receive a copy of
* the PHP License and are unable to obtain it through the web, please
* send a note to license@php.net so we can mail you a copy immediately.
*
* @category HTML
* @package HTML_QuickForm
* @author Ron McClain <ron@humaniq.com>
* @copyright 2001-2009 The PHP Group
* @license http://www.php.net/license/3_01.txt PHP License 3.01
* @version CVS: $Id: Object.php,v 1.6 2009/04/04 21:34:04 avb Exp $
* @link http://pear.php.net/package/HTML_QuickForm
*/
/**
* A concrete renderer for HTML_QuickForm, makes an object from form contents
*
* Based on HTML_Quickform_Renderer_Array code
*
* @category HTML
* @package HTML_QuickForm
* @author Ron McClain <ron@humaniq.com>
* @version Release: 3.2.11
* @since 3.1.1
*/
class HTML_QuickForm_Renderer_Object extends HTML_QuickForm_Renderer
{
/**#@+
* @access private
*/
/**
* The object being generated
* @var QuickformForm
*/
var $_obj= null;
/**
* Number of sections in the form (i.e. number of headers in it)
* @var integer $_sectionCount
*/
var $_sectionCount;
/**
* Current section number
* @var integer $_currentSection
*/
var $_currentSection;
/**
* Object representing current group
* @var object $_currentGroup
*/
var $_currentGroup = null;
/**
* Class of Element Objects
* @var object $_elementType
*/
var $_elementType = 'QuickFormElement';
/**
* Additional style information for different elements
* @var array $_elementStyles
*/
var $_elementStyles = array();
/**
* true: collect all hidden elements into string; false: process them as usual form elements
* @var bool $_collectHidden
*/
var $_collectHidden = false;
/**#@-*/
/**
* Constructor
*
* @param bool true: collect all hidden elements
* @access public
*/
function HTML_QuickForm_Renderer_Object($collecthidden = false)
{
$this->HTML_QuickForm_Renderer();
$this->_collectHidden = $collecthidden;
$this->_obj = new QuickformForm;
}
/**
* Return the rendered Object
* @access public
*/
function toObject()
{
return $this->_obj;
}
/**
* Set the class of the form elements. Defaults to QuickformElement.
* @param string Name of element class
* @access public
*/
function setElementType($type)
{
$this->_elementType = $type;
}
function startForm(&$form)
{
$this->_obj->frozen = $form->isFrozen();
$this->_obj->javascript = $form->getValidationScript();
$this->_obj->attributes = $form->getAttributes(true);
$this->_obj->requirednote = $form->getRequiredNote();
$this->_obj->errors = new StdClass;
if($this->_collectHidden) {
$this->_obj->hidden = '';
}
$this->_elementIdx = 1;
$this->_currentSection = null;
$this->_sectionCount = 0;
} // end func startForm
function renderHeader(&$header)
{
$hobj = new StdClass;
$hobj->header = $header->toHtml();
$this->_obj->sections[$this->_sectionCount] = $hobj;
$this->_currentSection = $this->_sectionCount++;
}
function renderElement(&$element, $required, $error)
{
$elObj = $this->_elementToObject($element, $required, $error);
if(!empty($error)) {
$name = $elObj->name;
$this->_obj->errors->$name = $error;
}
$this->_storeObject($elObj);
} // end func renderElement
function renderHidden(&$element)
{
if($this->_collectHidden) {
$this->_obj->hidden .= $element->toHtml() . "\n";
} else {
$this->renderElement($element, false, null);
}
} //end func renderHidden
function startGroup(&$group, $required, $error)
{
$this->_currentGroup = $this->_elementToObject($group, $required, $error);
if(!empty($error)) {
$name = $this->_currentGroup->name;
$this->_obj->errors->$name = $error;
}
} // end func startGroup
function finishGroup(&$group)
{
$this->_storeObject($this->_currentGroup);
$this->_currentGroup = null;
} // end func finishGroup
/**
* Creates an object representing an element
*
* @access private
* @param HTML_QuickForm_element form element being rendered
* @param required bool Whether an element is required
* @param error string Error associated with the element
* @return object
*/
function _elementToObject(&$element, $required, $error)
{
if($this->_elementType) {
$ret = new $this->_elementType;
}
$ret->name = $element->getName();
$ret->value = $element->getValue();
$ret->type = $element->getType();
$ret->frozen = $element->isFrozen();
$labels = $element->getLabel();
if (is_array($labels)) {
$ret->label = array_shift($labels);
foreach ($labels as $key => $label) {
$key = is_int($key)? $key + 2: $key;
$ret->{'label_' . $key} = $label;
}
} else {
$ret->label = $labels;
}
$ret->required = $required;
$ret->error = $error;
if(isset($this->_elementStyles[$ret->name])) {
$ret->style = $this->_elementStyles[$ret->name];
$ret->styleTemplate = "styles/". $ret->style .".html";
}
if($ret->type == 'group') {
$ret->separator = $element->_separator;
$ret->elements = array();
} else {
$ret->html = $element->toHtml();
}
return $ret;
}
/**
* Stores an object representation of an element in the form array
*
* @access private
* @param QuickformElement Object representation of an element
* @return void
*/
function _storeObject($elObj)
{
$name = $elObj->name;
if(is_object($this->_currentGroup) && $elObj->type != 'group') {
$this->_currentGroup->elements[] = $elObj;
} elseif (isset($this->_currentSection)) {
$this->_obj->sections[$this->_currentSection]->elements[] = $elObj;
} else {
$this->_obj->elements[] = $elObj;
}
}
function setElementStyle($elementName, $styleName = null)
{
if(is_array($elementName)) {
$this->_elementStyles = array_merge($this->_elementStyles, $elementName);
} else {
$this->_elementStyles[$elementName] = $styleName;
}
}
} // end class HTML_QuickForm_Renderer_Object
/**
* Convenience class for the form object passed to outputObject()
*
* Eg.
* <pre>
* {form.outputJavaScript():h}
* {form.outputHeader():h}
* <table>
* <tr>
* <td>{form.name.label:h}</td><td>{form.name.html:h}</td>
* </tr>
* </table>
* </form>
* </pre>
*
* @category HTML
* @package HTML_QuickForm
* @author Ron McClain <ron@humaniq.com>
* @version Release: 3.2.11
* @since 3.1.1
*/
class QuickformForm
{
/**
* Whether the form has been frozen
* @var boolean $frozen
*/
var $frozen;
/**
* Javascript for client-side validation
* @var string $javascript
*/
var $javascript;
/**
* Attributes for form tag
* @var string $attributes
*/
var $attributes;
/**
* Note about required elements
* @var string $requirednote
*/
var $requirednote;
/**
* Collected html of all hidden variables
* @var string $hidden
*/
var $hidden;
/**
* Set if there were validation errors.
* StdClass object with element names for keys and their
* error messages as values
* @var object $errors
*/
var $errors;
/**
* Array of QuickformElementObject elements. If there are headers in the form
* this will be empty and the elements will be in the
* separate sections
* @var array $elements
*/
var $elements;
/**
* Array of sections contained in the document
* @var array $sections
*/
var $sections;
/**
* Output &lt;form&gt; header
* {form.outputHeader():h}
* @return string &lt;form attributes&gt;
*/
function outputHeader()
{
return "<form " . $this->attributes . ">\n";
}
/**
* Output form javascript
* {form.outputJavaScript():h}
* @return string Javascript
*/
function outputJavaScript()
{
return $this->javascript;
}
} // end class QuickformForm
/**
* Convenience class describing a form element.
*
* The properties defined here will be available from
* your flexy templates by referencing
* {form.zip.label:h}, {form.zip.html:h}, etc.
*
* @category HTML
* @package HTML_QuickForm
* @author Ron McClain <ron@humaniq.com>
* @version Release: 3.2.11
* @since 3.1.1
*/
class QuickformElement
{
/**
* Element name
* @var string $name
*/
var $name;
/**
* Element value
* @var mixed $value
*/
var $value;
/**
* Type of element
* @var string $type
*/
var $type;
/**
* Whether the element is frozen
* @var boolean $frozen
*/
var $frozen;
/**
* Label for the element
* @var string $label
*/
var $label;
/**
* Whether element is required
* @var boolean $required
*/
var $required;
/**
* Error associated with the element
* @var string $error
*/
var $error;
/**
* Some information about element style
* @var string $style
*/
var $style;
/**
* HTML for the element
* @var string $html
*/
var $html;
/**
* If element is a group, the group separator
* @var mixed $separator
*/
var $separator;
/**
* If element is a group, an array of subelements
* @var array $elements
*/
var $elements;
function isType($type)
{
return ($this->type == $type);
}
function notFrozen()
{
return !$this->frozen;
}
function isButton()
{
return ($this->type == "submit" || $this->type == "reset");
}
/**
* XXX: why does it use Flexy when all other stuff here does not depend on it?
*/
function outputStyle()
{
ob_start();
HTML_Template_Flexy::staticQuickTemplate('styles/' . $this->style . '.html', $this);
$ret = ob_get_contents();
ob_end_clean();
return $ret;
}
} // end class QuickformElement
?>

View File

@@ -0,0 +1,286 @@
<?php
/* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4: */
/**
* QuickForm renderer for Flexy template engine, static version.
*
* PHP versions 4 and 5
*
* LICENSE: This source file is subject to version 3.01 of the PHP license
* that is available through the world-wide-web at the following URI:
* http://www.php.net/license/3_01.txt If you did not receive a copy of
* the PHP License and are unable to obtain it through the web, please
* send a note to license@php.net so we can mail you a copy immediately.
*
* @category HTML
* @package HTML_QuickForm
* @author Ron McClain <ron@humaniq.com>
* @copyright 2001-2009 The PHP Group
* @license http://www.php.net/license/3_01.txt PHP License 3.01
* @version CVS: $Id: ObjectFlexy.php,v 1.10 2009/04/04 21:34:04 avb Exp $
* @link http://pear.php.net/package/HTML_QuickForm
*/
/**
* QuickForm renderer for Flexy template engine, static version.
*
* A static renderer for HTML_Quickform. Makes a QuickFormFlexyObject
* from the form content suitable for use with a Flexy template
*
* Usage:
* <code>
* $form =& new HTML_QuickForm('form', 'POST');
* $template =& new HTML_Template_Flexy();
* $renderer =& new HTML_QuickForm_Renderer_ObjectFlexy(&$template);
* $renderer->setHtmlTemplate("html.html");
* $renderer->setLabelTemplate("label.html");
* $form->accept($renderer);
* $view = new StdClass;
* $view->form = $renderer->toObject();
* $template->compile("mytemplate.html");
* </code>
*
* Based on the code for HTML_QuickForm_Renderer_ArraySmarty
*
* @category HTML
* @package HTML_QuickForm
* @author Ron McClain <ron@humaniq.com>
* @version Release: 3.2.11
* @since 3.1.1
*/
class HTML_QuickForm_Renderer_ObjectFlexy extends HTML_QuickForm_Renderer_Object
{
/**#@+
* @access private
*/
/**
* HTML_Template_Flexy instance
* @var object $_flexy
*/
var $_flexy;
/**
* Current element index
* @var integer $_elementIdx
*/
var $_elementIdx;
/**
* The current element index inside a group
* @var integer $_groupElementIdx
*/
var $_groupElementIdx = 0;
/**
* Name of template file for form html
* @var string $_html
* @see setRequiredTemplate()
*/
var $_html = '';
/**
* Name of template file for form labels
* @var string $label
* @see setErrorTemplate()
*/
var $label = '';
/**
* Class of the element objects, so you can add your own
* element methods
* @var string $_elementType
*/
var $_elementType = 'QuickformFlexyElement';
/**#@-*/
/**
* Constructor
*
* @param HTML_Template_Flexy template object to use
* @public
*/
function HTML_QuickForm_Renderer_ObjectFlexy(&$flexy)
{
$this->HTML_QuickForm_Renderer_Object(true);
$this->_obj = new QuickformFlexyForm();
$this->_flexy =& $flexy;
} // end constructor
function renderHeader(&$header)
{
if($name = $header->getName()) {
$this->_obj->header->$name = $header->toHtml();
} else {
$this->_obj->header[$this->_sectionCount] = $header->toHtml();
}
$this->_currentSection = $this->_sectionCount++;
} // end func renderHeader
function startGroup(&$group, $required, $error)
{
parent::startGroup($group, $required, $error);
$this->_groupElementIdx = 1;
} //end func startGroup
/**
* Creates an object representing an element containing
* the key for storing this
*
* @access private
* @param HTML_QuickForm_element form element being rendered
* @param bool Whether an element is required
* @param string Error associated with the element
* @return object
*/
function _elementToObject(&$element, $required, $error)
{
$ret = parent::_elementToObject($element, $required, $error);
if($ret->type == 'group') {
$ret->html = $element->toHtml();
unset($ret->elements);
}
if(!empty($this->_label)) {
$this->_renderLabel($ret);
}
if(!empty($this->_html)) {
$this->_renderHtml($ret);
$ret->error = $error;
}
// Create an element key from the name
if (false !== ($pos = strpos($ret->name, '[')) || is_object($this->_currentGroup)) {
if (!$pos) {
$keys = '->{\'' . str_replace(array('\\', '\''), array('\\\\', '\\\''), $ret->name) . '\'}';
} else {
$keys = '->{\'' . str_replace(
array('\\', '\'', '[', ']'), array('\\\\', '\\\'', '\'}->{\'', ''),
$ret->name
) . '\'}';
}
// special handling for elements in native groups
if (is_object($this->_currentGroup)) {
// skip unnamed group items unless radios: no name -> no static access
// identification: have the same key string as the parent group
if ($this->_currentGroup->keys == $keys && 'radio' != $ret->type) {
return false;
}
// reduce string of keys by remove leading group keys
if (0 === strpos($keys, $this->_currentGroup->keys)) {
$keys = substr_replace($keys, '', 0, strlen($this->_currentGroup->keys));
}
}
} elseif (0 == strlen($ret->name)) {
$keys = '->{\'element_' . $this->_elementIdx . '\'}';
} else {
$keys = '->{\'' . str_replace(array('\\', '\''), array('\\\\', '\\\''), $ret->name) . '\'}';
}
// for radios: add extra key from value
if ('radio' == $ret->type && '[]' != substr($keys, -2)) {
$keys .= '->{\'' . str_replace(array('\\', '\''), array('\\\\', '\\\''), $ret->value) . '\'}';
}
$ret->keys = $keys;
$this->_elementIdx++;
return $ret;
}
/**
* Stores an object representation of an element in the
* QuickformFormObject instance
*
* @access private
* @param QuickformElement Object representation of an element
* @return void
*/
function _storeObject($elObj)
{
if ($elObj) {
$keys = $elObj->keys;
unset($elObj->keys);
if(is_object($this->_currentGroup) && ('group' != $elObj->type)) {
$code = '$this->_currentGroup' . $keys . ' = $elObj;';
} else {
$code = '$this->_obj' . $keys . ' = $elObj;';
}
eval($code);
}
}
/**
* Set the filename of the template to render html elements.
* In your template, {html} is replaced by the unmodified html.
* If the element is required, {required} will be true.
* Eg.
* <pre>
* {if:error}
* <font color="red" size="1">{error:h}</font><br />
* {end:}
* {html:h}
* </pre>
*
* @access public
* @param string Filename of template
* @return void
*/
function setHtmlTemplate($template)
{
$this->_html = $template;
}
/**
* Set the filename of the template to render form labels
* In your template, {label} is replaced by the unmodified label.
* {error} will be set to the error, if any. {required} will
* be true if this is a required field
* Eg.
* <pre>
* {if:required}
* <font color="orange" size="1">*</font>
* {end:}
* {label:h}
* </pre>
*
* @access public
* @param string Filename of template
* @return void
*/
function setLabelTemplate($template)
{
$this->_label = $template;
}
function _renderLabel(&$ret)
{
$this->_flexy->compile($this->_label);
$ret->label = $this->_flexy->bufferedOutputObject($ret);
}
function _renderHtml(&$ret)
{
$this->_flexy->compile($this->_html);
$ret->html = $this->_flexy->bufferedOutputObject($ret);
}
} // end class HTML_QuickForm_Renderer_ObjectFlexy
/**
* Adds nothing to QuickformForm, left for backwards compatibility
*
* @category HTML
* @package HTML_QuickForm
* @ignore
*/
class QuickformFlexyForm extends QuickformForm
{
}
/**
* Adds nothing to QuickformElement, left for backwards compatibility
*
* @category HTML
* @package HTML_QuickForm
* @ignore
*/
class QuickformFlexyElement extends QuickformElement
{
}
?>

View File

@@ -0,0 +1,191 @@
<?php
/* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4: */
/**
* A renderer that makes it quick and easy to create customized forms.
*
* PHP versions 4 and 5
*
* LICENSE: This source file is subject to version 3.01 of the PHP license
* that is available through the world-wide-web at the following URI:
* http://www.php.net/license/3_01.txt If you did not receive a copy of
* the PHP License and are unable to obtain it through the web, please
* send a note to license@php.net so we can mail you a copy immediately.
*
* @category HTML
* @package HTML_QuickForm
* @author Jason Rust <jrust@rustyparts.com>
* @copyright 2001-2009 The PHP Group
* @license http://www.php.net/license/3_01.txt PHP License 3.01
* @version CVS: $Id: QuickHtml.php,v 1.3 2009/04/04 21:34:04 avb Exp $
* @link http://pear.php.net/package/HTML_QuickForm
*/
/**
* A renderer that makes it quick and easy to create customized forms.
*
* This renderer has three main distinctives: an easy way to create
* custom-looking forms, the ability to separate the creation of form
* elements from their display, and being able to use QuickForm in
* widget-based template systems. See the online docs for more info.
* For a usage example see: docs/renderers/QuickHtml_example.php
*
* @category HTML
* @package HTML_QuickForm
* @author Jason Rust <jrust@rustyparts.com>
* @version Release: 3.2.11
* @since 3.1.1
*/
class HTML_QuickForm_Renderer_QuickHtml extends HTML_QuickForm_Renderer_Default
{
/**
* The array of rendered elements
* @var array
*/
var $renderedElements = array();
// }}}
// {{{ constructor
/**
* Constructor
*
* @access public
* @return void
*/
public function HTML_QuickForm_Renderer_QuickHtml()
{
$this->HTML_QuickForm_Renderer_Default();
// The default templates aren't used for this renderer
$this->clearAllTemplates();
}
/**
* returns the HTML generated for the form
*
* @param string $data (optional) Any extra data to put before the end of the form
*
* @access public
* @return string
*/
function toHtml($data = '')
{
// Render any elements that haven't been rendered explicitly by elementToHtml()
foreach (array_keys($this->renderedElements) as $key) {
if (!$this->renderedElements[$key]['rendered']) {
$this->renderedElements[$key]['rendered'] = true;
$data .= $this->renderedElements[$key]['html'] . "\n";
}
}
// Insert the extra data and form elements at the end of the form
$this->_html = str_replace('</form>', $data . "\n</form>", $this->_html);
return $this->_html;
}
/**
* Gets the html for an element and marks it as rendered.
*
* @param string $elementName The element name
* @param string $elementValue (optional) The value of the element. This is only useful
* for elements that have the same name (i.e. radio and checkbox), but
* different values
*
* @access public
* @return string The html for the QuickForm element
*/
public function elementToHtml($elementName, $elementValue = null)
{
$elementKey = null;
// Find the key for the element
foreach ($this->renderedElements as $key => $data) {
if ($data['name'] == $elementName &&
// See if the value must match as well
(is_null($elementValue) ||
$data['value'] == $elementValue)) {
$elementKey = $key;
break;
}
}
if (is_null($elementKey)) {
$msg = is_null($elementValue) ? "Element $elementName does not exist." :
"Element $elementName with value of $elementValue does not exist.";
throw new \Exception($msg);
} else {
if ($this->renderedElements[$elementKey]['rendered']) {
$msg = is_null($elementValue) ? "Element $elementName has already been rendered." :
"Element $elementName with value of $elementValue has already been rendered.";
throw new \Exception($msg);
} else {
$this->renderedElements[$elementKey]['rendered'] = true;
return $this->renderedElements[$elementKey]['html'];
}
}
}
/**
* Gets the html for an element and adds it to the array by calling
* parent::renderElement()
*
* @param HTML_QuickForm_element form element being visited
* @param bool Whether an element is required
* @param string An error message associated with an element
*
* @access public
* @return mixed HTML string of element if $immediateRender is set, else we just add the
* html to the global _html string
*/
public function renderElement(&$element, $required, $error)
{
$this->_html = '';
parent::renderElement($element, $required, $error);
if (!$this->_inGroup) {
$this->renderedElements[] = array(
'name' => $element->getName(),
'value' => $element->getValue(),
'html' => $this->_html,
'rendered' => false);
}
$this->_html = '';
}
/**
* Gets the html for a hidden element and adds it to the array.
*
* @param HTML_QuickForm_element hidden form element being visited
* @access public
* @return void
*/
public function renderHidden(&$element)
{
$this->renderedElements[] = array(
'name' => $element->getName(),
'value' => $element->getValue(),
'html' => $element->toHtml(),
'rendered' => false);
} // end func renderHidden
// }}}
// {{{ finishGroup()
/**
* Gets the html for the group element and adds it to the array by calling
* parent::finishGroup()
*
* @param HTML_QuickForm_group group being visited
* @access public
* @return void
*/
public function finishGroup(&$group)
{
$this->_html = '';
parent::finishGroup($group);
$this->renderedElements[] = array(
'name' => $group->getName(),
'value' => $group->getValue(),
'html' => $this->_html,
'rendered' => false);
$this->_html = '';
}
}

View File

@@ -0,0 +1,6 @@
<html>
<head>
</head>
<body>
</body>
</html>

View File

@@ -0,0 +1,80 @@
<?php
/**
* Abstract base class for QuickForm validation rules
*
* PHP versions 4 and 5
*
* LICENSE: This source file is subject to version 3.01 of the PHP license
* that is available through the world-wide-web at the following URI:
* http://www.php.net/license/3_01.txt If you did not receive a copy of
* the PHP License and are unable to obtain it through the web, please
* send a note to license@php.net so we can mail you a copy immediately.
*
* @category HTML
* @package HTML_QuickForm
* @author Bertrand Mansion <bmansion@mamasam.com>
* @copyright 2001-2009 The PHP Group
* @license http://www.php.net/license/3_01.txt PHP License 3.01
* @version CVS: $Id: Rule.php,v 1.4 2009/04/04 21:34:02 avb Exp $
* @link http://pear.php.net/package/HTML_QuickForm
*/
/**
* Abstract base class for QuickForm validation rules
*
* @category HTML
* @package HTML_QuickForm
* @author Bertrand Mansion <bmansion@mamasam.com>
* @version Release: 3.2.11
* @since 3.2
* @abstract
*/
class HTML_QuickForm_Rule
{
/**
* Name of the rule to use in validate method
*
* This property is used in more global rules like Callback and Regex
* to determine which callback and which regex is to be used for validation
*
* @var string
* @access public
*/
public $name;
/**
* Validates a value
*
* @access public
* @abstract
*/
public function validate($value, $options)
{
return true;
}
/**
* Sets the rule name
*
* @param string rule name
* @access public
*/
public function setName($ruleName)
{
$this->name = $ruleName;
}
/**
* Returns the javascript test (the test should return true if the value is INVALID)
*
* @param mixed Options for the rule
* @access public
* @return array first element is code to setup validation, second is the check itself
* @abstract
*/
function getValidationScript($options = null)
{
return array('', '');
}
}

View File

@@ -0,0 +1,48 @@
<?php
/* vim: set expandtab tabstop=4 shiftwidth=4: */
/**
* Rule for HTML_QuickForm to display a CAPTCHA image
*
* This package requires the use of a PHP session.
*
* PHP versions 4 and 5
*
* @category HTML
* @package HTML_QuickForm_CAPTCHA
* @author Philippe Jausions <Philippe.Jausions@11abacus.com>
* @copyright 2006-2008 by Philippe Jausions / 11abacus
* @license http://www.opensource.org/licenses/bsd-license.php New BSD
* @version CVS: $Id: CAPTCHA.php,v 1.1 2008/04/26 23:27:30 jausions Exp $
* @link http://pear.php.net/package/HTML_QuickForm_CAPTCHA
*/
/**
* Rule to compare a field with a CAPTCHA image
*
* @category HTML
* @package HTML_QuickForm_CAPTCHA
* @author Philippe Jausions <Philippe.Jausions@11abacus.com>
* @copyright 2006-2008 by Philippe Jausions / 11abacus
* @license http://www.opensource.org/licenses/bsd-license.php New BSD
* @version Release: 0.3.0
* @link http://pear.php.net/package/HTML_QuickForm_CAPTCHA
*/
class HTML_QuickForm_Rule_CAPTCHA extends HTML_QuickForm_Rule
{
/**
* Validates the data entered matches the CAPTCHA image that was
* displayed
*
* @param string $value data to validate
* @param HTML_QuickForm_CAPTCHA_Common $captcha element to check against
*
* @return boolean TRUE if valid, FALSE otherwise
* @access public
* @static
*/
function validate($value, $captcha)
{
return ($value == $captcha->getValue());
}
}

View File

@@ -0,0 +1,119 @@
<?php
/* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4: */
/**
* Validates values using callback functions or methods
*
* PHP versions 4 and 5
*
* LICENSE: This source file is subject to version 3.01 of the PHP license
* that is available through the world-wide-web at the following URI:
* http://www.php.net/license/3_01.txt If you did not receive a copy of
* the PHP License and are unable to obtain it through the web, please
* send a note to license@php.net so we can mail you a copy immediately.
*
* @category HTML
* @package HTML_QuickForm
* @author Bertrand Mansion <bmansion@mamasam.com>
* @copyright 2001-2009 The PHP Group
* @license http://www.php.net/license/3_01.txt PHP License 3.01
* @version CVS: $Id: Callback.php,v 1.9 2009/04/04 21:34:04 avb Exp $
* @link http://pear.php.net/package/HTML_QuickForm
*/
/**
* Validates values using callback functions or methods
*
* @category HTML
* @package HTML_QuickForm
* @author Bertrand Mansion <bmansion@mamasam.com>
* @version Release: 3.2.11
* @since 3.2
*/
class HTML_QuickForm_Rule_Callback extends HTML_QuickForm_Rule
{
/**
* Array of callbacks
*
* Array is in the format:
* $_data['rulename'] = array('functionname', 'classname');
* If the callback is not a method, then the class name is not set.
*
* @var array
* @access private
*/
var $_data = array();
/**
* Whether to use BC mode for specific rules
*
* Previous versions of QF passed element's name as a first parameter
* to validation functions, but not to validation methods. This behaviour
* is emulated if you are using 'function' as rule type when registering.
*
* @var array
* @access private
*/
var $_BCMode = array();
/**
* Validates a value using a callback
*
* @param string $value Value to be checked
* @param mixed $options Options for callback
* @access public
* @return boolean true if value is valid
*/
function validate($value, $options = null)
{
if (isset($this->_data[$this->name])) {
$callback = $this->_data[$this->name];
if (isset($callback[1])) {
return call_user_func(array($callback[1], $callback[0]), $value, $options);
} elseif ($this->_BCMode[$this->name]) {
return $callback[0]('', $value, $options);
} else {
return $callback[0]($value, $options);
}
} elseif (is_callable($options)) {
return call_user_func($options, $value);
} else {
return true;
}
} // end func validate
/**
* Adds new callbacks to the callbacks list
*
* @param string $name Name of rule
* @param string $callback Name of function or method
* @param string $class Name of class containing the method
* @param bool $BCMode Backwards compatibility mode
* @access public
*/
function addData($name, $callback, $class = null, $BCMode = false)
{
if (!empty($class)) {
$this->_data[$name] = array($callback, $class);
} else {
$this->_data[$name] = array($callback);
}
$this->_BCMode[$name] = $BCMode;
} // end func addData
function getValidationScript($options = null)
{
if (isset($this->_data[$this->name])) {
$callback = $this->_data[$this->name][0];
$params = ($this->_BCMode[$this->name]? "'', {jsVar}": '{jsVar}') .
(isset($options)? ", '{$options}'": '');
} else {
$callback = is_array($options)? $options[1]: $options;
$params = '{jsVar}';
}
return array('', "{jsVar} != '' && !{$callback}({$params})");
} // end func getValidationScript
} // end class HTML_QuickForm_Rule_Callback
?>

View File

@@ -0,0 +1,127 @@
<?php
/**
* Rule to compare two form fields
*
* PHP versions 4 and 5
*
* LICENSE: This source file is subject to version 3.01 of the PHP license
* that is available through the world-wide-web at the following URI:
* http://www.php.net/license/3_01.txt If you did not receive a copy of
* the PHP License and are unable to obtain it through the web, please
* send a note to license@php.net so we can mail you a copy immediately.
*
* @category HTML
* @package HTML_QuickForm
* @author Alexey Borzov <avb@php.net>
* @copyright 2001-2009 The PHP Group
* @license http://www.php.net/license/3_01.txt PHP License 3.01
* @version CVS: $Id: Compare.php,v 1.7 2009/04/04 21:34:04 avb Exp $
* @link http://pear.php.net/package/HTML_QuickForm
*/
/**
* Rule to compare two form fields
*
* The most common usage for this is to ensure that the password
* confirmation field matches the password field
*
* @category HTML
* @package HTML_QuickForm
* @author Alexey Borzov <avb@php.net>
* @version Release: 3.2.11
* @since 3.2
*/
class HTML_QuickForm_Rule_Compare extends HTML_QuickForm_Rule
{
/**
* Possible operators to use
* @var array
* @access private
*/
public $_operators = array(
'eq' => '===',
'neq' => '!==',
'gt' => '>',
'gte' => '>=',
'lt' => '<',
'lte' => '<=',
'==' => '===',
'!=' => '!=='
);
/**
* Returns the operator to use for comparing the values
*
* @access private
* @param string operator name
* @return string operator to use for validation
*/
public function _findOperator($name)
{
$name = trim($name);
if (empty($name)) {
return '===';
} elseif (isset($this->_operators[$name])) {
return $this->_operators[$name];
} elseif (in_array($name, $this->_operators)) {
return $name;
} else {
return '===';
}
}
/**
* @param array $values
* @param string $operator
* @return mixed
*/
public function validate($values, $operator = null)
{
$operator = $this->_findOperator($operator);
$a = $values[0];
$b = $values[1];
if ('===' != $operator && '!==' != $operator) {
$a = floatval($a);
$b = floatval($b);
} else {
$a = strval($a);
$b = strval($b);
}
switch ($operator) {
case '===':
return $a === $b;
break;
case '!==':
return $a !== $b;
break;
case '>':
return $a > $b;
break;
case '>=':
return $a >= $b;
break;
case '<':
return $a < $b;
break;
case '<=':
return $a <= $b;
break;
}
}
public function getValidationScript($operator = null)
{
$operator = $this->_findOperator($operator);
if ('===' != $operator && '!==' != $operator) {
$check = "!(Number({jsVar}[0]) {$operator} Number({jsVar}[1]))";
} else {
$check = "!(String({jsVar}[0]) {$operator} String({jsVar}[1]))";
}
return array('', "'' != {jsVar}[0] && {$check}");
}
}

View File

@@ -0,0 +1,47 @@
<?php
/* vim: set expandtab tabstop=4 shiftwidth=4: */
// +----------------------------------------------------------------------+
// | PHP version 4.0 |
// +----------------------------------------------------------------------+
// | Copyright (c) 1997-2003 The PHP Group |
// +----------------------------------------------------------------------+
// | This source file is subject to version 2.0 of the PHP license, |
// | that is bundled with this package in the file LICENSE, and is |
// | available at through the world-wide-web at |
// | http://www.php.net/license/2_02.txt. |
// | If you did not receive a copy of the PHP license and are unable to |
// | obtain it through the world-wide-web, please send a note to |
// | license@php.net so we can mail you a copy immediately. |
// +----------------------------------------------------------------------+
// | Author: Alexey Borzov <avb@php.net> |
// +----------------------------------------------------------------------+
//
// $Id: Compare.php 6184 2005-09-07 10:08:17Z bmol $
/**
* @package chamilo.library
*/
/**
* Rule to compare two form fields
*
* The most common usage for this is to ensure that the password
* confirmation field matches the password field
*
* @access public
* @package HTML_QuickForm
* @version $Revision: 6184 $
*/
class HTML_QuickForm_Rule_CompareDate extends HTML_QuickForm_Rule
{
function validate($values, $options)
{
if (!is_array($values[0]) && !is_array($values[1])) {
return api_strtotime($values[0]) < api_strtotime($values[1]);
} else {
$compareFn = create_function(
'$a, $b', 'return mktime($a[\'H\'],$a[\'i\'],0,$a[\'M\'],$a[\'d\'],$a[\'Y\']) <= mktime($b[\'H\'],$b[\'i\'],0,$b[\'M\'],$b[\'d\'],$b[\'Y\'] );'
);
return $compareFn($values[0], $values[1]);
}
}
}

View File

@@ -0,0 +1,20 @@
<?php
/* For licensing terms, see /license.txt */
/**
* QuickForm rule to check a date
* @package chamilo.include
*/
class Html_Quickform_Rule_Date extends HTML_QuickForm_Rule
{
/**
* Function to check a date
* @see HTML_QuickForm_Rule
* @param array $date An array with keys F (month), d (day) and Y (year)
* @return boolean True if date is valid
*/
function validate($date, $options)
{
$compareDate = create_function('$a', 'return checkdate($a[\'M\'],$a[\'d\'],$a[\'Y\']);');
return $compareDate($date);
}
}

View File

@@ -0,0 +1,68 @@
<?php
/* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4: */
/**
* Email validation rule
*
* PHP versions 4 and 5
*
* LICENSE: This source file is subject to version 3.01 of the PHP license
* that is available through the world-wide-web at the following URI:
* http://www.php.net/license/3_01.txt If you did not receive a copy of
* the PHP License and are unable to obtain it through the web, please
* send a note to license@php.net so we can mail you a copy immediately.
*
* @category HTML
* @package HTML_QuickForm
* @author Bertrand Mansion <bmansion@mamasam.com>
* @copyright 2001-2009 The PHP Group
* @license http://www.php.net/license/3_01.txt PHP License 3.01
* @version CVS: $Id: Email.php,v 1.7 2009/04/04 21:34:04 avb Exp $
* @link http://pear.php.net/package/HTML_QuickForm
*/
/**
* Email validation rule
*
* @category HTML
* @package HTML_QuickForm
* @author Bertrand Mansion <bmansion@mamasam.com>
* @version Release: 3.2.11
* @since 3.2
*/
class HTML_QuickForm_Rule_Email extends HTML_QuickForm_Rule
{
var $regex = '/^((\"[^\"\f\n\r\t\v\b]+\")|([\w\!\#\$\%\&\'\*\+\-\~\/\^\`\|\{\}]+(\.[\w\!\#\$\%\&\'\*\+\-\~\/\^\`\|\{\}]+)*))@((\[(((25[0-5])|(2[0-4][0-9])|([0-1]?[0-9]?[0-9]))\.((25[0-5])|(2[0-4][0-9])|([0-1]?[0-9]?[0-9]))\.((25[0-5])|(2[0-4][0-9])|([0-1]?[0-9]?[0-9]))\.((25[0-5])|(2[0-4][0-9])|([0-1]?[0-9]?[0-9])))\])|(((25[0-5])|(2[0-4][0-9])|([0-1]?[0-9]?[0-9]))\.((25[0-5])|(2[0-4][0-9])|([0-1]?[0-9]?[0-9]))\.((25[0-5])|(2[0-4][0-9])|([0-1]?[0-9]?[0-9]))\.((25[0-5])|(2[0-4][0-9])|([0-1]?[0-9]?[0-9])))|((([A-Za-z0-9\-])+\.)+[A-Za-z\-]+))$/';
/**
* Validates an email address
*
* @param string $email Email address
* @param boolean $checkDomain True if dns check should be performed
* @access public
* @return boolean true if email is valid
*/
function validate($email, $checkDomain = false)
{
// Fix for bug #10799: add 'D' modifier to regex
if (preg_match($this->regex . 'D', $email)) {
if ($checkDomain && function_exists('checkdnsrr')) {
$tokens = explode('@', $email);
if (checkdnsrr($tokens[1], 'MX') || checkdnsrr($tokens[1], 'A')) {
return true;
}
return false;
}
return true;
}
return false;
} // end func validate
function getValidationScript($options = null)
{
return array(" var regex = " . $this->regex . ";\n", "{jsVar} != '' && !regex.test({jsVar})");
} // end func getValidationScript
} // end class HTML_QuickForm_Rule_Email
?>

View File

@@ -0,0 +1,25 @@
<?php
/* For licensing terms, see /license.txt */
/**
* QuickForm rule to check a text field has a minimum of X chars
* @package chamilo.include
*/
class Html_Quickform_Rule_MinText extends HTML_QuickForm_Rule
{
/**
* Function to check a text field has a minimum of X chars
* @see HTML_QuickForm_Rule
* @param string $text A text
* @param int $count The minimum number of characters that the text should contain
* @return boolean True if text has the minimum number of chars required
*/
public function validate($text, $count)
{
$checkMinText = function($a, $b) {
return strlen(utf8_decode($a)) >= $b;
};
return $checkMinText($text, $count);
}
}

View File

@@ -0,0 +1,51 @@
<?php
/**
* Required elements validation
*
* PHP versions 4 and 5
*
* LICENSE: This source file is subject to version 3.01 of the PHP license
* that is available through the world-wide-web at the following URI:
* http://www.php.net/license/3_01.txt If you did not receive a copy of
* the PHP License and are unable to obtain it through the web, please
* send a note to license@php.net so we can mail you a copy immediately.
*
* @category HTML
* @package HTML_QuickForm
* @author Bertrand Mansion <bmansion@mamasam.com>
* @copyright 2001-2009 The PHP Group
* @license http://www.php.net/license/3_01.txt PHP License 3.01
* @version CVS: $Id: Required.php,v 1.6 2009/04/04 21:34:04 avb Exp $
* @link http://pear.php.net/package/HTML_QuickForm
*/
/**
* Required elements validation
*
* @category HTML
* @package HTML_QuickForm
* @author Yannick Warnier <yannick.warnier@beeznest.com>
* @version Based on release: 3.2.11
* @since 3.2
*/
class HTML_QuickForm_Rule_QuestionType extends HTML_QuickForm_Rule
{
/**
* Checks if a value is one of the accepted question types
*
* @param string $value Value to check
* @param mixed $options Not used yet
* @access public
* @return boolean true if value is not empty
*/
public function validate($value, $options = null)
{
// It seems this is a file.
if (in_array($value, preg_split('/:/', QUESTION_TYPES))) {
return true;
}
return false;
}
}

View File

@@ -0,0 +1,75 @@
<?php
/* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4: */
/**
* Checks that the length of value is within range
*
* PHP versions 4 and 5
*
* LICENSE: This source file is subject to version 3.01 of the PHP license
* that is available through the world-wide-web at the following URI:
* http://www.php.net/license/3_01.txt If you did not receive a copy of
* the PHP License and are unable to obtain it through the web, please
* send a note to license@php.net so we can mail you a copy immediately.
*
* @category HTML
* @package HTML_QuickForm
* @author Bertrand Mansion <bmansion@mamasam.com>
* @copyright 2001-2009 The PHP Group
* @license http://www.php.net/license/3_01.txt PHP License 3.01
* @version CVS: $Id: Range.php,v 1.8 2009/04/04 21:34:04 avb Exp $
* @link http://pear.php.net/package/HTML_QuickForm
*/
/**
* Checks that the length of value is within range
*
* @category HTML
* @package HTML_QuickForm
* @author Bertrand Mansion <bmansion@mamasam.com>
* @version Release: 3.2.11
* @since 3.2
*/
class HTML_QuickForm_Rule_Range extends HTML_QuickForm_Rule
{
/**
* Validates a value using a range comparison
*
* @param string $value Value to be checked
* @param mixed $options Int for length, array for range
* @access public
* @return boolean true if value is valid
*/
public function validate($value, $options)
{
$length = api_strlen($value);
switch ($this->name) {
case 'min_numeric_length':
return (float) $value >= $options;
case 'max_numeric_length':
return (float) $value <= $options;
case 'minlength':
return $length >= $options;
case 'maxlength':
return $length <= $options;
default:
return $length >= $options[0] && $length <= $options[1];
}
}
public function getValidationScript($options = null)
{
switch ($this->name) {
case 'minlength':
$test = '{jsVar}.length < '.$options;
break;
case 'maxlength':
$test = '{jsVar}.length > '.$options;
break;
default:
$test = '({jsVar}.length < '.$options[0].' || {jsVar}.length > '.$options[1].')';
}
return array('', "{jsVar} != '' && {$test}");
}
}

View File

@@ -0,0 +1,99 @@
<?php
/* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4: */
/**
* Validates values using regular expressions
*
* PHP versions 4 and 5
*
* LICENSE: This source file is subject to version 3.01 of the PHP license
* that is available through the world-wide-web at the following URI:
* http://www.php.net/license/3_01.txt If you did not receive a copy of
* the PHP License and are unable to obtain it through the web, please
* send a note to license@php.net so we can mail you a copy immediately.
*
* @category HTML
* @package HTML_QuickForm
* @author Bertrand Mansion <bmansion@mamasam.com>
* @copyright 2001-2009 The PHP Group
* @license http://www.php.net/license/3_01.txt PHP License 3.01
* @version CVS: $Id: Regex.php,v 1.6 2009/04/04 21:34:04 avb Exp $
* @link http://pear.php.net/package/HTML_QuickForm
*/
/**
* Validates values using regular expressions
*
* @category HTML
* @package HTML_QuickForm
* @author Bertrand Mansion <bmansion@mamasam.com>
* @version Release: 3.2.11
* @since 3.2
*/
class HTML_QuickForm_Rule_Regex extends HTML_QuickForm_Rule
{
/**
* Array of regular expressions
*
* Array is in the format:
* $_data['rulename'] = 'pattern';
*
* @var array
* @access private
*/
public $_data = array(
'lettersonly' => '/^[a-zA-Z]+$/',
'alphanumeric' => '/^[a-zA-Z0-9]+$/',
'numeric' => '/(^-?\d\d*\.\d*$)|(^-?\d\d*$)|(^-?\.\d\d*$)/',
'nopunctuation' => '/^[^().\/\*\^\?#!@$%+=,\"\'><~\[\]{}]+$/',
'nonzero' => '/^-?[1-9][0-9]*/',
);
/**
* Validates a value using a regular expression
*
* @param string $value Value to be checked
* @param string $regex Regular expression
* @access public
* @return boolean true if value is valid
*/
public function validate($value, $regex = null)
{
// Fix for bug #10799: add 'D' modifier to regex
if (isset($this->_data[$this->name])) {
if (!preg_match($this->_data[$this->name] . 'D', $value)) {
return false;
}
} else {
if (!preg_match($regex . 'D', $value)) {
return false;
}
}
return true;
} // end func validate
/**
* Adds new regular expressions to the list
*
* @param string $name Name of rule
* @param string $pattern Regular expression pattern
* @access public
*/
function addData($name, $pattern)
{
$this->_data[$name] = $pattern;
} // end func addData
function getValidationScript($options = null)
{
$regex = isset($this->_data[$this->name]) ? $this->_data[$this->name] : $options;
// bug #12376, converting unicode escapes and stripping 'u' modifier
if ($pos = strpos($regex, 'u', strrpos($regex, '/'))) {
$regex = substr($regex, 0, $pos) . substr($regex, $pos + 1);
$regex = preg_replace('/(?<!\\\\)(?>\\\\\\\\)*\\\\x{([a-fA-F0-9]+)}/', '\\u$1', $regex);
}
return array(" var regex = " . $regex . ";\n", "{jsVar} != '' && !regex.test({jsVar})");
}
}

View File

@@ -0,0 +1,72 @@
<?php
/**
* Required elements validation
*
* PHP versions 4 and 5
*
* LICENSE: This source file is subject to version 3.01 of the PHP license
* that is available through the world-wide-web at the following URI:
* http://www.php.net/license/3_01.txt If you did not receive a copy of
* the PHP License and are unable to obtain it through the web, please
* send a note to license@php.net so we can mail you a copy immediately.
*
* @category HTML
* @package HTML_QuickForm
* @author Bertrand Mansion <bmansion@mamasam.com>
* @copyright 2001-2009 The PHP Group
* @license http://www.php.net/license/3_01.txt PHP License 3.01
* @version CVS: $Id: Required.php,v 1.6 2009/04/04 21:34:04 avb Exp $
* @link http://pear.php.net/package/HTML_QuickForm
*/
/**
* Required elements validation
*
* @category HTML
* @package HTML_QuickForm
* @author Bertrand Mansion <bmansion@mamasam.com>
* @version Release: 3.2.11
* @since 3.2
*/
class HTML_QuickForm_Rule_Required extends HTML_QuickForm_Rule
{
/**
* Checks if an element is empty
*
* @param string $value Value to check
* @param mixed $options Not used yet
* @access public
* @return boolean true if value is not empty
*/
public function validate($value, $options = null)
{
// It seems this is a file.
if (is_array($value)) {
if (isset($value['name']) &&
isset($value['type']) &&
isset($value['tmp_name']) &&
isset($value['size']) &&
isset($value['error'])
){
if (empty($value['tmp_name'])) {
return false;
}
}
} else {
if ((string)$value == '') {
return false;
}
}
return true;
}
public function getValidationScript($options = null)
{
return array('', "{jsVar} == ''");
}
}

View File

@@ -0,0 +1,6 @@
<html>
<head>
</head>
<body>
</body>
</html>

View File

@@ -0,0 +1,387 @@
<?php
/* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4: */
/**
* Registers rule objects and uses them for validation
*
* PHP versions 4 and 5
*
* LICENSE: This source file is subject to version 3.01 of the PHP license
* that is available through the world-wide-web at the following URI:
* http://www.php.net/license/3_01.txt If you did not receive a copy of
* the PHP License and are unable to obtain it through the web, please
* send a note to license@php.net so we can mail you a copy immediately.
*
* @category HTML
* @package HTML_QuickForm
* @author Adam Daniel <adaniel1@eesus.jnj.com>
* @author Bertrand Mansion <bmansion@mamasam.com>
* @author Alexey Borzov <avb@php.net>
* @copyright 2001-2009 The PHP Group
* @license http://www.php.net/license/3_01.txt PHP License 3.01
* @version CVS: $Id: RuleRegistry.php,v 1.19 2009/04/04 21:34:02 avb Exp $
* @link http://pear.php.net/package/HTML_QuickForm
*/
/**
* Registers rule objects and uses them for validation
*
* @category HTML
* @package HTML_QuickForm
* @author Adam Daniel <adaniel1@eesus.jnj.com>
* @author Bertrand Mansion <bmansion@mamasam.com>
* @author Alexey Borzov <avb@php.net>
* @version Release: 3.2.11
* @since 3.2
*/
class HTML_QuickForm_RuleRegistry
{
/**
* Array containing references to used rules
* @var array
* @access private
*/
var $_rules = array();
/**
* Returns a singleton of HTML_QuickForm_RuleRegistry
*
* Usually, only one RuleRegistry object is needed, this is the reason
* why it is recommended to use this method to get the validation object.
*
* @access public
* @static
* @return HTML_QuickForm_RuleRegistry
*/
static function &singleton()
{
static $obj;
if (!isset($obj)) {
$obj = new HTML_QuickForm_RuleRegistry();
}
return $obj;
} // end func singleton
/**
* Registers a new validation rule
*
* In order to use a custom rule in your form, you need to register it
* first. For regular expressions, one can directly use the 'regex' type
* rule in addRule(), this is faster than registering the rule.
*
* Functions and methods can be registered. Use the 'function' type.
* When registering a method, specify the class name as second parameter.
*
* You can also register an HTML_QuickForm_Rule subclass with its own
* validate() method.
*
* @param string $ruleName Name of validation rule
* @param string $type Either: 'regex', 'function' or null
* @param string $data1 Name of function, regular expression or
* HTML_QuickForm_Rule object class name
* @param string $data2 Object parent of above function or HTML_QuickForm_Rule file path
* @access public
* @return void
*/
public function registerRule($ruleName, $type, $data1, $data2 = null)
{
$type = strtolower($type);
if ($type == 'regex') {
// Regular expression
$rule =& $this->getRule('regex');
$rule->addData($ruleName, $data1);
} elseif ($type == 'function' || $type == 'callback') {
// Callback function
$rule = $this->getRule('callback');
$rule->addData($ruleName, $data1, $data2, 'function' == $type);
} elseif (is_object($data1)) {
// An instance of HTML_QuickForm_Rule
$this->_rules[strtolower(get_class($data1))] = $data1;
}
}
/**
* Returns a reference to the requested rule object
*
* @param string $ruleName Name of the requested rule
* @access public
* @return HTML_QuickForm_Rule
*/
public function getRule($ruleName)
{
if (empty($ruleName)) {
return false;
}
$rules = array(
'required' => 'HTML_QuickForm_Rule_Required',
'maxlength' => 'HTML_QuickForm_Rule_Range',
'minlength' => 'HTML_QuickForm_Rule_Range',
'max_numeric_length' => 'HTML_QuickForm_Rule_Range',
'min_numeric_length' => 'HTML_QuickForm_Rule_Range',
'rangelength' => 'HTML_QuickForm_Rule_Range',
'email' => 'HTML_QuickForm_Rule_Email',
'regex' => 'HTML_QuickForm_Rule_Regex',
'lettersonly' => 'HTML_QuickForm_Rule_Regex',
'alphanumeric' => 'HTML_QuickForm_Rule_Regex',
'numeric' => 'HTML_QuickForm_Rule_Regex',
'nopunctuation' => 'HTML_QuickForm_Rule_Regex',
'nonzero' => 'HTML_QuickForm_Rule_Regex',
'callback' => 'HTML_QuickForm_Rule_Callback',
'compare' => 'HTML_QuickForm_Rule_Compare',
'date_compare' => 'HTML_QuickForm_Rule_DateCompare',
'comparedate' => 'HTML_QuickForm_Rule_CompareDate',
'errordate' => 'Html_Quickform_Rule_Date',
'captcha' => 'HTML_QuickForm_Rule_CAPTCHA',
'filetype' => 'HTML_QuickForm_Rule_Filetype',
'mobile_phone_number' => 'HTML_QuickForm_Rule_Mobile_Phone_Number',
'url' => 'HTML_QuickForm_Rule_Url',
'username' => 'HTML_QuickForm_Rule_Username',
'multiple_required' => 'HTML_QuickForm_Rule_MultipleRequired',
'datetime' => 'DateTimeRule',
'username_available' => 'HTML_QuickForm_Rule_UsernameAvailable',
'no_same_current_password' => 'HTML_QuickForm_Rule_NoSameCurrentPassword',
'compare_fields' => 'HTML_QuickForm_Compare_Fields',
'html' => 'HTML_QuickForm_Rule_HTML',
'CAPTCHA' => 'HTML_QuickForm_Rule_CAPTCHA',
'date' => 'HTML_QuickForm_Rule_Date',
'compare_datetime_text' => 'HTML_QuickForm_Rule_CompareDateTimeText',
'uploadedfile' => 'HTML_QuickForm_Rule_UploadFile',
'maxfilesize'=> 'HTML_QuickForm_Rule_MaxFileSize',
'mimetype' => 'HTML_QuickForm_Rule_MimeType',
'filename' => 'HTML_QuickForm_Rule_FileName',
'validquestiontype' => 'HTML_QuickForm_Rule_QuestionType',
'mintext' => 'Html_Quickform_Rule_MinText',
'internal_url' => 'HTML_QuickForm_Rule_InternalUrl',
);
$class = $rules[$ruleName];
if (empty($class)) {
return false;
}
if (!isset($this->_rules[$class])) {
$this->_rules[$class] = new $class();
}
$this->_rules[$class]->setName($ruleName);
return $this->_rules[$class];
}
/**
* Performs validation on the given values
*
* @param string $ruleName Name of the rule to be used
* @param mixed $values Can be a scalar or an array of values
* to be validated
* @param mixed $options Options used by the rule
* @param mixed $multiple Whether to validate an array of values altogether
* @access public
* @return mixed true if no error found, int of valid values (when an array of values is given) or false if error
*/
function validate($ruleName, $values, $options = null, $multiple = false)
{
$rule = $this->getRule($ruleName);
if (is_array($values) && !$multiple) {
$result = 0;
foreach ($values as $value) {
if ($rule->validate($value, $options) === true) {
$result++;
}
}
return ($result == 0) ? false : $result;
} else {
return $rule->validate($values, $options);
}
} // end func validate
/**
* Returns the validation test in javascript code
*
* @param array|HTML_QuickForm_element Element(s) the rule applies to
* @param string Element name, in case $element is
* not an array
* @param array Rule data
* @access public
* @return string JavaScript for the rule
*/
function getValidationScript(&$element, $elementName, $ruleData)
{
$reset = (isset($ruleData['reset'])) ? $ruleData['reset'] : false;
$rule = $this->getRule($ruleData['type']);
if (!is_array($element)) {
list($jsValue, $jsReset) = $this->_getJsValue($element, $elementName, $reset, null);
} else {
$jsValue = " value = new Array();\n";
$jsReset = '';
for ($i = 0; $i < count($element); $i++) {
list($tmp_value, $tmp_reset) = $this->_getJsValue($element[$i], $element[$i]->getName(), $reset, $i);
$jsValue .= "\n" . $tmp_value;
$jsReset .= $tmp_reset;
}
}
$jsField = isset($ruleData['group'])? $ruleData['group']: $elementName;
list ($jsPrefix, $jsCheck) = $rule->getValidationScript($ruleData['format']);
if (!isset($ruleData['howmany'])) {
$js = $jsValue . "\n" . $jsPrefix .
" if (" . str_replace('{jsVar}', 'value', $jsCheck) . " && !errFlag['{$jsField}']) {\n" .
" errFlag['{$jsField}'] = true;\n" .
" _qfMsg = _qfMsg + '\\n - {$ruleData['message']}';\n" .
$jsReset .
" }\n";
} else {
$js = $jsValue . "\n" . $jsPrefix .
" var res = 0;\n" .
" for (var i = 0; i < value.length; i++) {\n" .
" if (!(" . str_replace('{jsVar}', 'value[i]', $jsCheck) . ")) {\n" .
" res++;\n" .
" }\n" .
" }\n" .
" if (res < {$ruleData['howmany']} && !errFlag['{$jsField}']) {\n" .
" errFlag['{$jsField}'] = true;\n" .
" _qfMsg = _qfMsg + '\\n - {$ruleData['message']}';\n" .
$jsReset .
" }\n";
}
return $js;
} // end func getValidationScript
/**
* Returns JavaScript to get and to reset the element's value
*
* @access private
* @param HTML_QuickForm_element element being processed
* @param string element's name
* @param bool whether to generate JavaScript to reset
* the value
* @param integer value's index in the array (only used for
* multielement rules)
* @return array first item is value javascript, second is reset
*/
function _getJsValue(&$element, $elementName, $reset = false, $index = null)
{
$jsIndex = isset($index)? '[' . $index . ']': '';
$tmp_reset = $reset? " var field = frm.elements['$elementName'];\n": '';
if (is_a($element, 'html_quickform_group')) {
$value = " _qfGroups['{$elementName}'] = {";
$elements =& $element->getElements();
for ($i = 0, $count = count($elements); $i < $count; $i++) {
$append = ($elements[$i]->getType() == 'select' && $elements[$i]->getMultiple())? '[]': '';
$value .= "'" . $element->getElementName($i) . $append . "': true" .
($i < $count - 1? ', ': '');
}
$value .=
"};\n" .
" value{$jsIndex} = new Array();\n" .
" var valueIdx = 0;\n" .
" for (var i = 0; i < frm.elements.length; i++) {\n" .
" var _element = frm.elements[i];\n" .
" if (_element.name in _qfGroups['{$elementName}']) {\n" .
" switch (_element.type) {\n" .
" case 'checkbox':\n" .
" case 'radio':\n" .
" if (_element.checked) {\n" .
" value{$jsIndex}[valueIdx++] = _element.value;\n" .
" }\n" .
" break;\n" .
" case 'select-one':\n" .
" if (-1 != _element.selectedIndex) {\n" .
" value{$jsIndex}[valueIdx++] = _element.options[_element.selectedIndex].value;\n" .
" }\n" .
" break;\n" .
" case 'select-multiple':\n" .
" var tmpVal = new Array();\n" .
" var tmpIdx = 0;\n" .
" for (var j = 0; j < _element.options.length; j++) {\n" .
" if (_element.options[j].selected) {\n" .
" tmpVal[tmpIdx++] = _element.options[j].value;\n" .
" }\n" .
" }\n" .
" if (tmpIdx > 0) {\n" .
" value{$jsIndex}[valueIdx++] = tmpVal;\n" .
" }\n" .
" break;\n" .
" default:\n" .
" value{$jsIndex}[valueIdx++] = _element.value;\n" .
" }\n" .
" }\n" .
" }\n";
if ($reset) {
$tmp_reset =
" for (var i = 0; i < frm.elements.length; i++) {\n" .
" var _element = frm.elements[i];\n" .
" if (_element.name in _qfGroups['{$elementName}']) {\n" .
" switch (_element.type) {\n" .
" case 'checkbox':\n" .
" case 'radio':\n" .
" _element.checked = _element.defaultChecked;\n" .
" break;\n" .
" case 'select-one':\n" .
" case 'select-multiple':\n" .
" for (var j = 0; j < _element.options.length; j++) {\n" .
" _element.options[j].selected = _element.options[j].defaultSelected;\n" .
" }\n" .
" break;\n" .
" default:\n" .
" _element.value = _element.defaultValue;\n" .
" }\n" .
" }\n" .
" }\n";
}
} elseif ($element->getType() == 'select') {
if ($element->getMultiple()) {
$elementName .= '[]';
$value =
" value{$jsIndex} = new Array();\n" .
" var valueIdx = 0;\n" .
" for (var i = 0; i < frm.elements['{$elementName}'].options.length; i++) {\n" .
" if (frm.elements['{$elementName}'].options[i].selected) {\n" .
" value{$jsIndex}[valueIdx++] = frm.elements['{$elementName}'].options[i].value;\n" .
" }\n" .
" }\n";
} else {
$value = " value{$jsIndex} = frm.elements['{$elementName}'].selectedIndex == -1? '': frm.elements['{$elementName}'].options[frm.elements['{$elementName}'].selectedIndex].value;\n";
}
if ($reset) {
$tmp_reset .=
" for (var i = 0; i < field.options.length; i++) {\n" .
" field.options[i].selected = field.options[i].defaultSelected;\n" .
" }\n";
}
} elseif ($element->getType() == 'checkbox') {
if (is_a($element, 'html_quickform_advcheckbox')) {
$value = " value{$jsIndex} = frm.elements['$elementName'][1].checked? frm.elements['$elementName'][1].value: frm.elements['$elementName'][0].value;\n";
$tmp_reset .= $reset ? " field[1].checked = field[1].defaultChecked;\n" : '';
} else {
$value = " value{$jsIndex} = frm.elements['$elementName'].checked? '1': '';\n";
$tmp_reset .= $reset ? " field.checked = field.defaultChecked;\n" : '';
}
} elseif ($element->getType() == 'radio') {
$value = " value{$jsIndex} = '';\n" .
// Fix for bug #5644
" var els = 'length' in frm.elements['$elementName']? frm.elements['$elementName']: [ frm.elements['$elementName'] ];\n" .
" for (var i = 0; i < els.length; i++) {\n" .
" if (els[i].checked) {\n" .
" value{$jsIndex} = els[i].value;\n" .
" }\n" .
" }";
if ($reset) {
$tmp_reset .= " for (var i = 0; i < field.length; i++) {\n" .
" field[i].checked = field[i].defaultChecked;\n" .
" }";
}
} else {
$value = " value{$jsIndex} = frm.elements['$elementName'].value;";
$tmp_reset .= ($reset) ? " field.value = field.defaultValue;\n" : '';
}
return array($value, $tmp_reset);
}
}

View File

@@ -0,0 +1,69 @@
<?php
/**
* Class HTML_QuickForm_advanced_settings
*/
class HTML_QuickForm_advanced_settings extends HTML_QuickForm_static
{
/**
* Class constructor
*
* @param string $name
* @param string $label
*/
public function __construct($name = '', $label = '')
{
if (empty($label)) {
$label = get_lang('AdvancedParameters');
}
$this->updateAttributes(
array(
'label' => $label,
'name' => $name
)
);
$this->_type = 'html';
}
/**
* Accepts a renderer
*
* @param HTML_QuickForm_Renderer renderer object (only works with Default renderer!)
* @access public
* @return void
*/
function accept(&$renderer, $required = false, $error = null)
{
$renderer->renderHtml($this);
}
/**
* @return string
*/
public function toHtml()
{
$name = $this->getAttribute('name');
$text = $this->getAttribute('label');
$label = is_array($text) ? $text[0] : $text;
$html = '<div class="form-group"><div class="col-sm-10 col-sm-offset-2">';
if (is_array($text) && isset($text[1])) {
$html .= '<span class="clearfix">'.$text[1].'</span>';
}
$html .= '
<button id="'.$name.'" type="button" class="btn btn-default advanced_options" aria-pressed="false">
<em class="fa fa-bars"></em> '.$label.'
</button>
';
if (is_array($text) && isset($text[2])) {
$html .= '<div class="help-block">'.$text[2].'</div>';
}
$html .= '</div></div>';
return $html;
}
}

View File

@@ -0,0 +1,281 @@
<?php
/* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4: */
/**
* HTML class for an advanced checkbox type field
*
* PHP versions 4 and 5
*
* LICENSE: This source file is subject to version 3.01 of the PHP license
* that is available through the world-wide-web at the following URI:
* http://www.php.net/license/3_01.txt If you did not receive a copy of
* the PHP License and are unable to obtain it through the web, please
* send a note to license@php.net so we can mail you a copy immediately.
*
* @category HTML
* @package HTML_QuickForm
* @author Jason Rust <jrust@php.net>
* @author Alexey Borzov <avb@php.net>
* @copyright 2001-2009 The PHP Group
* @license http://www.php.net/license/3_01.txt PHP License 3.01
* @version CVS: $Id: advcheckbox.php,v 1.18 2009/04/04 21:34:02 avb Exp $
* @link http://pear.php.net/package/HTML_QuickForm
*/
/**
* HTML class for an advanced checkbox type field
*
* Basically this fixes a problem that HTML has had
* where checkboxes can only pass a single value (the
* value of the checkbox when checked). A value for when
* the checkbox is not checked cannot be passed, and
* furthermore the checkbox variable doesn't even exist if
* the checkbox was submitted unchecked.
*
* It works by prepending a hidden field with the same name and
* another "unchecked" value to the checbox. If the checkbox is
* checked, PHP overwrites the value of the hidden field with
* its value.
*
* @category HTML
* @package HTML_QuickForm
* @author Jason Rust <jrust@php.net>
* @author Alexey Borzov <avb@php.net>
* @version Release: 3.2.11
* @since 2.0
*/
class HTML_QuickForm_advcheckbox extends HTML_QuickForm_checkbox
{
// {{{ properties
/**
* The values passed by the hidden elment
*
* @var array
* @access private
*/
var $_values = null;
/**
* The default value
*
* @var boolean
* @access private
*/
var $_currentValue = null;
// }}}
// {{{ constructor
/**
* Class constructor
*
* @param string $elementName (optional)Input field name attribute
* @param string $elementLabel (optional)Input field label
* @param string $text (optional)Text to put after the checkbox
* @param mixed $attributes (optional)Either a typical HTML attribute string
* or an associative array
* @param mixed $values (optional)Values to pass if checked or not checked
*
* @since 1.0
* @access public
* @return void
*/
public function __construct($elementName=null, $elementLabel=null, $text=null, $attributes=null, $values=null)
{
parent::__construct($elementName, $elementLabel, $text, $attributes);
$this->setValues($values);
} //end constructor
// }}}
// {{{ getPrivateName()
/**
* Gets the private name for the element
*
* @param string $elementName The element name to make private
*
* @access public
* @return string
*
* @deprecated Deprecated since 3.2.6, both generated elements have the same name
*/
function getPrivateName($elementName)
{
return '__'.$elementName;
}
// }}}
// {{{ getOnclickJs()
/**
* Create the javascript for the onclick event which will
* set the value of the hidden field
*
* @param string $elementName The element name
*
* @access public
* @return string
*
* @deprecated Deprecated since 3.2.6, this element no longer uses any javascript
*/
function getOnclickJs($elementName)
{
$onclickJs = 'if (this.checked) { this.form[\''.$elementName.'\'].value=\''.addcslashes($this->_values[1], '\'').'\'; }';
$onclickJs .= 'else { this.form[\''.$elementName.'\'].value=\''.addcslashes($this->_values[0], '\'').'\'; }';
return $onclickJs;
}
// }}}
// {{{ setValues()
/**
* Sets the values used by the hidden element
*
* @param mixed $values The values, either a string or an array
*
* @access public
* @return void
*/
function setValues($values)
{
if (empty($values)) {
// give it default checkbox behavior
$this->_values = array('', 1);
} elseif (is_scalar($values)) {
// if it's string, then assume the value to
// be passed is for when the element is checked
$this->_values = array('', $values);
} else {
$this->_values = $values;
}
$this->updateAttributes(array('value' => $this->_values[1]));
$this->setChecked($this->_currentValue == $this->_values[1]);
}
// }}}
// {{{ setValue()
/**
* Sets the element's value
*
* @param mixed Element's value
* @access public
*/
function setValue($value)
{
$this->setChecked(isset($this->_values[1]) && $value == $this->_values[1]);
$this->_currentValue = $value;
}
// }}}
// {{{ getValue()
/**
* Returns the element's value
*
* @access public
* @return mixed
*/
function getValue()
{
if (is_array($this->_values)) {
return $this->_values[$this->getChecked()? 1: 0];
} else {
return null;
}
}
// }}}
// {{{ toHtml()
/**
* Returns the checkbox element in HTML
* and the additional hidden element in HTML
*
* @access public
* @return string
*/
function toHtml()
{
if ($this->_flagFrozen) {
return parent::toHtml();
} else {
return '<input' . $this->_getAttrString(array(
'type' => 'hidden',
'name' => $this->getName(),
'value' => $this->_values[0]
)) . ' />' . parent::toHtml();
}
} //end func toHtml
// }}}
// {{{ getFrozenHtml()
/**
* Unlike checkbox, this has to append a hidden input in both
* checked and non-checked states
*/
function getFrozenHtml()
{
return ($this->getChecked()? '<tt>[x]</tt>': '<tt>[ ]</tt>') .
$this->_getPersistantData();
}
// }}}
// {{{ onQuickFormEvent()
/**
* Called by HTML_QuickForm whenever form event is made on this element
*
* @param string $event Name of event
* @param mixed $arg event arguments
* @param object &$caller calling object
* @since 1.0
* @access public
* @return void
*/
function onQuickFormEvent($event, $arg, &$caller)
{
switch ($event) {
case 'updateValue':
// constant values override both default and submitted ones
// default values are overriden by submitted
$value = $this->_findValue($caller->_constantValues);
if (null === $value) {
$value = $this->_findValue($caller->_submitValues);
if (null === $value) {
$value = $this->_findValue($caller->_defaultValues);
}
}
if (null !== $value) {
$this->setValue($value);
}
break;
default:
parent::onQuickFormEvent($event, $arg, $caller);
}
return true;
} // end func onQuickFormLoad
// }}}
// {{{ exportValue()
/**
* This element has a value even if it is not checked, thus we override
* checkbox's behaviour here
*/
function exportValue(&$submitValues, $assoc)
{
$value = $this->_findValue($submitValues);
if (null === $value) {
$value = $this->getValue();
} elseif (is_array($this->_values) && ($value != $this->_values[0]) && ($value != $this->_values[1])) {
$value = null;
}
return $this->_prepareValue($value, $assoc);
}
// }}}
} //end class HTML_QuickForm_advcheckbox
?>

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,253 @@
<?php
/* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4: */
/**
* HTML class for an autocomplete element
*
* PHP versions 4 and 5
*
* LICENSE: This source file is subject to version 3.01 of the PHP license
* that is available through the world-wide-web at the following URI:
* http://www.php.net/license/3_01.txt If you did not receive a copy of
* the PHP License and are unable to obtain it through the web, please
* send a note to license@php.net so we can mail you a copy immediately.
*
* @category HTML
* @package HTML_QuickForm
* @author Matteo Di Giovinazzo <matteodg@infinito.it>
* @copyright 2001-2009 The PHP Group
* @license http://www.php.net/license/3_01.txt PHP License 3.01
* @version CVS: $Id: autocomplete.php,v 1.8 2009/04/04 21:34:02 avb Exp $
* @link http://pear.php.net/package/HTML_QuickForm
*/
/**
* HTML class for an autocomplete element
*
* Creates an HTML input text element that
* at every keypressed javascript event checks in an array of options
* if there's a match and autocompletes the text in case of match.
*
* For the JavaScript code thanks to Martin Honnen and Nicholas C. Zakas
* See {@link http://www.faqts.com/knowledge_base/view.phtml/aid/13562} and
* {@link http://www.sitepoint.com/article/1220}
*
* Example:
* <code>
* $autocomplete =& $form->addElement('autocomplete', 'fruit', 'Favourite fruit:');
* $options = array("Apple", "Orange", "Pear", "Strawberry");
* $autocomplete->setOptions($options);
* </code>
*
* @category HTML
* @package HTML_QuickForm
* @author Matteo Di Giovinazzo <matteodg@infinito.it>
* @version Release: 3.2.11
* @since 3.2
*/
class HTML_QuickForm_autocomplete extends HTML_QuickForm_text
{
// {{{ properties
/**
* Options for the autocomplete input text element
*
* @var array
* @access private
*/
public $_options = array();
/**
* "One-time" javascript (containing functions), see bug #4611
*
* @var string
* @access private
*/
public $_js = '';
// }}}
// {{{ constructor
/**
* Class constructor
*
* @param string $elementName (optional)Input field name attribute
* @param string $elementLabel (optional)Input field label in form
* @param array $options (optional)Autocomplete options
* @param mixed $attributes (optional)Either a typical HTML attribute string
* or an associative array. Date format is passed along the attributes.
* @access public
* @return void
*/
public function __construct($elementName = null, $elementLabel = null, $options = null, $attributes = null)
{
parent::__construct($elementName, $elementLabel, $attributes);
$this->_persistantFreeze = true;
$this->_type = 'autocomplete';
if (isset($options)) {
$this->setOptions($options);
}
} //end constructor
// }}}
// {{{ setOptions()
/**
* Sets the options for the autocomplete input text element
*
* @param array $options Array of options for the autocomplete input text element
* @access public
* @return void
*/
function setOptions($options)
{
$this->_options = array_values($options);
} // end func setOptions
// }}}
// {{{ toHtml()
/**
* Returns Html for the autocomplete input text element
*
* @access public
* @return string
*/
function toHtml()
{
// prevent problems with grouped elements
$arrayName = str_replace(array('[', ']'), array('__', ''), $this->getName()) . '_values';
$this->updateAttributes(array(
'onkeypress' => 'return autocomplete(this, event, ' . $arrayName . ');'
));
if ($this->_flagFrozen) {
$js = '';
} else {
$js = "<script type=\"text/javascript\">\n//<![CDATA[\n";
if (!defined('HTML_QUICKFORM_AUTOCOMPLETE_EXISTS')) {
$this->_js .= <<<EOS
/* begin javascript for autocomplete */
function setSelectionRange(input, selectionStart, selectionEnd) {
if (input.setSelectionRange) {
input.setSelectionRange(selectionStart, selectionEnd);
}
else if (input.createTextRange) {
var range = input.createTextRange();
range.collapse(true);
range.moveEnd("character", selectionEnd);
range.moveStart("character", selectionStart);
range.select();
}
input.focus();
}
function setCaretToPosition(input, position) {
setSelectionRange(input, position, position);
}
function replaceSelection (input, replaceString) {
var len = replaceString.length;
if (input.setSelectionRange) {
var selectionStart = input.selectionStart;
var selectionEnd = input.selectionEnd;
input.value = input.value.substring(0, selectionStart) + replaceString + input.value.substring(selectionEnd);
input.selectionStart = selectionStart + len;
input.selectionEnd = selectionStart + len;
}
else if (document.selection) {
var range = document.selection.createRange();
var saved_range = range.duplicate();
if (range.parentElement() == input) {
range.text = replaceString;
range.moveEnd("character", saved_range.selectionStart + len);
range.moveStart("character", saved_range.selectionStart + len);
range.select();
}
}
input.focus();
}
function autocompleteMatch (text, values) {
for (var i = 0; i < values.length; i++) {
if (values[i].toUpperCase().indexOf(text.toUpperCase()) == 0) {
return values[i];
}
}
return null;
}
function autocomplete(textbox, event, values) {
if (textbox.setSelectionRange || textbox.createTextRange) {
switch (event.keyCode) {
case 38: // up arrow
case 40: // down arrow
case 37: // left arrow
case 39: // right arrow
case 33: // page up
case 34: // page down
case 36: // home
case 35: // end
case 13: // enter
case 9: // tab
case 27: // esc
case 16: // shift
case 17: // ctrl
case 18: // alt
case 20: // caps lock
case 8: // backspace
case 46: // delete
return true;
break;
default:
var c = String.fromCharCode(
(event.charCode == undefined) ? event.keyCode : event.charCode
);
replaceSelection(textbox, c);
sMatch = autocompleteMatch(textbox.value, values);
var len = textbox.value.length;
if (sMatch != null) {
textbox.value = sMatch;
setSelectionRange(textbox, len, textbox.value.length);
}
return false;
}
}
else {
return true;
}
}
/* end javascript for autocomplete */
EOS;
define('HTML_QUICKFORM_AUTOCOMPLETE_EXISTS', true);
}
$jsEscape = array(
"\r" => '\r',
"\n" => '\n',
"\t" => '\t',
"'" => "\\'",
'"' => '\"',
'\\' => '\\\\'
);
$js .= $this->_js;
$js .= 'var ' . $arrayName . " = new Array();\n";
for ($i = 0; $i < count($this->_options); $i++) {
$js .= $arrayName . '[' . $i . "] = '" . strtr($this->_options[$i], $jsEscape) . "';\n";
}
$js .= "//]]>\n</script>";
}
return $js . parent::toHtml();
}// end func toHtml
// }}}
} // end class HTML_QuickForm_autocomplete
?>

View File

@@ -0,0 +1,264 @@
<?php
/* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4: */
/**
* HTML class for an <input type="button" /> elements
*
* PHP versions 4 and 5
*
* LICENSE: This source file is subject to version 3.01 of the PHP license
* that is available through the world-wide-web at the following URI:
* http://www.php.net/license/3_01.txt If you did not receive a copy of
* the PHP License and are unable to obtain it through the web, please
* send a note to license@php.net so we can mail you a copy immediately.
*
* @category HTML
* @package HTML_QuickForm
* @author Adam Daniel <adaniel1@eesus.jnj.com>
* @author Bertrand Mansion <bmansion@mamasam.com>
* @copyright 2001-2009 The PHP Group
* @license http://www.php.net/license/3_01.txt PHP License 3.01
* @version CVS: $Id: button.php,v 1.6 2009/04/04 21:34:02 avb Exp $
* @link http://pear.php.net/package/HTML_QuickForm
*/
/**
* HTML class for an <input type="button" /> elements
*
* @category HTML
* @package HTML_QuickForm
* @author Adam Daniel <adaniel1@eesus.jnj.com>
* @author Bertrand Mansion <bmansion@mamasam.com>
* @version Release: 3.2.11
* @since 1.0
*/
class HTML_QuickForm_button extends HTML_QuickForm_input
{
private $icon;
private $style;
private $size;
private $class;
/**
* @param string $name input name example 'submit'
* @param string $text button text to show
* @param string $icon icons based in font-awesome
* @param string $style i.e default|primary|success|info|warning|danger|link
* @param string $size large|default|small|extra-small
* @param string $class
* @param array $attributes
*/
public function __construct(
$name,
$text,
$icon = 'check',
$style = 'default',
$size = 'default',
$class = null,
$attributes = array()
) {
$this->setIcon($icon);
$this->setStyle($style);
$this->setSize($size);
$this->setClass($class);
$columnsSize = isset($attributes['cols-size']) ? $attributes['cols-size'] : null;
$this->setColumnsSize($columnsSize);
parent::__construct(
$name,
null,
$attributes
);
$this->_persistantFreeze = false;
$this->setValue($text);
$this->setType('submit');
}
/**
* @return string
*/
public function toHtml()
{
if ($this->_flagFrozen) {
return $this->getFrozenHtml();
} else {
$value = null;
if (isset($this->_attributes['value'])) {
$value = $this->_attributes['value'];
unset($this->_attributes['value']);
}
unset($this->_attributes['class']);
$icon = $this->getIcon();
if (!empty($icon)) {
$icon = '<em class="' . $this->getIcon() . '"></em> ';
}
$class = $this->getClass().' '.$this->getStyle().' '.$this->getSize();
return
$this->_getTabs() . '
<button class="'.$class.'" ' . $this->_getAttrString($this->_attributes) . '>'.
$icon.
$value.
'</button>';
}
}
/**
* @return mixed
*/
public function getClass()
{
return $this->class;
}
/**
* @param mixed $class
*/
public function setClass($class)
{
$this->class = $class;
}
/**
* @return mixed
*/
public function getIcon()
{
return $this->icon;
}
/**
* @param mixed $icon
*/
public function setIcon($icon)
{
// Try and sanitize $icon in case it's an array (take the first element and consider it's a string)
if (is_array($icon)) {
$icon = @strval($icon[0]);
}
$this->icon = !empty($icon) ? 'fa fa-'.$icon : null;
}
/**
* @return mixed
*/
public function getStyle()
{
return $this->style;
}
/**
* @param mixed $style
*/
public function setStyle($style)
{
$style = !empty($style) ? 'btn btn-'.$style : null;
$this->style = $style;
}
/**
* @return mixed
*/
public function getSize()
{
return $this->size;
}
/**
* @param mixed $size
*/
public function setSize($size)
{
switch ($size) {
case 'large':
$size = 'btn-lg';
break;
case 'small':
$size = 'btn-sm';
break;
case 'extra-small':
$size = 'btn-xs';
break;
case 'default':
$size = null;
break;
}
$size = !empty($size) ? $size : null;
$this->size = $size;
}
/**
* Freeze the element so that only its value is returned
*
* @access public
* @return void
*/
public function freeze()
{
return false;
}
/**
* @param string $layout
*
* @return string
*/
public function getTemplate($layout)
{
$size = $this->calculateSize();
$attributes = $this->getAttributes();
$template = ' {element} ';
switch ($layout) {
case FormValidator::LAYOUT_HORIZONTAL:
if (isset($attributes['custom']) && $attributes['custom'] == true) {
$template = '
{icon}
{element}
';
} else {
$template = '
<div class="form-group {error_class}">
<label {label-for} class="col-sm-'.$size[0].' control-label" >
<!-- BEGIN required --><span class="form_required">*</span><!-- END required -->
{label}
</label>
<div class="col-sm-'.$size[1].'">
{icon}
{element}
<!-- BEGIN label_2 -->
<p class="help-block">{label_2}</p>
<!-- END label_2 -->
<!-- BEGIN error -->
<span class="help-inline help-block">{error}</span>
<!-- END error -->
</div>
<div class="col-sm-'.$size[2].'">
<!-- BEGIN label_3 -->
{label_3}
<!-- END label_3 -->
</div>
</div>';
}
break;
case FormValidator::LAYOUT_INLINE:
case FormValidator::LAYOUT_GRID:
default:
$template = '<div class="form-group"> {element} </div>';
break;
case FormValidator::LAYOUT_BOX_NO_LABEL:
break;
}
return $template;
}
}

View File

@@ -0,0 +1,347 @@
<?php
/**
* HTML class for a checkbox type field.
*
* PHP versions 4 and 5
*
* LICENSE: This source file is subject to version 3.01 of the PHP license
* that is available through the world-wide-web at the following URI:
* http://www.php.net/license/3_01.txt If you did not receive a copy of
* the PHP License and are unable to obtain it through the web, please
* send a note to license@php.net so we can mail you a copy immediately.
*
* @category HTML
*
* @author Adam Daniel <adaniel1@eesus.jnj.com>
* @author Bertrand Mansion <bmansion@mamasam.com>
* @author Alexey Borzov <avb@php.net>
* @copyright 2001-2009 The PHP Group
* @license http://www.php.net/license/3_01.txt PHP License 3.01
*
* @version CVS: $Id: checkbox.php,v 1.23 2009/04/04 21:34:02 avb Exp $
*
* @see http://pear.php.net/package/HTML_QuickForm
*/
/**
* HTML class for a checkbox type field.
*
* @category HTML
*
* @author Adam Daniel <adaniel1@eesus.jnj.com>
* @author Bertrand Mansion <bmansion@mamasam.com>
* @author Alexey Borzov <avb@php.net>
*
* @version Release: 3.2.11
*
* @since 1.0
*/
class HTML_QuickForm_checkbox extends HTML_QuickForm_input
{
/**
* Checkbox display text.
*
* @var string
*
* @since 1.1
*/
public $_text = '';
public $labelClass;
public $checkboxClass;
/**
* Class constructor.
*
* @param string $elementName (optional)Input field name attribute
* @param string $elementLabel (optional)Input field value
* @param string $text (optional)Checkbox display text
* @param mixed $attributes (optional)Either a typical HTML attribute string
* or an associative array
*
* @since 1.0
*
* @return void
*/
public function __construct(
$elementName = null,
$elementLabel = null,
$text = '',
$attributes = null
) {
$this->labelClass = isset($attributes['label-class']) ? $attributes['label-class'] : '';
$this->checkboxClass = isset($attributes['checkbox-class']) ? $attributes['checkbox-class'] : 'checkbox';
if (isset($attributes['label-class'])) {
unset($attributes['label-class']);
}
if (isset($attributes['checkbox-class'])) {
unset($attributes['checkbox-class']);
}
parent::__construct($elementName, $elementLabel, $attributes);
$this->_persistantFreeze = true;
$this->_text = $text;
$this->setType('checkbox');
if (!isset($attributes['value'])) {
$this->updateAttributes(['value' => 1]);
} else {
$this->updateAttributes(['value' => $attributes['value']]);
}
$this->_generateId();
}
/**
* Sets whether a checkbox is checked.
*
* @param bool $checked Whether the field is checked or not
*
* @since 1.0
*
* @return void
*/
public function setChecked($checked)
{
if (!$checked) {
$this->removeAttribute('checked');
} else {
$this->updateAttributes(['checked' => 'checked']);
}
}
/**
* Returns whether a checkbox is checked.
*
* @since 1.0
*
* @return bool
*/
public function getChecked()
{
return (bool) $this->getAttribute('checked');
}
/**
* Returns the checkbox element in HTML.
*
* @since 1.0
*
* @return string
*/
public function toHtml()
{
if (0 == strlen($this->_text)) {
$label = '';
} elseif ($this->_flagFrozen) {
$label = $this->_text;
} else {
$labelClass = $this->labelClass;
$checkClass = $this->checkboxClass;
$name = $this->_attributes['name'];
$label = '<div id="'.$name.'" class="'.$checkClass.'">
<label class="'.$labelClass.'">'.
HTML_QuickForm_input::toHtml().' '.$this->_text.
'</label>
</div>
';
return $label;
}
return HTML_QuickForm_input::toHtml().$label;
}
/**
* @param string $layout
*
* @return string
*/
public function getTemplate($layout)
{
$size = $this->calculateSize();
switch ($layout) {
case FormValidator::LAYOUT_INLINE:
return '
<div class="input-group">
<label {label-for} >
<!-- BEGIN required --><span class="form_required">*</span><!-- END required -->
{label}
</label>
</div>
<div class="input-group {error_class}">
{element}
</div>
';
break;
case FormValidator::LAYOUT_HORIZONTAL:
return '
<div class="form-group {error_class}">
<label {label-for} class="col-sm-'.$size[0].' control-label {extra_label_class}" >
<!-- BEGIN required --><span class="form_required">*</span><!-- END required -->
{label}
</label>
<div class="col-sm-'.$size[1].'">
{icon}
{element}
<!-- BEGIN label_2 -->
<p class="help-block">{label_2}</p>
<!-- END label_2 -->
<!-- BEGIN error -->
<span class="help-inline help-block">{error}</span>
<!-- END error -->
</div>
<div class="col-sm-'.$size[2].'">
<!-- BEGIN label_3 -->
{label_3}
<!-- END label_3 -->
</div>
</div>';
break;
case FormValidator::LAYOUT_BOX_NO_LABEL:
return '
<div class="input-group">
{icon}
{element}
</div>';
break;
case FormValidator::LAYOUT_GRID:
case FormValidator::LAYOUT_BOX:
return '
<div class="input-group">
<label>{label}</label>
{icon}
{element}
</div>';
break;
}
}
/**
* Returns the value of field without HTML tags.
*
* @since 1.0
*
* @return string
*/
public function getFrozenHtml()
{
if ($this->getChecked()) {
return '<code>[x]</code>'.
$this->_getPersistantData();
}
return '<code>[ ]</code>';
}
/**
* Sets the checkbox text.
*
* @param string $text
*
* @since 1.1
*
* @return void
*/
public function setText($text)
{
$this->_text = $text;
}
/**
* Returns the checkbox text.
*
* @since 1.1
*
* @return string
*/
public function getText()
{
return $this->_text;
}
/**
* Sets the value of the form element.
*
* @param string $value Default value of the form element
*
* @since 1.0
*
* @return void
*/
public function setValue($value)
{
return $this->setChecked($value);
}
/**
* Returns the value of the form element.
*
* @since 1.0
*
* @return bool
*/
public function getValue()
{
return $this->getChecked();
}
/**
* Called by HTML_QuickForm whenever form event is made on this element.
*
* @param string $event Name of event
* @param mixed $arg event arguments
* @param object &$caller calling object
*
* @since 1.0
*
* @return void
*/
public function onQuickFormEvent($event, $arg, &$caller)
{
switch ($event) {
case 'updateValue':
// constant values override both default and submitted ones
// default values are overriden by submitted
$value = $this->_findValue($caller->_constantValues);
if (null === $value) {
// if no boxes were checked, then there is no value in the array
// yet we don't want to display default value in this case
if ($caller->isSubmitted()) {
$value = $this->_findValue($caller->_submitValues);
} else {
$value = $this->_findValue($caller->_defaultValues);
}
}
if (null !== $value || $caller->isSubmitted()) {
$this->setChecked($value);
}
break;
case 'setGroupValue':
$this->setChecked($arg);
break;
default:
parent::onQuickFormEvent($event, $arg, $caller);
}
return true;
}
/**
* Return true if the checkbox is checked, null if it is not checked (getValue() returns false).
*/
public function exportValue(&$submitValues, $assoc = false)
{
$value = $this->_findValue($submitValues);
if (null === $value) {
$value = $this->getChecked() ? true : null;
}
return $this->_prepareValue($value, $assoc);
}
}

View File

@@ -0,0 +1,520 @@
<?php
/* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4: */
/**
* Class for a group of elements used to input dates (and times).
*
* PHP versions 4 and 5
*
* LICENSE: This source file is subject to version 3.01 of the PHP license
* that is available through the world-wide-web at the following URI:
* http://www.php.net/license/3_01.txt If you did not receive a copy of
* the PHP License and are unable to obtain it through the web, please
* send a note to license@php.net so we can mail you a copy immediately.
*
* @category HTML
* @package HTML_QuickForm
* @author Alexey Borzov <avb@php.net>
* @copyright 2001-2009 The PHP Group
* @license http://www.php.net/license/3_01.txt PHP License 3.01
* @version CVS: $Id: date.php,v 1.62 2009/04/04 21:34:02 avb Exp $
* @link http://pear.php.net/package/HTML_QuickForm
*/
/**
* Class for a group of elements used to input dates (and times).
*
* Inspired by original 'date' element but reimplemented as a subclass
* of HTML_QuickForm_group
*
* @category HTML
* @package HTML_QuickForm
* @author Alexey Borzov <avb@php.net>
* @version Release: 3.2.11
* @since 3.1
*/
class HTML_QuickForm_date extends HTML_QuickForm_group
{
// {{{ properties
/**
* Various options to control the element's display.
*
* @access private
* @var array
*/
var $_options = array(
'language' => 'en',
'format' => 'dMY',
'minYear' => 2001,
'maxYear' => 2090,
'addEmptyOption' => false,
'emptyOptionValue' => '',
'emptyOptionText' => '&nbsp;',
'optionIncrement' => array('i' => 1, 's' => 1)
);
/**
* These complement separators, they are appended to the resultant HTML
* @access private
* @var array
*/
var $_wrap = array('', '');
/**
* Options in different languages
*
* Note to potential translators: to avoid encoding problems please send
* your translations with "weird" letters encoded as HTML Unicode entities
*
* @access private
* @var array
*/
var $_locale = array(
'en' => array (
'weekdays_short'=> array ('Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat'),
'weekdays_long' => array ('Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday'),
'months_short' => array ('Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'),
'months_long' => array ('January', 'February', 'March', 'April', 'May', 'June', 'July', 'August', 'September', 'October', 'November', 'December')
),
'de' => array (
'weekdays_short'=> array ('So', 'Mon', 'Di', 'Mi', 'Do', 'Fr', 'Sa'),
'weekdays_long' => array ('Sonntag', 'Montag', 'Dienstag', 'Mittwoch', 'Donnerstag', 'Freitag', 'Samstag'),
'months_short' => array ('Jan', 'Feb', 'M&#xe4;rz', 'April', 'Mai', 'Juni', 'Juli', 'Aug', 'Sept', 'Okt', 'Nov', 'Dez'),
'months_long' => array ('Januar', 'Februar', 'M&#xe4;rz', 'April', 'Mai', 'Juni', 'Juli', 'August', 'September', 'Oktober', 'November', 'Dezember')
),
'fr' => array (
'weekdays_short'=> array ('Dim', 'Lun', 'Mar', 'Mer', 'Jeu', 'Ven', 'Sam'),
'weekdays_long' => array ('Dimanche', 'Lundi', 'Mardi', 'Mercredi', 'Jeudi', 'Vendredi', 'Samedi'),
'months_short' => array ('Jan', 'F&#xe9;v', 'Mar', 'Avr', 'Mai', 'Juin', 'Juil', 'Ao&#xfb;t', 'Sep', 'Oct', 'Nov', 'D&#xe9;c'),
'months_long' => array ('Janvier', 'F&#xe9;vrier', 'Mars', 'Avril', 'Mai', 'Juin', 'Juillet', 'Ao&#xfb;t', 'Septembre', 'Octobre', 'Novembre', 'D&#xe9;cembre')
),
'hu' => array (
'weekdays_short'=> array ('V', 'H', 'K', 'Sze', 'Cs', 'P', 'Szo'),
'weekdays_long' => array ('vas&#xe1;rnap', 'h&#xe9;tf&#x151;', 'kedd', 'szerda', 'cs&#xfc;t&#xf6;rt&#xf6;k', 'p&#xe9;ntek', 'szombat'),
'months_short' => array ('jan', 'feb', 'm&#xe1;rc', '&#xe1;pr', 'm&#xe1;j', 'j&#xfa;n', 'j&#xfa;l', 'aug', 'szept', 'okt', 'nov', 'dec'),
'months_long' => array ('janu&#xe1;r', 'febru&#xe1;r', 'm&#xe1;rcius', '&#xe1;prilis', 'm&#xe1;jus', 'j&#xfa;nius', 'j&#xfa;lius', 'augusztus', 'szeptember', 'okt&#xf3;ber', 'november', 'december')
),
'pl' => array (
'weekdays_short'=> array ('Nie', 'Pn', 'Wt', '&#x15a;r', 'Czw', 'Pt', 'Sob'),
'weekdays_long' => array ('Niedziela', 'Poniedzia&#x142;ek', 'Wtorek', '&#x15a;roda', 'Czwartek', 'Pi&#x105;tek', 'Sobota'),
'months_short' => array ('Sty', 'Lut', 'Mar', 'Kwi', 'Maj', 'Cze', 'Lip', 'Sie', 'Wrz', 'Pa&#x17a;', 'Lis', 'Gru'),
'months_long' => array ('Stycze&#x144;', 'Luty', 'Marzec', 'Kwiecie&#x144;', 'Maj', 'Czerwiec', 'Lipiec', 'Sierpie&#x144;', 'Wrzesie&#x144;', 'Pa&#x17a;dziernik', 'Listopad', 'Grudzie&#x144;')
),
'sl' => array (
'weekdays_short'=> array ('Ned', 'Pon', 'Tor', 'Sre', 'Cet', 'Pet', 'Sob'),
'weekdays_long' => array ('Nedelja', 'Ponedeljek', 'Torek', 'Sreda', 'Cetrtek', 'Petek', 'Sobota'),
'months_short' => array ('Jan', 'Feb', 'Mar', 'Apr', 'Maj', 'Jun', 'Jul', 'Avg', 'Sep', 'Okt', 'Nov', 'Dec'),
'months_long' => array ('Januar', 'Februar', 'Marec', 'April', 'Maj', 'Junij', 'Julij', 'Avgust', 'September', 'Oktober', 'November', 'December')
),
'ru' => array (
'weekdays_short'=> array ('&#x412;&#x441;', '&#x41f;&#x43d;', '&#x412;&#x442;', '&#x421;&#x440;', '&#x427;&#x442;', '&#x41f;&#x442;', '&#x421;&#x431;'),
'weekdays_long' => array ('&#x412;&#x43e;&#x441;&#x43a;&#x440;&#x435;&#x441;&#x435;&#x43d;&#x44c;&#x435;', '&#x41f;&#x43e;&#x43d;&#x435;&#x434;&#x435;&#x43b;&#x44c;&#x43d;&#x438;&#x43a;', '&#x412;&#x442;&#x43e;&#x440;&#x43d;&#x438;&#x43a;', '&#x421;&#x440;&#x435;&#x434;&#x430;', '&#x427;&#x435;&#x442;&#x432;&#x435;&#x440;&#x433;', '&#x41f;&#x44f;&#x442;&#x43d;&#x438;&#x446;&#x430;', '&#x421;&#x443;&#x431;&#x431;&#x43e;&#x442;&#x430;'),
'months_short' => array ('&#x42f;&#x43d;&#x432;', '&#x424;&#x435;&#x432;', '&#x41c;&#x430;&#x440;', '&#x410;&#x43f;&#x440;', '&#x41c;&#x430;&#x439;', '&#x418;&#x44e;&#x43d;', '&#x418;&#x44e;&#x43b;', '&#x410;&#x432;&#x433;', '&#x421;&#x435;&#x43d;', '&#x41e;&#x43a;&#x442;', '&#x41d;&#x43e;&#x44f;', '&#x414;&#x435;&#x43a;'),
'months_long' => array ('&#x42f;&#x43d;&#x432;&#x430;&#x440;&#x44c;', '&#x424;&#x435;&#x432;&#x440;&#x430;&#x43b;&#x44c;', '&#x41c;&#x430;&#x440;&#x442;', '&#x410;&#x43f;&#x440;&#x435;&#x43b;&#x44c;', '&#x41c;&#x430;&#x439;', '&#x418;&#x44e;&#x43d;&#x44c;', '&#x418;&#x44e;&#x43b;&#x44c;', '&#x410;&#x432;&#x433;&#x443;&#x441;&#x442;', '&#x421;&#x435;&#x43d;&#x442;&#x44f;&#x431;&#x440;&#x44c;', '&#x41e;&#x43a;&#x442;&#x44f;&#x431;&#x440;&#x44c;', '&#x41d;&#x43e;&#x44f;&#x431;&#x440;&#x44c;', '&#x414;&#x435;&#x43a;&#x430;&#x431;&#x440;&#x44c;')
),
'es' => array (
'weekdays_short'=> array ('Dom', 'Lun', 'Mar', 'Mi&#xe9;', 'Jue', 'Vie', 'S&#xe1;b'),
'weekdays_long' => array ('Domingo', 'Lunes', 'Martes', 'Mi&#xe9;rcoles', 'Jueves', 'Viernes', 'S&#xe1;bado'),
'months_short' => array ('Ene', 'Feb', 'Mar', 'Abr', 'May', 'Jun', 'Jul', 'Ago', 'Sep', 'Oct', 'Nov', 'Dic'),
'months_long' => array ('Enero', 'Febrero', 'Marzo', 'Abril', 'Mayo', 'Junio', 'Julio', 'Agosto', 'Septiembre', 'Octubre', 'Noviembre', 'Diciembre')
),
'da' => array (
'weekdays_short'=> array ('S&#xf8;n', 'Man', 'Tir', 'Ons', 'Tor', 'Fre', 'L&#xf8;r'),
'weekdays_long' => array ('S&#xf8;ndag', 'Mandag', 'Tirsdag', 'Onsdag', 'Torsdag', 'Fredag', 'L&#xf8;rdag'),
'months_short' => array ('Jan', 'Feb', 'Mar', 'Apr', 'Maj', 'Jun', 'Jul', 'Aug', 'Sep', 'Okt', 'Nov', 'Dec'),
'months_long' => array ('Januar', 'Februar', 'Marts', 'April', 'Maj', 'Juni', 'Juli', 'August', 'September', 'Oktober', 'November', 'December')
),
'is' => array (
'weekdays_short'=> array ('Sun', 'M&#xe1;n', '&#xde;ri', 'Mi&#xf0;', 'Fim', 'F&#xf6;s', 'Lau'),
'weekdays_long' => array ('Sunnudagur', 'M&#xe1;nudagur', '&#xde;ri&#xf0;judagur', 'Mi&#xf0;vikudagur', 'Fimmtudagur', 'F&#xf6;studagur', 'Laugardagur'),
'months_short' => array ('Jan', 'Feb', 'Mar', 'Apr', 'Ma&#xed;', 'J&#xfa;n', 'J&#xfa;l', '&#xc1;g&#xfa;', 'Sep', 'Okt', 'N&#xf3;v', 'Des'),
'months_long' => array ('Jan&#xfa;ar', 'Febr&#xfa;ar', 'Mars', 'Apr&#xed;l', 'Ma&#xed;', 'J&#xfa;n&#xed;', 'J&#xfa;l&#xed;', '&#xc1;g&#xfa;st', 'September', 'Okt&#xf3;ber', 'N&#xf3;vember', 'Desember')
),
'it' => array (
'weekdays_short'=> array ('Dom', 'Lun', 'Mar', 'Mer', 'Gio', 'Ven', 'Sab'),
'weekdays_long' => array ('Domenica', 'Luned&#xec;', 'Marted&#xec;', 'Mercoled&#xec;', 'Gioved&#xec;', 'Venerd&#xec;', 'Sabato'),
'months_short' => array ('Gen', 'Feb', 'Mar', 'Apr', 'Mag', 'Giu', 'Lug', 'Ago', 'Set', 'Ott', 'Nov', 'Dic'),
'months_long' => array ('Gennaio', 'Febbraio', 'Marzo', 'Aprile', 'Maggio', 'Giugno', 'Luglio', 'Agosto', 'Settembre', 'Ottobre', 'Novembre', 'Dicembre')
),
'sk' => array (
'weekdays_short'=> array ('Ned', 'Pon', 'Uto', 'Str', '&#x8a;tv', 'Pia', 'Sob'),
'weekdays_long' => array ('Nede&#x17e;a', 'Pondelok', 'Utorok', 'Streda', '&#x8a;tvrtok', 'Piatok', 'Sobota'),
'months_short' => array ('Jan', 'Feb', 'Mar', 'Apr', 'M&#xe1;j', 'J&#xfa;n', 'J&#xfa;l', 'Aug', 'Sep', 'Okt', 'Nov', 'Dec'),
'months_long' => array ('Janu&#xe1;r', 'Febru&#xe1;r', 'Marec', 'Apr&#xed;l', 'M&#xe1;j', 'J&#xfa;n', 'J&#xfa;l', 'August', 'September', 'Okt&#xf3;ber', 'November', 'December')
),
'cs' => array (
'weekdays_short'=> array ('Ne', 'Po', '&#xda;t', 'St', '&#x10c;t', 'P&#xe1;', 'So'),
'weekdays_long' => array ('Ned&#x11b;le', 'Pond&#x11b;l&#xed;', '&#xda;ter&#xfd;', 'St&#x159;eda', '&#x10c;tvrtek', 'P&#xe1;tek', 'Sobota'),
'months_short' => array ('Led', '&#xda;no', 'B&#x159;e', 'Dub', 'Kv&#x11b;', '&#x10c;en', '&#x10c;ec', 'Srp', 'Z&#xe1;&#x159;', '&#x158;&#xed;j', 'Lis', 'Pro'),
'months_long' => array ('Leden', '&#xda;nor', 'B&#x159;ezen', 'Duben', 'Kv&#x11b;ten', '&#x10c;erven', '&#x10c;ervenec', 'Srpen', 'Z&#xe1;&#x159;&#xed;', '&#x158;&#xed;jen', 'Listopad', 'Prosinec')
),
'hy' => array (
'weekdays_short'=> array ('&#x53f;&#x580;&#x56f;', '&#x535;&#x580;&#x56f;', '&#x535;&#x580;&#x584;', '&#x549;&#x580;&#x584;', '&#x540;&#x576;&#x563;', '&#x548;&#x582;&#x580;', '&#x547;&#x562;&#x569;'),
'weekdays_long' => array ('&#x53f;&#x56b;&#x580;&#x561;&#x56f;&#x56b;', '&#x535;&#x580;&#x56f;&#x578;&#x582;&#x577;&#x561;&#x562;&#x569;&#x56b;', '&#x535;&#x580;&#x565;&#x584;&#x577;&#x561;&#x562;&#x569;&#x56b;', '&#x549;&#x578;&#x580;&#x565;&#x584;&#x577;&#x561;&#x562;&#x569;&#x56b;', '&#x540;&#x56b;&#x576;&#x563;&#x577;&#x561;&#x562;&#x569;&#x56b;', '&#x548;&#x582;&#x580;&#x562;&#x561;&#x569;', '&#x547;&#x561;&#x562;&#x561;&#x569;'),
'months_short' => array ('&#x540;&#x576;&#x57e;', '&#x553;&#x57f;&#x580;', '&#x544;&#x580;&#x57f;', '&#x531;&#x57a;&#x580;', '&#x544;&#x575;&#x57d;', '&#x540;&#x576;&#x57d;', '&#x540;&#x56c;&#x57d;', '&#x555;&#x563;&#x57d;', '&#x54d;&#x57a;&#x57f;', '&#x540;&#x56f;&#x57f;', '&#x546;&#x575;&#x574;', '&#x534;&#x56f;&#x57f;'),
'months_long' => array ('&#x540;&#x578;&#x582;&#x576;&#x57e;&#x561;&#x580;', '&#x553;&#x565;&#x57f;&#x580;&#x57e;&#x561;&#x580;', '&#x544;&#x561;&#x580;&#x57f;', '&#x531;&#x57a;&#x580;&#x56b;&#x56c;', '&#x544;&#x561;&#x575;&#x56b;&#x57d;', '&#x540;&#x578;&#x582;&#x576;&#x56b;&#x57d;', '&#x540;&#x578;&#x582;&#x56c;&#x56b;&#x57d;', '&#x555;&#x563;&#x578;&#x57d;&#x57f;&#x578;&#x57d;', '&#x54d;&#x565;&#x57a;&#x57f;&#x565;&#x574;&#x562;&#x565;&#x580;', '&#x540;&#x578;&#x56f;&#x57f;&#x565;&#x574;&#x562;&#x565;&#x580;', '&#x546;&#x578;&#x575;&#x565;&#x574;&#x562;&#x565;&#x580;', '&#x534;&#x565;&#x56f;&#x57f;&#x565;&#x574;&#x562;&#x565;&#x580;')
),
'nl' => array (
'weekdays_short'=> array ('Zo', 'Ma', 'Di', 'Wo', 'Do', 'Vr', 'Za'),
'weekdays_long' => array ('Zondag', 'Maandag', 'Dinsdag', 'Woensdag', 'Donderdag', 'Vrijdag', 'Zaterdag'),
'months_short' => array ('Jan', 'Feb', 'Mar', 'Apr', 'Mei', 'Jun', 'Jul', 'Aug', 'Sep', 'Okt', 'Nov', 'Dec'),
'months_long' => array ('Januari', 'Februari', 'Maart', 'April', 'Mei', 'Juni', 'Juli', 'Augustus', 'September', 'Oktober', 'November', 'December')
),
'et' => array (
'weekdays_short'=> array ('P', 'E', 'T', 'K', 'N', 'R', 'L'),
'weekdays_long' => array ('P&#xfc;hap&#xe4;ev', 'Esmasp&#xe4;ev', 'Teisip&#xe4;ev', 'Kolmap&#xe4;ev', 'Neljap&#xe4;ev', 'Reede', 'Laup&#xe4;ev'),
'months_short' => array ('Jaan', 'Veebr', 'M&#xe4;rts', 'Aprill', 'Mai', 'Juuni', 'Juuli', 'Aug', 'Sept', 'Okt', 'Nov', 'Dets'),
'months_long' => array ('Jaanuar', 'Veebruar', 'M&#xe4;rts', 'Aprill', 'Mai', 'Juuni', 'Juuli', 'August', 'September', 'Oktoober', 'November', 'Detsember')
),
'tr' => array (
'weekdays_short'=> array ('Paz', 'Pzt', 'Sal', '&#xc7;ar', 'Per', 'Cum', 'Cts'),
'weekdays_long' => array ('Pazar', 'Pazartesi', 'Sal&#x131;', '&#xc7;ar&#x15f;amba', 'Per&#x15f;embe', 'Cuma', 'Cumartesi'),
'months_short' => array ('Ock', '&#x15e;bt', 'Mrt', 'Nsn', 'Mys', 'Hzrn', 'Tmmz', 'A&#x11f;st', 'Eyl', 'Ekm', 'Ksm', 'Arlk'),
'months_long' => array ('Ocak', '&#x15e;ubat', 'Mart', 'Nisan', 'May&#x131;s', 'Haziran', 'Temmuz', 'A&#x11f;ustos', 'Eyl&#xfc;l', 'Ekim', 'Kas&#x131;m', 'Aral&#x131;k')
),
'no' => array (
'weekdays_short'=> array ('S&#xf8;n', 'Man', 'Tir', 'Ons', 'Tor', 'Fre', 'L&#xf8;r'),
'weekdays_long' => array ('S&#xf8;ndag', 'Mandag', 'Tirsdag', 'Onsdag', 'Torsdag', 'Fredag', 'L&#xf8;rdag'),
'months_short' => array ('Jan', 'Feb', 'Mar', 'Apr', 'Mai', 'Jun', 'Jul', 'Aug', 'Sep', 'Okt', 'Nov', 'Des'),
'months_long' => array ('Januar', 'Februar', 'Mars', 'April', 'Mai', 'Juni', 'Juli', 'August', 'September', 'Oktober', 'November', 'Desember')
),
'eo' => array (
'weekdays_short'=> array ('Dim', 'Lun', 'Mar', 'Mer', '&#x134;a&#x16D;', 'Ven', 'Sab'),
'weekdays_long' => array ('Diman&#x109;o', 'Lundo', 'Mardo', 'Merkredo', '&#x134;a&#x16D;do', 'Vendredo', 'Sabato'),
'months_short' => array ('Jan', 'Feb', 'Mar', 'Apr', 'Maj', 'Jun', 'Jul', 'A&#x16D;g', 'Sep', 'Okt', 'Nov', 'Dec'),
'months_long' => array ('Januaro', 'Februaro', 'Marto', 'Aprilo', 'Majo', 'Junio', 'Julio', 'A&#x16D;gusto', 'Septembro', 'Oktobro', 'Novembro', 'Decembro')
),
'ua' => array (
'weekdays_short'=> array('&#x41d;&#x434;&#x43b;', '&#x41f;&#x43d;&#x434;', '&#x412;&#x442;&#x440;', '&#x421;&#x440;&#x434;', '&#x427;&#x442;&#x432;', '&#x41f;&#x442;&#x43d;', '&#x421;&#x431;&#x442;'),
'weekdays_long' => array('&#x41d;&#x435;&#x434;&#x456;&#x43b;&#x44f;', '&#x41f;&#x43e;&#x43d;&#x435;&#x434;&#x456;&#x43b;&#x43e;&#x43a;', '&#x412;&#x456;&#x432;&#x442;&#x43e;&#x440;&#x43e;&#x43a;', '&#x421;&#x435;&#x440;&#x435;&#x434;&#x430;', '&#x427;&#x435;&#x442;&#x432;&#x435;&#x440;', '&#x41f;\'&#x44f;&#x442;&#x43d;&#x438;&#x446;&#x44f;', '&#x421;&#x443;&#x431;&#x43e;&#x442;&#x430;'),
'months_short' => array('&#x421;&#x456;&#x447;', '&#x41b;&#x44e;&#x442;', '&#x411;&#x435;&#x440;', '&#x41a;&#x432;&#x456;', '&#x422;&#x440;&#x430;', '&#x427;&#x435;&#x440;', '&#x41b;&#x438;&#x43f;', '&#x421;&#x435;&#x440;', '&#x412;&#x435;&#x440;', '&#x416;&#x43e;&#x432;', '&#x41b;&#x438;&#x441;', '&#x413;&#x440;&#x443;'),
'months_long' => array('&#x421;&#x456;&#x447;&#x435;&#x43d;&#x44c;', '&#x41b;&#x44e;&#x442;&#x438;&#x439;', '&#x411;&#x435;&#x440;&#x435;&#x437;&#x435;&#x43d;&#x44c;', '&#x41a;&#x432;&#x456;&#x442;&#x435;&#x43d;&#x44c;', '&#x422;&#x440;&#x430;&#x432;&#x435;&#x43d;&#x44c;', '&#x427;&#x435;&#x440;&#x432;&#x435;&#x43d;&#x44c;', '&#x41b;&#x438;&#x43f;&#x435;&#x43d;&#x44c;', '&#x421;&#x435;&#x440;&#x43f;&#x435;&#x43d;&#x44c;', '&#x412;&#x435;&#x440;&#x435;&#x441;&#x435;&#x43d;&#x44c;', '&#x416;&#x43e;&#x432;&#x442;&#x435;&#x43d;&#x44c;', '&#x41b;&#x438;&#x441;&#x442;&#x43e;&#x43f;&#x430;&#x434;', '&#x413;&#x440;&#x443;&#x434;&#x435;&#x43d;&#x44c;')
),
'ro' => array (
'weekdays_short'=> array ('Dum', 'Lun', 'Mar', 'Mie', 'Joi', 'Vin', 'Sam'),
'weekdays_long' => array ('Duminica', 'Luni', 'Marti', 'Miercuri', 'Joi', 'Vineri', 'Sambata'),
'months_short' => array ('Ian', 'Feb', 'Mar', 'Apr', 'Mai', 'Iun', 'Iul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'),
'months_long' => array ('Ianuarie', 'Februarie', 'Martie', 'Aprilie', 'Mai', 'Iunie', 'Iulie', 'August', 'Septembrie', 'Octombrie', 'Noiembrie', 'Decembrie')
),
'he' => array (
'weekdays_short'=> array ('&#1512;&#1488;&#1513;&#1493;&#1503;', '&#1513;&#1504;&#1497;', '&#1513;&#1500;&#1497;&#1513;&#1497;', '&#1512;&#1489;&#1497;&#1506;&#1497;', '&#1495;&#1502;&#1497;&#1513;&#1497;', '&#1513;&#1497;&#1513;&#1497;', '&#1513;&#1489;&#1514;'),
'weekdays_long' => array ('&#1497;&#1493;&#1501; &#1512;&#1488;&#1513;&#1493;&#1503;', '&#1497;&#1493;&#1501; &#1513;&#1504;&#1497;', '&#1497;&#1493;&#1501; &#1513;&#1500;&#1497;&#1513;&#1497;', '&#1497;&#1493;&#1501; &#1512;&#1489;&#1497;&#1506;&#1497;', '&#1497;&#1493;&#1501; &#1495;&#1502;&#1497;&#1513;&#1497;', '&#1497;&#1493;&#1501; &#1513;&#1497;&#1513;&#1497;', '&#1513;&#1489;&#1514;'),
'months_short' => array ('&#1497;&#1504;&#1493;&#1488;&#1512;', '&#1508;&#1489;&#1512;&#1493;&#1488;&#1512;', '&#1502;&#1512;&#1509;', '&#1488;&#1508;&#1512;&#1497;&#1500;', '&#1502;&#1488;&#1497;', '&#1497;&#1493;&#1504;&#1497;', '&#1497;&#1493;&#1500;&#1497;', '&#1488;&#1493;&#1490;&#1493;&#1505;&#1496;', '&#1505;&#1508;&#1496;&#1502;&#1489;&#1512;', '&#1488;&#1493;&#1511;&#1496;&#1493;&#1489;&#1512;', '&#1504;&#1493;&#1489;&#1502;&#1489;&#1512;', '&#1491;&#1510;&#1502;&#1489;&#1512;'),
'months_long' => array ('&#1497;&#1504;&#1493;&#1488;&#1512;', '&#1508;&#1489;&#1512;&#1493;&#1488;&#1512;', '&#1502;&#1512;&#1509;', '&#1488;&#1508;&#1512;&#1497;&#1500;', '&#1502;&#1488;&#1497;', '&#1497;&#1493;&#1504;&#1497;', '&#1497;&#1493;&#1500;&#1497;', '&#1488;&#1493;&#1490;&#1493;&#1505;&#1496;', '&#1505;&#1508;&#1496;&#1502;&#1489;&#1512;', '&#1488;&#1493;&#1511;&#1496;&#1493;&#1489;&#1512;', '&#1504;&#1493;&#1489;&#1502;&#1489;&#1512;', '&#1491;&#1510;&#1502;&#1489;&#1512;')
),
'sv' => array (
'weekdays_short'=> array ('S&#xf6;n', 'M&#xe5;n', 'Tis', 'Ons', 'Tor', 'Fre', 'L&#xf6;r'),
'weekdays_long' => array ('S&#xf6;ndag', 'M&#xe5;ndag', 'Tisdag', 'Onsdag', 'Torsdag', 'Fredag', 'L&#xf6;rdag'),
'months_short' => array ('Jan', 'Feb', 'Mar', 'Apr', 'Maj', 'Jun', 'Jul', 'Aug', 'Sep', 'Okt', 'Nov', 'Dec'),
'months_long' => array ('Januari', 'Februari', 'Mars', 'April', 'Maj', 'Juni', 'Juli', 'Augusti', 'September', 'Oktober', 'November', 'December')
),
'pt' => array (
'weekdays_short'=> array ('Dom', 'Seg', 'Ter', 'Qua', 'Qui', 'Sex', 'S&aacute;b'),
'weekdays_long' => array ('Domingo', 'Segunda-feira', 'Ter&ccedil;a-feira', 'Quarta-feira', 'Quinta-feira', 'Sexta-feira', 'S&aacute;bado'),
'months_short' => array ('Jan', 'Fev', 'Mar', 'Abr', 'Mai', 'Jun', 'Jul', 'Ago', 'Set', 'Out', 'Nov', 'Dez'),
'months_long' => array ('Janeiro', 'Fevereiro', 'Mar&ccedil;o', 'Abril', 'Maio', 'Junho', 'Julho', 'Agosto', 'Setembro', 'Outubro', 'Novembro', 'Dezembro')
),
'tw' => array (
'weekdays_short'=> array ('&#36913;&#26085;','&#36913;&#19968;', '&#36913;&#20108;','&#36913;&#19977;', '&#36913;&#22235;','&#36913;&#20116;', '&#36913;&#20845;'),
'weekdays_long' => array ('&#26143;&#26399;&#26085;', '&#26143;&#26399;&#19968;', '&#26143;&#26399;&#20108;', '&#26143;&#26399;&#19977;', '&#26143;&#26399;&#22235;', '&#26143;&#26399;&#20116;', '&#26143;&#26399;&#20845;'),
'months_short' => array ('&#19968;&#26376;', '&#20108;&#26376;', '&#19977;&#26376;', '&#22235;&#26376;', '&#20116;&#26376;', '&#20845;&#26376;', '&#19971;&#26376;', '&#20843;&#26376;', '&#20061;&#26376;', '&#21313;&#26376;', '&#21313;&#19968;&#26376;', '&#21313;&#20108;&#26376;'),
'months_long' => array ('&#19968;&#26376;', '&#20108;&#26376;', '&#19977;&#26376;', '&#22235;&#26376;', '&#20116;&#26376;', '&#20845;&#26376;', '&#19971;&#26376;', '&#20843;&#26376;', '&#20061;&#26376;', '&#21313;&#26376;', '&#21313;&#19968;&#26376;', '&#21313;&#20108;&#26376;')
),
'pt-br' => array (
'weekdays_short'=> array ('Dom', 'Seg', 'Ter', 'Qua', 'Qui', 'Sex', 'S&aacute;b'),
'weekdays_long' => array ('Domingo', 'Segunda', 'Ter&ccedil;a', 'Quarta', 'Quinta', 'Sexta', 'S&aacute;bado'),
'months_short' => array ('Jan', 'Fev', 'Mar', 'Abr', 'Mai', 'Jun', 'Jul', 'Ago', 'Set', 'Out', 'Nov', 'Dez'),
'months_long' => array ('Janeiro', 'Fevereiro', 'Mar&ccedil;o', 'Abril', 'Maio', 'Junho', 'Julho', 'Agosto', 'Setembro', 'Outubro', 'Novembro', 'Dezembro')
)
);
// }}}
// {{{ constructor
/**
* Class constructor
*
* The following keys may appear in $options array:
* - 'language': date language
* - 'format': Format of the date, based on PHP's date() function.
* The following characters are currently recognised in format string:
* <pre>
* D => Short names of days
* l => Long names of days
* d => Day numbers
* M => Short names of months
* F => Long names of months
* m => Month numbers
* Y => Four digit year
* y => Two digit year
* h => 12 hour format
* H => 23 hour format
* i => Minutes
* s => Seconds
* a => am/pm
* A => AM/PM
* </pre>
* - 'minYear': Minimum year in year select
* - 'maxYear': Maximum year in year select
* - 'addEmptyOption': Should an empty option be added to the top of
* each select box?
* - 'emptyOptionValue': The value passed by the empty option.
* - 'emptyOptionText': The text displayed for the empty option.
* - 'optionIncrement': Step to increase the option values by (works for 'i' and 's')
*
* @access public
* @param string Element's name
* @param mixed Label(s) for an element
* @param array Options to control the element's display
* @param mixed Either a typical HTML attribute string or an associative array
*/
public function __construct($elementName = null, $elementLabel = null, $options = array(), $attributes = null)
{
parent::__construct($elementName, $elementLabel, $attributes);
$this->_persistantFreeze = true;
$this->_appendName = true;
$this->_type = 'date';
// Added by Ivan Tcholakov, 16-MAR-2010.
$current_year = intval(api_get_local_time());
$this->_options['minYear'] = $current_year - 9;
$this->_options['maxYear'] = $current_year + 1;
//
// set the options, do not bother setting bogus ones
if (is_array($options)) {
foreach ($options as $name => $value) {
if ('language' == $name) {
$this->_options['language'] = isset($this->_locale[$value])? $value: 'en';
} elseif (isset($this->_options[$name])) {
if (is_array($value) && is_array($this->_options[$name])) {
$this->_options[$name] = @array_merge($this->_options[$name], $value);
} else {
$this->_options[$name] = $value;
}
}
}
}
}
function _createElements()
{
$this->_separator = $this->_elements = array();
$separator = '';
$locale =& $this->_locale[$this->_options['language']];
$backslash = false;
// Modified by Ivan Tcholakov, 16-MAR-2010.
for ($i = 0, $length = api_strlen($this->_options['format']); $i < $length; $i++) {
$sign = api_substr($this->_options['format'], $i, 1);
//
if ($backslash) {
$backslash = false;
$separator .= $sign;
} else {
$loadSelect = true;
switch ($sign) {
case 'D':
// Sunday is 0 like with 'w' in date()
$options = $locale['weekdays_short'];
break;
case 'l':
$options = $locale['weekdays_long'];
break;
case 'd':
$options = $this->_createOptionList(1, 31);
break;
case 'M':
$options = $locale['months_short'];
array_unshift($options , '');
unset($options[0]);
break;
case 'm':
$options = $this->_createOptionList(1, 12);
break;
case 'F':
$options = $locale['months_long'];
array_unshift($options , '');
unset($options[0]);
break;
case 'Y':
$options = $this->_createOptionList(
$this->_options['minYear'],
$this->_options['maxYear'],
$this->_options['minYear'] > $this->_options['maxYear']? -1: 1
);
break;
case 'y':
$options = $this->_createOptionList(
$this->_options['minYear'],
$this->_options['maxYear'],
$this->_options['minYear'] > $this->_options['maxYear']? -1: 1
);
array_walk($options, create_function('&$v,$k','$v = substr($v,-2);'));
break;
case 'h':
$options = $this->_createOptionList(1, 12);
break;
case 'g':
$options = $this->_createOptionList(1, 12);
array_walk($options, create_function('&$v,$k', '$v = intval($v);'));
break;
case 'H':
$options = $this->_createOptionList(0, 23);
break;
case 'i':
$options = $this->_createOptionList(0, 59, $this->_options['optionIncrement']['i']);
break;
case 's':
$options = $this->_createOptionList(0, 59, $this->_options['optionIncrement']['s']);
break;
case 'a':
$options = array('am' => 'am', 'pm' => 'pm');
break;
case 'A':
$options = array('AM' => 'AM', 'PM' => 'PM');
break;
case 'W':
$options = $this->_createOptionList(1, 53);
break;
case '\\':
$backslash = true;
$loadSelect = false;
break;
default:
$separator .= (' ' == $sign? '&nbsp;': $sign);
$loadSelect = false;
}
if ($loadSelect) {
if (0 < count($this->_elements)) {
$this->_separator[] = $separator;
} else {
$this->_wrap[0] = $separator;
}
$separator = '';
// Should we add an empty option to the top of the select?
if (!is_array($this->_options['addEmptyOption']) && $this->_options['addEmptyOption'] ||
is_array($this->_options['addEmptyOption']) && !empty($this->_options['addEmptyOption'][$sign])) {
// Using '+' array operator to preserve the keys
if (is_array($this->_options['emptyOptionText']) && !empty($this->_options['emptyOptionText'][$sign])) {
$options = array($this->_options['emptyOptionValue'] => $this->_options['emptyOptionText'][$sign]) + $options;
} else {
$options = array($this->_options['emptyOptionValue'] => $this->_options['emptyOptionText']) + $options;
}
}
$this->_elements[] = new HTML_QuickForm_select($sign, null, $options, $this->getAttributes());
}
}
}
$this->_wrap[1] = $separator . ($backslash? '\\': '');
}
// }}}
// {{{ _createOptionList()
/**
* Creates an option list containing the numbers from the start number to the end, inclusive
*
* @param int The start number
* @param int The end number
* @param int Increment by this value
* @access private
* @return array An array of numeric options.
*/
function _createOptionList($start, $end, $step = 1)
{
for ($i = $start, $options = array(); $start > $end? $i >= $end: $i <= $end; $i += $step) {
$options[$i] = sprintf('%02d', $i);
}
return $options;
}
// }}}
// {{{ _trimLeadingZeros()
/**
* Trims leading zeros from the (numeric) string
*
* @param string A numeric string, possibly with leading zeros
* @return string String with leading zeros removed
*/
function _trimLeadingZeros($str)
{
if (0 == strcmp($str, $this->_options['emptyOptionValue'])) {
return $str;
}
$trimmed = ltrim($str, '0');
return strlen($trimmed)? $trimmed: '0';
}
// }}}
// {{{ setValue()
function setValue($value)
{
if (empty($value)) {
$value = array();
} elseif (is_scalar($value)) {
if (!is_numeric($value)) {
$value = strtotime($value);
}
// might be a unix epoch, then we fill all possible values
$arr = explode('-', date('w-j-n-Y-g-G-i-s-a-A-W', (int)$value));
$value = array(
'D' => $arr[0],
'l' => $arr[0],
'd' => $arr[1],
'M' => $arr[2],
'm' => $arr[2],
'F' => $arr[2],
'Y' => $arr[3],
'y' => $arr[3],
'h' => $arr[4],
'g' => $arr[4],
'H' => $arr[5],
'i' => $this->_trimLeadingZeros($arr[6]),
's' => $this->_trimLeadingZeros($arr[7]),
'a' => $arr[8],
'A' => $arr[9],
'W' => $this->_trimLeadingZeros($arr[10])
);
} else {
$value = array_map(array($this, '_trimLeadingZeros'), $value);
}
parent::setValue($value);
}
// }}}
// {{{ toHtml()
function toHtml()
{
include_once 'HTML/QuickForm/Renderer/Default.php';
$renderer = new HTML_QuickForm_Renderer_Default();
$renderer->setElementTemplate('{element}');
parent::accept($renderer);
return $this->_wrap[0] . $renderer->toHtml() . $this->_wrap[1];
}
// }}}
// {{{ accept()
function accept(&$renderer, $required = false, $error = null)
{
$renderer->renderElement($this, $required, $error);
}
// }}}
// {{{ onQuickFormEvent()
function onQuickFormEvent($event, $arg, &$caller)
{
if ('updateValue' == $event) {
// we need to call setValue(), 'cause the default/constant value
// may be in fact a timestamp, not an array
return HTML_QuickForm_element::onQuickFormEvent($event, $arg, $caller);
} else {
return parent::onQuickFormEvent($event, $arg, $caller);
}
}
}

View File

@@ -0,0 +1,628 @@
<?php
/**
* Base class for form elements
*
* PHP versions 4 and 5
*
* LICENSE: This source file is subject to version 3.01 of the PHP license
* that is available through the world-wide-web at the following URI:
* http://www.php.net/license/3_01.txt If you did not receive a copy of
* the PHP License and are unable to obtain it through the web, please
* send a note to license@php.net so we can mail you a copy immediately.
*
* @category HTML
* @package HTML_QuickForm
* @author Adam Daniel <adaniel1@eesus.jnj.com>
* @author Bertrand Mansion <bmansion@mamasam.com>
* @author Alexey Borzov <avb@php.net>
* @copyright 2001-2009 The PHP Group
* @license http://www.php.net/license/3_01.txt PHP License 3.01
* @version CVS: $Id: element.php,v 1.37 2009/04/04 21:34:02 avb Exp $
* @link http://pear.php.net/package/HTML_QuickForm
*/
/**
* Base class for form elements
*
* @category HTML
* @package HTML_QuickForm
* @author Adam Daniel <adaniel1@eesus.jnj.com>
* @author Bertrand Mansion <bmansion@mamasam.com>
* @author Alexey Borzov <avb@php.net>
* @version Release: 3.2.11
* @since 1.0
* @abstract
*/
class HTML_QuickForm_element extends HTML_Common
{
private $layout;
private $icon;
private $template;
private $customFrozenTemplate = '';
protected $inputSize;
/**
* Label of the field
* @var string
*/
public $_label = '';
/**
* Label "for" a field... (Chamilo LMS customization)
* @var string
* @access private
*/
public $_label_for = '';
/**
* Form element type
* @var string
* @since 1.0
* @access private
*/
public $_type = '';
/**
* Flag to tell if element is frozen
* @var boolean
* @since 1.0
* @access private
*/
public $_flagFrozen = false;
/**
* Does the element support persistant data when frozen
* @var boolean
* @since 1.3
* @access private
*/
public $_persistantFreeze = false;
protected $columnsSize;
/**
* Class constructor
*
* @param string Name of the element
* @param string|array Label(s) for the element
* @param mixed Associative array of tag attributes or HTML attributes name="value" pairs
*
* @return void
* @since 1.0
*/
public function __construct($elementName = null, $elementLabel = null, $attributes = null)
{
parent::__construct($attributes);
if (isset($elementName)) {
$this->setName($elementName);
}
if (isset($elementLabel)) {
$labelFor = '';
// Default Inputs generate this
if (!empty($attributes['id'])) {
$labelFor = $attributes['id'];
}
// Default Labels generate this
if (!empty($attributes['for'])) {
$labelFor = $attributes['for'];
}
$this->setLabel($elementLabel, $labelFor);
}
}
/**
* @return null
*/
public function getColumnsSize()
{
return $this->columnsSize;
}
/**
* @param null $columnsSize
*/
public function setColumnsSize($columnsSize)
{
$this->columnsSize = $columnsSize;
}
/**
* @return string
*/
public function getLayout()
{
return $this->layout;
}
/**
* @param string $layout
*/
public function setLayout($layout)
{
$this->layout = $layout;
}
/**
* @return string
*/
public function getIcon()
{
return $this->icon;
}
/**
* @return string
*/
public function getIconToHtml()
{
return $this->icon;
}
/**
* @param mixed $icon
*/
public function setIcon($icon)
{
$this->icon = $icon;
}
/**
* Returns the current API version
*
* @since 1.0
* @access public
* @return float
*/
public function apiVersion()
{
return 3.2;
}
/**
* Returns element type
*
* @since 1.0
* @access public
* @return string
*/
public function getType()
{
return $this->_type;
}
/**
* Sets the input field name
*
* @param string $name Input field name attribute
* @since 1.0
* @access public
* @return void
*/
public function setName($name)
{
}
/**
* Returns the element name
*
* @since 1.0
* @access public
* @return string
*/
public function getName()
{
}
/**
* Sets the value of the form element
*
* @param string $value Default value of the form element
* @since 1.0
* @access public
* @return void
*/
public function setValue($value)
{
}
/**
* Returns the value of the form element
*
* @since 1.0
* @access public
* @return mixed
*/
public function getValue()
{
return null;
}
/**
* @return string
*/
public function getCleanValue()
{
return $this->cleanValueFromParameter($this->getValue());
}
/**
* @param string $value
*
* @return string
*/
public function cleanValueFromParameter($value)
{
return @htmlspecialchars($value, ENT_COMPAT, HTML_Common::charset());
}
/**
* Freeze the element so that only its value is returned
*
* @access public
* @return void
*/
public function freeze()
{
$this->_flagFrozen = true;
}
/**
* Unfreezes the element so that it becomes editable
*
* @access public
* @return void
* @since 3.2.4
*/
public function unfreeze()
{
$this->_flagFrozen = false;
}
/**
* Returns the value of field without HTML tags
*
* @since 1.0
* @access public
* @return string
*/
public function getFrozenHtml()
{
$value = $this->getValue();
// Modified by Ivan Tcholakov, 16-MAR-2010.
//return ('' != $value? htmlspecialchars($value): '&nbsp;') .
// $this->_getPersistantData();
if (!empty($value)) {
$value = $this->getCleanValue();
} else {
$value = '&nbsp;';
}
$value .= $this->_getPersistantData();
return '<span class="freeze">'.$value.'</span>';
}
/**
* Used by getFrozenHtml() to pass the element's value if _persistantFreeze is on
*
* @access private
* @return string
*/
function _getPersistantData()
{
if (!$this->_persistantFreeze) {
return '';
}
$id = $this->getAttribute('id');
return '<input' . $this->_getAttrString(array(
'type' => 'hidden',
'name' => $this->getName(),
'value' => $this->getValue()
) + (isset($id)? array('id' => $id): array())) . ' />';
}
/**
* Returns whether or not the element is frozen
*
* @since 1.3
* @return bool
*/
public function isFrozen()
{
return $this->_flagFrozen;
}
/**
* Sets wether an element value should be kept in an hidden field
* when the element is frozen or not
*
* @param bool $persistant True if persistant value
* @since 2.0
*/
public function setPersistantFreeze($persistant=false)
{
$this->_persistantFreeze = $persistant;
}
/**
* Sets display text for the element
*
* @param string|array $label Display text for the element
* @param string|null $labelFor Optionally add a "for" attribute
*
* @since 1.3
*/
public function setLabel($label, $labelFor = null)
{
$this->_label = $label;
if (!empty($labelFor)) {
$this->_label_for = $labelFor;
}
}
/**
* Returns display text for the element
*
* @since 1.3
* @return string
*/
public function getLabel()
{
return $this->_label;
}
/**
* Returns "for" attribute for the element
*
* @return string
*/
public function getLabelFor()
{
return $this->_label_for;
}
/**
* Tries to find the element value from the values array
*
* @since 2.7
* @access private
* @return mixed
*/
function _findValue(&$values)
{
if (empty($values)) {
return null;
}
$elementName = $this->getName();
if (isset($values[$elementName])) {
return $values[$elementName];
} elseif (strpos($elementName, '[')) {
// Fix checkbox
if ($this->_type === 'checkbox') {
$attributeValue = $this->getAttribute('value');
$elementNameCheckBox = str_replace('[]', '', $elementName);
if (isset($values[$elementNameCheckBox]) &&
is_array($values[$elementNameCheckBox])
) {
if (in_array($attributeValue, $values[$elementNameCheckBox])) {
return true;
}
return false;
}
}
$replacedName = str_replace(
array('\\', '\'', ']', '['),
array('\\\\', '\\\'', '', "']['"),
$elementName
);
$myVar = "['$replacedName']";
return eval("return (isset(\$values$myVar)) ? \$values$myVar : null;");
} else {
return null;
}
}
/**
* Called by HTML_QuickForm whenever form event is made on this element
*
* @param string $event Name of event
* @param mixed $arg event arguments
* @param object &$caller calling object
* @since 1.0
* @access public
* @return void
*/
public function onQuickFormEvent($event, $arg, &$caller)
{
switch ($event) {
case 'createElement':
//$className = get_class($this);
//$this->$className($arg[0], $arg[1], $arg[2], $arg[3], $arg[4], $arg[5], $arg[6]);
break;
case 'addElement':
$this->onQuickFormEvent('createElement', $arg, $caller);
$this->onQuickFormEvent('updateValue', null, $caller);
break;
case 'updateValue':
// constant values override both default and submitted ones
// default values are overriden by submitted
$value = $this->_findValue($caller->_constantValues);
if (null === $value) {
$value = $this->_findValue($caller->_submitValues);
if (null === $value) {
$value = $this->_findValue($caller->_defaultValues);
}
}
if (null !== $value) {
$this->setValue($value);
}
break;
case 'setGroupValue':
$this->setValue($arg);
}
return true;
}
/**
* Accepts a renderer
*
* @param HTML_QuickForm_Renderer renderer object
* @param bool Whether an element is required
* @param string An error message associated with an element
* @access public
* @return void
*/
public function accept(&$renderer, $required=false, $error=null)
{
$renderer->renderElement($this, $required, $error);
}
/**
* Automatically generates and assigns an 'id' attribute for the element.
*
* Currently used to ensure that labels work on radio buttons and
* checkboxes. Per idea of Alexander Radivanovich.
*
* @access private
* @return void
*/
public function _generateId()
{
static $idx = 1;
if (!$this->getAttribute('id')) {
$this->updateAttributes(array('id' => 'qf_' . substr(md5(microtime() . $idx++), 0, 6)));
}
}
/**
* Returns a 'safe' element's value
*
* @param array array of submitted values to search
* @param bool whether to return the value as associative array
* @access public
* @return mixed
*/
public function exportValue(&$submitValues, $assoc = false)
{
$value = $this->_findValue($submitValues);
if (null === $value) {
$value = $this->getValue();
}
return $this->_prepareValue($value, $assoc);
}
/**
* Used by exportValue() to prepare the value for returning
*
* @param mixed the value found in exportValue()
* @param bool whether to return the value as associative array
* @access private
* @return mixed
*/
public function _prepareValue($value, $assoc)
{
if (null === $value) {
return null;
} elseif (!$assoc) {
return $value;
} else {
$name = $this->getName();
if (!strpos($name, '[')) {
return array($name => $value);
} else {
$valueAry = array();
$myIndex = "['" . str_replace(
array('\\', '\'', ']', '['), array('\\\\', '\\\'', '', "']['"),
$name
) . "']";
eval("\$valueAry$myIndex = \$value;");
return $valueAry;
}
}
}
/**
* @param mixed $template
* @return HTML_QuickForm_element
*/
public function setTemplate($template)
{
$this->template = $template;
return $this;
}
/**
* @return string
*/
public function getCustomFrozenTemplate()
{
return $this->customFrozenTemplate;
}
/**
* @param string $customFrozenTemplate
* @return HTML_QuickForm_element
*/
public function setCustomFrozenTemplate($customFrozenTemplate)
{
$this->customFrozenTemplate = $customFrozenTemplate;
return $this;
}
/**
* @return null
*/
public function getInputSize()
{
return $this->inputSize;
}
/**
* @param null $inputSize
*/
public function setInputSize($inputSize)
{
$this->inputSize = $inputSize;
}
/**
* @return array
*/
public function calculateSize()
{
$size = $this->getColumnsSize();
if (empty($size)) {
$sizeTemp = $this->getInputSize();
if (empty($size)) {
$sizeTemp = 8;
}
$size = array(2, $sizeTemp, 2);
} else {
if (is_array($size)) {
if (count($size) != 3) {
$sizeTemp = $this->getInputSize();
if (empty($size)) {
$sizeTemp = 8;
}
$size = array(2, $sizeTemp, 2);
}
} else {
// else just keep the $size array as received
$size = array(2, (int) $size, 2);
}
}
return $size;
}
}

View File

@@ -0,0 +1,64 @@
<?php
/**
* HTML class for a password type field
*
* @category HTML
* @package HTML_QuickForm
* @author Adam Daniel <adaniel1@eesus.jnj.com>
* @author Bertrand Mansion <bmansion@mamasam.com>
* @version Release: 3.2.11
* @since 1.0
*/
class HTML_QuickForm_email extends HTML_QuickForm_input
{
/**
* Class constructor
*
* @param string $elementName (optional)Input field name attribute
* @param string $elementLabel (optional)Input field label
* @param mixed $attributes (optional)Either a typical HTML attribute string
* or an associative array
* @since 1.0
* @access public
* @return void
* @throws
*/
public function __construct(
$elementName = null,
$elementLabel = null,
$attributes = null
) {
if (is_array($attributes) || empty($attributes)) {
$attributes['class'] = 'form-control';
}
parent::__construct($elementName, $elementLabel, $attributes);
$this->setType('email');
}
/**
* Sets size of password element
*
* @param string $size Size of password field
* @since 1.0
* @access public
* @return void
*/
public function setSize($size)
{
$this->updateAttributes(array('size'=>$size));
}
/**
* Sets maxlength of password element
*
* @param string $maxlength Maximum length of password field
* @since 1.0
* @access public
* @return void
*/
public function setMaxlength($maxlength)
{
$this->updateAttributes(array('maxlength'=>$maxlength));
}
}

View File

@@ -0,0 +1,506 @@
<?php
/**
* HTML class for a file upload field
*
* PHP versions 4 and 5
*
* LICENSE: This source file is subject to version 3.01 of the PHP license
* that is available through the world-wide-web at the following URI:
* http://www.php.net/license/3_01.txt If you did not receive a copy of
* the PHP License and are unable to obtain it through the web, please
* send a note to license@php.net so we can mail you a copy immediately.
*
* @category HTML
* @package HTML_QuickForm
* @author Adam Daniel <adaniel1@eesus.jnj.com>
* @author Bertrand Mansion <bmansion@mamasam.com>
* @author Alexey Borzov <avb@php.net>
* @copyright 2001-2009 The PHP Group
* @license http://www.php.net/license/3_01.txt PHP License 3.01
* @version CVS: $Id: file.php,v 1.25 2009/04/04 21:34:02 avb Exp $
* @link http://pear.php.net/package/HTML_QuickForm
*/
/**
* HTML class for a file upload field
*
* @category HTML
* @package HTML_QuickForm
* @author Adam Daniel <adaniel1@eesus.jnj.com>
* @author Bertrand Mansion <bmansion@mamasam.com>
* @author Alexey Borzov <avb@php.net>
* @version Release: 3.2.11
* @since 1.0
*/
class HTML_QuickForm_file extends HTML_QuickForm_input
{
/**
* Uploaded file data, from $_FILES
* @var array
*/
var $_value = null;
/**
* Class constructor
*
* @param string Input field name attribute
* @param string Input field label
* @param mixed (optional)Either a typical HTML attribute string
* or an associative array
* @since 1.0
* @access public
*/
public function __construct($elementName=null, $elementLabel=null, $attributes=null)
{
parent::__construct($elementName, $elementLabel, $attributes);
$this->setType('file');
}
/**
* Sets size of file element
*
* @param int Size of file element
* @since 1.0
* @access public
*/
function setSize($size)
{
$this->updateAttributes(array('size' => $size));
}
/**
* Returns size of file element
*
* @since 1.0
* @access public
* @return int
*/
function getSize()
{
return $this->getAttribute('size');
}
/**
* Freeze the element so that only its value is returned
*
* @access public
* @return bool
*/
function freeze()
{
return false;
}
/**
* Sets value for file element.
*
* Actually this does nothing. The function is defined here to override
* HTML_Quickform_input's behaviour of setting the 'value' attribute. As
* no sane user-agent uses <input type="file">'s value for anything
* (because of security implications) we implement file's value as a
* read-only property with a special meaning.
*
* @param mixed Value for file element
* @since 3.0
* @access public
*/
function setValue($value)
{
return null;
}
/**
* Returns information about the uploaded file
*
* @since 3.0
* @access public
* @return array
*/
public function getValue()
{
return $this->_value;
} // end func getValue
// }}}
// {{{ onQuickFormEvent()
/**
* Called by HTML_QuickForm whenever form event is made on this element
*
* @param string Name of event
* @param mixed event arguments
* @param object calling object
* @since 1.0
* @access public
* @return bool
*/
public function onQuickFormEvent($event, $arg, &$caller)
{
switch ($event) {
case 'updateValue':
if ($caller->getAttribute('method') == 'get') {
throw new \Exception('Cannot add a file upload field to a GET method form');
}
$this->_value = $this->_findValue();
$caller->updateAttributes(array('enctype' => 'multipart/form-data'));
$caller->setMaxFileSize();
break;
case 'addElement':
$this->onQuickFormEvent('createElement', $arg, $caller);
return $this->onQuickFormEvent('updateValue', null, $caller);
break;
case 'createElement':
//$className = get_class($this);
//$this &= new $className($arg[0], $arg[1], $arg[2]);
break;
}
return true;
}
/**
* Moves an uploaded file into the destination
*
* @param string Destination directory path
* @param string New file name
* @access public
* @return bool Whether the file was moved successfully
*/
public function moveUploadedFile($dest, $fileName = '')
{
if ($dest != '' && substr($dest, -1) != '/') {
$dest .= '/';
}
$fileName = ($fileName != '') ? $fileName : basename($this->_value['name']);
return move_uploaded_file($this->_value['tmp_name'], $dest . $fileName);
}
/**
* Checks if the element contains an uploaded file
*
* @access public
* @return bool true if file has been uploaded, false otherwise
*/
public function isUploadedFile()
{
return self::_ruleIsUploadedFile($this->_value);
}
/**
* Checks if the given element contains an uploaded file
*
* @param array Uploaded file info (from $_FILES)
* @access private
* @return bool true if file has been uploaded, false otherwise
*/
public static function _ruleIsUploadedFile($elementValue)
{
if ((isset($elementValue['error']) && $elementValue['error'] == 0) ||
(!empty($elementValue['tmp_name']) && $elementValue['tmp_name'] != 'none')) {
return is_uploaded_file($elementValue['tmp_name']);
} else {
return false;
}
}
/**
* Tries to find the element value from the values array
*
* Needs to be redefined here as $_FILES is populated differently from
* other arrays when element name is of the form foo[bar]
*
* @access public
* @return mixed
*/
public function _findValue(&$values = null)
{
if (empty($_FILES)) {
return null;
}
$elementName = $this->getName();
if (isset($_FILES[$elementName])) {
return $_FILES[$elementName];
} elseif (false !== ($pos = strpos($elementName, '['))) {
$base = str_replace(
array('\\', '\''), array('\\\\', '\\\''),
substr($elementName, 0, $pos)
);
$idx = "['" . str_replace(
array('\\', '\'', ']', '['), array('\\\\', '\\\'', '', "']['"),
substr($elementName, $pos + 1, -1)
) . "']";
$props = array('name', 'type', 'size', 'tmp_name', 'error');
$code = "if (!isset(\$_FILES['{$base}']['name']{$idx})) {\n" .
" return null;\n" .
"} else {\n" .
" \$value = array();\n";
foreach ($props as $prop) {
$code .= " \$value['{$prop}'] = \$_FILES['{$base}']['{$prop}']{$idx};\n";
}
return eval($code . " return \$value;\n}\n");
} else {
return null;
}
}
/**
* @return string
*/
public function getElementJS($param)
{
$id = $this->getAttribute('id');
$ratio = 'aspectRatio: 16 / 9';
$cropMove = '';
if (!empty($param['ratio'])) {
$ratio = 'aspectRatio: '.$param['ratio'].',';
}
$scalable = 'false';
if (!empty($param['scalable']) && $param['scalable'] != 'false') {
$ratio = '';
$scalable = $param['scalable'];
}
if (!empty($param['maxRatio']) && !empty($param['minRatio'])) {
$ratio = 'autoCropArea: 1, ';
$scalable = 'true';
$cropMove = ',cropmove: function (e) {
var cropBoxData = $image.cropper(\'getCropBoxData\');
var minAspectRatio = ' . $param['minRatio'] . ';
var maxAspectRatio = ' . $param['maxRatio'] . ';
var cropBoxWidth = cropBoxData.width;
var aspectRatio = cropBoxWidth / cropBoxData.height;
if (aspectRatio < minAspectRatio) {
$image.cropper(\'setCropBoxData\', {
height: cropBoxWidth / minAspectRatio
});
} else if (aspectRatio > maxAspectRatio) {
$image.cropper(\'setCropBoxData\', {
height: cropBoxWidth / maxAspectRatio
});
}
}';
}
return '<script>
$(function() {
var $inputFile = $(\'#'.$id.'\'),
$image = $(\'#'.$id.'_preview_image\'),
$input = $(\'[name="'.$id.'_crop_result"]\'),
$cropButton = $(\'#'.$id.'_crop_button\'),
$formGroup = $(\'#'.$id.'-form-group\');
function isValidType(file) {
var fileTypes = [\'image/jpg\', \'image/jpeg\', \'image/gif\', \'image/png\'];
for(var i = 0; i < fileTypes.length; i++) {
if(file.type === fileTypes[i]) {
return true;
}
}
return false;
}
function imageCropper() {
$formGroup.show();
$cropButton.show();
$image
.cropper(\'destroy\')
.cropper({
'.$ratio.'
responsive : true,
center : false,
guides : false,
movable: false,
zoomable: false,
rotatable: false,
scalable: '.$scalable.',
crop: function(e) {
// Output the result data for cropping image.
$input.val(e.x + \',\' + e.y + \',\' + e.width + \',\' + e.height);
}
' . $cropMove . '
});
}
$inputFile.on(\'change\', function () {
var inputFile = this,
file = inputFile.files[0],
fileReader = new FileReader();
if (!isValidType(file)) {
$formGroup.hide();
$cropButton.hide();
if (inputFile.setCustomValidity) {
inputFile.setCustomValidity(
inputFile.title ? inputFile.title : \''.get_lang('OnlyImagesAllowed').'\'
);
}
return;
}
if (inputFile.setCustomValidity) {
inputFile.setCustomValidity(\'\');
}
fileReader.readAsDataURL(file);
fileReader.onload = function () {
$image
.attr(\'src\', this.result)
.on(\'load\', imageCropper);
};
});
$cropButton.on(\'click\', function () {
var canvas = $image.cropper(\'getCroppedCanvas\'),
dataUrl = canvas.toDataURL();
$image.attr(\'src\', dataUrl).cropper(\'destroy\').off(\'load\', imageCropper);
$(\'[name="'.$id.'_crop_image_base_64"]\').val(dataUrl);
$cropButton.hide();
});
});
</script>';
}
/**
* @return string
*/
public function toHtml()
{
$js = '';
if (isset($this->_attributes['crop_image'])) {
$ratio = '16 / 9';
if (!empty($this->_attributes['crop_ratio'])) {
$ratio = $this->_attributes['crop_ratio'];
}
$scalable = 'false';
if (!empty($this->_attributes['crop_scalable'])) {
$scalable = $this->_attributes['crop_scalable'];
}
$maxRatio = $minRatio = null;
if (!empty($this->_attributes['crop_min_ratio']) && !empty($this->_attributes['crop_max_ratio'])) {
$minRatio = $this->_attributes['crop_min_ratio'];
$maxRatio = $this->_attributes['crop_max_ratio'];
}
$js = $this->getElementJS(array('ratio' => $ratio, 'scalable' => $scalable, 'minRatio' => $minRatio, 'maxRatio' => $maxRatio));
}
if ($this->isFrozen()) {
return $this->getFrozenHtml();
} else {
$class = '';
if (isset($this->_attributes['custom']) && $this->_attributes['custom']) {
$class = 'input-file';
}
return $js.$this->_getTabs().
'<input class="'.$class.'" '.$this->_getAttrString($this->_attributes).' />';
}
}
/**
* @param string $layout
*
* @return string
*/
public function getTemplate($layout)
{
$name = $this->getName();
$attributes = $this->getAttributes();
$size = $this->calculateSize();
switch ($layout) {
case FormValidator::LAYOUT_INLINE:
return '
<div class="form-group {error_class}">
<label {label-for} >
<!-- BEGIN required --><span class="form_required">*</span><!-- END required -->
{label}
</label>
{element}
</div>';
break;
case FormValidator::LAYOUT_HORIZONTAL:
if (isset($attributes['custom']) && $attributes['custom']) {
$template = '
<div class="input-file-container">
{element}
<label tabindex="0" {label-for} class="input-file-trigger">
<i class="fa fa-picture-o fa-lg" aria-hidden="true"></i> {label}
</label>
</div>
<p class="file-return"></p>
<script>
document.querySelector("html").classList.add(\'js\');
var fileInput = document.querySelector( ".input-file" ),
button = document.querySelector( ".input-file-trigger" ),
the_return = document.querySelector(".file-return");
button.addEventListener("keydown", function(event) {
if ( event.keyCode == 13 || event.keyCode == 32 ) {
fileInput.focus();
}
});
button.addEventListener("click", function(event) {
fileInput.focus();
return false;
});
fileInput.addEventListener("change", function(event) {
fileName = this.value;
if (this.files[0]) {
fileName = this.files[0].name;
}
the_return.textContent = fileName;
});
</script>
';
} else {
$template = '
<div id="file_'.$name.'" class="form-group {error_class}">
<label {label-for} class="col-sm-'.$size[0].' control-label" >
<!-- BEGIN required --><span class="form_required">*</span><!-- END required -->
{label}
</label>
<div class="col-sm-'.$size[1].'">
{icon}
{element}
<!-- BEGIN label_2 -->
<p class="help-block">{label_2}</p>
<!-- END label_2 -->
<!-- BEGIN error -->
<span class="help-inline help-block">{error}</span>
<!-- END error -->
</div>
<div class="col-sm-'.$size[2].'">
<!-- BEGIN label_3 -->
{label_3}
<!-- END label_3 -->
</div>
</div>';
}
return $template;
break;
case FormValidator::LAYOUT_BOX_NO_LABEL:
return '
<label {label-for}>{label}</label>
<div class="input-group">
{icon}
{element}
</div>';
break;
}
}
}

View File

@@ -0,0 +1,615 @@
<?php
/**
* HTML class for a form element group.
*
* PHP versions 4 and 5
*
* LICENSE: This source file is subject to version 3.01 of the PHP license
* that is available through the world-wide-web at the following URI:
* http://www.php.net/license/3_01.txt If you did not receive a copy of
* the PHP License and are unable to obtain it through the web, please
* send a note to license@php.net so we can mail you a copy immediately.
*
* @category HTML
*
* @author Adam Daniel <adaniel1@eesus.jnj.com>
* @author Bertrand Mansion <bmansion@mamasam.com>
* @author Alexey Borzov <avb@php.net>
* @copyright 2001-2009 The PHP Group
* @license http://www.php.net/license/3_01.txt PHP License 3.01
*
* @version CVS: $Id: group.php,v 1.40 2009/04/04 21:34:03 avb Exp $
*
* @see http://pear.php.net/package/HTML_QuickForm
*/
/**
* HTML class for a form element group.
*
* @category HTML
*
* @author Adam Daniel <adaniel1@eesus.jnj.com>
* @author Bertrand Mansion <bmansion@mamasam.com>
* @author Alexey Borzov <avb@php.net>
*
* @version Release: 3.2.11
*
* @since 1.0
*/
class HTML_QuickForm_group extends HTML_QuickForm_element
{
/**
* Name of the element.
*
* @var string
*
* @since 1.0
*/
private $_name = '';
/**
* Array of grouped elements.
*
* @var array
*
* @since 1.0
*/
private $_elements = [];
/**
* String to separate elements.
*
* @var mixed
*
* @since 2.5
*/
public $_separator = null;
/**
* Required elements in this group.
*
* @var array
*
* @since 2.5
*/
private $_required = [];
/**
* Whether to change elements' names to $groupName[$elementName] or leave them as is.
*
* @var bool
*
* @since 3.0
*/
private $_appendName = true;
/**
* Class constructor.
*
* @param string $elementName (optional)Group name
* @param array $elementLabel (optional)Group label
* @param array $elements (optional)Group elements
* @param mixed $separator (optional)Use a string for one separator,
* use an array to alternate the separators
* @param bool $appendName (optional)whether to change elements' names to
* the form $groupName[$elementName] or leave
* them as is
*
* @since 1.0
*
* @return void
*/
public function __construct(
$elementName = null,
$elementLabel = null,
$elements = null,
$separator = null,
$appendName = true
) {
parent::__construct($elementName, $elementLabel);
$this->_type = 'group';
if (isset($elements) && is_array($elements)) {
$this->setElements($elements);
}
$this->_separator = '';
if (isset($separator)) {
$this->_separator = $separator;
}
if (isset($appendName)) {
$this->_appendName = $appendName;
}
}
/**
* Sets the group name.
*
* @param string $name Group name
*
* @since 1.0
*
* @return void
*/
public function setName($name)
{
$this->_name = $name;
}
/**
* Returns the group name.
*
* @since 1.0
*
* @return string
*/
public function getName()
{
return $this->_name;
}
/**
* Sets values for group's elements.
*
* @param mixed Values for group's elements
*
* @since 1.0
*
* @return void
*/
public function setValue($value)
{
$this->_createElementsIfNotExist();
foreach (array_keys($this->_elements) as $key) {
if (!$this->_appendName) {
$v = $this->_elements[$key]->_findValue($value);
if (null !== $v) {
$this->_elements[$key]->onQuickFormEvent('setGroupValue', $v, $this);
}
} else {
$elementName = $this->_elements[$key]->getName();
$index = strlen($elementName) ? $elementName : $key;
if (is_array($value)) {
if (isset($value[$index])) {
$this->_elements[$key]->onQuickFormEvent('setGroupValue', $value[$index], $this);
}
} elseif (isset($value)) {
$this->_elements[$key]->onQuickFormEvent('setGroupValue', $value, $this);
}
}
}
}
/**
* Returns the value of the group.
*
* @since 1.0
*
* @return mixed
*/
public function getValue()
{
$value = null;
foreach (array_keys($this->_elements) as $key) {
$element = &$this->_elements[$key];
switch ($element->getType()) {
case 'radio':
$v = $element->getChecked() ? $element->getValue() : null;
break;
case 'checkbox':
$v = $element->getChecked() ? true : null;
break;
default:
$v = $element->getValue();
}
if (null !== $v) {
$elementName = $element->getName();
if (is_null($elementName)) {
$value = $v;
} else {
if (!is_array($value)) {
$value = is_null($value) ? [] : [$value];
}
if ('' === $elementName) {
$value[] = $v;
} else {
$value[$elementName] = $v;
}
}
}
}
return $value;
}
/**
* Sets the grouped elements.
*
* @param array $elements Array of elements
*
* @since 1.1
*
* @return void
*/
public function setElements($elements)
{
$this->_elements = array_values($elements);
if ($this->_flagFrozen) {
$this->freeze();
}
}
/**
* Gets the grouped elements.
*
* @since 2.4
*
* @return array
*/
public function &getElements()
{
$this->_createElementsIfNotExist();
return $this->_elements;
}
/**
* Gets the group type based on its elements
* Will return 'mixed' if elements contained in the group
* are of different types.
*
* @return string group elements type
*/
public function getGroupType()
{
$this->_createElementsIfNotExist();
$prevType = '';
foreach (array_keys($this->_elements) as $key) {
$type = $this->_elements[$key]->getType();
if ($type != $prevType && '' != $prevType) {
return 'mixed';
}
$prevType = $type;
}
return $type;
}
/**
* Returns Html for the group.
*
* @since 1.0
*
* @return string
*/
public function toHtml()
{
$renderer = new HTML_QuickForm_Renderer_Default();
$renderer->setElementTemplate('{element}');
$this->accept($renderer);
return $renderer->toHtml();
}
/**
* Returns the element name inside the group such as found in the html form.
*
* @param mixed $index Element name or element index in the group
*
* @since 3.0
*
* @return mixed string with element name, false if not found
*/
public function getElementName($index)
{
$this->_createElementsIfNotExist();
$elementName = false;
if (is_int($index) && isset($this->_elements[$index])) {
$elementName = $this->_elements[$index]->getName();
if (isset($elementName) && '' == $elementName) {
$elementName = $index;
}
if ($this->_appendName) {
if (is_null($elementName)) {
$elementName = $this->getName();
} else {
$elementName = $this->getName().'['.$elementName.']';
}
}
} elseif (is_string($index)) {
foreach (array_keys($this->_elements) as $key) {
$elementName = $this->_elements[$key]->getName();
if ($index == $elementName) {
if ($this->_appendName) {
$elementName = $this->getName().'['.$elementName.']';
}
break;
} elseif ($this->_appendName && $this->getName().'['.$elementName.']' == $index) {
break;
}
}
}
return $elementName;
}
/**
* Returns the value of field without HTML tags.
*
* @since 1.3
*
* @return string
*/
public function getFrozenHtml()
{
$flags = [];
$this->_createElementsIfNotExist();
foreach (array_keys($this->_elements) as $key) {
if (false === ($flags[$key] = $this->_elements[$key]->isFrozen())) {
$this->_elements[$key]->freeze();
}
}
$html = $this->toHtml();
foreach (array_keys($this->_elements) as $key) {
if (!$flags[$key]) {
$this->_elements[$key]->unfreeze();
}
}
return $html;
}
/**
* Called by HTML_QuickForm whenever form event is made on this element.
*
* @param string $event Name of event
* @param mixed $arg event arguments
* @param object &$caller calling object
*
* @since 1.0
*
* @return void
*/
public function onQuickFormEvent($event, $arg, &$caller)
{
switch ($event) {
case 'updateValue':
$this->_createElementsIfNotExist();
foreach (array_keys($this->_elements) as $key) {
if ($this->_appendName) {
$elementName = $this->_elements[$key]->getName();
if (is_null($elementName)) {
$this->_elements[$key]->setName($this->getName());
} elseif ('' === $elementName) {
$this->_elements[$key]->setName($this->getName().'['.$key.']');
} else {
$this->_elements[$key]->setName($this->getName().'['.$elementName.']');
}
}
$this->_elements[$key]->onQuickFormEvent('updateValue', $arg, $caller);
if ($this->_appendName) {
$this->_elements[$key]->setName($elementName);
}
}
break;
default:
parent::onQuickFormEvent($event, $arg, $caller);
}
return true;
}
/**
* Accepts a renderer.
*
* @param HTML_QuickForm_Renderer renderer object
* @param bool Whether a group is required
* @param string An error message associated with a group
*
* @return void
*/
public function accept(&$renderer, $required = false, $error = null)
{
$this->_createElementsIfNotExist();
$renderer->startGroup($this, $required, $error);
$name = $this->getName();
/** @var HTML_QuickForm_element $element */
foreach (array_keys($this->_elements) as $key) {
$element = &$this->_elements[$key];
$element->setLayout($this->getLayout());
if ($this->_appendName) {
$elementName = $element->getName();
if (isset($elementName)) {
$element->setName($name.'['.(strlen($elementName) ? $elementName : $key).']');
} else {
$element->setName($name);
}
}
$required = !$element->isFrozen() && in_array($element->getName(), $this->_required);
$element->accept($renderer, $required);
// restore the element's name
if ($this->_appendName) {
$element->setName($elementName);
}
}
$renderer->finishGroup($this);
}
/**
* As usual, to get the group's value we access its elements and call
* their exportValue() methods.
*/
public function exportValue(&$submitValues, $assoc = false)
{
$value = null;
foreach (array_keys($this->_elements) as $key) {
$elementName = $this->_elements[$key]->getName();
if ($this->_appendName) {
if (is_null($elementName)) {
$this->_elements[$key]->setName($this->getName());
} elseif ('' === $elementName) {
$this->_elements[$key]->setName($this->getName().'['.$key.']');
} else {
$this->_elements[$key]->setName($this->getName().'['.$elementName.']');
}
}
$v = $this->_elements[$key]->exportValue($submitValues, $assoc);
if ($this->_appendName) {
$this->_elements[$key]->setName($elementName);
}
if (null !== $v) {
// Make $value an array, we will use it like one
if (null === $value) {
$value = [];
}
if ($assoc) {
// just like HTML_QuickForm::exportValues()
$value = HTML_QuickForm::arrayMerge($value, $v);
} else {
// just like getValue(), but should work OK every time here
if (is_null($elementName)) {
$value = $v;
} elseif ('' === $elementName) {
$value[] = $v;
} else {
$value[$elementName] = $v;
}
}
}
}
// do not pass the value through _prepareValue, we took care of this already
return $value;
}
/**
* Creates the group's elements.
*
* This should be overriden by child classes that need to create their
* elements. The method will be called automatically when needed, calling
* it from the constructor is discouraged as the constructor is usually
* called _twice_ on element creation, first time with _no_ parameters.
*
* @abstract
*/
public function _createElements()
{
// abstract
}
/**
* A wrapper around _createElements().
*
* This method calls _createElements() if the group's _elements array
* is empty. It also performs some updates, e.g. freezes the created
* elements if the group is already frozen.
*/
public function _createElementsIfNotExist()
{
if (empty($this->_elements)) {
$this->_createElements();
if ($this->_flagFrozen) {
$this->freeze();
}
}
}
public function freeze()
{
parent::freeze();
foreach (array_keys($this->_elements) as $key) {
$this->_elements[$key]->freezeSeeOnlySelected = $this->freezeSeeOnlySelected;
$this->_elements[$key]->freeze();
}
}
public function unfreeze()
{
parent::unfreeze();
foreach (array_keys($this->_elements) as $key) {
$this->_elements[$key]->unfreeze();
}
}
public function setPersistantFreeze($persistant = false)
{
parent::setPersistantFreeze($persistant);
foreach (array_keys($this->_elements) as $key) {
$this->_elements[$key]->setPersistantFreeze($persistant);
}
}
/**
* @param string $layout
*
* @return string
*/
public function getTemplate($layout)
{
$size = $this->calculateSize();
switch ($layout) {
case FormValidator::LAYOUT_INLINE:
return '
<div class="input-group">
<label {label-for} >
<!-- BEGIN required --><span class="form_required">*</span><!-- END required -->
{label}
</label>
</div>
<div class="input-group {error_class}">
{element}
</div>
';
break;
case FormValidator::LAYOUT_HORIZONTAL:
return '
<div class="form-group {error_class}" id="'.$this->getName().'-group">
<label {label-for} class="col-sm-'.$size[0].' control-label {extra_label_class}" >
<!-- BEGIN required --><span class="form_required">*</span><!-- END required -->
{label}
</label>
<div class="col-sm-'.$size[1].'">
{icon}
{element}
<!-- BEGIN label_2 -->
<p class="help-block">{label_2}</p>
<!-- END label_2 -->
<!-- BEGIN error -->
<span class="help-inline help-block">{error}</span>
<!-- END error -->
</div>
<div class="col-sm-'.$size[2].'">
<!-- BEGIN label_3 -->
{label_3}
<!-- END label_3 -->
</div>
</div>';
break;
case FormValidator::LAYOUT_BOX_NO_LABEL:
return '
<div class="input-group">
{icon}
{element}
</div>';
break;
case FormValidator::LAYOUT_BOX:
return '
<div class="input-group">
<label>{label}</label>
{icon}
{element}
</div>';
break;
}
}
}

View File

@@ -0,0 +1,62 @@
<?php
/**
* A pseudo-element used for adding headers to form
*
* PHP versions 4 and 5
*
* LICENSE: This source file is subject to version 3.01 of the PHP license
* that is available through the world-wide-web at the following URI:
* http://www.php.net/license/3_01.txt If you did not receive a copy of
* the PHP License and are unable to obtain it through the web, please
* send a note to license@php.net so we can mail you a copy immediately.
*
* @category HTML
* @package HTML_QuickForm
* @author Alexey Borzov <avb@php.net>
* @copyright 2001-2009 The PHP Group
* @license http://www.php.net/license/3_01.txt PHP License 3.01
* @version CVS: $Id: header.php,v 1.3 2009/04/04 21:34:03 avb Exp $
* @link http://pear.php.net/package/HTML_QuickForm
*/
/**
* A pseudo-element used for adding headers to form
*
* @category HTML
* @package HTML_QuickForm
* @author Alexey Borzov <avb@php.net>
* @version Release: 3.2.11
* @since 3.0
*/
class HTML_QuickForm_header extends HTML_QuickForm_static
{
/**
* Class constructor
*
* @param string $elementName Header name
* @param string $text Header text
* @access public
* @return void
*/
public function __construct($elementName = null, $text = null)
{
if (!empty($elementName)) {
$text = $elementName;
}
parent::__construct($elementName, null, $text);
$this->_type = 'header';
}
/**
* Accepts a renderer
*
* @param HTML_QuickForm_Renderer renderer object
* @access public
* @return void
*/
function accept(&$renderer, $required=false, $error=null)
{
$renderer->renderHeader($this);
}
}

View File

@@ -0,0 +1,76 @@
<?php
/**
* HTML class for a hidden type element
*
* PHP versions 4 and 5
*
* LICENSE: This source file is subject to version 3.01 of the PHP license
* that is available through the world-wide-web at the following URI:
* http://www.php.net/license/3_01.txt If you did not receive a copy of
* the PHP License and are unable to obtain it through the web, please
* send a note to license@php.net so we can mail you a copy immediately.
*
* @category HTML
* @package HTML_QuickForm
* @author Adam Daniel <adaniel1@eesus.jnj.com>
* @author Bertrand Mansion <bmansion@mamasam.com>
* @copyright 2001-2009 The PHP Group
* @license http://www.php.net/license/3_01.txt PHP License 3.01
* @version CVS: $Id: hidden.php,v 1.12 2009/04/04 21:34:03 avb Exp $
* @link http://pear.php.net/package/HTML_QuickForm
*/
/**
* HTML class for a hidden type element
*
* @category HTML
* @package HTML_QuickForm
* @author Adam Daniel <adaniel1@eesus.jnj.com>
* @author Bertrand Mansion <bmansion@mamasam.com>
* @version Release: 3.2.11
* @since 1.0
*/
class HTML_QuickForm_hidden extends HTML_QuickForm_input
{
/**
* Class constructor
*
* @param string $elementName (optional)Input field name attribute
* @param string $value (optional)Input field value
* @param mixed $attributes (optional)Either a typical HTML attribute string
* or an associative array
* @since 1.0
* @access public
* @return void
*/
public function __construct($elementName = null, $value = '', $attributes = null)
{
parent::__construct($elementName, null, $attributes);
$this->setType('hidden');
$this->setValue($value);
}
/**
* Freeze the element so that only its value is returned
*
* @access public
* @return void
*/
public function freeze()
{
return false;
}
/**
* Accepts a renderer
*
* @param HTML_QuickForm_Renderer renderer object
* @access public
* @return void
*/
public function accept(&$renderer, $required = false, $error = null)
{
$renderer->renderHidden($this);
}
}

View File

@@ -0,0 +1,101 @@
<?php
/**
* Hidden select pseudo-element
*
* PHP versions 4 and 5
*
* LICENSE: This source file is subject to version 3.01 of the PHP license
* that is available through the world-wide-web at the following URI:
* http://www.php.net/license/3_01.txt If you did not receive a copy of
* the PHP License and are unable to obtain it through the web, please
* send a note to license@php.net so we can mail you a copy immediately.
*
* @category HTML
* @package HTML_QuickForm
* @author Isaac Shepard <ishepard@bsiweb.com>
* @copyright 2001-2009 The PHP Group
* @license http://www.php.net/license/3_01.txt PHP License 3.01
* @version CVS: $Id: hiddenselect.php,v 1.7 2009/04/04 21:34:03 avb Exp $
* @link http://pear.php.net/package/HTML_QuickForm
*/
/**
* Hidden select pseudo-element
*
* This class takes the same arguments as a select element, but instead
* of creating a select ring it creates hidden elements for all values
* already selected with setDefault or setConstant. This is useful if
* you have a select ring that you don't want visible, but you need all
* selected values to be passed.
*
* @category HTML
* @package HTML_QuickForm
* @author Isaac Shepard <ishepard@bsiweb.com>
* @version Release: 3.2.11
* @since 2.1
*/
class HTML_QuickForm_hiddenselect extends HTML_QuickForm_select
{
/**
* Class constructor
*
* @param string Select name attribute
* @param mixed Label(s) for the select (not used)
* @param mixed Data to be used to populate options
* @param mixed Either a typical HTML attribute string or an associative array (not used)
* @since 1.0
* @access public
* @return void
*/
public function __construct($elementName=null, $elementLabel=null, $options=null, $attributes=null)
{
parent::__construct($elementName, $elementLabel, $attributes);
$this->_persistantFreeze = true;
$this->_type = 'hiddenselect';
if (isset($options)) {
$this->load($options);
}
}
/**
* Returns the SELECT in HTML
*
* @since 1.0
* @access public
* @return string
* @throws
*/
function toHtml()
{
if (empty($this->_values)) {
return '';
}
$tabs = $this->_getTabs();
$name = $this->getPrivateName();
$strHtml = '';
foreach ($this->_values as $key => $val) {
for ($i = 0, $optCount = count($this->_options); $i < $optCount; $i++) {
if ($val == $this->_options[$i]['attr']['value']) {
$strHtml .= $tabs . '<input' . $this->_getAttrString(array(
'type' => 'hidden',
'name' => $name,
'value' => $val
)) . " />\n" ;
}
}
}
return $strHtml;
}
/**
* This is essentially a hidden element and should be rendered as one
*/
public function accept(&$renderer)
{
$renderer->renderHidden($this);
}
}

View File

@@ -0,0 +1,63 @@
<?php
/**
* A pseudo-element used for adding raw HTML to form
*
* PHP versions 4 and 5
*
* LICENSE: This source file is subject to version 3.01 of the PHP license
* that is available through the world-wide-web at the following URI:
* http://www.php.net/license/3_01.txt If you did not receive a copy of
* the PHP License and are unable to obtain it through the web, please
* send a note to license@php.net so we can mail you a copy immediately.
*
* @category HTML
* @package HTML_QuickForm
* @author Alexey Borzov <avb@php.net>
* @copyright 2001-2009 The PHP Group
* @license http://www.php.net/license/3_01.txt PHP License 3.01
* @version CVS: $Id: html.php,v 1.3 2009/04/04 21:34:03 avb Exp $
* @link http://pear.php.net/package/HTML_QuickForm
*/
/**
* A pseudo-element used for adding raw HTML to form
*
* Intended for use with the default renderer only, template-based
* ones may (and probably will) completely ignore this
*
* @category HTML
* @package HTML_QuickForm
* @author Alexey Borzov <avb@php.net>
* @version Release: 3.2.11
* @since 3.0
* @deprecated Please use the templates rather than add raw HTML via this element
*/
class HTML_QuickForm_html extends HTML_QuickForm_static
{
/**
* Class constructor
*
* @param string $text raw HTML to add
* @access public
* @return void
*/
public function __construct($text = null)
{
parent::__construct(null, null, $text);
$this->_type = 'html';
}
/**
* Accepts a renderer
*
* @param HTML_QuickForm_Renderer renderer object (only works with Default renderer!)
* @access public
* @return void
*/
public function accept(&$renderer, $required = false, $error = null)
{
$renderer->renderHtml($this);
}
}

View File

@@ -0,0 +1,112 @@
<?php
/* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4: */
/**
* HTML class for an <input type="image" /> element
*
* PHP versions 4 and 5
*
* LICENSE: This source file is subject to version 3.01 of the PHP license
* that is available through the world-wide-web at the following URI:
* http://www.php.net/license/3_01.txt If you did not receive a copy of
* the PHP License and are unable to obtain it through the web, please
* send a note to license@php.net so we can mail you a copy immediately.
*
* @category HTML
* @package HTML_QuickForm
* @author Adam Daniel <adaniel1@eesus.jnj.com>
* @author Bertrand Mansion <bmansion@mamasam.com>
* @copyright 2001-2009 The PHP Group
* @license http://www.php.net/license/3_01.txt PHP License 3.01
* @version CVS: $Id: image.php,v 1.6 2009/04/04 21:34:03 avb Exp $
* @link http://pear.php.net/package/HTML_QuickForm
*/
/**
* HTML class for an <input type="image" /> element
*
* @category HTML
* @package HTML_QuickForm
* @author Adam Daniel <adaniel1@eesus.jnj.com>
* @author Bertrand Mansion <bmansion@mamasam.com>
* @version Release: 3.2.11
* @since 1.0
*/
class HTML_QuickForm_image extends HTML_QuickForm_input
{
// {{{ constructor
/**
* Class constructor
*
* @param string $elementName (optional)Element name attribute
* @param string $src (optional)Image source
* @param mixed $attributes (optional)Either a typical HTML attribute string
* or an associative array
* @since 1.0
* @access public
* @return void
*/
public function __construct($elementName=null, $src='', $attributes=null)
{
parent::__construct($elementName, null, $attributes);
$this->setType('image');
$this->setSource($src);
} // end class constructor
// }}}
// {{{ setSource()
/**
* Sets source for image element
*
* @param string $src source for image element
* @since 1.0
* @access public
* @return void
*/
function setSource($src)
{
$this->updateAttributes(array('src' => $src));
} // end func setSource
// }}}
// {{{ setBorder()
/**
* Sets border size for image element
*
* @param string $border border for image element
* @since 1.0
* @access public
* @return void
*/
function setBorder($border)
{
$this->updateAttributes(array('border' => $border));
}
/**
* Sets alignment for image element
*
* @param string $align alignment for image element
* @since 1.0
* @access public
* @return void
*/
function setAlign($align)
{
$this->updateAttributes(array('align' => $align));
}
/**
* Freeze the element so that only its value is returned
*
* @access public
* @return void
*/
function freeze()
{
return false;
}
}

View File

@@ -0,0 +1,6 @@
<html>
<head>
</head>
<body>
</body>
</html>

View File

@@ -0,0 +1,159 @@
<?php
/**
* Base class for <input /> form elements
*
* PHP versions 4 and 5
*
* LICENSE: This source file is subject to version 3.01 of the PHP license
* that is available through the world-wide-web at the following URI:
* http://www.php.net/license/3_01.txt If you did not receive a copy of
* the PHP License and are unable to obtain it through the web, please
* send a note to license@php.net so we can mail you a copy immediately.
*
* @category HTML
* @package HTML_QuickForm
* @author Adam Daniel <adaniel1@eesus.jnj.com>
* @author Bertrand Mansion <bmansion@mamasam.com>
* @copyright 2001-2009 The PHP Group
* @license http://www.php.net/license/3_01.txt PHP License 3.01
* @version CVS: $Id: input.php,v 1.10 2009/04/04 21:34:03 avb Exp $
* @link http://pear.php.net/package/HTML_QuickForm
*/
/**
* Base class for <input /> form elements
*
* @category HTML
* @package HTML_QuickForm
* @author Adam Daniel <adaniel1@eesus.jnj.com>
* @author Bertrand Mansion <bmansion@mamasam.com>
* @version Release: 3.2.11
* @since 1.0
* @abstract
*/
class HTML_QuickForm_input extends HTML_QuickForm_element
{
/**
* Sets the element type
*
* @param string $type Element type
* @since 1.0
* @access public
* @return void
*/
public function setType($type)
{
$this->_type = $type;
$this->updateAttributes(array('type'=>$type));
}
/**
* Sets the input field name
*
* @param string $name Input field name attribute
* @since 1.0
* @access public
* @return void
*/
public function setName($name)
{
$this->updateAttributes(array('name'=>$name));
}
/**
* Returns the element name
*
* @since 1.0
* @access public
* @return string
*/
public function getName()
{
return $this->getAttribute('name');
}
/**
* Sets the value of the form element
*
* @param string $value Default value of the form element
* @since 1.0
* @access public
* @return void
*/
public function setValue($value)
{
$this->updateAttributes(array('value' => $value));
}
/**
* Returns the value of the form element
*
* @since 1.0
* @access public
* @return string
*/
public function getValue()
{
return $this->getAttribute('value');
}
/**
* Returns the input field in HTML
*
* @since 1.0
* @access public
* @return string
*/
public function toHtml()
{
if ($this->isFrozen()) {
return $this->getFrozenHtml();
}
return $this->_getTabs().'<input'.$this->_getAttrString($this->_attributes).' />';
}
/**
* Called by HTML_QuickForm whenever form event is made on this element
*
* @param string $event Name of event
* @param mixed $arg event arguments
* @param object &$caller calling object
* @since 1.0
* @access public
* @return void
* @throws
*/
public function onQuickFormEvent($event, $arg, &$caller)
{
// do not use submit values for button-type elements
$type = $this->getType();
if (('updateValue' != $event) ||
('submit' != $type && 'reset' != $type && 'image' != $type && 'button' != $type)) {
parent::onQuickFormEvent($event, $arg, $caller);
} else {
$value = $this->_findValue($caller->_constantValues);
if (null === $value) {
$value = $this->_findValue($caller->_defaultValues);
}
if (null !== $value) {
$this->setValue($value);
}
}
return true;
}
/**
* We don't need values from button-type elements (except submit) and files
*/
public function exportValue(&$submitValues, $assoc = false)
{
$type = $this->getType();
if ('reset' === $type || 'image' === $type || 'button' === $type || 'file' === $type) {
return null;
}
return parent::exportValue($submitValues, $assoc);
}
}

View File

@@ -0,0 +1,38 @@
<?php
/**
* HTML class for static data
* @example $form->addElement('label', 'My label', 'Content');
*/
/**
* A pseudo-element used for adding raw HTML to form
*
* Intended for use with the default renderer only, template-based
* ones may (and probably will) completely ignore this
*
* @category HTML
* @package HTML_QuickForm
* @author Alexey Borzov <avb@php.net>
* @version Release: 3.2.11
* @since 3.0
* @deprecated Please use the templates rather than add raw HTML via this element
*/
class HTML_QuickForm_label extends HTML_QuickForm_static
{
/**
* Class constructor
*
* @param string $text raw HTML to add
* @access public
* @return void
*/
public function __construct(
$label = null,
$text = null,
$attributes = null
) {
parent::__construct(null, $label, $text, $attributes);
$this->_type = 'html';
}
}

View File

@@ -0,0 +1,163 @@
<?php
/**
* HTML class for a link type field
*
* PHP versions 4 and 5
*
* LICENSE: This source file is subject to version 3.01 of the PHP license
* that is available through the world-wide-web at the following URI:
* http://www.php.net/license/3_01.txt If you did not receive a copy of
* the PHP License and are unable to obtain it through the web, please
* send a note to license@php.net so we can mail you a copy immediately.
*
* @category HTML
* @package HTML_QuickForm
* @author Adam Daniel <adaniel1@eesus.jnj.com>
* @author Bertrand Mansion <bmansion@mamasam.com>
* @copyright 2001-2009 The PHP Group
* @license http://www.php.net/license/3_01.txt PHP License 3.01
* @version CVS: $Id: link.php,v 1.4 2009/04/04 21:34:04 avb Exp $
* @link http://pear.php.net/package/HTML_QuickForm
*/
/**
* HTML class for a link type field
*
* @category HTML
* @package HTML_QuickForm
* @author Adam Daniel <adaniel1@eesus.jnj.com>
* @author Bertrand Mansion <bmansion@mamasam.com>
* @version Release: 3.2.11
* @since 2.0
*/
class HTML_QuickForm_link extends HTML_QuickForm_static
{
/**
* Link display text
* @var string
* @since 1.0
* @access private
*/
var $_text = '';
/**
* Class constructor
*
* @param string $elementLabel (optional)Link label
* @param string $href (optional)Link href
* @param string $text (optional)Link display text
* @param mixed $attributes (optional)Either a typical HTML attribute string
* or an associative array
* @since 1.0
* @access public
* @return void
* @throws
*/
public function __construct($elementName=null, $elementLabel=null, $href=null, $text=null, $attributes=null)
{
parent::__construct($elementName, $elementLabel, $attributes);
$this->_persistantFreeze = false;
$this->_type = 'link';
$this->setHref($href);
$this->_text = $text;
}
/**
* Sets the input field name
*
* @param string $name Input field name attribute
* @since 1.0
* @access public
* @return void
* @throws
*/
function setName($name)
{
$this->updateAttributes(array('name'=>$name));
}
/**
* Returns the element name
*
* @since 1.0
* @access public
* @return string
* @throws
*/
function getName()
{
return $this->getAttribute('name');
}
/**
* Sets value for textarea element
*
* @param string $value Value for password element
* @since 1.0
* @access public
* @return void
* @throws
*/
function setValue($value)
{
return;
}
/**
* Returns the value of the form element
*
* @since 1.0
* @access public
* @return void
* @throws
*/
function getValue()
{
return;
}
/**
* Sets the links href
*
* @param string $href
* @since 1.0
* @access public
* @return void
* @throws
*/
function setHref($href)
{
$this->updateAttributes(array('href'=>$href));
}
/**
* Returns the textarea element in HTML
*
* @since 1.0
* @access public
* @return string
* @throws
*/
function toHtml()
{
$tabs = $this->_getTabs();
$html = "$tabs<a".$this->_getAttrString($this->_attributes).">";
$html .= $this->_text;
$html .= "</a>";
return $html;
}
/**
* Returns the value of field without HTML tags (in this case, value is changed to a mask)
*
* @since 1.0
* @access public
* @return string
* @throws
*/
function getFrozenHtml()
{
return;
}
}

View File

@@ -0,0 +1,130 @@
<?php
/**
* HTML class for a password type field
*
* PHP versions 4 and 5
*
* LICENSE: This source file is subject to version 3.01 of the PHP license
* that is available through the world-wide-web at the following URI:
* http://www.php.net/license/3_01.txt If you did not receive a copy of
* the PHP License and are unable to obtain it through the web, please
* send a note to license@php.net so we can mail you a copy immediately.
*
* @category HTML
* @package HTML_QuickForm
* @author Adam Daniel <adaniel1@eesus.jnj.com>
* @author Bertrand Mansion <bmansion@mamasam.com>
* @copyright 2001-2009 The PHP Group
* @license http://www.php.net/license/3_01.txt PHP License 3.01
* @version CVS: $Id: password.php,v 1.8 2009/04/04 21:34:04 avb Exp $
* @link http://pear.php.net/package/HTML_QuickForm
*/
/**
* HTML class for a password type field
*
* @category HTML
* @package HTML_QuickForm
* @author Adam Daniel <adaniel1@eesus.jnj.com>
* @author Bertrand Mansion <bmansion@mamasam.com>
* @version Release: 3.2.11
* @since 1.0
*/
class HTML_QuickForm_password extends HTML_QuickForm_text
{
/**
* Class constructor
*
* @param string $elementName (optional)Input field name attribute
* @param string $elementLabel (optional)Input field label
* @param mixed $attributes (optional)Either a typical HTML attribute string
* or an associative array
*
* @throws
* @since 1.0
* @access public
*/
public function __construct($elementName = null, $elementLabel = null, $attributes = null)
{
$attributes['class'] = isset($attributes['class']) ? $attributes['class'] : 'form-control';
parent::__construct($elementName, $elementLabel, $attributes);
$this->setType('password');
}
/**
* Sets size of password element
*
* @param string $size Size of password field
*
* @return void
* @since 1.0
* @access public
*/
public function setSize($size)
{
$this->updateAttributes(array('size' => $size));
}
/**
* Sets maxlength of password element
*
* @param string $maxlength Maximum length of password field
*
* @return void
* @since 1.0
* @access public
*/
public function setMaxlength($maxlength)
{
$this->updateAttributes(array('maxlength' => $maxlength));
}
/**
* Returns the value of field without HTML tags (in this case, value is changed to a mask)
*
* @return string
* @throws
* @since 1.0
* @access public
*/
public function getFrozenHtml()
{
$value = $this->getValue();
return ('' != $value ? '**********' : '&nbsp;').
$this->_getPersistantData();
}
/**
* @return string
*/
public function toHtml()
{
if (parent::isFrozen()) {
return parent::getFrozenHtml();
}
$input = '<input '.$this->_getAttrString($this->_attributes).' />';
if (empty($this->_attributes['show_hide'])) {
return $input;
}
$this->removeAttribute('show_hide');
$label = get_lang('ShowOrHide');
$pwdId = $this->_attributes['id'];
$id = $pwdId.'_toggle';
return '<div class="input-group" id="add-user__input-password">
'.$input.'
<span class="input-group-addon">
<input type="checkbox" title="'.$label.'" aria-label="'.$label.'" id="'.$id.'">
</span>
</div>
<script>document.getElementById(\''.$id.'\').onchange = function () {
document.getElementById(\''.$pwdId.'\').setAttribute(\'type\', this.checked ? \'text\' : \'password\')
};</script>';
}
}

View File

@@ -0,0 +1,255 @@
<?php
/**
* HTML class for a radio type element
*
* PHP versions 4 and 5
*
* LICENSE: This source file is subject to version 3.01 of the PHP license
* that is available through the world-wide-web at the following URI:
* http://www.php.net/license/3_01.txt If you did not receive a copy of
* the PHP License and are unable to obtain it through the web, please
* send a note to license@php.net so we can mail you a copy immediately.
*
* @category HTML
* @package HTML_QuickForm
* @author Adam Daniel <adaniel1@eesus.jnj.com>
* @author Bertrand Mansion <bmansion@mamasam.com>
* @copyright 2001-2009 The PHP Group
* @license http://www.php.net/license/3_01.txt PHP License 3.01
* @version CVS: $Id: radio.php,v 1.20 2009/04/04 21:34:04 avb Exp $
* @link http://pear.php.net/package/HTML_QuickForm
*/
/**
* HTML class for a radio type element
*
* @category HTML
* @package HTML_QuickForm
* @author Adam Daniel <adaniel1@eesus.jnj.com>
* @author Bertrand Mansion <bmansion@mamasam.com>
* @version Release: 3.2.11
* @since 1.0
*/
class HTML_QuickForm_radio extends HTML_QuickForm_input
{
public $_text = '';
public $labelClass;
public $radioClass;
/**
* Class constructor
*
* @param string Input field name attribute
* @param mixed Label(s) for a field
* @param string Text to display near the radio
* @param string Input field value
* @param mixed Either a typical HTML attribute string or an associative array
*
* @return void
* @since 1.0
*/
public function __construct(
$elementName = null,
$elementLabel = null,
$text = null,
$value = null,
$attributes = null
) {
$this->labelClass = isset($attributes['label-class']) ? $attributes['label-class'] : '';
$this->radioClass = isset($attributes['radio-class']) ? $attributes['radio-class'] : 'radio';
if (isset($attributes['label-class'])) {
unset($attributes['label-class']);
}
if (isset($attributes['radio-class'])) {
unset($attributes['radio-class']);
}
$columnsSize = isset($attributes['cols-size']) ? $attributes['cols-size'] : null;
$this->setColumnsSize($columnsSize);
parent::__construct($elementName, $elementLabel, $attributes);
if (isset($value)) {
$this->setValue($value);
}
$this->_persistantFreeze = true;
$this->setType('radio');
$this->_text = $text;
$this->_generateId();
}
/**
* Returns the radio element in HTML
*
* @return string
* @since 1.0
*/
public function toHtml()
{
if (0 == strlen($this->_text)) {
$label = '';
} elseif ($this->isFrozen()) {
$label = $this->_text;
if ($this->freezeSeeOnlySelected) {
$invisible = $this->getChecked() ? '' : ' style="display:none"';
return "<div $invisible>".HTML_QuickForm_input::toHtml().$this->_text."</div>";
}
} else {
$labelClass = $this->labelClass;
$radioClass = $this->radioClass;
$label = '<div class="'.$radioClass.'">
<label class="'.$labelClass.'">'.
HTML_QuickForm_input::toHtml().
''.
$this->_text.
'</label>
</div>';
return $label;
}
return parent::toHtml().$label;
}
/**
* Returns whether radio button is checked
*
* @return string
* @since 1.0
*/
public function getChecked()
{
return $this->getAttribute('checked');
}
/**
* Returns the value of field without HTML tags
*
* @return string
* @since 1.0
*/
public function getFrozenHtml()
{
if ($this->getChecked()) {
return '<br /><code>(x)</code>'.
$this->_getPersistantData();
}
return '<br /><code>( )</code>';
}
/**
* Returns the radio text
*
* @return string
* @since 1.1
* @access public
*/
public function getText()
{
return $this->_text;
}
/**
* Sets the radio text
*
* @param string $text Text to display near the radio button
*
* @return void
* @since 1.1
* @access public
*/
public function setText($text)
{
$this->_text = $text;
}
/**
* Called by HTML_QuickForm whenever form event is made on this element
*
* @param string $event Name of event
* @param mixed $arg event arguments
* @param object &$caller calling object
*
* @return void
* @since 1.0
* @access public
*/
public function onQuickFormEvent($event, $arg, &$caller)
{
switch ($event) {
case 'updateValue':
// constant values override both default and submitted ones
// default values are overriden by submitted
$value = $this->_findValue($caller->_constantValues);
if (null === $value) {
$value = $this->_findValue($caller->_submitValues);
if (null === $value) {
$value = $this->_findValue($caller->_defaultValues);
}
}
if (!is_null($value) && $value == $this->getValue()) {
$this->setChecked(true);
} else {
$this->setChecked(false);
}
break;
case 'setGroupValue':
if ($arg == $this->getValue()) {
$this->setChecked(true);
} else {
$this->setChecked(false);
}
break;
default:
parent::onQuickFormEvent($event, $arg, $caller);
}
return true;
}
/**
* Sets whether radio button is checked
*
* @param bool $checked Whether the field is checked or not
*
* @return void
* @since 1.0
* @access public
*/
public function setChecked($checked)
{
if (!$checked) {
$this->removeAttribute('checked');
} else {
$this->updateAttributes(array('checked' => 'checked'));
}
}
/**
* Returns the value attribute if the radio is checked, null if it is not
*/
public function exportValue(&$submitValues, $assoc = false)
{
$value = $this->_findValue($submitValues);
if (null === $value) {
$value = $this->getChecked() ? $this->getValue() : null;
} elseif ($value != $this->getValue()) {
$value = null;
}
return $this->_prepareValue($value, $assoc);
}
/**
* @return null
*/
public function getColumnsSize()
{
return $this->columnsSize;
}
}

View File

@@ -0,0 +1,33 @@
<?php
class HTML_QuickForm_reset extends HTML_QuickForm_button
{
/**
* Class constructor
*
* @param string $elementName (optional)Input field name attribute
* @param string $value (optional)Input field value
* @param mixed $attributes (optional)Either a typical HTML attribute string
* or an associative array
* @since 1.0
* @access public
* @return void
*/
public function __construct($elementName=null, $value=null, $attributes=null)
{
parent::__construct($elementName, null, $attributes);
$this->setValue($value);
$this->setType('reset');
}
/**
* Freeze the element so that only its value is returned
*
* @access public
* @return void
*/
function freeze()
{
return false;
}
}

View File

@@ -0,0 +1,627 @@
<?php
/**
* Class to dynamically create an HTML SELECT
*
* PHP versions 4 and 5
*
* LICENSE: This source file is subject to version 3.01 of the PHP license
* that is available through the world-wide-web at the following URI:
* http://www.php.net/license/3_01.txt If you did not receive a copy of
* the PHP License and are unable to obtain it through the web, please
* send a note to license@php.net so we can mail you a copy immediately.
*
* @category HTML
* @package HTML_QuickForm
* @author Adam Daniel <adaniel1@eesus.jnj.com>
* @author Bertrand Mansion <bmansion@mamasam.com>
* @author Alexey Borzov <avb@php.net>
* @copyright 2001-2009 The PHP Group
* @license http://www.php.net/license/3_01.txt PHP License 3.01
* @version CVS: $Id: select.php,v 1.34 2009/04/04 21:34:04 avb Exp $
* @link http://pear.php.net/package/HTML_QuickForm
*/
/**
* Class to dynamically create an HTML SELECT
*
* @category HTML
* @package HTML_QuickForm
* @author Adam Daniel <adaniel1@eesus.jnj.com>
* @author Bertrand Mansion <bmansion@mamasam.com>
* @author Alexey Borzov <avb@php.net>
* @version Release: 3.2.11
* @since 1.0
*/
class HTML_QuickForm_select extends HTML_QuickForm_element
{
/**
* Contains the select options
*
* @var array
* @since 1.0
* @access private
*/
protected $_options = [];
private $_optgroups = [];
/**
* Default values of the SELECT
*
* @var array
* @since 1.0
* @access private
*/
protected $_values = [];
/**
* Class constructor
*
* @param string $elementName Select name attribute
* @param mixed $elementLabel Label(s) for the select
* @param mixed $options Data to be used to populate options
* @param mixed $attributes Either a typical HTML attribute string or an associative array
* @since 1.0
* @access public
*/
public function __construct(
$elementName,
$elementLabel = '',
$options = null,
$attributes = null
) {
$addBlank = '';
if (is_array($attributes) || empty($attributes)) {
$oldClass = '';
if (!empty($attributes['class'])) {
$oldClass = $attributes['class'];
}
if (empty($attributes)) {
$attributes = []; // Initialize variable to avoid warning in PHP 7.1
}
$attributes['class'] = $oldClass . ' selectpicker form-control';
$attributes['data-live-search'] = 'true';
if (isset($attributes['disable_js']) && $attributes['disable_js']) {
$attributes['class'] = 'form-control';
$attributes['data-live-search'] = '';
}
if (isset($attributes['extra_class']) && $attributes['extra_class']) {
$attributes['class'] .= ' '.$attributes['extra_class'];
unset($attributes['extra_class']);
}
if (isset($attributes['placeholder'])) {
$addBlank = $attributes['placeholder'];
}
}
$columnsSize = isset($attributes['cols-size']) ? $attributes['cols-size'] : null;
$this->setColumnsSize($columnsSize);
parent::__construct($elementName, $elementLabel, $attributes);
$this->_persistantFreeze = true;
$this->_type = 'select';
if ($addBlank !== '') {
if (isset($options)) {
$options = ['' => $addBlank] + $options;
} else {
$options = ['' => $addBlank];
}
}
if (isset($options)) {
$this->load($options);
}
}
public function setOptions($options)
{
$this->load($options);
}
/**
* Loads options from different types of data sources
*
* This method is a simulated overloaded method. The arguments, other than the
* first are optional and only mean something depending on the type of the first argument.
* If the first argument is an array then all arguments are passed in order to loadArray.
* If the first argument is a db_result then all arguments are passed in order to loadDbResult.
* If the first argument is a string or a DB connection then all arguments are
* passed in order to loadQuery.
* @param mixed $options Options source currently supports assoc array or DB_result
* @param mixed $param1 (optional) See function detail
* @param mixed $param2 (optional) See function detail
* @param mixed $param3 (optional) See function detail
* @param mixed $param4 (optional) See function detail
* @since 1.1
* @access public
* @return PEAR_Error on error or true
* @throws PEAR_Error
*/
protected function load(&$options, $param1=null, $param2=null, $param3=null, $param4=null)
{
switch (true) {
case is_array($options):
return $this->loadArray($options, $param1);
break;
}
}
/**
* Loads the options from an associative array
*
* @param array $arr Associative array of options
* @param mixed $values (optional) Array or comma delimited string of selected values
* @since 1.0
* @access public
* @return PEAR_Error on error or true
* @throws PEAR_Error
*/
private function loadArray($arr, $values = null)
{
if (!is_array($arr)) {
return false;
}
if (isset($values)) {
$this->setSelected($values);
}
foreach ($arr as $key => $val) {
// Fix in order to use list of entities.
if (is_object($val)) {
$key = $val->getId();
$val = $val->__toString();
}
// Warning: new API since release 2.3
$this->addOption($val, $key);
}
return true;
}
/**
* Returns the current API version
*
* @since 1.0
* @access public
* @return double
*/
function apiVersion()
{
return 2.3;
}
/**
* Sets the default values of the select box
*
* @param mixed $values Array or comma delimited string of selected values
* @since 1.0
* @access public
* @return void
*/
public function setSelected($values)
{
if (is_string($values) && $this->getMultiple()) {
$values = explode('[ ]?,[ ]?', $values);
}
if (is_array($values)) {
$this->_values = array_values($values);
} else {
$this->_values = array($values);
}
}
/**
* Sets the input field name
*
* @param string $name Input field name attribute
* @since 1.0
* @access public
* @return void
*/
public function setName($name)
{
$this->updateAttributes(array('name' => $name));
}
/**
* Returns the element name
*
* @since 1.0
* @access public
* @return string
*/
public function getName()
{
return $this->getAttribute('name');
}
/**
* Returns the element name (possibly with brackets appended)
*
* @since 1.0
* @access public
* @return string
*/
public function getPrivateName()
{
if ($this->getAttribute('multiple')) {
return $this->getName().'[]';
}
return $this->getName();
}
/**
* Sets the value of the form element
*
* @param mixed $values Array or comma delimited string of selected values
* @since 1.0
* @access public
* @return void
*/
public function setValue($value)
{
$this->setSelected($value);
}
/**
* Returns an array of the selected values
*
* @since 1.0
* @access public
* @return array of selected values
*/
public function getValue()
{
return $this->_values;
}
/**
* Sets the select field size, only applies to 'multiple' selects
*
* @param int $size Size of select field
* @since 1.0
* @access public
* @return void
*/
public function setSize($size)
{
$this->updateAttributes(array('size' => $size));
}
/**
* Returns the select field size
*
* @since 1.0
* @access public
* @return int
*/
public function getSize()
{
return $this->getAttribute('size');
}
/**
* Sets the select mutiple attribute
*
* @param bool $multiple Whether the select supports multi-selections
* @since 1.2
* @access public
* @return void
*/
public function setMultiple($multiple)
{
if ($multiple) {
$this->updateAttributes(array('multiple' => 'multiple'));
} else {
$this->removeAttribute('multiple');
}
}
/**
* Returns the select mutiple attribute
*
* @since 1.2
* @access public
* @return bool true if multiple select, false otherwise
*/
public function getMultiple()
{
return (bool) $this->getAttribute('multiple');
}
/**
* Adds a new OPTION to the SELECT
*
* @param string $text Display text for the OPTION
* @param string $value Value for the OPTION
* @param mixed $attributes Either a typical HTML attribute string
* or an associative array
* @since 1.0
* @access public
* @return void
*/
public function addOption($text, $value, $attributes = null, $return_array = false)
{
if (null === $attributes) {
$attributes = array('value' => (string)$value);
} else {
$attributes = $this->_parseAttributes($attributes);
if (isset($attributes['selected'])) {
// the 'selected' attribute will be set in toHtml()
$this->_removeAttr('selected', $attributes);
if (is_null($this->_values)) {
$this->_values = array($value);
} elseif (!in_array($value, $this->_values)) {
$this->_values[] = $value;
}
}
$this->_updateAttrArray($attributes, array('value' => (string)$value));
}
if ($return_array) {
return array('text' => $text, 'attr' => $attributes);
} else {
$this->_options[] = array('text' => $text, 'attr' => $attributes);
}
}
/**
* Adds a new OPTION to the SELECT
*
* @param string $text Display text for the OPTION
* @param string $value Value for the OPTION
* @param mixed $attributes Either a typical HTML attribute string
* or an associative array
* @since 1.0
* @access public
* @return void
*/
public function addOptGroup($options, $label)
{
foreach ($options as $option) {
$this->addOption($option['text'], $option['value'], $option, true);
}
$this->_optgroups[] = array('label' => $label, 'options' => $options);
}
/**
* Returns the SELECT in HTML
*
* @since 1.0
* @access public
* @return string
*/
public function toHtml()
{
if ($this->_flagFrozen) {
return $this->getFrozenHtml();
} else {
$tabs = $this->_getTabs();
$strHtml = '';
if ($this->getComment() != '') {
$strHtml .= $tabs . '<!-- ' . $this->getComment() . " //-->\n";
}
if (!$this->getMultiple()) {
$attrString = $this->_getAttrString($this->_attributes);
} else {
$myName = $this->getName();
$this->setName($myName . '[]');
$attrString = $this->_getAttrString($this->_attributes);
$this->setName($myName);
}
$strHtml .= $tabs . '<select ' . $attrString . ">\n";
$strValues = is_array($this->_values)? array_map('strval', $this->_values): array();
foreach ($this->_options as $option) {
if (!empty($strValues) && in_array($option['attr']['value'], $strValues, true)) {
$option['attr']['selected'] = 'selected';
}
$strHtml .= $tabs . "<option" . $this->_getAttrString($option['attr']) . '>' .
$option['text'] . "</option>";
}
foreach ($this->_optgroups as $optgroup) {
$strHtml .= $tabs . '<optgroup label="' . $optgroup['label'] . '">';
foreach ($optgroup['options'] as $option) {
$text = $option['text'];
unset($option['text']);
if (!empty($strValues) && in_array($option['value'], $strValues)) {
$option['selected'] = 'selected';
}
$strHtml .= $tabs . " <option" . $this->_getAttrString($option) . '>' .$text . "</option>";
}
$strHtml .= "</optgroup>";
}
return $strHtml.$tabs.'</select>';
}
}
/**
* Returns the value of field without HTML tags
*
* @since 1.0
* @access public
* @return string
*/
public function getFrozenHtml()
{
$value = array();
if (is_array($this->_values)) {
foreach ($this->_values as $key => $val) {
for ($i = 0, $optCount = count($this->_options); $i < $optCount; $i++) {
if (0 == strcmp($val, $this->_options[$i]['attr']['value'])) {
$value[$key] = $this->_options[$i]['text'];
break;
}
}
}
}
$html = empty($value)? '&nbsp;': join('<br />', $value);
if ($this->_persistantFreeze) {
$name = $this->getPrivateName();
// Only use id attribute if doing single hidden input
if (1 == count($value)) {
$id = $this->getAttribute('id');
$idAttr = isset($id)? array('id' => $id): array();
} else {
$idAttr = array();
}
foreach ($value as $key => $item) {
$html .= '<input' . $this->_getAttrString(array(
'type' => 'hidden',
'name' => $name,
'value' => $this->_values[$key]
) + $idAttr) . ' />';
}
}
return $html;
}
/**
* We check the options and return only the values that _could_ have been
* selected. We also return a scalar value if select is not "multiple"
*/
public function exportValue(&$submitValues, $assoc = false)
{
$value = $this->_findValue($submitValues);
if (is_null($value)) {
$value = $this->getValue();
} elseif(!is_array($value)) {
$value = array($value);
}
if (is_array($value) && !empty($this->_options)) {
$cleanValue = null;
foreach ($value as $v) {
for ($i = 0, $optCount = count($this->_options); $i < $optCount; $i++) {
if (0 == strcmp($v, $this->_options[$i]['attr']['value'])) {
$cleanValue[] = $v;
break;
}
}
}
} else {
$cleanValue = $value;
}
if (is_array($cleanValue) && !$this->getMultiple()) {
if (empty($cleanValue)) {
return $this->_prepareValue(null, $assoc);
}
return $this->_prepareValue($cleanValue[0], $assoc);
} else {
return $this->_prepareValue($cleanValue, $assoc);
}
}
public function onQuickFormEvent($event, $arg, &$caller)
{
if ('updateValue' === $event) {
$value = $this->_findValue($caller->_constantValues);
if (null === $value) {
$value = $this->_findValue($caller->_submitValues);
// Fix for bug #4465 & #5269
// XXX: should we push this to element::onQuickFormEvent()?
if (null === $value && (!$caller->isSubmitted() || !$this->getMultiple())) {
$value = $this->_findValue($caller->_defaultValues);
}
}
if (null !== $value) {
$this->setValue($value);
}
return true;
}
return parent::onQuickFormEvent($event, $arg, $caller);
}
/**
* @param FormValidator $form
*/
public function updateSelectWithSelectedOption(FormValidator $form)
{
$id = $this->getAttribute('id');
$form->addHtml(
'<script>
$(function(){
var optionClass = $("#'.$id.'").find("option:checked").attr("class");
$("#'.$id.'").attr("class", "form-control " + optionClass);
$("#'.$id.'").on("change", function() {
var optionClass = ($(this).find("option:checked").attr("class"));
$(this).attr("class", "form-control " + optionClass);
});
});
</script>'
);
}
/**
* @param string $layout
*
* @return string
*/
public function getTemplate($layout)
{
$size = $this->calculateSize();
switch ($layout) {
case FormValidator::LAYOUT_INLINE:
return '
<div class="form-group {error_class}">
<label {label-for} >
<!-- BEGIN required --><span class="form_required">*</span><!-- END required -->
{label}
</label>
{element}
</div>';
break;
case FormValidator::LAYOUT_HORIZONTAL:
return '
<div class="form-group {error_class}">
<label {label-for} class="col-sm-'.$size[0].' control-label {extra_label_class}" >
<!-- BEGIN required --><span class="form_required">*</span><!-- END required -->
{label}
</label>
<div class="col-sm-'.$size[1].'">
{icon}
{element}
<!-- BEGIN label_2 -->
<p class="help-block">{label_2}</p>
<!-- END label_2 -->
<!-- BEGIN error -->
<span class="help-inline help-block">{error}</span>
<!-- END error -->
</div>
<div class="col-sm-'.$size[2].'">
<!-- BEGIN label_3 -->
{label_3}
<!-- END label_3 -->
</div>
</div>';
break;
case FormValidator::LAYOUT_BOX_NO_LABEL:
return '
<div class="input-group">
{icon}
{element}
</div>';
break;
case FormValidator::LAYOUT_GRID:
case FormValidator::LAYOUT_BOX:
return '
<div class="form-group">
<label>{label}</label>
{icon}
{element}
</div>';
break;
}
}
}

View File

@@ -0,0 +1,164 @@
<?php
/* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4: */
/**
* HTML class for static data
*
* PHP versions 4 and 5
*
* LICENSE: This source file is subject to version 3.01 of the PHP license
* that is available through the world-wide-web at the following URI:
* http://www.php.net/license/3_01.txt If you did not receive a copy of
* the PHP License and are unable to obtain it through the web, please
* send a note to license@php.net so we can mail you a copy immediately.
*
* @category HTML
* @package HTML_QuickForm
* @author Wojciech Gdela <eltehaem@poczta.onet.pl>
* @copyright 2001-2009 The PHP Group
* @license http://www.php.net/license/3_01.txt PHP License 3.01
* @version CVS: $Id: static.php,v 1.8 2009/04/04 21:34:04 avb Exp $
* @link http://pear.php.net/package/HTML_QuickForm
*/
/**
* HTML class for static data
*
* @category HTML
* @package HTML_QuickForm
* @author Wojciech Gdela <eltehaem@poczta.onet.pl>
* @version Release: 3.2.11
* @since 2.7
*/
class HTML_QuickForm_static extends HTML_QuickForm_element
{
/**
* Display text
* @var string
* @access private
*/
var $_text = null;
/**
* Class constructor
*
* @param string $elementLabel (optional)Label
* @param string $text (optional)Display text
* @access public
* @return void
*/
public function __construct($elementName = null, $elementLabel = null, $text = null, $attributes = null)
{
parent::__construct($elementName, $elementLabel, $attributes);
$this->_persistantFreeze = false;
$this->_type = 'static';
$this->_text = $text;
}
/**
* Sets the element name
*
* @param string $name Element name
* @access public
* @return void
*/
function setName($name)
{
$this->updateAttributes(array('name'=>$name));
}
/**
* Returns the element name
*
* @access public
* @return string
*/
function getName()
{
return $this->getAttribute('name');
}
/**
* Sets the text
*
* @param string $text
* @access public
* @return void
*/
function setText($text)
{
$this->_text = $text;
}
/**
* Sets the text (uses the standard setValue call to emulate a form element.
*
* @param string $text
* @access public
* @return void
*/
function setValue($text)
{
$this->setText($text);
}
/**
* Returns the static text element in HTML
*
* @access public
* @return string
*/
public function toHtml()
{
return $this->_getTabs() . $this->_text;
}
/**
* Returns the value of field without HTML tags
*
* @access public
* @return string
*/
function getFrozenHtml()
{
return $this->toHtml();
}
/**
* Called by HTML_QuickForm whenever form event is made on this element
*
* @param string $event Name of event
* @param mixed $arg event arguments
* @param object &$caller calling object
* @since 1.0
* @access public
* @return void
* @throws
*/
function onQuickFormEvent($event, $arg, &$caller)
{
switch ($event) {
case 'updateValue':
// do NOT use submitted values for static elements
$value = $this->_findValue($caller->_constantValues);
if (null === $value) {
$value = $this->_findValue($caller->_defaultValues);
}
if (null !== $value) {
$this->setValue($value);
}
break;
default:
parent::onQuickFormEvent($event, $arg, $caller);
}
return true;
}
/**
* We override this here because we don't want any values from static elements
*/
function exportValue(&$submitValues, $assoc = false)
{
return null;
}
}

View File

@@ -0,0 +1,74 @@
<?php
/* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4: */
/**
* HTML class for a submit type element
*
* PHP versions 4 and 5
*
* LICENSE: This source file is subject to version 3.01 of the PHP license
* that is available through the world-wide-web at the following URI:
* http://www.php.net/license/3_01.txt If you did not receive a copy of
* the PHP License and are unable to obtain it through the web, please
* send a note to license@php.net so we can mail you a copy immediately.
*
* @category HTML
* @package HTML_QuickForm
* @author Adam Daniel <adaniel1@eesus.jnj.com>
* @author Bertrand Mansion <bmansion@mamasam.com>
* @copyright 2001-2009 The PHP Group
* @license http://www.php.net/license/3_01.txt PHP License 3.01
* @version CVS: $Id: submit.php,v 1.6 2009/04/04 21:34:04 avb Exp $
* @link http://pear.php.net/package/HTML_QuickForm
*/
/**
* HTML class for a submit type element
*
* @category HTML
* @package HTML_QuickForm
* @author Adam Daniel <adaniel1@eesus.jnj.com>
* @author Bertrand Mansion <bmansion@mamasam.com>
* @version Release: 3.2.11
* @since 1.0
*/
class HTML_QuickForm_submit extends HTML_QuickForm_input
{
/**
* Class constructor
*
* @param string Input field name attribute
* @param string Input field value
* @param mixed Either a typical HTML attribute string or an associative array
* @since 1.0
* @access public
* @return void
*/
public function __construct($elementName=null, $value=null, $attributes=null)
{
parent::__construct($elementName, null, $attributes);
$this->setValue($value);
$this->setType('submit');
}
/**
* Freeze the element so that only its value is returned
*
* @access public
* @return void
*/
function freeze()
{
return false;
}
/**
* Only return the value if it is found within $submitValues (i.e. if
* this particular submit button was clicked)
*/
function exportValue(&$submitValues, $assoc = false)
{
return $this->_prepareValue($this->_findValue($submitValues), $assoc);
}
}

View File

@@ -0,0 +1,210 @@
<?php
/**
* HTML class for a text field
*
* PHP versions 4 and 5
*
* LICENSE: This source file is subject to version 3.01 of the PHP license
* that is available through the world-wide-web at the following URI:
* http://www.php.net/license/3_01.txt If you did not receive a copy of
* the PHP License and are unable to obtain it through the web, please
* send a note to license@php.net so we can mail you a copy immediately.
*
* @category HTML
* @package HTML_QuickForm
* @author Adam Daniel <adaniel1@eesus.jnj.com>
* @author Bertrand Mansion <bmansion@mamasam.com>
* @copyright 2001-2009 The PHP Group
* @license http://www.php.net/license/3_01.txt PHP License 3.01
* @version CVS: $Id: text.php,v 1.7 2009/04/04 21:34:04 avb Exp $
* @link http://pear.php.net/package/HTML_QuickForm
*/
/**
* HTML class for a text field
*
* @category HTML
* @package HTML_QuickForm
* @author Adam Daniel <adaniel1@eesus.jnj.com>
* @author Bertrand Mansion <bmansion@mamasam.com>
* @version Release: 3.2.11
* @since 1.0
*/
class HTML_QuickForm_text extends HTML_QuickForm_input
{
/**
* Class constructor
*
* @param string $elementName (optional)Input field name attribute
* @param string $elementLabel (optional)Input field label
* @param mixed $attributes (optional)Either a typical HTML attribute string
* or an associative array
* @since 1.0
* @access public
* @return void
*/
public function __construct(
$elementName = null,
$elementLabel = null,
$attributes = []
) {
if (is_string($attributes) && empty($attributes)) {
$attributes = [];
}
if (is_array($attributes) || empty($attributes)) {
$classFromAttributes = isset($attributes['class']) ? $attributes['class'] : '';
$attributes['class'] = $classFromAttributes.' form-control';
}
$inputSize = isset($attributes['input-size']) ? $attributes['input-size'] : null;
$this->setInputSize($inputSize);
$columnsSize = isset($attributes['cols-size']) ? $attributes['cols-size'] : null;
$this->setColumnsSize($columnsSize);
$icon = isset($attributes['icon']) ? $attributes['icon'] : null;
$this->setIcon($icon);
if (!empty($inputSize)) {
unset($attributes['input-size']);
}
if (!empty($icon)) {
unset($attributes['icon']);
}
parent::__construct($elementName, $elementLabel, $attributes);
$this->_persistantFreeze = true;
$this->setType('text');
}
/**
* Show an icon at the left side of an input
* @return string
*/
public function getIconToHtml()
{
$icon = $this->getIcon();
if (empty($icon)) {
return '';
}
return '<div class="input-group-addon">
<em class="fa fa-'.$icon.'"></em>
</div>';
}
/**
* @param string $layout
*
* @return string
*/
public function getTemplate($layout)
{
$size = $this->calculateSize();
$attributes = $this->getAttributes();
$template = '<label {label-for}>{label}</label>
<div class="input-group">
{icon}
{element}
</div>';
switch ($layout) {
case FormValidator::LAYOUT_GRID:
case FormValidator::LAYOUT_INLINE:
$template = '
<div class="form-group {error_class}">
<label {label-for} >
<!-- BEGIN required --><span class="form_required">*</span><!-- END required -->
{label}
</label>
{element}
<!-- BEGIN label_2 -->
<p class="help-block">{label_2}</p>
<!-- END label_2 -->
</div>';
break;
case FormValidator::LAYOUT_HORIZONTAL:
$template = '
<div class="form-group {error_class}">
<label {label-for} class="col-sm-'.$size[0].' control-label" >
<!-- BEGIN required --><span class="form_required">*</span><!-- END required -->
{label}
</label>
<div class="col-sm-'.$size[1].'">
{icon}
{element}
<!-- BEGIN label_2 -->
<p class="help-block">{label_2}</p>
<!-- END label_2 -->
<!-- BEGIN error -->
<span class="help-inline help-block">{error}</span>
<!-- END error -->
</div>
<div class="col-sm-'.$size[2].'">
<!-- BEGIN label_3 -->
{label_3}
<!-- END label_3 -->
</div>
</div>';
break;
case FormValidator::LAYOUT_BOX_NO_LABEL:
if (isset($attributes['custom']) && $attributes['custom'] == true) {
$template = '
<div class="input-group">
{icon}
{element}
<div class="input-group-btn">
<button class="btn btn-default" type="submit">
<em class="fa fa-search"></em>
</button>
</div>
</div>
';
}
break;
}
return $template;
}
/**
* Sets size of text field
*
* @param string $size Size of text field
* @since 1.3
* @access public
* @return void
*/
public function setSize($size)
{
$this->updateAttributes(array('size' => $size));
}
/**
* Sets maxlength of text field
*
* @param string $maxlength Maximum length of text field
* @since 1.3
* @access public
* @return void
*/
public function setMaxlength($maxlength)
{
$this->updateAttributes(array('maxlength' => $maxlength));
}
/**
* @return string
*/
public function toHtml()
{
if ($this->isFrozen()) {
return $this->getFrozenHtml();
}
return '<input '.$this->_getAttrString($this->_attributes).' />';
}
}

View File

@@ -0,0 +1,263 @@
<?php
/**
* HTML class for a textarea type field
*
* PHP versions 4 and 5
*
* LICENSE: This source file is subject to version 3.01 of the PHP license
* that is available through the world-wide-web at the following URI:
* http://www.php.net/license/3_01.txt If you did not receive a copy of
* the PHP License and are unable to obtain it through the web, please
* send a note to license@php.net so we can mail you a copy immediately.
*
* @category HTML
* @package HTML_QuickForm
* @author Adam Daniel <adaniel1@eesus.jnj.com>
* @author Bertrand Mansion <bmansion@mamasam.com>
* @copyright 2001-2009 The PHP Group
* @license http://www.php.net/license/3_01.txt PHP License 3.01
* @version CVS: $Id: textarea.php,v 1.13 2009/04/04 21:34:04 avb Exp $
* @link http://pear.php.net/package/HTML_QuickForm
*/
/**
* HTML class for a textarea type field
*
* @category HTML
* @package HTML_QuickForm
* @author Adam Daniel <adaniel1@eesus.jnj.com>
* @author Bertrand Mansion <bmansion@mamasam.com>
* @version Release: 3.2.11
* @since 1.0
*/
class HTML_QuickForm_textarea extends HTML_QuickForm_element
{
/**
* Field value
* @var string
* @since 1.0
* @access private
*/
public $_value;
/**
* Class constructor
*
* @param string $elementName Input field name attribute
* @param string|array $label Label(s) for a field
* @param mixed $attributes Either a typical HTML attribute string or an associative array
*/
public function __construct(
$elementName = null,
$label = null,
$attributes = null
) {
$attributes['class'] = isset($attributes['class']) ? $attributes['class'] : 'form-control';
$columnsSize = isset($attributes['cols-size']) ? $attributes['cols-size'] : null;
$this->setColumnsSize($columnsSize);
parent::__construct($elementName, $label, $attributes);
$id = $this->getAttribute('id');
if (empty($id)) {
$name = $this->getAttribute('name');
$this->setAttribute('id', uniqid($name.'_'));
}
$this->_persistantFreeze = true;
$this->_type = 'textarea';
$this->_value = null;
}
/**
* Sets the input field name
*
* @param string $name Input field name attribute
* @since 1.0
* @access public
* @return void
*/
public function setName($name)
{
$this->updateAttributes(array('name' => $name));
}
/**
* Returns the element name
*
* @since 1.0
* @access public
* @return string
*/
public function getName()
{
return $this->getAttribute('name');
}
/**
* Sets value for textarea element
*
* @param string $value Value for textarea element
* @since 1.0
* @access public
* @return void
*/
public function setValue($value)
{
$this->_value = $value;
}
/**
* Returns the value of the form element
*
* @since 1.0
* @access public
* @return string
*/
public function getValue()
{
return $this->_value;
}
/**
* Sets height in rows for textarea element
*
* @param string $rows Height expressed in rows
* @since 1.0
* @access public
* @return void
*/
public function setRows($rows)
{
$this->updateAttributes(array('rows' => $rows));
}
/**
* Sets width in cols for textarea element
*
* @param string $cols Width expressed in cols
* @since 1.0
* @access public
* @return void
*/
public function setCols($cols)
{
$this->updateAttributes(array('cols' => $cols));
}
/**
* Returns the textarea element in HTML
*
* @since 1.0
* @access public
* @return string
*/
public function toHtml()
{
if ($this->_flagFrozen) {
return $this->getFrozenHtml();
} else {
return $this->_getTabs().
'<textarea' . $this->_getAttrString($this->_attributes) . '>' .
// because we wrap the form later we don't want the text indented
// Modified by Ivan Tcholakov, 16-MAR-2010.
//preg_replace("/(\r\n|\n|\r)/", '&#010;', htmlspecialchars($this->_value)) .
preg_replace("/(\r\n|\n|\r)/", '&#010;', $this->getCleanValue()) .
//
'</textarea>';
}
}
/**
* Returns the value of field without HTML tags (in this case, value is changed to a mask)
*
* @since 1.0
* @access public
* @return string
*/
public function getFrozenHtml()
{
$value = $this->getCleanValue();
if ($this->getAttribute('wrap') == 'off') {
$html = $this->_getTabs() . '<pre>' . $value."</pre>\n";
} else {
$html = nl2br($value)."\n";
}
return $html . $this->_getPersistantData();
}
/**
* @param string $layout
*
* @return string
*/
public function getTemplate($layout)
{
$size = $this->getColumnsSize();
$this->removeAttribute('cols-size');
if (empty($size)) {
$size = [2, 8, 2];
}
switch ($layout) {
case FormValidator::LAYOUT_INLINE:
return '
<div class="form-group {error_class}">
<label {label-for} >
<!-- BEGIN required --><span class="form_required">*</span><!-- END required -->
{label}
</label>
{element}
</div>';
break;
case FormValidator::LAYOUT_HORIZONTAL:
return '
<div class="form-group {error_class}">
<label {label-for} class="col-sm-'.$size[0].' control-label" >
<!-- BEGIN required --><span class="form_required">*</span><!-- END required -->
{label}
</label>
<div class="col-sm-'.$size[1].'">
{icon}
{element}
<!-- BEGIN label_2 -->
<p class="help-block">{label_2}</p>
<!-- END label_2 -->
<!-- BEGIN error -->
<span class="help-inline help-block">{error}</span>
<!-- END error -->
</div>
<div class="col-sm-'.$size[2].'">
<!-- BEGIN label_3 -->
{label_3}
<!-- END label_3 -->
</div>
</div>';
break;
case FormValidator::LAYOUT_BOX_NO_LABEL:
return '
<label {label-for}>{label}</label>
<div class="input-group">
{icon}
{element}
</div>';
break;
case FormValidator::LAYOUT_GRID:
case FormValidator::LAYOUT_BOX:
return '
<label {label-for}>{label}</label>
<div class="input-group">
{label}
{icon}
{element}
</div>';
break;
}
}
}

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,916 @@
<?php
/**
* Storage class for HTML::Table data
*
* This class stores data for tables built with HTML_Table. When having
* more than one instance, it can be used for grouping the table into the
* parts <thead>...</thead>, <tfoot>...</tfoot> and <tbody>...</tbody>.
*
* PHP versions 4 and 5
*
* LICENSE:
*
* Copyright (c) 2005-2007, Adam Daniel <adaniel1@eesus.jnj.com>,
* Bertrand Mansion <bmansion@mamasam.com>,
* Mark Wiesemann <wiesemann@php.net>
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* * The names of the authors may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
* IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
* THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
* OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* @category HTML
* @package HTML_Table
* @author Adam Daniel <adaniel1@eesus.jnj.com>
* @author Bertrand Mansion <bmansion@mamasam.com>
* @license http://www.opensource.org/licenses/bsd-license.php New BSD License
* @version CVS: $Id: Storage.php,v 1.16 2007/04/29 16:31:06 wiesemann Exp $
* @link http://pear.php.net/package/HTML_Table
*/
/**
* Storage class for HTML::Table data
*
* This class stores data for tables built with HTML_Table. When having
* more than one instance, it can be used for grouping the table into the
* parts <thead>...</thead>, <tfoot>...</tfoot> and <tbody>...</tbody>.
*
* @category HTML
* @package HTML_Table
* @author Adam Daniel <adaniel1@eesus.jnj.com>
* @author Bertrand Mansion <bmansion@mamasam.com>
* @author Mark Wiesemann <wiesemann@php.net>
* @copyright 2005-2006 The PHP Group
* @license http://www.opensource.org/licenses/bsd-license.php New BSD License
* @version Release: @package_version@
* @link http://pear.php.net/package/HTML_Table
*/
class HTML_Table_Storage extends HTML_Common
{
/**
* Value to insert into empty cells
* @var string
* @access private
*/
var $_autoFill = '&nbsp;';
/**
* Automatically adds a new row or column if a given row or column index
* does not exist
* @var bool
* @access private
*/
var $_autoGrow = true;
/**
* Array containing the table structure
* @var array
* @access private
*/
var $_structure = array();
/**
* Number of rows composing in the table
* @var int
* @access private
*/
var $_rows = 0;
/**
* Number of column composing the table
* @var int
* @access private
*/
var $_cols = 0;
/**
* Tracks the level of nested tables
* @var int
* @access private
*/
var $_nestLevel = 0;
/**
* Whether to use <thead>, <tfoot> and <tbody> or not
* @var bool
* @access private
*/
var $_useTGroups = false;
/**
* Class constructor
* @param int $tabOffset
* @param bool $useTGroups Whether to use <thead>, <tfoot> and
* <tbody> or not
* @access public
*/
public function __construct($tabOffset = 0, $useTGroups = false)
{
parent::__construct(null, (int)$tabOffset);
$this->_useTGroups = (boolean)$useTGroups;
}
/**
* Sets the useTGroups value
* @param boolean $useTGroups
* @access public
*/
public function setUseTGroups($useTGroups)
{
$this->_useTGroups = $useTGroups;
}
/**
* Returns the useTGroups value
* @access public
* @return boolean
*/
public function getUseTGroups()
{
return $this->_useTGroups;
}
/**
* Sets the autoFill value
* @param mixed $fill
* @access public
*/
public function setAutoFill($fill)
{
$this->_autoFill = $fill;
}
/**
* Returns the autoFill value
* @access public
* @return mixed
*/
public function getAutoFill()
{
return $this->_autoFill;
}
/**
* Sets the autoGrow value
* @param bool $fill
* @access public
*/
public function setAutoGrow($grow)
{
$this->_autoGrow = $grow;
}
/**
* Returns the autoGrow value
* @access public
* @return mixed
*/
public function getAutoGrow()
{
return $this->_autoGrow;
}
/**
* Sets the number of rows in the table
* @param int $rows
* @access public
*/
function setRowCount($rows)
{
$this->_rows = $rows;
}
/**
* Sets the number of columns in the table
* @param int $cols
* @access public
*/
function setColCount($cols)
{
$this->_cols = $cols;
}
/**
* Returns the number of rows in the table
* @access public
* @return int
*/
function getRowCount()
{
return $this->_rows;
}
/**
* Gets the number of columns in the table
*
* If a row index is specified, the count will not take
* the spanned cells into account in the return value.
*
* @param int Row index to serve for cols count
* @access public
* @return int
*/
function getColCount($row = null)
{
if (!is_null($row)) {
$count = 0;
foreach ($this->_structure[$row] as $cell) {
if (is_array($cell)) {
$count++;
}
}
return $count;
}
return $this->_cols;
}
/**
* Sets a rows type 'TH' or 'TD'
* @param int $row Row index
* @param string $type 'TH' or 'TD'
* @access public
*/
function setRowType($row, $type)
{
for ($counter = 0; $counter < $this->_cols; $counter++) {
$this->_structure[$row][$counter]['type'] = $type;
}
}
/**
* Sets a columns type 'TH' or 'TD'
* @param int $col Column index
* @param string $type 'TH' or 'TD'
* @access public
*/
function setColType($col, $type)
{
for ($counter = 0; $counter < $this->_rows; $counter++) {
$this->_structure[$counter][$col]['type'] = $type;
}
}
/**
* Sets the cell attributes for an existing cell.
*
* If the given indices do not exist and autoGrow is true then the given
* row and/or col is automatically added. If autoGrow is false then an
* error is returned.
* @param int $row Row index
* @param int $col Column index
* @param mixed $attributes Associative array or string of table
* row attributes
* @access public
* @throws PEAR_Error
*/
function setCellAttributes($row, $col, $attributes)
{
if ( isset($this->_structure[$row][$col])
&& $this->_structure[$row][$col] == '__SPANNED__'
) {
return;
}
$attributes = $this->_parseAttributes($attributes);
$err = $this->_adjustEnds($row, $col, 'setCellAttributes', $attributes);
if (PEAR::isError($err)) {
return $err;
}
$this->_structure[$row][$col]['attr'] = $attributes;
// Fix use of rowspan/colspan
//$this->_updateSpanGrid($row, $col);
}
/**
* Updates the cell attributes passed but leaves other existing attributes
* intact
* @param int $row Row index
* @param int $col Column index
* @param mixed $attributes Associative array or string of table row
* attributes
* @access public
*/
function updateCellAttributes($row, $col, $attributes)
{
if ( isset($this->_structure[$row][$col])
&& $this->_structure[$row][$col] == '__SPANNED__'
) {
return;
}
$attributes = $this->_parseAttributes($attributes);
$err = $this->_adjustEnds($row, $col, 'updateCellAttributes', $attributes);
if (PEAR::isError($err)) {
return $err;
}
$this->_updateAttrArray($this->_structure[$row][$col]['attr'], $attributes);
//$this->_updateSpanGrid($row, $col);
}
/**
* Returns the attributes for a given cell
* @param int $row Row index
* @param int $col Column index
* @return array
* @access public
*/
function getCellAttributes($row, $col)
{
if ( isset($this->_structure[$row][$col])
&& $this->_structure[$row][$col] != '__SPANNED__'
) {
return $this->_structure[$row][$col]['attr'];
} elseif (!isset($this->_structure[$row][$col])) {
throw new \Exception('Invalid table cell reference[' .$row . '][' . $col . '] in HTML_Table::getCellAttributes');
}
}
/**
* Sets the cell contents for an existing cell
*
* If the given indices do not exist and autoGrow is true then the given
* row and/or col is automatically added. If autoGrow is false then an
* error is returned.
* @param int $row Row index
* @param int $col Column index
* @param mixed $contents May contain html or any object with a
* toHTML() method; if it is an array (with
* strings and/or objects), $col will be used
* as start offset and the array elements will
* be set to this and the following columns
* in $row
* @param string $type (optional) Cell type either 'TH' or 'TD'
* @access public
* @throws PEAR_Error
*/
function setCellContents($row, $col, $contents, $type = 'TD')
{
if (is_array($contents)) {
foreach ($contents as $singleContent) {
$ret = $this->_setSingleCellContents($row, $col, $singleContent,
$type);
if (PEAR::isError($ret)) {
return $ret;
}
$col++;
}
} else {
$ret = $this->_setSingleCellContents($row, $col, $contents, $type);
if (PEAR::isError($ret)) {
return $ret;
}
}
}
/**
* Sets the cell contents for a single existing cell
*
* If the given indices do not exist and autoGrow is true then the given
* row and/or col is automatically added. If autoGrow is false then an
* error is returned.
* @param int $row Row index
* @param int $col Column index
* @param mixed $contents May contain html or any object with a
* toHTML() method; if it is an array (with
* strings and/or objects), $col will be used
* as start offset and the array elements will
* be set to this and the following columns
* in $row
* @param string $type (optional) Cell type either 'TH' or 'TD'
* @access private
* @throws PEAR_Error
*/
function _setSingleCellContents($row, $col, $contents, $type = 'TD')
{
if ( isset($this->_structure[$row][$col])
&& $this->_structure[$row][$col] == '__SPANNED__'
) {
return;
}
$err = $this->_adjustEnds($row, $col, 'setCellContents');
if (PEAR::isError($err)) {
return $err;
}
$this->_structure[$row][$col]['contents'] = $contents;
$this->_structure[$row][$col]['type'] = $type;
}
/**
* Returns the cell contents for an existing cell
* @param int $row Row index
* @param int $col Column index
* @access public
* @return mixed
*/
function getCellContents($row, $col)
{
if ( isset($this->_structure[$row][$col])
&& $this->_structure[$row][$col] == '__SPANNED__'
) {
return;
}
if (!isset($this->_structure[$row][$col])) {
throw new \Exception('Invalid table cell reference[' .$row . '][' . $col . '] in HTML_Table::getCellContents');
}
return $this->_structure[$row][$col]['contents'];
}
/**
* Sets the contents of a header cell
* @param int $row
* @param int $col
* @param mixed $contents
* @param mixed $attributes Associative array or string of table row
* attributes
* @access public
*/
function setHeaderContents($row, $col, $contents, $attributes = null)
{
$this->setCellContents($row, $col, $contents, 'TH');
if (!is_null($attributes)) {
$this->updateCellAttributes($row, $col, $attributes);
}
}
/**
* Adds a table row and returns the row identifier
* @param array $contents (optional) Must be a indexed array of valid
* cell contents
* @param mixed $attributes (optional) Associative array or string of
* table row attributes. This can
* also be an array of attributes,
* in which case the attributes
* will be repeated in a loop.
* @param string $type (optional) Cell type either 'th' or 'td'
* @param bool $inTR false if attributes are to be
* applied in TD tags; true if
* attributes are to be applied in
* TR tag
* @return int
* @access public
*/
function addRow($contents = [], $attributes = null, $type = 'td',
$inTR = false)
{
if (isset($contents) && !is_array($contents)) {
throw new \Exception('First parameter to HTML_Table::addRow must be an array');
}
if (is_null($contents)) {
$contents = array();
}
$type = strtolower($type);
$row = $this->_rows++;
foreach ($contents as $col => $content) {
if ($type == 'td') {
$this->setCellContents($row, $col, $content);
} elseif ($type == 'th') {
$this->setHeaderContents($row, $col, $content);
}
}
$this->setRowAttributes($row, $attributes, $inTR);
return $row;
}
/**
* Sets the row attributes for an existing row
* @param int $row Row index
* @param mixed $attributes Associative array or string of table
* row attributes. This can also be an
* array of attributes, in which case the
* attributes will be repeated in a loop.
* @param bool $inTR false if attributes are to be applied
* in TD tags; true if attributes are to
* be applied in TR tag
* @access public
* @throws PEAR_Error
*/
function setRowAttributes($row, $attributes, $inTR = false)
{
if (!$inTR) {
$multiAttr = $this->_isAttributesArray($attributes);
for ($i = 0; $i < $this->_cols; $i++) {
if ($multiAttr) {
$this->setCellAttributes($row, $i,
$attributes[$i - ((ceil(($i + 1) / count($attributes))) - 1) * count($attributes)]);
} else {
$this->setCellAttributes($row, $i, $attributes);
}
}
} else {
$attributes = $this->_parseAttributes($attributes);
$err = $this->_adjustEnds($row, 0, 'setRowAttributes', $attributes);
if (PEAR::isError($err)) {
return $err;
}
$this->_structure[$row]['attr'] = $attributes;
}
}
/**
* Updates the row attributes for an existing row
* @param int $row Row index
* @param mixed $attributes Associative array or string of table
* row attributes
* @param bool $inTR false if attributes are to be applied
* in TD tags; true if attributes are to
* be applied in TR tag
* @access public
* @throws PEAR_Error
*/
function updateRowAttributes($row, $attributes = null, $inTR = false)
{
if (!$inTR) {
$multiAttr = $this->_isAttributesArray($attributes);
for ($i = 0; $i < $this->_cols; $i++) {
if ($multiAttr) {
$this->updateCellAttributes($row, $i,
$attributes[$i - ((ceil(($i + 1) / count($attributes))) - 1) * count($attributes)]);
} else {
$this->updateCellAttributes($row, $i, $attributes);
}
}
} else {
$attributes = $this->_parseAttributes($attributes);
$err = $this->_adjustEnds($row, 0, 'updateRowAttributes', $attributes);
if (PEAR::isError($err)) {
return $err;
}
$this->_updateAttrArray($this->_structure[$row]['attr'], $attributes);
}
}
/**
* Returns the attributes for a given row as contained in the TR tag
* @param int $row Row index
* @return array
* @access public
*/
function getRowAttributes($row)
{
if (isset($this->_structure[$row]['attr'])) {
return $this->_structure[$row]['attr'];
}
return;
}
/**
* Alternates the row attributes starting at $start
* @param int $start Row index of row in which alternating
* begins
* @param mixed $attributes1 Associative array or string of table
* row attributes
* @param mixed $attributes2 Associative array or string of table
* row attributes
* @param bool $inTR false if attributes are to be applied
* in TD tags; true if attributes are to
* be applied in TR tag
* @param int $firstAttributes (optional) Which attributes should be
* applied to the first row, 1 or 2.
* @access public
*/
function altRowAttributes($start, $attributes1, $attributes2, $inTR = false,
$firstAttributes = 1)
{
for ($row = $start; $row < $this->_rows; $row++) {
if (($row + $start + ($firstAttributes - 1)) % 2 == 0) {
$attributes = $attributes1;
} else {
$attributes = $attributes2;
}
$this->updateRowAttributes($row, $attributes, $inTR);
}
}
/**
* Adds a table column and returns the column identifier
* @param array $contents (optional) Must be a indexed array of valid
* cell contents
* @param mixed $attributes (optional) Associative array or string of
* table row attributes
* @param string $type (optional) Cell type either 'th' or 'td'
* @return int
* @access public
*/
function addCol($contents = null, $attributes = null, $type = 'td')
{
if (isset($contents) && !is_array($contents)) {
throw new \Exception('First parameter to HTML_Table::addCol must be an array');
}
if (is_null($contents)) {
$contents = array();
}
$type = strtolower($type);
$col = $this->_cols++;
foreach ($contents as $row => $content) {
if ($type == 'td') {
$this->setCellContents($row, $col, $content);
} elseif ($type == 'th') {
$this->setHeaderContents($row, $col, $content);
}
}
$this->setColAttributes($col, $attributes);
return $col;
}
/**
* Sets the column attributes for an existing column
* @param int $col Column index
* @param mixed $attributes (optional) Associative array or string
* of table row attributes
* @access public
*/
function setColAttributes($col, $attributes = null)
{
$multiAttr = $this->_isAttributesArray($attributes);
for ($i = 0; $i < $this->_rows; $i++) {
if ($multiAttr) {
$this->setCellAttributes($i, $col,
$attributes[$i - ((ceil(($i + 1) / count($attributes))) - 1) * count($attributes)]);
} else {
$this->setCellAttributes($i, $col, $attributes);
}
}
}
/**
* Updates the column attributes for an existing column
* @param int $col Column index
* @param mixed $attributes (optional) Associative array or string
* of table row attributes
* @access public
*/
function updateColAttributes($col, $attributes = null)
{
$multiAttr = $this->_isAttributesArray($attributes);
for ($i = 0; $i < $this->_rows; $i++) {
if ($multiAttr) {
$this->updateCellAttributes($i, $col,
$attributes[$i - ((ceil(($i + 1) / count($attributes))) - 1) * count($attributes)]);
} else {
$this->updateCellAttributes($i, $col, $attributes);
}
}
}
/**
* Sets the attributes for all cells
* @param mixed $attributes (optional) Associative array or
* string of table row attributes
* @access public
*/
function setAllAttributes($attributes = null)
{
for ($i = 0; $i < $this->_rows; $i++) {
$this->setRowAttributes($i, $attributes);
}
}
/**
* Updates the attributes for all cells
* @param mixed $attributes (optional) Associative array or
* string of table row attributes
* @access public
*/
function updateAllAttributes($attributes = null)
{
for ($i = 0; $i < $this->_rows; $i++) {
$this->updateRowAttributes($i, $attributes);
}
}
/**
* Returns the table rows as HTML
* @access public
* @return string
*/
function toHtml($tabs = null, $tab = null)
{
$strHtml = '';
if (is_null($tabs)) {
$tabs = $this->_getTabs();
}
if (is_null($tab)) {
$tab = $this->_getTab();
}
$lnEnd = $this->_getLineEnd();
if ($this->_useTGroups) {
$extraTab = $tab;
} else {
$extraTab = '';
}
if ($this->_cols > 0) {
for ($i = 0 ; $i < $this->_rows ; $i++) {
$attr = '';
if (isset($this->_structure[$i]['attr'])) {
$attr = $this->_getAttrString($this->_structure[$i]['attr']);
}
$strHtml .= $tabs .$tab . $extraTab . '<tr'.$attr.'>' . $lnEnd;
for ($j = 0 ; $j < $this->_cols ; $j++) {
$attr = '';
$contents = '';
$type = 'td';
if (isset($this->_structure[$i][$j]) && $this->_structure[$i][$j] == '__SPANNED__') {
continue;
}
if (isset($this->_structure[$i][$j]['type'])) {
$type = (strtolower($this->_structure[$i][$j]['type']) == 'th' ? 'th' : 'td');
}
if (isset($this->_structure[$i][$j]['attr'])) {
$attr = $this->_structure[$i][$j]['attr'];
}
if (isset($this->_structure[$i][$j]['contents'])) {
$contents = $this->_structure[$i][$j]['contents'];
}
if (is_object($contents)) {
// changes indent and line end settings on nested tables
if (is_subclass_of($contents, 'html_common')) {
$contents->setTab($tab . $extraTab);
$contents->setTabOffset($this->_tabOffset + 3);
$contents->_nestLevel = $this->_nestLevel + 1;
$contents->setLineEnd($this->_getLineEnd());
}
if (method_exists($contents, 'toHtml')) {
$contents = $contents->toHtml();
} elseif (method_exists($contents, 'toString')) {
$contents = $contents->toString();
}
}
if (is_array($contents)) {
$contents = implode(', ', $contents);
}
$typeContent = $tabs . $tab . $tab . $extraTab . "<$type" . $this->_getAttrString($attr) . '>';
if ($contents || is_numeric($contents)) {
$typeContent .= $contents;
} elseif (empty($contents)) {
if (isset($this->_autoFill) && $this->_autoFill) {
$contents = $this->_autoFill;
}
}
$typeContent .= "</$type>" . $lnEnd;
if (!empty($contents) || is_numeric($contents)) {
$strHtml .= $typeContent;
}
}
$strHtml .= $tabs . $tab . $extraTab . '</tr>' . $lnEnd;
}
}
return $strHtml;
}
function toArray($tabs = null, $tab = null)
{
$data = [];
if ($this->_cols > 0) {
for ($i = 0 ; $i < $this->_rows ; $i++) {
$item = [];
for ($j = 0 ; $j < $this->_cols ; $j++) {
$contents = '';
if (isset($this->_structure[$i][$j]) && $this->_structure[$i][$j] == '__SPANNED__') {
continue;
}
if (isset($this->_structure[$i][$j]['contents'])) {
$contents = $this->_structure[$i][$j]['contents'];
}
if (is_object($contents)) {
if (method_exists($contents, 'toHtml')) {
$contents = $contents->toHtml();
} elseif (method_exists($contents, 'toString')) {
$contents = $contents->toString();
}
$item = $contents;
}
if (is_array($contents)) {
$contents = implode(', ', $contents);
}
$item[] = $contents;
}
$data[] = $item;
}
}
return $data;
}
/**
* Checks if rows or columns are spanned
* @param int $row Row index
* @param int $col Column index
* @access private
*/
function _updateSpanGrid($row, $col)
{
if (isset($this->_structure[$row][$col]['attr']['colspan'])) {
$colspan = $this->_structure[$row][$col]['attr']['colspan'];
}
if (isset($this->_structure[$row][$col]['attr']['rowspan'])) {
$rowspan = $this->_structure[$row][$col]['attr']['rowspan'];
}
if (isset($colspan)) {
for ($j = $col + 1; (($j < $this->_cols) && ($j <= ($col + $colspan - 1))); $j++) {
$this->_structure[$row][$j] = '__SPANNED__';
}
}
if (isset($rowspan)) {
for ($i = $row + 1; (($i < $this->_rows) && ($i <= ($row + $rowspan - 1))); $i++) {
$this->_structure[$i][$col] = '__SPANNED__';
}
}
if (isset($colspan) && isset($rowspan)) {
for ($i = $row + 1; (($i < $this->_rows) && ($i <= ($row + $rowspan - 1))); $i++) {
for ($j = $col + 1; (($j <= $this->_cols) && ($j <= ($col + $colspan - 1))); $j++) {
$this->_structure[$i][$j] = '__SPANNED__';
}
}
}
}
/**
* Adjusts ends (total number of rows and columns)
* @param int $row Row index
* @param int $col Column index
* @param string $method Method name of caller
* Used to populate PEAR_Error if thrown.
* @param array $attributes Assoc array of attributes
* Default is an empty array.
* @access private
* @throws PEAR_Error
*/
function _adjustEnds($row, $col, $method, $attributes = array())
{
$colspan = isset($attributes['colspan']) ? $attributes['colspan'] : 1;
$rowspan = isset($attributes['rowspan']) ? $attributes['rowspan'] : 1;
if (!is_numeric($row) or !is_numeric($col)) {
//throw new Exception('Row or column index is not numerical');
return;
}
if (($row + $rowspan - 1) >= $this->_rows) {
if ($this->_autoGrow) {
$this->_rows = $row + $rowspan;
} else {
/*return PEAR::raiseError('Invalid table row reference[' .
$row . '] in HTML_Table::' . $method);*/
}
}
if (($col + $colspan - 1) >= $this->_cols) {
if ($this->_autoGrow) {
$this->_cols = $col + $colspan;
} else {
/*return PEAR::raiseError('Invalid table column reference[' .
$col . '] in HTML_Table::' . $method);*/
}
}
}
/**
* Tells if the parameter is an array of attribute arrays/strings
* @param mixed $attributes Variable to test
* @access private
* @return bool
*/
function _isAttributesArray($attributes)
{
if (is_array($attributes) && isset($attributes[0])) {
if (is_array($attributes[0]) || (is_string($attributes[0]) && count($attributes) > 1)) {
return true;
}
}
return false;
}
}
?>

View File

@@ -0,0 +1,6 @@
<html>
<head>
</head>
<body>
</body>
</html>

View File

@@ -0,0 +1,6 @@
<html>
<head>
</head>
<body>
</body>
</html>

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,26 @@
<?php
/**
* Exception for Image_Text
*
* PHP version 5
*
* @category Image
* @package Image_Text
* @author Daniel O'Connor <daniel.oconnor@gmail.com>
* @license http://www.php.net/license/3_01.txt PHP License
* @link http://pear.php.net/package/Image_Text
*/
/**
* Exception for Image_Text
*
* @category Image
* @package Image_Text
* @author Daniel O'Connor <daniel.oconnor@gmail.com>
* @author Michael Cramer <michael@bigmichi1.de>
* @license http://www.php.net/license/3_01.txt PHP License
* @link http://pear.php.net/package/Image_Text
*/
class Image_Text_Exception extends PEAR_Exception
{
}

View File

@@ -0,0 +1,226 @@
<?php
/* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4: */
/**
* Stream wrapper for reading data stored in an OLE file.
*
* PHP versions 4 and 5
*
* LICENSE: This source file is subject to version 3.0 of the PHP license
* that is available through the world-wide-web at the following URI:
* http://www.php.net/license/3_0.txt. If you did not receive a copy of
* the PHP License and are unable to obtain it through the web, please
* send a note to license@php.net so we can mail you a copy immediately.
*
* @category Structures
* @package OLE
* @author Christian Schmidt <schmidt@php.net>
* @license http://www.php.net/license/3_0.txt PHP License 3.0
* @version CVS: $Id: ChainedBlockStream.php,v 1.1 2007/02/13 21:00:42 schmidt Exp $
* @link http://pear.php.net/package/OLE
* @since File available since Release 0.6.0
*/
/**
* Stream wrapper for reading data stored in an OLE file. Implements methods
* for PHP's stream_wrapper_register(). For creating streams using this
* wrapper, use OLE_PPS_File::getStream().
*
* @category Structures
* @package OLE
* @author Christian Schmidt <schmidt@php.net>
* @license http://www.php.net/license/3_0.txt PHP License 3.0
* @version Release: @package_version@
* @link http://pear.php.net/package/OLE
* @since Class available since Release 0.6.0
*/
class OLE_ChainedBlockStream extends PEAR
{
/**
* The OLE container of the file that is being read.
* @var OLE
*/
var $ole;
/**
* Parameters specified by fopen().
* @var array
*/
var $params;
/**
* The binary data of the file.
* @var string
*/
var $data;
/**
* The file pointer.
* @var int byte offset
*/
var $pos;
/**
* Implements support for fopen().
* For creating streams using this wrapper, use OLE_PPS_File::getStream().
* @param string resource name including scheme, e.g.
* ole-chainedblockstream://oleInstanceId=1
* @param string only "r" is supported
* @param int mask of STREAM_REPORT_ERRORS and STREAM_USE_PATH
* @param string absolute path of the opened stream (out parameter)
* @return bool true on success
*/
function stream_open($path, $mode, $options, &$openedPath)
{
if ($mode != 'r') {
if ($options & STREAM_REPORT_ERRORS) {
trigger_error('Only reading is supported', E_USER_WARNING);
}
return false;
}
// 25 is length of "ole-chainedblockstream://"
parse_str(substr($path, 25), $this->params);
if (!isset($this->params['oleInstanceId'],
$this->params['blockId'],
$GLOBALS['_OLE_INSTANCES'][$this->params['oleInstanceId']])) {
if ($options & STREAM_REPORT_ERRORS) {
trigger_error('OLE stream not found', E_USER_WARNING);
}
return false;
}
$this->ole = $GLOBALS['_OLE_INSTANCES'][$this->params['oleInstanceId']];
$blockId = $this->params['blockId'];
$this->data = '';
if (isset($this->params['size']) &&
$this->params['size'] < $this->ole->bigBlockThreshold &&
$blockId != $this->ole->root->_StartBlock) {
// Block id refers to small blocks
$rootPos = $this->ole->_getBlockOffset($this->ole->root->_StartBlock);
while ($blockId != -2) {
$pos = $rootPos + $blockId * $this->ole->bigBlockSize;
$blockId = $this->ole->sbat[$blockId];
fseek($this->ole->_file_handle, $pos);
$this->data .= fread($this->ole->_file_handle, $this->ole->bigBlockSize);
}
} else {
// Block id refers to big blocks
while ($blockId != -2) {
$pos = $this->ole->_getBlockOffset($blockId);
fseek($this->ole->_file_handle, $pos);
$this->data .= fread($this->ole->_file_handle, $this->ole->bigBlockSize);
$blockId = $this->ole->bbat[$blockId];
}
}
if (isset($this->params['size'])) {
$this->data = substr($this->data, 0, $this->params['size']);
}
if ($options & STREAM_USE_PATH) {
$openedPath = $path;
}
return true;
}
/**
* Implements support for fclose().
* @return string
*/
function stream_close()
{
$this->ole = null;
unset($GLOBALS['_OLE_INSTANCES']);
}
/**
* Implements support for fread(), fgets() etc.
* @param int maximum number of bytes to read
* @return string
*/
function stream_read($count)
{
if ($this->stream_eof()) {
return false;
}
$s = substr($this->data, $this->pos, $count);
$this->pos += $count;
return $s;
}
/**
* Implements support for feof().
* @return bool TRUE if the file pointer is at EOF; otherwise FALSE
*/
function stream_eof()
{
$eof = $this->pos >= strlen($this->data);
// Workaround for bug in PHP 5.0.x: http://bugs.php.net/27508
if (version_compare(PHP_VERSION, '5.0', '>=') &&
version_compare(PHP_VERSION, '5.1', '<')) {
$eof = !$eof;
}
return $eof;
}
/**
* Returns the position of the file pointer, i.e. its offset into the file
* stream. Implements support for ftell().
* @return int
*/
function stream_tell()
{
return $this->pos;
}
/**
* Implements support for fseek().
* @param int byte offset
* @param int SEEK_SET, SEEK_CUR or SEEK_END
* @return bool
*/
function stream_seek($offset, $whence)
{
if ($whence == SEEK_SET && $offset >= 0) {
$this->pos = $offset;
} elseif ($whence == SEEK_CUR && -$offset <= $this->pos) {
$this->pos += $offset;
} elseif ($whence == SEEK_END && -$offset <= sizeof($this->data)) {
$this->pos = strlen($this->data) + $offset;
} else {
return false;
}
return true;
}
/**
* Implements support for fstat(). Currently the only supported field is
* "size".
* @return array
*/
function stream_stat()
{
return array(
'size' => strlen($this->data),
);
}
// Methods used by stream_wrapper_register() that are not implemented:
// bool stream_flush ( void )
// int stream_write ( string data )
// bool rename ( string path_from, string path_to )
// bool mkdir ( string path, int mode, int options )
// bool rmdir ( string path, int options )
// bool dir_opendir ( string path, int options )
// array url_stat ( string path, int flags )
// string dir_readdir ( void )
// bool dir_rewinddir ( void )
// bool dir_closedir ( void )
}
?>

View File

@@ -0,0 +1,568 @@
<?php
/* vim: set expandtab tabstop=4 shiftwidth=4: */
// +----------------------------------------------------------------------+
// | PHP Version 4 |
// +----------------------------------------------------------------------+
// | Copyright (c) 1997-2002 The PHP Group |
// +----------------------------------------------------------------------+
// | This source file is subject to version 2.02 of the PHP license, |
// | that is bundled with this package in the file LICENSE, and is |
// | available at through the world-wide-web at |
// | http://www.php.net/license/2_02.txt. |
// | If you did not receive a copy of the PHP license and are unable to |
// | obtain it through the world-wide-web, please send a note to |
// | license@php.net so we can mail you a copy immediately. |
// +----------------------------------------------------------------------+
// | Author: Xavier Noguer <xnoguer@php.net> |
// | Based on OLE::Storage_Lite by Kawai, Takanori |
// +----------------------------------------------------------------------+
//
// $Id: OLE.php,v 1.15 2007/12/18 20:59:11 schmidt Exp $
/**
* Constants for OLE package
*/
define('OLE_PPS_TYPE_ROOT', 5);
define('OLE_PPS_TYPE_DIR', 1);
define('OLE_PPS_TYPE_FILE', 2);
define('OLE_DATA_SIZE_SMALL', 0x1000);
define('OLE_LONG_INT_SIZE', 4);
define('OLE_PPS_SIZE', 0x80);
/**
* Array for storing OLE instances that are accessed from
* OLE_ChainedBlockStream::stream_open().
* @var array
*/
$GLOBALS['_OLE_INSTANCES'] = array();
/**
* OLE package base class.
*
* @category Structures
* @package OLE
* @author Xavier Noguer <xnoguer@php.net>
* @author Christian Schmidt <schmidt@php.net>
*/
class OLE extends PEAR
{
/**
* The file handle for reading an OLE container
* @var resource
*/
var $_file_handle;
/**
* Array of PPS's found on the OLE container
* @var array
*/
var $_list;
/**
* Root directory of OLE container
* @var OLE_PPS_Root
*/
var $root;
/**
* Big Block Allocation Table
* @var array (blockId => nextBlockId)
*/
var $bbat;
/**
* Short Block Allocation Table
* @var array (blockId => nextBlockId)
*/
var $sbat;
/**
* Size of big blocks. This is usually 512.
* @var int number of octets per block.
*/
var $bigBlockSize;
/**
* Size of small blocks. This is usually 64.
* @var int number of octets per block
*/
var $smallBlockSize;
/**
* Creates a new OLE object
* @access public
*/
function OLE()
{
$this->_list = array();
}
/**
* Destructor (using PEAR)
* Just closes the file handle on the OLE file.
*
* @access private
*/
function _OLE()
{
fclose($this->_file_handle);
}
/**
* Reads an OLE container from the contents of the file given.
*
* @access public
* @param string $file
* @return mixed true on success, PEAR_Error on failure
*/
function read($file)
{
$fh = @fopen($file, "r");
if (!$fh) {
return $this->raiseError("Can't open file $file");
}
$this->_file_handle = $fh;
$signature = fread($fh, 8);
if ("\xD0\xCF\x11\xE0\xA1\xB1\x1A\xE1" != $signature) {
return $this->raiseError("File doesn't seem to be an OLE container.");
}
fseek($fh, 28);
if (fread($fh, 2) != "\xFE\xFF") {
// This shouldn't be a problem in practice
return $this->raiseError("Only Little-Endian encoding is supported.");
}
// Size of blocks and short blocks in bytes
$this->bigBlockSize = pow(2, $this->_readInt2($fh));
$this->smallBlockSize = pow(2, $this->_readInt2($fh));
// Skip UID, revision number and version number
fseek($fh, 44);
// Number of blocks in Big Block Allocation Table
$bbatBlockCount = $this->_readInt4($fh);
// Root chain 1st block
$directoryFirstBlockId = $this->_readInt4($fh);
// Skip unused bytes
fseek($fh, 56);
// Streams shorter than this are stored using small blocks
$this->bigBlockThreshold = $this->_readInt4($fh);
// Block id of first sector in Short Block Allocation Table
$sbatFirstBlockId = $this->_readInt4($fh);
// Number of blocks in Short Block Allocation Table
$sbbatBlockCount = $this->_readInt4($fh);
// Block id of first sector in Master Block Allocation Table
$mbatFirstBlockId = $this->_readInt4($fh);
// Number of blocks in Master Block Allocation Table
$mbbatBlockCount = $this->_readInt4($fh);
$this->bbat = array();
// Remaining 4 * 109 bytes of current block is beginning of Master
// Block Allocation Table
$mbatBlocks = array();
for ($i = 0; $i < 109; $i++) {
$mbatBlocks[] = $this->_readInt4($fh);
}
// Read rest of Master Block Allocation Table (if any is left)
$pos = $this->_getBlockOffset($mbatFirstBlockId);
for ($i = 0; $i < $mbbatBlockCount; $i++) {
fseek($fh, $pos);
for ($j = 0; $j < $this->bigBlockSize / 4 - 1; $j++) {
$mbatBlocks[] = $this->_readInt4($fh);
}
// Last block id in each block points to next block
$pos = $this->_getBlockOffset($this->_readInt4($fh));
}
// Read Big Block Allocation Table according to chain specified by
// $mbatBlocks
for ($i = 0; $i < $bbatBlockCount; $i++) {
$pos = $this->_getBlockOffset($mbatBlocks[$i]);
fseek($fh, $pos);
for ($j = 0 ; $j < $this->bigBlockSize / 4; $j++) {
$this->bbat[] = $this->_readInt4($fh);
}
}
// Read short block allocation table (SBAT)
$this->sbat = array();
$shortBlockCount = $sbbatBlockCount * $this->bigBlockSize / 4;
$sbatFh = $this->getStream($sbatFirstBlockId);
for ($blockId = 0; $blockId < $shortBlockCount; $blockId++) {
$this->sbat[$blockId] = $this->_readInt4($sbatFh);
}
fclose($sbatFh);
$this->_readPpsWks($directoryFirstBlockId);
return true;
}
/**
* @param int $blockId block id
* @return int byte offset from beginning of file
* @access private
*/
function _getBlockOffset($blockId)
{
return 512 + $blockId * $this->bigBlockSize;
}
/**
* Returns a stream for use with fread() etc. External callers should
* use OLE_PPS_File::getStream().
* @param int|PPS $blockIdOrPps block id or PPS
* @return resource read-only stream
*/
function getStream($blockIdOrPps)
{
include_once 'OLE/ChainedBlockStream.php';
static $isRegistered = false;
if (!$isRegistered) {
stream_wrapper_register('ole-chainedblockstream',
'OLE_ChainedBlockStream');
$isRegistered = true;
}
// Store current instance in global array, so that it can be accessed
// in OLE_ChainedBlockStream::stream_open().
// Object is removed from self::$instances in OLE_Stream::close().
$GLOBALS['_OLE_INSTANCES'][] = $this;
$instanceId = end(array_keys($GLOBALS['_OLE_INSTANCES']));
$path = 'ole-chainedblockstream://oleInstanceId=' . $instanceId;
if (is_a($blockIdOrPps, 'OLE_PPS')) {
$path .= '&blockId=' . $blockIdOrPps->_StartBlock;
$path .= '&size=' . $blockIdOrPps->Size;
} else {
$path .= '&blockId=' . $blockIdOrPps;
}
return fopen($path, 'r');
}
/**
* Reads a signed char.
* @param resource $fh file handle
* @return int
* @access private
*/
function _readInt1($fh)
{
list(, $tmp) = unpack("c", fread($fh, 1));
return $tmp;
}
/**
* Reads an unsigned short (2 octets).
* @param resource $fh file handle
* @return int
* @access private
*/
function _readInt2($fh)
{
list(, $tmp) = unpack("v", fread($fh, 2));
return $tmp;
}
/**
* Reads an unsigned long (4 octets).
* @param resource file handle
* @return int
* @access private
*/
function _readInt4($fh)
{
list(, $tmp) = unpack("V", fread($fh, 4));
return $tmp;
}
/**
* Gets information about all PPS's on the OLE container from the PPS WK's
* creates an OLE_PPS object for each one.
*
* @access private
* @param integer $blockId the block id of the first block
* @return mixed true on success, PEAR_Error on failure
*/
function _readPpsWks($blockId)
{
$fh = $this->getStream($blockId);
for ($pos = 0; ; $pos += 128) {
fseek($fh, $pos, SEEK_SET);
$nameUtf16 = fread($fh, 64);
$nameLength = $this->_readInt2($fh);
$nameUtf16 = substr($nameUtf16, 0, $nameLength - 2);
// Simple conversion from UTF-16LE to ISO-8859-1
$name = str_replace("\x00", "", $nameUtf16);
$type = $this->_readInt1($fh);
switch ($type) {
case OLE_PPS_TYPE_ROOT:
require_once 'OLE/PPS/Root.php';
$pps = new OLE_PPS_Root(null, null, array());
$this->root = $pps;
break;
case OLE_PPS_TYPE_DIR:
$pps = new OLE_PPS(null, null, null, null, null,
null, null, null, null, array());
break;
case OLE_PPS_TYPE_FILE:
require_once 'OLE/PPS/File.php';
$pps = new OLE_PPS_File($name);
break;
default:
continue;
}
fseek($fh, 1, SEEK_CUR);
$pps->Type = $type;
$pps->Name = $name;
$pps->PrevPps = $this->_readInt4($fh);
$pps->NextPps = $this->_readInt4($fh);
$pps->DirPps = $this->_readInt4($fh);
fseek($fh, 20, SEEK_CUR);
$pps->Time1st = OLE::OLE2LocalDate(fread($fh, 8));
$pps->Time2nd = OLE::OLE2LocalDate(fread($fh, 8));
$pps->_StartBlock = $this->_readInt4($fh);
$pps->Size = $this->_readInt4($fh);
$pps->No = count($this->_list);
$this->_list[] = $pps;
// check if the PPS tree (starting from root) is complete
if (isset($this->root) &&
$this->_ppsTreeComplete($this->root->No)) {
break;
}
}
fclose($fh);
// Initialize $pps->children on directories
foreach ($this->_list as $pps) {
if ($pps->Type == OLE_PPS_TYPE_DIR || $pps->Type == OLE_PPS_TYPE_ROOT) {
$nos = array($pps->DirPps);
$pps->children = array();
while ($nos) {
$no = array_pop($nos);
if ($no != -1) {
$childPps = $this->_list[$no];
$nos[] = $childPps->PrevPps;
$nos[] = $childPps->NextPps;
$pps->children[] = $childPps;
}
}
}
}
return true;
}
/**
* It checks whether the PPS tree is complete (all PPS's read)
* starting with the given PPS (not necessarily root)
*
* @access private
* @param integer $index The index of the PPS from which we are checking
* @return boolean Whether the PPS tree for the given PPS is complete
*/
function _ppsTreeComplete($index)
{
return isset($this->_list[$index]) &&
($pps = $this->_list[$index]) &&
($pps->PrevPps == -1 ||
$this->_ppsTreeComplete($pps->PrevPps)) &&
($pps->NextPps == -1 ||
$this->_ppsTreeComplete($pps->NextPps)) &&
($pps->DirPps == -1 ||
$this->_ppsTreeComplete($pps->DirPps));
}
/**
* Checks whether a PPS is a File PPS or not.
* If there is no PPS for the index given, it will return false.
* @param integer $index The index for the PPS
* @return bool true if it's a File PPS, false otherwise
* @access public
*/
function isFile($index)
{
if (isset($this->_list[$index])) {
return ($this->_list[$index]->Type == OLE_PPS_TYPE_FILE);
}
return false;
}
/**
* Checks whether a PPS is a Root PPS or not.
* If there is no PPS for the index given, it will return false.
* @param integer $index The index for the PPS.
* @return bool true if it's a Root PPS, false otherwise
* @access public
*/
function isRoot($index)
{
if (isset($this->_list[$index])) {
return ($this->_list[$index]->Type == OLE_PPS_TYPE_ROOT);
}
return false;
}
/**
* Gives the total number of PPS's found in the OLE container.
* @return integer The total number of PPS's found in the OLE container
* @access public
*/
function ppsTotal()
{
return count($this->_list);
}
/**
* Gets data from a PPS
* If there is no PPS for the index given, it will return an empty string.
* @param integer $index The index for the PPS
* @param integer $position The position from which to start reading
* (relative to the PPS)
* @param integer $length The amount of bytes to read (at most)
* @return string The binary string containing the data requested
* @access public
* @see OLE_PPS_File::getStream()
*/
function getData($index, $position, $length)
{
// if position is not valid return empty string
if (!isset($this->_list[$index]) ||
$position >= $this->_list[$index]->Size ||
$position < 0) {
return '';
}
$fh = $this->getStream($this->_list[$index]);
$data = stream_get_contents($fh, $length, $position);
fclose($fh);
return $data;
}
/**
* Gets the data length from a PPS
* If there is no PPS for the index given, it will return 0.
* @param integer $index The index for the PPS
* @return integer The amount of bytes in data the PPS has
* @access public
*/
function getDataLength($index)
{
if (isset($this->_list[$index])) {
return $this->_list[$index]->Size;
}
return 0;
}
/**
* Utility function to transform ASCII text to Unicode
*
* @access public
* @static
* @param string $ascii The ASCII string to transform
* @return string The string in Unicode
*/
function Asc2Ucs($ascii)
{
$rawname = '';
for ($i = 0; $i < strlen($ascii); $i++) {
$rawname .= $ascii{$i} . "\x00";
}
return $rawname;
}
/**
* Utility function
* Returns a string for the OLE container with the date given
*
* @access public
* @static
* @param integer $date A timestamp
* @return string The string for the OLE container
*/
function LocalDate2OLE($date = null)
{
if (!isset($date)) {
return "\x00\x00\x00\x00\x00\x00\x00\x00";
}
// factor used for separating numbers into 4 bytes parts
$factor = pow(2, 32);
// days from 1-1-1601 until the beggining of UNIX era
$days = 134774;
// calculate seconds
$big_date = $days * 24 * 3600 +
gmmktime(date("H",$date),date("i",$date),date("s",$date),
date("m",$date),date("d",$date),date("Y",$date));
// multiply just to make MS happy
$big_date *= 10000000;
$high_part = floor($big_date / $factor);
// lower 4 bytes
$low_part = floor((($big_date / $factor) - $high_part) * $factor);
// Make HEX string
$res = '';
for ($i = 0; $i < 4; $i++) {
$hex = $low_part % 0x100;
$res .= pack('c', $hex);
$low_part /= 0x100;
}
for ($i = 0; $i < 4; $i++) {
$hex = $high_part % 0x100;
$res .= pack('c', $hex);
$high_part /= 0x100;
}
return $res;
}
/**
* Returns a timestamp from an OLE container's date
* @param integer $string A binary string with the encoded date
* @return string The timestamp corresponding to the string
* @access public
* @static
*/
function OLE2LocalDate($string)
{
if (strlen($string) != 8) {
return new PEAR_Error("Expecting 8 byte string");
}
// factor used for separating numbers into 4 bytes parts
$factor = pow(2,32);
$high_part = 0;
for ($i = 0; $i < 4; $i++) {
list(, $high_part) = unpack('C', $string{(7 - $i)});
if ($i < 3) {
$high_part *= 0x100;
}
}
$low_part = 0;
for ($i = 4; $i < 8; $i++) {
list(, $low_part) = unpack('C', $string{(7 - $i)});
if ($i < 7) {
$low_part *= 0x100;
}
}
$big_date = ($high_part * $factor) + $low_part;
// translate to seconds
$big_date /= 10000000;
// days from 1-1-1601 until the beggining of UNIX era
$days = 134774;
// translate to seconds from beggining of UNIX era
$big_date -= $days * 24 * 3600;
return floor($big_date);
}
}
?>

View File

@@ -0,0 +1,222 @@
<?php
/* vim: set expandtab tabstop=4 shiftwidth=4: */
// +----------------------------------------------------------------------+
// | PHP Version 4 |
// +----------------------------------------------------------------------+
// | Copyright (c) 1997-2002 The PHP Group |
// +----------------------------------------------------------------------+
// | This source file is subject to version 2.02 of the PHP license, |
// | that is bundled with this package in the file LICENSE, and is |
// | available at through the world-wide-web at |
// | http://www.php.net/license/2_02.txt. |
// | If you did not receive a copy of the PHP license and are unable to |
// | obtain it through the world-wide-web, please send a note to |
// | license@php.net so we can mail you a copy immediately. |
// +----------------------------------------------------------------------+
// | Author: Xavier Noguer <xnoguer@php.net> |
// | Based on OLE::Storage_Lite by Kawai, Takanori |
// +----------------------------------------------------------------------+
//
// $Id: PPS.php,v 1.7 2007/02/13 21:00:42 schmidt Exp $
require_once 'PEAR.php';
require_once 'OLE.php';
/**
* Class for creating PPS's for OLE containers
*
* @author Xavier Noguer <xnoguer@php.net>
* @category Structures
* @package OLE
*/
class OLE_PPS extends PEAR
{
/**
* The PPS index
* @var integer
*/
var $No;
/**
* The PPS name (in Unicode)
* @var string
*/
var $Name;
/**
* The PPS type. Dir, Root or File
* @var integer
*/
var $Type;
/**
* The index of the previous PPS
* @var integer
*/
var $PrevPps;
/**
* The index of the next PPS
* @var integer
*/
var $NextPps;
/**
* The index of it's first child if this is a Dir or Root PPS
* @var integer
*/
var $DirPps;
/**
* A timestamp
* @var integer
*/
var $Time1st;
/**
* A timestamp
* @var integer
*/
var $Time2nd;
/**
* Starting block (small or big) for this PPS's data inside the container
* @var integer
*/
var $_StartBlock;
/**
* The size of the PPS's data (in bytes)
* @var integer
*/
var $Size;
/**
* The PPS's data (only used if it's not using a temporary file)
* @var string
*/
var $_data;
/**
* Array of child PPS's (only used by Root and Dir PPS's)
* @var array
*/
var $children = array();
/**
* Pointer to OLE container
* @var OLE
*/
var $ole;
/**
* The constructor
*
* @access public
* @param integer $No The PPS index
* @param string $name The PPS name
* @param integer $type The PPS type. Dir, Root or File
* @param integer $prev The index of the previous PPS
* @param integer $next The index of the next PPS
* @param integer $dir The index of it's first child if this is a Dir or Root PPS
* @param integer $time_1st A timestamp
* @param integer $time_2nd A timestamp
* @param string $data The (usually binary) source data of the PPS
* @param array $children Array containing children PPS for this PPS
*/
function OLE_PPS($No, $name, $type, $prev, $next, $dir, $time_1st, $time_2nd, $data, $children)
{
$this->No = $No;
$this->Name = $name;
$this->Type = $type;
$this->PrevPps = $prev;
$this->NextPps = $next;
$this->DirPps = $dir;
$this->Time1st = $time_1st;
$this->Time2nd = $time_2nd;
$this->_data = $data;
$this->children = $children;
if ($data != '') {
$this->Size = strlen($data);
} else {
$this->Size = 0;
}
}
/**
* Returns the amount of data saved for this PPS
*
* @access private
* @return integer The amount of data (in bytes)
*/
function _DataLen()
{
if (!isset($this->_data)) {
return 0;
}
if (isset($this->_PPS_FILE)) {
fseek($this->_PPS_FILE, 0);
$stats = fstat($this->_PPS_FILE);
return $stats[7];
} else {
return strlen($this->_data);
}
}
/**
* Returns a string with the PPS's WK (What is a WK?)
*
* @access private
* @return string The binary string
*/
function _getPpsWk()
{
$ret = $this->Name;
for ($i = 0; $i < (64 - strlen($this->Name)); $i++) {
$ret .= "\x00";
}
$ret .= pack("v", strlen($this->Name) + 2) // 66
. pack("c", $this->Type) // 67
. pack("c", 0x00) //UK // 68
. pack("V", $this->PrevPps) //Prev // 72
. pack("V", $this->NextPps) //Next // 76
. pack("V", $this->DirPps) //Dir // 80
. "\x00\x09\x02\x00" // 84
. "\x00\x00\x00\x00" // 88
. "\xc0\x00\x00\x00" // 92
. "\x00\x00\x00\x46" // 96 // Seems to be ok only for Root
. "\x00\x00\x00\x00" // 100
. OLE::LocalDate2OLE($this->Time1st) // 108
. OLE::LocalDate2OLE($this->Time2nd) // 116
. pack("V", isset($this->_StartBlock)?
$this->_StartBlock:0) // 120
. pack("V", $this->Size) // 124
. pack("V", 0); // 128
return $ret;
}
/**
* Updates index and pointers to previous, next and children PPS's for this
* PPS. I don't think it'll work with Dir PPS's.
*
* @access private
* @param array &$pps_array Reference to the array of PPS's for the whole OLE
* container
* @return integer The index for this PPS
*/
function _savePpsSetPnt(&$pps_array)
{
$pps_array[count($pps_array)] = &$this;
$this->No = count($pps_array) - 1;
$this->PrevPps = 0xFFFFFFFF;
$this->NextPps = 0xFFFFFFFF;
if (count($this->children) > 0) {
$this->DirPps = $this->children[0]->_savePpsSetPnt($pps_array);
} else {
$this->DirPps = 0xFFFFFFFF;
}
return $this->No;
}
}
?>

View File

@@ -0,0 +1,122 @@
<?php
/* vim: set expandtab tabstop=4 shiftwidth=4: */
// +----------------------------------------------------------------------+
// | PHP Version 4 |
// +----------------------------------------------------------------------+
// | Copyright (c) 1997-2002 The PHP Group |
// +----------------------------------------------------------------------+
// | This source file is subject to version 2.02 of the PHP license, |
// | that is bundled with this package in the file LICENSE, and is |
// | available at through the world-wide-web at |
// | http://www.php.net/license/2_02.txt. |
// | If you did not receive a copy of the PHP license and are unable to |
// | obtain it through the world-wide-web, please send a note to |
// | license@php.net so we can mail you a copy immediately. |
// +----------------------------------------------------------------------+
// | Author: Xavier Noguer <xnoguer@php.net> |
// | Based on OLE::Storage_Lite by Kawai, Takanori |
// +----------------------------------------------------------------------+
//
// $Id: File.php,v 1.11 2007/02/13 21:00:42 schmidt Exp $
/**
* Class for creating File PPS's for OLE containers
*
* @author Xavier Noguer <xnoguer@php.net>
* @category Structures
* @package OLE
*/
class OLE_PPS_File extends OLE_PPS
{
/**
* The temporary dir for storing the OLE file
* @var string
*/
var $_tmp_dir;
/**
* The constructor
*
* @access public
* @param string $name The name of the file (in Unicode)
* @see OLE::Asc2Ucs()
*/
function OLE_PPS_File($name)
{
$this->_tmp_dir = '';
$this->OLE_PPS(
null,
$name,
OLE_PPS_TYPE_FILE,
null,
null,
null,
null,
null,
'',
array());
}
/**
* Sets the temp dir used for storing the OLE file
*
* @access public
* @param string $dir The dir to be used as temp dir
* @return true if given dir is valid, false otherwise
*/
function setTempDir($dir)
{
if (is_dir($dir)) {
$this->_tmp_dir = $dir;
return true;
}
return false;
}
/**
* Initialization method. Has to be called right after OLE_PPS_File().
*
* @access public
* @return mixed true on success. PEAR_Error on failure
*/
function init()
{
$this->_tmp_filename = tempnam($this->_tmp_dir, "OLE_PPS_File");
$fh = @fopen($this->_tmp_filename, "w+b");
if ($fh == false) {
return $this->raiseError("Can't create temporary file");
}
$this->_PPS_FILE = $fh;
if ($this->_PPS_FILE) {
fseek($this->_PPS_FILE, 0);
}
return true;
}
/**
* Append data to PPS
*
* @access public
* @param string $data The data to append
*/
function append($data)
{
if ($this->_PPS_FILE) {
fwrite($this->_PPS_FILE, $data);
} else {
$this->_data .= $data;
}
}
/**
* Returns a stream for reading this file using fread() etc.
* @return resource a read-only stream
*/
function getStream()
{
$this->ole->getStream($this);
}
}
?>

View File

@@ -0,0 +1,485 @@
<?php
/* vim: set expandtab tabstop=4 shiftwidth=4: */
// +----------------------------------------------------------------------+
// | PHP Version 4 |
// +----------------------------------------------------------------------+
// | Copyright (c) 1997-2002 The PHP Group |
// +----------------------------------------------------------------------+
// | This source file is subject to version 2.02 of the PHP license, |
// | that is bundled with this package in the file LICENSE, and is |
// | available at through the world-wide-web at |
// | http://www.php.net/license/2_02.txt. |
// | If you did not receive a copy of the PHP license and are unable to |
// | obtain it through the world-wide-web, please send a note to |
// | license@php.net so we can mail you a copy immediately. |
// +----------------------------------------------------------------------+
// | Author: Xavier Noguer <xnoguer@php.net> |
// | Based on OLE::Storage_Lite by Kawai, Takanori |
// +----------------------------------------------------------------------+
//
// $Id: Root.php,v 1.9 2005/04/23 21:53:49 dufuz Exp $
require_once __DIR__.'/../PPS.php';
/**
* Class for creating Root PPS's for OLE containers
*
* @author Xavier Noguer <xnoguer@php.net>
* @category Structures
* @package OLE
*/
class OLE_PPS_Root extends OLE_PPS
{
/**
* The temporary dir for storing the OLE file
* @var string
*/
var $_tmp_dir;
/**
* Constructor
*
* @access public
* @param integer $time_1st A timestamp
* @param integer $time_2nd A timestamp
*/
function OLE_PPS_Root($time_1st, $time_2nd, $raChild)
{
$this->_tmp_dir = '';
$this->OLE_PPS(
null,
OLE::Asc2Ucs('Root Entry'),
OLE_PPS_TYPE_ROOT,
null,
null,
null,
$time_1st,
$time_2nd,
null,
$raChild);
}
/**
* Sets the temp dir used for storing the OLE file
*
* @access public
* @param string $dir The dir to be used as temp dir
* @return true if given dir is valid, false otherwise
*/
function setTempDir($dir)
{
if (is_dir($dir)) {
$this->_tmp_dir = $dir;
return true;
}
return false;
}
/**
* Method for saving the whole OLE container (including files).
* In fact, if called with an empty argument (or '-'), it saves to a
* temporary file and then outputs it's contents to stdout.
*
* @param string $filename The name of the file where to save the OLE container
* @access public
* @return mixed true on success, PEAR_Error on failure
*/
function save($filename)
{
// Initial Setting for saving
$this->_BIG_BLOCK_SIZE = pow(2,
((isset($this->_BIG_BLOCK_SIZE))? $this->_adjust2($this->_BIG_BLOCK_SIZE) : 9));
$this->_SMALL_BLOCK_SIZE= pow(2,
((isset($this->_SMALL_BLOCK_SIZE))? $this->_adjust2($this->_SMALL_BLOCK_SIZE): 6));
// Open temp file if we are sending output to stdout
if (($filename == '-') || ($filename == '')) {
$this->_tmp_filename = tempnam($this->_tmp_dir, "OLE_PPS_Root");
$this->_FILEH_ = @fopen($this->_tmp_filename,"w+b");
if ($this->_FILEH_ == false) {
return $this->raiseError("Can't create temporary file.");
}
} else {
$this->_FILEH_ = @fopen($filename, "wb");
if ($this->_FILEH_ == false) {
return $this->raiseError("Can't open $filename. It may be in use or protected.");
}
}
// Make an array of PPS's (for Save)
$aList = array();
$this->_savePpsSetPnt($aList);
// calculate values for header
list($iSBDcnt, $iBBcnt, $iPPScnt) = $this->_calcSize($aList); //, $rhInfo);
// Save Header
$this->_saveHeader($iSBDcnt, $iBBcnt, $iPPScnt);
// Make Small Data string (write SBD)
$this->_data = $this->_makeSmallData($aList);
// Write BB
$this->_saveBigData($iSBDcnt, $aList);
// Write PPS
$this->_savePps($aList);
// Write Big Block Depot and BDList and Adding Header informations
$this->_saveBbd($iSBDcnt, $iBBcnt, $iPPScnt);
// Close File, send it to stdout if necessary
if (($filename == '-') || ($filename == '')) {
fseek($this->_FILEH_, 0);
fpassthru($this->_FILEH_);
@fclose($this->_FILEH_);
// Delete the temporary file.
@unlink($this->_tmp_filename);
} else {
@fclose($this->_FILEH_);
}
return true;
}
/**
* Calculate some numbers
*
* @access private
* @param array $raList Reference to an array of PPS's
* @return array The array of numbers
*/
function _calcSize(&$raList)
{
// Calculate Basic Setting
list($iSBDcnt, $iBBcnt, $iPPScnt) = array(0,0,0);
$iSmallLen = 0;
$iSBcnt = 0;
for ($i = 0; $i < count($raList); $i++) {
if ($raList[$i]->Type == OLE_PPS_TYPE_FILE) {
$raList[$i]->Size = $raList[$i]->_DataLen();
if ($raList[$i]->Size < OLE_DATA_SIZE_SMALL) {
$iSBcnt += floor($raList[$i]->Size / $this->_SMALL_BLOCK_SIZE)
+ (($raList[$i]->Size % $this->_SMALL_BLOCK_SIZE)? 1: 0);
} else {
$iBBcnt += (floor($raList[$i]->Size / $this->_BIG_BLOCK_SIZE) +
(($raList[$i]->Size % $this->_BIG_BLOCK_SIZE)? 1: 0));
}
}
}
$iSmallLen = $iSBcnt * $this->_SMALL_BLOCK_SIZE;
$iSlCnt = floor($this->_BIG_BLOCK_SIZE / OLE_LONG_INT_SIZE);
$iSBDcnt = floor($iSBcnt / $iSlCnt) + (($iSBcnt % $iSlCnt)? 1:0);
$iBBcnt += (floor($iSmallLen / $this->_BIG_BLOCK_SIZE) +
(( $iSmallLen % $this->_BIG_BLOCK_SIZE)? 1: 0));
$iCnt = count($raList);
$iBdCnt = $this->_BIG_BLOCK_SIZE / OLE_PPS_SIZE;
$iPPScnt = (floor($iCnt/$iBdCnt) + (($iCnt % $iBdCnt)? 1: 0));
return array($iSBDcnt, $iBBcnt, $iPPScnt);
}
/**
* Helper function for caculating a magic value for block sizes
*
* @access private
* @param integer $i2 The argument
* @see save()
* @return integer
*/
function _adjust2($i2)
{
$iWk = log($i2)/log(2);
return ($iWk > floor($iWk))? floor($iWk)+1:$iWk;
}
/**
* Save OLE header
*
* @access private
* @param integer $iSBDcnt
* @param integer $iBBcnt
* @param integer $iPPScnt
*/
function _saveHeader($iSBDcnt, $iBBcnt, $iPPScnt)
{
$FILE = $this->_FILEH_;
// Calculate Basic Setting
$iBlCnt = $this->_BIG_BLOCK_SIZE / OLE_LONG_INT_SIZE;
$i1stBdL = ($this->_BIG_BLOCK_SIZE - 0x4C) / OLE_LONG_INT_SIZE;
$iBdExL = 0;
$iAll = $iBBcnt + $iPPScnt + $iSBDcnt;
$iAllW = $iAll;
$iBdCntW = floor($iAllW / $iBlCnt) + (($iAllW % $iBlCnt)? 1: 0);
$iBdCnt = floor(($iAll + $iBdCntW) / $iBlCnt) + ((($iAllW+$iBdCntW) % $iBlCnt)? 1: 0);
// Calculate BD count
if ($iBdCnt > $i1stBdL) {
while (1) {
$iBdExL++;
$iAllW++;
$iBdCntW = floor($iAllW / $iBlCnt) + (($iAllW % $iBlCnt)? 1: 0);
$iBdCnt = floor(($iAllW + $iBdCntW) / $iBlCnt) + ((($iAllW+$iBdCntW) % $iBlCnt)? 1: 0);
if ($iBdCnt <= ($iBdExL*$iBlCnt+ $i1stBdL)) {
break;
}
}
}
// Save Header
fwrite($FILE,
"\xD0\xCF\x11\xE0\xA1\xB1\x1A\xE1"
. "\x00\x00\x00\x00"
. "\x00\x00\x00\x00"
. "\x00\x00\x00\x00"
. "\x00\x00\x00\x00"
. pack("v", 0x3b)
. pack("v", 0x03)
. pack("v", -2)
. pack("v", 9)
. pack("v", 6)
. pack("v", 0)
. "\x00\x00\x00\x00"
. "\x00\x00\x00\x00"
. pack("V", $iBdCnt)
. pack("V", $iBBcnt+$iSBDcnt) //ROOT START
. pack("V", 0)
. pack("V", 0x1000)
. pack("V", 0) //Small Block Depot
. pack("V", 1)
);
// Extra BDList Start, Count
if ($iBdCnt < $i1stBdL) {
fwrite($FILE,
pack("V", -2). // Extra BDList Start
pack("V", 0) // Extra BDList Count
);
} else {
fwrite($FILE, pack("V", $iAll+$iBdCnt) . pack("V", $iBdExL));
}
// BDList
for ($i = 0; $i < $i1stBdL && $i < $iBdCnt; $i++) {
fwrite($FILE, pack("V", $iAll+$i));
}
if ($i < $i1stBdL) {
for ($j = 0; $j < ($i1stBdL-$i); $j++) {
fwrite($FILE, (pack("V", -1)));
}
}
}
/**
* Saving big data (PPS's with data bigger than OLE_DATA_SIZE_SMALL)
*
* @access private
* @param integer $iStBlk
* @param array &$raList Reference to array of PPS's
*/
function _saveBigData($iStBlk, &$raList)
{
$FILE = $this->_FILEH_;
// cycle through PPS's
for ($i = 0; $i < count($raList); $i++) {
if ($raList[$i]->Type != OLE_PPS_TYPE_DIR) {
$raList[$i]->Size = $raList[$i]->_DataLen();
if (($raList[$i]->Size >= OLE_DATA_SIZE_SMALL) ||
(($raList[$i]->Type == OLE_PPS_TYPE_ROOT) && isset($raList[$i]->_data)))
{
// Write Data
if (isset($raList[$i]->_PPS_FILE)) {
$iLen = 0;
fseek($raList[$i]->_PPS_FILE, 0); // To The Top
while($sBuff = fread($raList[$i]->_PPS_FILE, 4096)) {
$iLen += strlen($sBuff);
fwrite($FILE, $sBuff);
}
} else {
fwrite($FILE, $raList[$i]->_data);
}
if ($raList[$i]->Size % $this->_BIG_BLOCK_SIZE) {
for ($j = 0; $j < ($this->_BIG_BLOCK_SIZE - ($raList[$i]->Size % $this->_BIG_BLOCK_SIZE)); $j++) {
fwrite($FILE, "\x00");
}
}
// Set For PPS
$raList[$i]->_StartBlock = $iStBlk;
$iStBlk +=
(floor($raList[$i]->Size / $this->_BIG_BLOCK_SIZE) +
(($raList[$i]->Size % $this->_BIG_BLOCK_SIZE)? 1: 0));
}
// Close file for each PPS, and unlink it
if (isset($raList[$i]->_PPS_FILE)) {
@fclose($raList[$i]->_PPS_FILE);
$raList[$i]->_PPS_FILE = null;
@unlink($raList[$i]->_tmp_filename);
}
}
}
}
/**
* get small data (PPS's with data smaller than OLE_DATA_SIZE_SMALL)
*
* @access private
* @param array &$raList Reference to array of PPS's
*/
function _makeSmallData(&$raList)
{
$sRes = '';
$FILE = $this->_FILEH_;
$iSmBlk = 0;
for ($i = 0; $i < count($raList); $i++) {
// Make SBD, small data string
if ($raList[$i]->Type == OLE_PPS_TYPE_FILE) {
if ($raList[$i]->Size <= 0) {
continue;
}
if ($raList[$i]->Size < OLE_DATA_SIZE_SMALL) {
$iSmbCnt = floor($raList[$i]->Size / $this->_SMALL_BLOCK_SIZE)
+ (($raList[$i]->Size % $this->_SMALL_BLOCK_SIZE)? 1: 0);
// Add to SBD
for ($j = 0; $j < ($iSmbCnt-1); $j++) {
fwrite($FILE, pack("V", $j+$iSmBlk+1));
}
fwrite($FILE, pack("V", -2));
// Add to Data String(this will be written for RootEntry)
if ($raList[$i]->_PPS_FILE) {
fseek($raList[$i]->_PPS_FILE, 0); // To The Top
while ($sBuff = fread($raList[$i]->_PPS_FILE, 4096)) {
$sRes .= $sBuff;
}
} else {
$sRes .= $raList[$i]->_data;
}
if ($raList[$i]->Size % $this->_SMALL_BLOCK_SIZE) {
for ($j = 0; $j < ($this->_SMALL_BLOCK_SIZE - ($raList[$i]->Size % $this->_SMALL_BLOCK_SIZE)); $j++) {
$sRes .= "\x00";
}
}
// Set for PPS
$raList[$i]->_StartBlock = $iSmBlk;
$iSmBlk += $iSmbCnt;
}
}
}
$iSbCnt = floor($this->_BIG_BLOCK_SIZE / OLE_LONG_INT_SIZE);
if ($iSmBlk % $iSbCnt) {
for ($i = 0; $i < ($iSbCnt - ($iSmBlk % $iSbCnt)); $i++) {
fwrite($FILE, pack("V", -1));
}
}
return $sRes;
}
/**
* Saves all the PPS's WKs
*
* @access private
* @param array $raList Reference to an array with all PPS's
*/
function _savePps(&$raList)
{
// Save each PPS WK
for ($i = 0; $i < count($raList); $i++) {
fwrite($this->_FILEH_, $raList[$i]->_getPpsWk());
}
// Adjust for Block
$iCnt = count($raList);
$iBCnt = $this->_BIG_BLOCK_SIZE / OLE_PPS_SIZE;
if ($iCnt % $iBCnt) {
for ($i = 0; $i < (($iBCnt - ($iCnt % $iBCnt)) * OLE_PPS_SIZE); $i++) {
fwrite($this->_FILEH_, "\x00");
}
}
}
/**
* Saving Big Block Depot
*
* @access private
* @param integer $iSbdSize
* @param integer $iBsize
* @param integer $iPpsCnt
*/
function _saveBbd($iSbdSize, $iBsize, $iPpsCnt)
{
$FILE = $this->_FILEH_;
// Calculate Basic Setting
$iBbCnt = $this->_BIG_BLOCK_SIZE / OLE_LONG_INT_SIZE;
$i1stBdL = ($this->_BIG_BLOCK_SIZE - 0x4C) / OLE_LONG_INT_SIZE;
$iBdExL = 0;
$iAll = $iBsize + $iPpsCnt + $iSbdSize;
$iAllW = $iAll;
$iBdCntW = floor($iAllW / $iBbCnt) + (($iAllW % $iBbCnt)? 1: 0);
$iBdCnt = floor(($iAll + $iBdCntW) / $iBbCnt) + ((($iAllW+$iBdCntW) % $iBbCnt)? 1: 0);
// Calculate BD count
if ($iBdCnt >$i1stBdL) {
while (1) {
$iBdExL++;
$iAllW++;
$iBdCntW = floor($iAllW / $iBbCnt) + (($iAllW % $iBbCnt)? 1: 0);
$iBdCnt = floor(($iAllW + $iBdCntW) / $iBbCnt) + ((($iAllW+$iBdCntW) % $iBbCnt)? 1: 0);
if ($iBdCnt <= ($iBdExL*$iBbCnt+ $i1stBdL)) {
break;
}
}
}
// Making BD
// Set for SBD
if ($iSbdSize > 0) {
for ($i = 0; $i < ($iSbdSize - 1); $i++) {
fwrite($FILE, pack("V", $i+1));
}
fwrite($FILE, pack("V", -2));
}
// Set for B
for ($i = 0; $i < ($iBsize - 1); $i++) {
fwrite($FILE, pack("V", $i+$iSbdSize+1));
}
fwrite($FILE, pack("V", -2));
// Set for PPS
for ($i = 0; $i < ($iPpsCnt - 1); $i++) {
fwrite($FILE, pack("V", $i+$iSbdSize+$iBsize+1));
}
fwrite($FILE, pack("V", -2));
// Set for BBD itself ( 0xFFFFFFFD : BBD)
for ($i = 0; $i < $iBdCnt; $i++) {
fwrite($FILE, pack("V", 0xFFFFFFFD));
}
// Set for ExtraBDList
for ($i = 0; $i < $iBdExL; $i++) {
fwrite($FILE, pack("V", 0xFFFFFFFC));
}
// Adjust for Block
if (($iAllW + $iBdCnt) % $iBbCnt) {
for ($i = 0; $i < ($iBbCnt - (($iAllW + $iBdCnt) % $iBbCnt)); $i++) {
fwrite($FILE, pack("V", -1));
}
}
// Extra BDList
if ($iBdCnt > $i1stBdL) {
$iN=0;
$iNb=0;
for ($i = $i1stBdL;$i < $iBdCnt; $i++, $iN++) {
if ($iN >= ($iBbCnt - 1)) {
$iN = 0;
$iNb++;
fwrite($FILE, pack("V", $iAll+$iBdCnt+$iNb));
}
fwrite($FILE, pack("V", $iBsize+$iSbdSize+$iPpsCnt+$i));
}
if (($iBdCnt-$i1stBdL) % ($iBbCnt-1)) {
for ($i = 0; $i < (($iBbCnt - 1) - (($iBdCnt - $i1stBdL) % ($iBbCnt - 1))); $i++) {
fwrite($FILE, pack("V", -1));
}
}
fwrite($FILE, pack("V", -2));
}
}
}
?>

View File

@@ -0,0 +1,6 @@
<html>
<head>
</head>
<body>
</body>
</html>

View File

@@ -0,0 +1,6 @@
<html>
<head>
</head>
<body>
</body>
</html>

956
main/inc/lib/pear/PEAR.php Normal file
View File

@@ -0,0 +1,956 @@
<?php
/**
* PEAR, the PHP Extension and Application Repository
*
* PEAR class and PEAR_Error class
*
* PHP versions 4 and 5
*
* @category pear
* @package PEAR
* @author Sterling Hughes <sterling@php.net>
* @author Stig Bakken <ssb@php.net>
* @author Tomas V.V.Cox <cox@idecnet.com>
* @author Greg Beaver <cellog@php.net>
* @copyright 1997-2009 The Authors
* @license http://opensource.org/licenses/bsd-license.php New BSD License
* @version CVS: $Id: PEAR.php 286670 2009-08-02 14:16:06Z dufuz $
* @link http://pear.php.net/package/PEAR
* @since File available since Release 0.1
*/
/**#@+
* ERROR constants
*/
define('PEAR_ERROR_RETURN', 1);
define('PEAR_ERROR_PRINT', 2);
define('PEAR_ERROR_TRIGGER', 4);
define('PEAR_ERROR_DIE', 8);
define('PEAR_ERROR_CALLBACK', 16);
/**
* WARNING: obsolete
* @deprecated
*/
define('PEAR_ERROR_EXCEPTION', 32);
/**#@-*/
define('PEAR_ZE2', (function_exists('version_compare') &&
version_compare(zend_version(), "2-dev", "ge")));
if (substr(PHP_OS, 0, 3) == 'WIN') {
define('OS_WINDOWS', true);
define('OS_UNIX', false);
define('PEAR_OS', 'Windows');
} else {
define('OS_WINDOWS', false);
define('OS_UNIX', true);
define('PEAR_OS', 'Unix'); // blatant assumption
}
$GLOBALS['_PEAR_default_error_mode'] = PEAR_ERROR_RETURN;
$GLOBALS['_PEAR_default_error_options'] = E_USER_NOTICE;
$GLOBALS['_PEAR_destructor_object_list'] = array();
$GLOBALS['_PEAR_shutdown_funcs'] = array();
$GLOBALS['_PEAR_error_handler_stack'] = array();
@ini_set('track_errors', true);
/**
* Base class for other PEAR classes. Provides rudimentary
* emulation of destructors.
*
* If you want a destructor in your class, inherit PEAR and make a
* destructor method called _yourclassname (same name as the
* constructor, but with a "_" prefix). Also, in your constructor you
* have to call the PEAR constructor: $this->PEAR();.
* The destructor method will be called without parameters. Note that
* at in some SAPI implementations (such as Apache), any output during
* the request shutdown (in which destructors are called) seems to be
* discarded. If you need to get any debug information from your
* destructor, use error_log(), syslog() or something similar.
*
* IMPORTANT! To use the emulated destructors you need to create the
* objects by reference: $obj =& new PEAR_child;
*
* @category pear
* @package PEAR
* @author Stig Bakken <ssb@php.net>
* @author Tomas V.V. Cox <cox@idecnet.com>
* @author Greg Beaver <cellog@php.net>
* @copyright 1997-2006 The PHP Group
* @license http://opensource.org/licenses/bsd-license.php New BSD License
* @version Release: 1.9.0
* @link http://pear.php.net/package/PEAR
* @see PEAR_Error
* @since Class available since PHP 4.0.2
* @link http://pear.php.net/manual/en/core.pear.php#core.pear.pear
*/
class PEAR
{
// {{{ properties
/**
* Whether to enable internal debug messages.
*
* @var bool
* @access private
*/
var $_debug = false;
/**
* Default error mode for this object.
*
* @var int
* @access private
*/
var $_default_error_mode = null;
/**
* Default error options used for this object when error mode
* is PEAR_ERROR_TRIGGER.
*
* @var int
* @access private
*/
var $_default_error_options = null;
/**
* Default error handler (callback) for this object, if error mode is
* PEAR_ERROR_CALLBACK.
*
* @var string
* @access private
*/
var $_default_error_handler = '';
/**
* Which class to use for error objects.
*
* @var string
* @access private
*/
var $_error_class = 'PEAR_Error';
/**
* An array of expected errors.
*
* @var array
* @access private
*/
var $_expected_errors = array();
// }}}
// {{{ constructor
/**
* Constructor. Registers this object in
* $_PEAR_destructor_object_list for destructor emulation if a
* destructor object exists.
*
* @param string $error_class (optional) which class to use for
* error objects, defaults to PEAR_Error.
* @access public
* @return void
*/
public function __construct($error_class = null)
{
$classname = strtolower(get_class($this));
if ($this->_debug) {
print "PEAR constructor called, class=$classname\n";
}
if ($error_class !== null) {
$this->_error_class = $error_class;
}
while ($classname && strcasecmp($classname, "pear")) {
$destructor = "_$classname";
if (method_exists($this, $destructor)) {
global $_PEAR_destructor_object_list;
$_PEAR_destructor_object_list[] = &$this;
if (!isset($GLOBALS['_PEAR_SHUTDOWN_REGISTERED'])) {
register_shutdown_function("_PEAR_call_destructors");
$GLOBALS['_PEAR_SHUTDOWN_REGISTERED'] = true;
}
break;
} else {
$classname = get_parent_class($classname);
}
}
}
/**
* If you have a class that's mostly/entirely static, and you need static
* properties, you can use this method to simulate them. Eg. in your method(s)
* do this: $myVar = &PEAR::getStaticProperty('myclass', 'myVar');
* You MUST use a reference, or they will not persist!
*
* @access public
* @param string $class The calling classname, to prevent clashes
* @param string $var The variable to retrieve.
* @return mixed A reference to the variable. If not set it will be
* auto initialised to NULL.
*/
function &getStaticProperty($class, $var)
{
static $properties;
if (!isset($properties[$class])) {
$properties[$class] = array();
}
if (!array_key_exists($var, $properties[$class])) {
$properties[$class][$var] = null;
}
return $properties[$class][$var];
}
// }}}
// {{{ registerShutdownFunc()
/**
* Use this function to register a shutdown method for static
* classes.
*
* @access public
* @param mixed $func The function name (or array of class/method) to call
* @param mixed $args The arguments to pass to the function
* @return void
*/
function registerShutdownFunc($func, $args = array())
{
// if we are called statically, there is a potential
// that no shutdown func is registered. Bug #6445
if (!isset($GLOBALS['_PEAR_SHUTDOWN_REGISTERED'])) {
register_shutdown_function("_PEAR_call_destructors");
$GLOBALS['_PEAR_SHUTDOWN_REGISTERED'] = true;
}
$GLOBALS['_PEAR_shutdown_funcs'][] = array($func, $args);
}
// }}}
// {{{ isError()
/**
* Tell whether a value is a PEAR error.
*
* @param mixed $data the value to test
* @param int $code if $data is an error object, return true
* only if $code is a string and
* $obj->getMessage() == $code or
* $code is an integer and $obj->getCode() == $code
* @access public
* @return bool true if parameter is an error
*/
static function isError($data, $code = null)
{
if (!is_a($data, 'PEAR_Error')) {
return false;
}
if (is_null($code)) {
return true;
} elseif (is_string($code)) {
return $data->getMessage() == $code;
}
return $data->getCode() == $code;
}
// }}}
// {{{ setErrorHandling()
/**
* Sets how errors generated by this object should be handled.
* Can be invoked both in objects and statically. If called
* statically, setErrorHandling sets the default behaviour for all
* PEAR objects. If called in an object, setErrorHandling sets
* the default behaviour for that object.
*
* @param int $mode
* One of PEAR_ERROR_RETURN, PEAR_ERROR_PRINT,
* PEAR_ERROR_TRIGGER, PEAR_ERROR_DIE,
* PEAR_ERROR_CALLBACK or PEAR_ERROR_EXCEPTION.
*
* @param mixed $options
* When $mode is PEAR_ERROR_TRIGGER, this is the error level (one
* of E_USER_NOTICE, E_USER_WARNING or E_USER_ERROR).
*
* When $mode is PEAR_ERROR_CALLBACK, this parameter is expected
* to be the callback function or method. A callback
* function is a string with the name of the function, a
* callback method is an array of two elements: the element
* at index 0 is the object, and the element at index 1 is
* the name of the method to call in the object.
*
* When $mode is PEAR_ERROR_PRINT or PEAR_ERROR_DIE, this is
* a printf format string used when printing the error
* message.
*
* @access public
* @return void
* @see PEAR_ERROR_RETURN
* @see PEAR_ERROR_PRINT
* @see PEAR_ERROR_TRIGGER
* @see PEAR_ERROR_DIE
* @see PEAR_ERROR_CALLBACK
* @see PEAR_ERROR_EXCEPTION
*
* @since PHP 4.0.5
*/
function setErrorHandling($mode = null, $options = null)
{
if (isset($this) && is_a($this, 'PEAR')) {
$setmode = &$this->_default_error_mode;
$setoptions = &$this->_default_error_options;
} else {
$setmode = &$GLOBALS['_PEAR_default_error_mode'];
$setoptions = &$GLOBALS['_PEAR_default_error_options'];
}
switch ($mode) {
case PEAR_ERROR_EXCEPTION:
case PEAR_ERROR_RETURN:
case PEAR_ERROR_PRINT:
case PEAR_ERROR_TRIGGER:
case PEAR_ERROR_DIE:
case null:
$setmode = $mode;
$setoptions = $options;
break;
case PEAR_ERROR_CALLBACK:
$setmode = $mode;
// class/object method callback
if (is_callable($options)) {
$setoptions = $options;
} else {
trigger_error("invalid error callback", E_USER_WARNING);
}
break;
default:
trigger_error("invalid error mode", E_USER_WARNING);
break;
}
}
// }}}
// {{{ expectError()
/**
* This method is used to tell which errors you expect to get.
* Expected errors are always returned with error mode
* PEAR_ERROR_RETURN. Expected error codes are stored in a stack,
* and this method pushes a new element onto it. The list of
* expected errors are in effect until they are popped off the
* stack with the popExpect() method.
*
* Note that this method can not be called statically
*
* @param mixed $code a single error code or an array of error codes to expect
*
* @return int the new depth of the "expected errors" stack
* @access public
*/
function expectError($code = '*')
{
if (is_array($code)) {
array_push($this->_expected_errors, $code);
} else {
array_push($this->_expected_errors, array($code));
}
return sizeof($this->_expected_errors);
}
/**
* This method checks unsets an error code if available
*
* @param mixed error code
* @return bool true if the error code was unset, false otherwise
* @access private
* @since PHP 4.3.0
*/
function _checkDelExpect($error_code)
{
$deleted = false;
foreach ($this->_expected_errors AS $key => $error_array) {
if (in_array($error_code, $error_array)) {
unset($this->_expected_errors[$key][array_search($error_code, $error_array)]);
$deleted = true;
}
// clean up empty arrays
if (0 == count($this->_expected_errors[$key])) {
unset($this->_expected_errors[$key]);
}
}
return $deleted;
}
/**
* This method is a wrapper that returns an instance of the
* configured error class with this object's default error
* handling applied. If the $mode and $options parameters are not
* specified, the object's defaults are used.
*
* @param mixed $message a text error message or a PEAR error object
*
* @param int $code a numeric error code (it is up to your class
* to define these if you want to use codes)
*
* @param int $mode One of PEAR_ERROR_RETURN, PEAR_ERROR_PRINT,
* PEAR_ERROR_TRIGGER, PEAR_ERROR_DIE,
* PEAR_ERROR_CALLBACK, PEAR_ERROR_EXCEPTION.
*
* @param mixed $options If $mode is PEAR_ERROR_TRIGGER, this parameter
* specifies the PHP-internal error level (one of
* E_USER_NOTICE, E_USER_WARNING or E_USER_ERROR).
* If $mode is PEAR_ERROR_CALLBACK, this
* parameter specifies the callback function or
* method. In other error modes this parameter
* is ignored.
*
* @param string $userinfo If you need to pass along for example debug
* information, this parameter is meant for that.
*
* @param string $error_class The returned error object will be
* instantiated from this class, if specified.
*
* @param bool $skipmsg If true, raiseError will only pass error codes,
* the error message parameter will be dropped.
*
* @access public
* @return object a PEAR error object
* @see PEAR::setErrorHandling
* @since PHP 4.0.5
*/
public static function &raiseError($message = null,
$code = null,
$mode = null,
$options = null,
$userinfo = null,
$error_class = null,
$skipmsg = false)
{
// The error is yet a PEAR error object
if (is_object($message)) {
$code = $message->getCode();
$userinfo = $message->getUserInfo();
$error_class = $message->getType();
$message->error_message_prefix = '';
$message = $message->getMessage();
}
if (isset($this) && isset($this->_expected_errors) && sizeof($this->_expected_errors) > 0 && sizeof($exp = end($this->_expected_errors))) {
if ($exp[0] == "*" ||
(is_int(reset($exp)) && in_array($code, $exp)) ||
(is_string(reset($exp)) && in_array($message, $exp))) {
$mode = PEAR_ERROR_RETURN;
}
}
// No mode given, try global ones
if ($mode === null) {
// Class error handler
if (isset($this) && isset($this->_default_error_mode)) {
$mode = $this->_default_error_mode;
$options = $this->_default_error_options;
// Global error handler
} elseif (isset($GLOBALS['_PEAR_default_error_mode'])) {
$mode = $GLOBALS['_PEAR_default_error_mode'];
$options = $GLOBALS['_PEAR_default_error_options'];
}
}
if ($error_class !== null) {
$ec = $error_class;
} elseif (isset($this) && isset($this->_error_class)) {
$ec = $this->_error_class;
} else {
$ec = 'PEAR_Error';
}
if ($skipmsg) {
$a = new $ec($code, $mode, $options, $userinfo);
} else {
$a = new $ec($message, $code, $mode, $options, $userinfo);
}
return $a;
}
// }}}
// {{{ throwError()
/**
* Simpler form of raiseError with fewer options. In most cases
* message, code and userinfo are enough.
*
* @param string $message
*
*/
function &throwError($message = null,
$code = null,
$userinfo = null)
{
if (isset($this) && is_a($this, 'PEAR')) {
$a = &$this->raiseError($message, $code, null, null, $userinfo);
return $a;
}
$a = &PEAR::raiseError($message, $code, null, null, $userinfo);
return $a;
}
/**
* Push a new error handler on top of the error handler options stack. With this
* you can easily override the actual error handler for some code and restore
* it later with popErrorHandling.
*
* @param mixed $mode (same as setErrorHandling)
* @param mixed $options (same as setErrorHandling)
*
* @return bool Always true
*
* @see PEAR::setErrorHandling
*/
function pushErrorHandling($mode, $options = null)
{
$stack = &$GLOBALS['_PEAR_error_handler_stack'];
if (isset($this) && is_a($this, 'PEAR')) {
$def_mode = &$this->_default_error_mode;
$def_options = &$this->_default_error_options;
} else {
$def_mode = &$GLOBALS['_PEAR_default_error_mode'];
$def_options = &$GLOBALS['_PEAR_default_error_options'];
}
$stack[] = array($def_mode, $def_options);
if (isset($this) && is_a($this, 'PEAR')) {
$this->setErrorHandling($mode, $options);
} else {
PEAR::setErrorHandling($mode, $options);
}
$stack[] = array($mode, $options);
return true;
}
// }}}
// {{{ loadExtension()
/**
* OS independant PHP extension load. Remember to take care
* on the correct extension name for case sensitive OSes.
*
* @param string $ext The extension name
* @return bool Success or not on the dl() call
*/
function loadExtension($ext)
{
if (!extension_loaded($ext)) {
// if either returns true dl() will produce a FATAL error, stop that
if ((ini_get('enable_dl') != 1) || (ini_get('safe_mode') == 1)) {
return false;
}
if (OS_WINDOWS) {
$suffix = '.dll';
} elseif (PHP_OS == 'HP-UX') {
$suffix = '.sl';
} elseif (PHP_OS == 'AIX') {
$suffix = '.a';
} elseif (PHP_OS == 'OSX') {
$suffix = '.bundle';
} else {
$suffix = '.so';
}
return @dl('php_'.$ext.$suffix) || @dl($ext.$suffix);
}
return true;
}
// }}}
}
// {{{ _PEAR_call_destructors()
// Added by Chamilo team, 16-MAR-2010
if (!function_exists('_PEAR_call_destructors')) {
//
function _PEAR_call_destructors()
{
global $_PEAR_destructor_object_list;
if (is_array($_PEAR_destructor_object_list) &&
sizeof($_PEAR_destructor_object_list))
{
reset($_PEAR_destructor_object_list);
if (PEAR_ZE2) {
$destructLifoExists = PEAR5::getStaticProperty('PEAR', 'destructlifo');
} else {
$destructLifoExists = PEAR::getStaticProperty('PEAR', 'destructlifo');
}
if ($destructLifoExists) {
$_PEAR_destructor_object_list = array_reverse($_PEAR_destructor_object_list);
}
while (list($k, $objref) = each($_PEAR_destructor_object_list)) {
$classname = get_class($objref);
while ($classname) {
$destructor = "_$classname";
if (method_exists($objref, $destructor)) {
$objref->$destructor();
break;
} else {
$classname = get_parent_class($classname);
}
}
}
// Empty the object list to ensure that destructors are
// not called more than once.
$_PEAR_destructor_object_list = array();
}
// Now call the shutdown functions
if (isset($GLOBALS['_PEAR_shutdown_funcs']) AND is_array($GLOBALS['_PEAR_shutdown_funcs']) AND !empty($GLOBALS['_PEAR_shutdown_funcs'])) {
foreach ($GLOBALS['_PEAR_shutdown_funcs'] as $value) {
call_user_func_array($value[0], $value[1]);
}
}
}
//
}
//
// }}}
/**
* Standard PEAR error class for PHP 4
*
* This class is supserseded by {@link PEAR_Exception} in PHP 5
*
* @category pear
* @package PEAR
* @author Stig Bakken <ssb@php.net>
* @author Tomas V.V. Cox <cox@idecnet.com>
* @author Gregory Beaver <cellog@php.net>
* @copyright 1997-2006 The PHP Group
* @license http://opensource.org/licenses/bsd-license.php New BSD License
* @version Release: 1.9.0
* @link http://pear.php.net/manual/en/core.pear.pear-error.php
* @see PEAR::raiseError(), PEAR::throwError()
* @since Class available since PHP 4.0.2
*/
class PEAR_Error
{
// {{{ properties
var $error_message_prefix = '';
var $mode = PEAR_ERROR_RETURN;
var $level = E_USER_NOTICE;
var $code = -1;
var $message = '';
var $userinfo = '';
var $backtrace = null;
// }}}
// {{{ constructor
/**
* PEAR_Error constructor
*
* @param string $message message
*
* @param int $code (optional) error code
*
* @param int $mode (optional) error mode, one of: PEAR_ERROR_RETURN,
* PEAR_ERROR_PRINT, PEAR_ERROR_DIE, PEAR_ERROR_TRIGGER,
* PEAR_ERROR_CALLBACK or PEAR_ERROR_EXCEPTION
*
* @param mixed $options (optional) error level, _OR_ in the case of
* PEAR_ERROR_CALLBACK, the callback function or object/method
* tuple.
*
* @param string $userinfo (optional) additional user/debug info
*
* @access public
*
*/
public function __construct(
$message = 'unknown error',
$code = null,
$mode = null,
$options = null,
$userinfo = null
) {
if ($mode === null) {
$mode = PEAR_ERROR_RETURN;
}
$this->message = $message;
$this->code = $code;
$this->mode = $mode;
$this->userinfo = $userinfo;
if (PEAR_ZE2) {
$skiptrace = PEAR5::getStaticProperty('PEAR_Error', 'skiptrace');
} else {
$skiptrace = PEAR::getStaticProperty('PEAR_Error', 'skiptrace');
}
if (!$skiptrace) {
$this->backtrace = debug_backtrace();
if (isset($this->backtrace[0]) && isset($this->backtrace[0]['object'])) {
unset($this->backtrace[0]['object']);
}
}
if ($mode & PEAR_ERROR_CALLBACK) {
$this->level = E_USER_NOTICE;
$this->callback = $options;
} else {
if ($options === null) {
$options = E_USER_NOTICE;
}
$this->level = $options;
$this->callback = null;
}
if ($this->mode & PEAR_ERROR_PRINT) {
if (is_null($options) || is_int($options)) {
$format = "%s";
} else {
$format = $options;
}
printf($format, $this->getMessage());
}
if ($this->mode & PEAR_ERROR_TRIGGER) {
trigger_error($this->getMessage(), $this->level);
}
if ($this->mode & PEAR_ERROR_DIE) {
$msg = $this->getMessage();
if (is_null($options) || is_int($options)) {
$format = "%s";
if (substr($msg, -1) != "\n") {
$msg .= "\n";
}
} else {
$format = $options;
}
die(sprintf($format, $msg));
}
if ($this->mode & PEAR_ERROR_CALLBACK) {
if (is_callable($this->callback)) {
call_user_func($this->callback, $this);
}
}
if ($this->mode & PEAR_ERROR_EXCEPTION) {
trigger_error("PEAR_ERROR_EXCEPTION is obsolete, use class PEAR_Exception for exceptions", E_USER_WARNING);
eval('$e = new Exception($this->message, $this->code);throw($e);');
}
}
// }}}
// {{{ getMode()
/**
* Get the error mode from an error object.
*
* @return int error mode
* @access public
*/
function getMode() {
return $this->mode;
}
// }}}
// {{{ getCallback()
/**
* Get the callback function/method from an error object.
*
* @return mixed callback function or object/method array
* @access public
*/
function getCallback() {
return $this->callback;
}
// }}}
// {{{ getMessage()
/**
* Get the error message from an error object.
*
* @return string full error message
* @access public
*/
function getMessage()
{
return ($this->error_message_prefix . $this->message);
}
// }}}
// {{{ getCode()
/**
* Get error code from an error object
*
* @return int error code
* @access public
*/
function getCode()
{
return $this->code;
}
// }}}
// {{{ getType()
/**
* Get the name of this error/exception.
*
* @return string error/exception name (type)
* @access public
*/
function getType()
{
return get_class($this);
}
// }}}
// {{{ getUserInfo()
/**
* Get additional user-supplied information.
*
* @return string user-supplied information
* @access public
*/
function getUserInfo()
{
return $this->userinfo;
}
// }}}
// {{{ getDebugInfo()
/**
* Get additional debug information supplied by the application.
*
* @return string debug information
* @access public
*/
function getDebugInfo()
{
return $this->getUserInfo();
}
// }}}
// {{{ getBacktrace()
/**
* Get the call backtrace from where the error was generated.
* Supported with PHP 4.3.0 or newer.
*
* @param int $frame (optional) what frame to fetch
* @return array Backtrace, or NULL if not available.
* @access public
*/
function getBacktrace($frame = null)
{
if (defined('PEAR_IGNORE_BACKTRACE')) {
return null;
}
if ($frame === null) {
return $this->backtrace;
}
return $this->backtrace[$frame];
}
// }}}
// {{{ addUserInfo()
function addUserInfo($info)
{
if (empty($this->userinfo)) {
$this->userinfo = $info;
} else {
$this->userinfo .= " ** $info";
}
}
// }}}
// {{{ toString()
function __toString()
{
return $this->getMessage();
}
// }}}
// {{{ toString()
/**
* Make a string representation of this object.
*
* @return string a string with an object summary
* @access public
*/
function toString() {
$modes = array();
$levels = array(E_USER_NOTICE => 'notice',
E_USER_WARNING => 'warning',
E_USER_ERROR => 'error');
if ($this->mode & PEAR_ERROR_CALLBACK) {
if (is_array($this->callback)) {
$callback = (is_object($this->callback[0]) ?
strtolower(get_class($this->callback[0])) :
$this->callback[0]) . '::' .
$this->callback[1];
} else {
$callback = $this->callback;
}
return sprintf('[%s: message="%s" code=%d mode=callback '.
'callback=%s prefix="%s" info="%s"]',
strtolower(get_class($this)), $this->message, $this->code,
$callback, $this->error_message_prefix,
$this->userinfo);
}
if ($this->mode & PEAR_ERROR_PRINT) {
$modes[] = 'print';
}
if ($this->mode & PEAR_ERROR_TRIGGER) {
$modes[] = 'trigger';
}
if ($this->mode & PEAR_ERROR_DIE) {
$modes[] = 'die';
}
if ($this->mode & PEAR_ERROR_RETURN) {
$modes[] = 'return';
}
return sprintf('[%s: message="%s" code=%d mode=%s level=%s '.
'prefix="%s" info="%s"]',
strtolower(get_class($this)), $this->message, $this->code,
implode("|", $modes), $levels[$this->level],
$this->error_message_prefix,
$this->userinfo);
}
// }}}
}
/*
* Local Variables:
* mode: php
* tab-width: 4
* c-basic-offset: 4
* End:
*/

View File

@@ -0,0 +1,33 @@
<?php
/**
* This is only meant for PHP 5 to get rid of certain strict warning
* that doesn't get hidden since it's in the shutdown function
*/
class PEAR5
{
/**
* If you have a class that's mostly/entirely static, and you need static
* properties, you can use this method to simulate them. Eg. in your method(s)
* do this: $myVar = &PEAR5::getStaticProperty('myclass', 'myVar');
* You MUST use a reference, or they will not persist!
*
* @access public
* @param string $class The calling classname, to prevent clashes
* @param string $var The variable to retrieve.
* @return mixed A reference to the variable. If not set it will be
* auto initialised to NULL.
*/
static function &getStaticProperty($class, $var)
{
static $properties;
if (!isset($properties[$class])) {
$properties[$class] = array();
}
if (!array_key_exists($var, $properties[$class])) {
$properties[$class][$var] = null;
}
return $properties[$class][$var];
}
}

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,292 @@
<?php
/* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4: */
/**
* Contains the Pager_HtmlWidgets class
*
* PHP versions 4 and 5
*
* LICENSE: Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR "AS IS" AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE FREEBSD PROJECT OR CONTRIBUTORS BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* @category HTML
* @package Pager
* @author Lorenzo Alberton <l.alberton@quipo.it>
* @copyright 2003-2007 Lorenzo Alberton
* @license http://www.debian.org/misc/bsd.license BSD License (3 Clause)
* @version CVS: $Id: HtmlWidgets.php,v 1.7 2009/03/13 16:51:37 quipo Exp $
* @link http://pear.php.net/package/Pager
*/
/**
* Pager_HtmlWidgets
*
* @category HTML
* @package Pager
* @author Lorenzo Alberton <l.alberton@quipo.it>
* @copyright 2003-2007 Lorenzo Alberton
* @license http://www.debian.org/misc/bsd.license BSD License (3 Clause)
* @link http://pear.php.net/package/Pager
*/
class Pager_HtmlWidgets
{
var $pager = null;
// {{{ constructor
/**
* Constructor
*
* @param object &$pager Pager instance
*/
function Pager_HtmlWidgets(&$pager)
{
$this->pager =& $pager;
}
// }}}
// {{{ getPerPageSelectBox()
/**
* Returns a string with a XHTML SELECT menu,
* useful for letting the user choose how many items per page should be
* displayed. If parameter useSessions is TRUE, this value is stored in
* a session var. The string isn't echoed right now so you can use it
* with template engines.
*
* @param integer $start starting value for the select menu
* @param integer $end ending value for the select menu
* @param integer $step step between values in the select menu
* @param boolean $showAllData If true, perPage is set equal to totalItems.
* @param array $extraParams (or string $optionText for BC reasons)
* - 'optionText': text to show in each option.
* Use '%d' where you want to see the number of pages selected.
* - 'attributes': (html attributes) Tag attributes or
* HTML attributes (id="foo" pairs), will be inserted in the
* <select> tag
* - 'checkMaxLimit': if true, Pager checks if $end is bigger
* than $totalItems, and doesn't show the extra select options
* - 'autoSubmit': if TRUE, add some js code
* to submit the form on the onChange event
*
* @return string xhtml select box
* @access public
*/
function getPerPageSelectBox($start=5, $end=30, $step=5, $showAllData=false, $extraParams=array())
{
// FIXME: needs POST support
$optionText = '%d';
$attributes = '';
$checkMaxLimit = false;
if (is_string($extraParams)) {
//old behavior, BC maintained
$optionText = $extraParams;
} else {
if (array_key_exists('optionText', $extraParams)) {
$optionText = $extraParams['optionText'];
}
if (array_key_exists('attributes', $extraParams)) {
$attributes = $extraParams['attributes'];
}
if (array_key_exists('checkMaxLimit', $extraParams)) {
$checkMaxLimit = $extraParams['checkMaxLimit'];
}
}
if (!strstr($optionText, '%d')) {
return $this->pager->raiseError(
$this->pager->errorMessage(ERROR_PAGER_INVALID_PLACEHOLDER),
ERROR_PAGER_INVALID_PLACEHOLDER
);
}
$start = (int)$start;
$end = (int)$end;
$step = (int)$step;
if (!empty($_SESSION[$this->pager->_sessionVar])) {
$selected = (int)$_SESSION[$this->pager->_sessionVar];
} else {
$selected = $this->pager->_perPage;
}
if ($checkMaxLimit && $this->pager->_totalItems >= 0 && $this->pager->_totalItems < $end) {
$end = $this->pager->_totalItems;
}
$tmp = '<select name="'.$this->pager->_sessionVar.'"';
if (!empty($attributes)) {
$tmp .= ' '.$attributes;
}
if (!empty($extraParams['autoSubmit'])) {
if ('GET' == $this->pager->_httpMethod) {
$selector = '\' + '.'this.options[this.selectedIndex].value + \'';
if ($this->pager->_append) {
$tmpLinkData = $this->pager->_linkData;
if (isset($tmpLinkData[$this->pager->_urlVar])) {
$tmpLinkData[$this->pager->_urlVar] = $this->pager->getCurrentPageID();
}
$tmpLinkData[$this->pager->_sessionVar] = '1';
$href = '?' . $this->pager->_http_build_query_wrapper($tmpLinkData);
$href = htmlentities($this->pager->_url, ENT_COMPAT, 'UTF-8'). preg_replace(
'/(&|&amp;|\?)('.$this->pager->_sessionVar.'=)(\d+)/',
'\\1\\2'.$selector,
htmlentities($href, ENT_COMPAT, 'UTF-8')
);
} else {
$href = htmlentities($this->pager->_url . str_replace('%d', $selector, $this->pager->_fileName), ENT_COMPAT, 'UTF-8');
}
$tmp .= ' onchange="document.location.href=\''
. $href .'\''
. '"';
} elseif ($this->pager->_httpMethod == 'POST') {
$tmp .= " onchange='"
. $this->pager->_generateFormOnClick($this->pager->_url, $this->pager->_linkData)
. "'";
$tmp = preg_replace(
'/(input\.name = \"'.$this->pager->_sessionVar.'\"; input\.value =) \"(\d+)\";/',
'\\1 this.options[this.selectedIndex].value;',
$tmp
);
}
}
$tmp .= '>';
$last = $start;
for ($i=$start; $i<=$end; $i+=$step) {
$last = $i;
$tmp .= '<option value="'.$i.'"';
if ($i == $selected) {
$tmp .= ' selected="selected"';
}
$tmp .= '>'.sprintf($optionText, $i).'</option>';
}
if ($showAllData && $last != $this->pager->_totalItems) {
$tmp .= '<option value="'.$this->pager->_totalItems.'"';
if ($this->pager->_totalItems == $selected) {
$tmp .= ' selected="selected"';
}
$tmp .= '>';
if (empty($this->pager->_showAllText)) {
$tmp .= str_replace('%d', $this->pager->_totalItems, $optionText);
} else {
$tmp .= $this->pager->_showAllText;
}
$tmp .= '</option>';
}
if (substr($tmp, -9, 9) !== '</option>') {
//empty select
$tmp .= '<option />';
}
$tmp .= '</select>';
return $tmp;
}
// }}}
// {{{ getPageSelectBox()
/**
* Returns a string with a XHTML SELECT menu with the page numbers,
* useful as an alternative to the links
*
* @param array $params - 'optionText': text to show in each option.
* Use '%d' where you want to see the number
* of pages selected.
* - 'autoSubmit': if TRUE, add some js code
* to submit the form on the onChange event
* @param string $extraAttributes (html attributes) Tag attributes or
* HTML attributes (id="foo" pairs), will be
* inserted in the <select> tag
*
* @return string xhtml select box
* @access public
*/
function getPageSelectBox($params = array(), $extraAttributes = '')
{
$optionText = '%d';
if (array_key_exists('optionText', $params)) {
$optionText = $params['optionText'];
}
if (!strstr($optionText, '%d')) {
return $this->pager->raiseError(
$this->pager->errorMessage(ERROR_PAGER_INVALID_PLACEHOLDER),
ERROR_PAGER_INVALID_PLACEHOLDER
);
}
$tmp = '<select name="'.$this->pager->_urlVar.'"';
if (!empty($extraAttributes)) {
$tmp .= ' '.$extraAttributes;
}
if (!empty($params['autoSubmit'])) {
if ($this->pager->_httpMethod == 'GET') {
$selector = '\' + '.'this.options[this.selectedIndex].value + \'';
if ($this->pager->_append) {
$href = '?' . $this->pager->_http_build_query_wrapper($this->pager->_linkData);
// Modified by Ivan Tcholakov, 17-OCT-2008.
//$href = htmlentities($this->pager->_url, ENT_COMPAT, 'UTF-8'). preg_replace(
// '/(&|&amp;|\?)('.$this->pager->_urlVar.'=)(\d+)/',
// '\\1\\2'.$selector,
// htmlentities($href, ENT_COMPAT, 'UTF-8')
$href = api_htmlentities($this->pager->_url). preg_replace(
'/(&|&amp;|\?)('.$this->pager->_urlVar.'=)(\d+)/',
'\\1\\2'.$selector,
api_htmlentities($href)
);
//
} else {
// Modified by Ivan Tcholakov, 17-OCT-2008.
//$href = htmlentities($this->pager->_url . str_replace('%d', $selector, $this->pager->_fileName), ENT_COMPAT, 'UTF-8');
$href = api_htmlentities($this->pager->_url . str_replace('%d', $selector, $this->pager->_fileName));
//
}
$tmp .= ' onchange="javascript: document.location.href=\''
. $href .'\''
. '"';
} elseif ($this->pager->_httpMethod == 'POST') {
$tmp .= " onchange='"
. $this->pager->_generateFormOnClick($this->pager->_url, $this->pager->_linkData)
. "'";
$tmp = preg_replace(
'/(input\.name = \"'.$this->pager->_urlVar.'\"; input\.value =) \"(\d+)\";/',
'\\1 this.options[this.selectedIndex].value;',
$tmp
);
}
}
$tmp .= '>';
$start = 1;
$end = $this->pager->numPages();
$selected = $this->pager->getCurrentPageID();
for ($i=$start; $i<=$end; $i++) {
$tmp .= '<option value="'.$i.'"';
if ($i == $selected) {
$tmp .= ' selected="selected"';
}
$tmp .= '>'.sprintf($optionText, $i).'</option>';
}
$tmp .= '</select>';
return $tmp;
}
// }}}
}
?>

View File

@@ -0,0 +1,260 @@
<?php
/* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4: */
/**
* Contains the Pager_Jumping class
*
* PHP versions 4 and 5
*
* LICENSE: Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR "AS IS" AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE FREEBSD PROJECT OR CONTRIBUTORS BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* @category HTML
* @package Pager
* @author Lorenzo Alberton <l.alberton@quipo.it>
* @author Richard Heyes <richard@phpguru.org>
* @copyright 2003-2008 Lorenzo Alberton, Richard Heyes
* @license http://www.debian.org/misc/bsd.license BSD License (3 Clause)
* @version CVS: $Id: Jumping.php,v 1.20 2008/03/05 13:57:45 quipo Exp $
* @link http://pear.php.net/package/Pager
*/
/**
* require PEAR::Pager_Common base class
*/
require_once 'Pager/Common.php';
/**
* Pager_Jumping - Generic data paging class ("jumping window" style)
* Handles paging a set of data. For usage see the example.php provided.
*
* @category HTML
* @package Pager
* @author Lorenzo Alberton <l.alberton@quipo.it>
* @author Richard Heyes <richard@phpguru.org>
* @copyright 2003-2008 Lorenzo Alberton, Richard Heyes
* @license http://www.debian.org/misc/bsd.license BSD License (3 Clause)
* @link http://pear.php.net/package/Pager
*/
class Pager_Jumping extends Pager_Common
{
// {{{ Pager_Jumping()
/**
* Constructor
*
* @param array $options Associative array of option names and their values
*
* @access public
*/
function Pager_Jumping($options = array())
{
$err = $this->setOptions($options);
if ($err !== PAGER_OK) {
return $this->raiseError($this->errorMessage($err), $err);
}
$this->build();
}
// }}}
// {{{ getPageIdByOffset()
/**
* Returns pageID for given offset
*
* @param integer $index Offset to get pageID for
*
* @return int PageID for given offset
*/
function getPageIdByOffset($index)
{
if (!isset($this->_pageData)) {
$this->_generatePageData();
}
if (($index % $this->_perPage) > 0) {
$pageID = ceil((float)$index / (float)$this->_perPage);
} else {
$pageID = $index / $this->_perPage;
}
return $pageID;
}
// }}}
// {{{ getPageRangeByPageId()
/**
* Given a PageId, it returns the limits of the range of pages displayed.
* While getOffsetByPageId() returns the offset of the data within the
* current page, this method returns the offsets of the page numbers interval.
* E.g., if you have pageId=3 and delta=10, it will return (1, 10).
* PageID of 8 would give you (1, 10) as well, because 1 <= 8 <= 10.
* PageID of 11 would give you (11, 20).
* If the method is called without parameter, pageID is set to currentPage#.
*
* @param integer $pageid PageID to get offsets for
*
* @return array First and last offsets
* @access public
*/
function getPageRangeByPageId($pageid = null)
{
$pageid = isset($pageid) ? (int)$pageid : $this->_currentPage;
if (isset($this->_pageData[$pageid]) || is_null($this->_itemData)) {
// I'm sure I'm missing something here, but this formula works
// so I'm using it until I find something simpler.
$start = ((($pageid + (($this->_delta - ($pageid % $this->_delta))) % $this->_delta) / $this->_delta) - 1) * $this->_delta +1;
return array(
max($start, 1),
min($start+$this->_delta-1, $this->_totalPages)
);
} else {
return array(0, 0);
}
}
// }}}
// {{{ getLinks()
/**
* Returns back/next/first/last and page links,
* both as ordered and associative array.
*
* NB: in original PEAR::Pager this method accepted two parameters,
* $back_html and $next_html. Now the only parameter accepted is
* an integer ($pageID), since the html text for prev/next links can
* be set in the constructor. If a second parameter is provided, then
* the method act as it previously did. This hack's only purpose is to
* mantain backward compatibility.
*
* @param integer $pageID Optional pageID. If specified, links for that
* page are provided instead of current one.
* [ADDED IN NEW PAGER VERSION]
* @param string $next_html HTML to put inside the next link
* [deprecated: use the factory instead]
*
* @return array Back/pages/next links
*/
function getLinks($pageID=null, $next_html='')
{
//BC hack
if (!empty($next_html)) {
$back_html = $pageID;
$pageID = null;
} else {
$back_html = '';
}
if (!is_null($pageID)) {
$this->links = '';
if ($this->_totalPages > $this->_delta) {
$this->links .= $this->_printFirstPage();
}
$_sav = $this->_currentPage;
$this->_currentPage = $pageID;
$this->links .= $this->_getBackLink('', $back_html);
$this->links .= $this->_getPageLinks();
$this->links .= $this->_getNextLink('', $next_html);
if ($this->_totalPages > $this->_delta) {
$this->links .= $this->_printLastPage();
}
}
$back = str_replace('&nbsp;', '', $this->_getBackLink());
$next = str_replace('&nbsp;', '', $this->_getNextLink());
$pages = $this->_getPageLinks();
$first = $this->_printFirstPage();
$last = $this->_printLastPage();
$all = $this->links;
$linkTags = $this->linkTags;
$linkTagsRaw = $this->linkTagsRaw;
if (!is_null($pageID)) {
$this->_currentPage = $_sav;
}
return array(
$back,
$pages,
trim($next),
$first,
$last,
$all,
$linkTags,
'back' => $back,
'pages' => $pages,
'next' => $next,
'first' => $first,
'last' => $last,
'all' => $all,
'linktags' => $linkTags,
'linkTagsRaw' => $linkTagsRaw,
);
}
// }}}
// {{{ _getPageLinks()
/**
* Returns pages link
*
* @param string $url URL to use in the link
* [deprecated: use the constructor instead]
*
* @return string Links
* @access private
*/
function _getPageLinks($url = '')
{
//legacy setting... the preferred way to set an option now
//is adding it to the constuctor
if (!empty($url)) {
$this->_path = $url;
}
//If there's only one page, don't display links
if ($this->_clearIfVoid && ($this->_totalPages < 2)) {
return '';
}
$links = '';
$limits = $this->getPageRangeByPageId($this->_currentPage);
for ($i=$limits[0]; $i<=min($limits[1], $this->_totalPages); $i++) {
if ($i != $this->_currentPage) {
$this->range[$i] = false;
$this->_linkData[$this->_urlVar] = $i;
$links .= $this->_renderLink(str_replace('%d', $i, $this->_altPage), $i);
} else {
$this->range[$i] = true;
$links .= $this->_curPageSpanPre . $i . $this->_curPageSpanPost;
}
$links .= $this->_spacesBefore
. (($i != $this->_totalPages) ? $this->_separator.$this->_spacesAfter : '');
}
return $links;
}
// }}}
}
?>

View File

@@ -0,0 +1,173 @@
<?php
/**
* Contains the Pager class
*
* PHP versions 4 and 5
*
* LICENSE: Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR "AS IS" AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE FREEBSD PROJECT OR CONTRIBUTORS BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* @category HTML
* @package Pager
* @author Lorenzo Alberton <l.alberton@quipo.it>
* @author Richard Heyes <richard@phpguru.org>
* @copyright 2003-2008 Lorenzo Alberton, Richard Heyes
* @license http://www.debian.org/misc/bsd.license BSD License (3 Clause)
* @version CVS: $Id: Pager.php,v 1.26 2008/02/02 16:55:04 quipo Exp $
* @link http://pear.php.net/package/Pager
*/
/**
* Pager - Wrapper class for [Sliding|Jumping]-window Pager
* Usage examples can be found in the PEAR manual
*
* @category HTML
* @package Pager
* @author Lorenzo Alberton <l.alberton@quipo.it>
* @author Richard Heyes <richard@phpguru.org>
* @copyright 2003-2008 Lorenzo Alberton, Richard Heyes
* @license http://www.debian.org/misc/bsd.license BSD License (3 Clause)
* @link http://pear.php.net/package/Pager
*/
class Pager
{
/**
* Constructor
*
* -------------------------------------------------------------------------
* VALID options are (default values are set some lines before):
* - mode (string): "Jumping" or "Sliding" -window - It determines
* pager behaviour. See the manual for more details
* - totalItems (int): # of items to page.
* - perPage (int): # of items per page.
* - delta (int): # of page #s to show before and after the current
* one
* - linkClass (string): name of CSS class used for link styling.
* - append (bool): if true pageID is appended as GET value to the
* URL - if false it is embedded in the URL
* according to "fileName" specs
* - httpMethod (string): Specifies the HTTP method to use. Valid values
* are 'GET' or 'POST'
* according to "fileName" specs
* - importQuery (bool): if true (default behaviour), variables and
* values are imported from the submitted data
* (query string) and used in the generated links
* otherwise they're ignored completely
* - path (string): complete path to the page (without the page name)
* - fileName (string): name of the page, with a %d if append=true
* - urlVar (string): name of pageNumber URL var, for example "pageID"
* - altPrev (string): alt text to display for prev page, on prev link.
* - altNext (string): alt text to display for next page, on next link.
* - altPage (string): alt text to display before the page number.
* - prevImg (string): sth (it can be text such as "<< PREV" or an
* <img/> as well...) to display instead of "<<".
* - nextImg (string): same as prevImg, used for NEXT link, instead of
* the default value, which is ">>".
* - separator (string): what to use to separate numbers (can be an
* <img/>, a comma, an hyphen, or whatever.
* - spacesBeforeSeparator
* (int): number of spaces before the separator.
* - firstPagePre (string):
* string used before first page number (can be an
* <img/>, a "{", an empty string, or whatever.
* - firstPageText (string):
* string used in place of first page number
* - firstPagePost (string):
* string used after first page number (can be an
* <img/>, a "}", an empty string, or whatever.
* - lastPagePre (string):
* similar to firstPagePre.
* - lastPageText (string):
* similar to firstPageText.
* - lastPagePost (string):
* similar to firstPagePost.
* - spacesAfterSeparator
* (int): number of spaces after the separator.
* - firstLinkTitle (string):
* string used as title in <link rel="first"> tag
* - lastLinkTitle (string):
* string used as title in <link rel="last"> tag
* - prevLinkTitle (string):
* string used as title in <link rel="prev"> tag
* - nextLinkTitle (string):
* string used as title in <link rel="next"> tag
* - curPageLinkClassName
* (string): name of CSS class used for current page link.
* - clearIfVoid(bool): if there's only one page, don't display pager.
* - extraVars (array): additional URL vars to be added to the querystring
* - excludeVars (array): URL vars to be excluded in the querystring
* - itemData (array): array of items to page.
* - useSessions (bool): if true, number of items to display per page is
* stored in the $_SESSION[$_sessionVar] var.
* - closeSession (bool): if true, the session is closed just after R/W.
* - sessionVar (string): name of the session var for perPage value.
* A value != from default can be useful when
* using more than one Pager istance in the page.
* - pearErrorMode (constant):
* PEAR_ERROR mode for raiseError().
* Default is PEAR_ERROR_RETURN.
* -------------------------------------------------------------------------
* REQUIRED options are:
* - fileName IF append==false (default is true)
* - itemData OR totalItems (if itemData is set, totalItems is overwritten)
* -------------------------------------------------------------------------
*
* @param mixed $options Associative array of option names and their values
*
* @access public
*/
public function __construct($options = array())
{
}
/**
* Return a pager based on $mode and $options
*
* @param array $options Optional parameters for the storage class
*
* @return object Storage object
* @static
* @access public
*/
static function &factory($options = array())
{
$mode = (isset($options['mode']) ? ucfirst($options['mode']) : 'Jumping');
$classname = 'Pager_' . $mode;
$classfile = 'Pager' . DIRECTORY_SEPARATOR . $mode . '.php';
// Attempt to include a custom version of the named class, but don't treat
// a failure as fatal. The caller may have already included their own
// version of the named class.
if (!class_exists($classname)) {
include_once $classfile;
}
// If the class exists, return a new instance of it.
if (class_exists($classname)) {
$pager = new $classname($options);
return $pager;
}
$null = null;
return $null;
}
}

View File

@@ -0,0 +1,294 @@
<?php
/* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4: */
/**
* Contains the Pager_Sliding class
*
* PHP versions 4 and 5
*
* LICENSE: Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR "AS IS" AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE FREEBSD PROJECT OR CONTRIBUTORS BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* @category HTML
* @package Pager
* @author Lorenzo Alberton <l.alberton@quipo.it>
* @copyright 2003-2008 Lorenzo Alberton
* @license http://www.debian.org/misc/bsd.license BSD License (3 Clause)
* @version CVS: $Id: Sliding.php,v 1.18 2008/01/06 13:36:22 quipo Exp $
* @link http://pear.php.net/package/Pager
*/
/**
* Pager_Sliding - Generic data paging class ("sliding window" style)
* Usage examples can be found in the PEAR manual
*
* @category HTML
* @package Pager
* @author Lorenzo Alberton <l.alberton@quipo.it>
* @copyright 2003-2008 Lorenzo Alberton
* @license http://www.debian.org/misc/bsd.license BSD License (3 Clause)
* @link http://pear.php.net/package/Pager
*/
class Pager_Sliding extends Pager_Common
{
/**
* Constructor
*
* @param array $options Associative array of option names and their values
*
* @access public
*/
public function __construct($options = array())
{
//set default Pager_Sliding options
$this->_delta = 2;
$this->_prevImg = '&laquo;';
$this->_nextImg = '&raquo;';
$this->_separator = '|';
$this->_spacesBeforeSeparator = 3;
$this->_spacesAfterSeparator = 3;
$this->_curPageSpanPre = '<b>';
$this->_curPageSpanPost = '</b>';
//set custom options
$err = $this->setOptions($options);
if ($err !== PAGER_OK) {
return $this->raiseError($this->errorMessage($err), $err);
}
$this->build();
}
// }}}
// {{{ getPageIdByOffset()
/**
* "Overload" PEAR::Pager method. VOID. Not needed here...
*
* @param integer $index Offset to get pageID for
*
* @return void
* @deprecated
* @access public
*/
function getPageIdByOffset($index)
{
}
// }}}
// {{{ getPageRangeByPageId()
/**
* Given a PageId, it returns the limits of the range of pages displayed.
* While getOffsetByPageId() returns the offset of the data within the
* current page, this method returns the offsets of the page numbers interval.
* E.g., if you have pageId=5 and delta=2, it will return (3, 7).
* PageID of 9 would give you (4, 8).
* If the method is called without parameter, pageID is set to currentPage#.
*
* @param integer $pageid PageID to get offsets for
*
* @return array First and last offsets
* @access public
*/
function getPageRangeByPageId($pageid = null)
{
$pageid = isset($pageid) ? (int)$pageid : $this->_currentPage;
if (!isset($this->_pageData)) {
$this->_generatePageData();
}
if (isset($this->_pageData[$pageid]) || is_null($this->_itemData)) {
if ($this->_expanded) {
$min_surplus = ($pageid <= $this->_delta) ? ($this->_delta - $pageid + 1) : 0;
$max_surplus = ($pageid >= ($this->_totalPages - $this->_delta)) ?
($pageid - ($this->_totalPages - $this->_delta)) : 0;
} else {
$min_surplus = $max_surplus = 0;
}
return array(
max($pageid - $this->_delta - $max_surplus, 1),
min($pageid + $this->_delta + $min_surplus, $this->_totalPages)
);
}
return array(0, 0);
}
// }}}
// {{{ getLinks()
/**
* Returns back/next/first/last and page links,
* both as ordered and associative array.
*
* @param integer $pageID Optional pageID. If specified, links for that page
* are provided instead of current one.
* @param string $dummy used to comply with parent signature (leave empty)
*
* @return array back/pages/next/first/last/all links
* @access public
*/
function getLinks($pageID = null, $dummy='')
{
if (!is_null($pageID)) {
$_sav = $this->_currentPage;
$this->_currentPage = $pageID;
$this->links = '';
if ($this->_totalPages > (2 * $this->_delta + 1)) {
$this->links .= $this->_printFirstPage();
}
$this->links .= $this->_getBackLink();
$this->links .= $this->_getPageLinks();
$this->links .= $this->_getNextLink();
if ($this->_totalPages > (2 * $this->_delta + 1)) {
$this->links .= $this->_printLastPage();
}
}
$back = str_replace('&nbsp;', '', $this->_getBackLink());
$next = str_replace('&nbsp;', '', $this->_getNextLink());
$pages = $this->_getPageLinks();
$first = $this->_printFirstPage();
$last = $this->_printLastPage();
$all = $this->links;
$linkTags = $this->linkTags;
$linkTagsRaw = $this->linkTagsRaw;
if (!is_null($pageID)) {
$this->_currentPage = $_sav;
}
return array(
$back,
$pages,
trim($next),
$first,
$last,
$all,
$linkTags,
'back' => $back,
'pages' => $pages,
'next' => $next,
'first' => $first,
'last' => $last,
'all' => $all,
'linktags' => $linkTags,
'linkTagsRaw' => $linkTagsRaw,
);
}
// }}}
// {{{ _getPageLinks()
/**
* Returns pages link
*
* @param string $url URL string [deprecated]
*
* @return string Links
* @access private
*/
function _getPageLinks($url = '')
{
//legacy setting... the preferred way to set an option now
//is adding it to the constuctor
if (!empty($url)) {
$this->_path = $url;
}
//If there's only one page, don't display links
if ($this->_clearIfVoid && ($this->_totalPages < 2)) {
return '';
}
$links = '';
if ($this->_totalPages > (2 * $this->_delta + 1)) {
if ($this->_expanded) {
if (($this->_totalPages - $this->_delta) <= $this->_currentPage) {
$expansion_before = $this->_currentPage - ($this->_totalPages - $this->_delta);
} else {
$expansion_before = 0;
}
for ($i = $this->_currentPage - $this->_delta - $expansion_before; $expansion_before; $expansion_before--, $i++) {
$print_separator_flag = ($i != $this->_currentPage + $this->_delta); // && ($i != $this->_totalPages - 1)
$this->range[$i] = false;
$this->_linkData[$this->_urlVar] = $i;
$links .= $this->_renderLink(str_replace('%d', $i, $this->_altPage), $i)
. $this->_spacesBefore
. ($print_separator_flag ? $this->_separator.$this->_spacesAfter : '');
}
}
$expansion_after = 0;
for ($i = $this->_currentPage - $this->_delta; ($i <= $this->_currentPage + $this->_delta) && ($i <= $this->_totalPages); $i++) {
if ($i < 1) {
++$expansion_after;
continue;
}
// check when to print separator
$print_separator_flag = (($i != $this->_currentPage + $this->_delta) && ($i != $this->_totalPages));
if ($i == $this->_currentPage) {
$this->range[$i] = true;
$links .= $this->_curPageSpanPre . $i . $this->_curPageSpanPost;
} else {
$this->range[$i] = false;
$this->_linkData[$this->_urlVar] = $i;
$links .= $this->_renderLink(str_replace('%d', $i, $this->_altPage), $i);
}
$links .= $this->_spacesBefore
. ($print_separator_flag ? $this->_separator.$this->_spacesAfter : '');
}
if ($this->_expanded && $expansion_after) {
$links .= $this->_separator . $this->_spacesAfter;
for ($i = $this->_currentPage + $this->_delta +1; $expansion_after; $expansion_after--, $i++) {
$print_separator_flag = ($expansion_after != 1);
$this->range[$i] = false;
$this->_linkData[$this->_urlVar] = $i;
$links .= $this->_renderLink(str_replace('%d', $i, $this->_altPage), $i)
. $this->_spacesBefore
. ($print_separator_flag ? $this->_separator.$this->_spacesAfter : '');
}
}
} else {
//if $this->_totalPages <= (2*Delta+1) show them all
for ($i=1; $i<=$this->_totalPages; $i++) {
if ($i != $this->_currentPage) {
$this->range[$i] = false;
$this->_linkData[$this->_urlVar] = $i;
$links .= $this->_renderLink(str_replace('%d', $i, $this->_altPage), $i);
} else {
$this->range[$i] = true;
$links .= $this->_curPageSpanPre . $i . $this->_curPageSpanPost;
}
$links .= $this->_spacesBefore
. (($i != $this->_totalPages) ? $this->_separator.$this->_spacesAfter : '');
}
}
return $links;
}
// }}}
}
?>

View File

@@ -0,0 +1,6 @@
<html>
<head>
</head>
<body>
</body>
</html>

View File

@@ -0,0 +1,156 @@
<?php
/**
* Text_CAPTCHA - creates a CAPTCHA for Turing tests.
* Base class file for using Text_CAPTCHA.
*
* PHP version 5
*
* @category Text
* @package Text_CAPTCHA
* @author Christian Wenz <wenz@php.net>
* @license http://www.opensource.org/licenses/bsd-license.php BSD License
* @link http://pear.php.net/package/Text_CAPTCHA
*/
/**
* Text_CAPTCHA - creates a CAPTCHA for Turing tests.
* Class to create a Turing test for websites by creating an image, ASCII art or
* something else with some (obfuscated) characters.
*
* @category Text
* @package Text_CAPTCHA
* @author Christian Wenz <wenz@php.net>
* @author Michael Cramer <michael@bigmichi1.de>
* @license http://www.opensource.org/licenses/bsd-license.php BSD License
* @link http://pear.php.net/package/Text_CAPTCHA
*/
class Text_CAPTCHA
{
/**
* driver for Text_CAPTCHA
*
* @var Text_CAPTCHA_Driver_Base
*/
private $_driver;
/**
* check if an initial driver init was done.
*
* @var bool
*/
private $_driverInitDone = false;
/**
* Constructor for the TEXT_CAPTCHA object with the given driver.
*
* @param Text_CAPTCHA_Driver $driver driver
*
* @throws Text_CAPTCHA_Exception no driver given
*/
function __construct($driver)
{
if (is_null($driver)) {
throw new Text_CAPTCHA_Exception("No driver given");
}
$this->_driver = $driver;
$this->_driverInitDone = false;
}
/**
* Create a new Text_CAPTCHA object.
*
* @param string $driver name of driver class to initialize
*
* @return Text_CAPTCHA a newly created Text_CAPTCHA object
* @throws Text_CAPTCHA_Exception when driver could not be loaded
*
*/
public static function factory($driver)
{
$driver = basename($driver);
$class = 'Text_CAPTCHA_Driver_' . $driver;
/*$file = str_replace('_', '/', $class) . '.php';
//check if it exists and can be loaded
if (!@fclose(@fopen($file, 'r', true))) {
throw new Text_CAPTCHA_Exception(
'Driver ' . $driver . ' cannot be loaded.'
);
}
//continue with including the driver
include_once $file;*/
$driver = new $class;
return new Text_CAPTCHA($driver);
}
/**
* Create random CAPTCHA phrase
*
* @param boolean|string $newPhrase new Phrase to use or true to generate a new
* one
*
* @return void
* @throws Text_CAPTCHA_Exception when driver is not initialized
*/
public final function generate($newPhrase = false)
{
if (!$this->_driverInitDone) {
throw new Text_CAPTCHA_Exception("Driver not initialized");
}
if ($newPhrase === true || is_null($this->_driver->getPhrase())) {
$this->_driver->createPhrase();
} else if (strlen($newPhrase) > 0) {
$this->_driver->setPhrase($newPhrase);
}
$this->_driver->createCAPTCHA();
}
/**
* Reinitialize the entire Text_CAPTCHA object.
*
* @param array $options Options to pass in.
*
* @return void
*/
public final function init($options = array())
{
$this->_driver->resetDriver();
$this->_driver->initDriver($options);
$this->_driverInitDone = true;
$this->generate();
}
/**
* Place holder for the real getCAPTCHA() method used by extended classes to
* return the generated CAPTCHA (as an image resource, as an ASCII text, ...).
*
* @return string|object
*/
public final function getCAPTCHA()
{
return $this->_driver->getCAPTCHA();
}
/**
* Return secret CAPTCHA phrase.
*
* @return string secret phrase
*/
public final function getPhrase()
{
return $this->_driver->getPhrase();
}
/**
* Place holder for the real getCAPTCHA() method used by extended classes to
* return the generated CAPTCHA (as an image resource, as an ASCII text, ...).
*
* @return string|object
*/
public function getCAPTCHAAsJPEG()
{
return $this->_driver->_getCAPTCHAAsJPEG();
}
}

View File

@@ -0,0 +1,56 @@
<?php
/**
* Interface for Drivers
*
* PHP version 5
*
* @category Text
* @package Text_CAPTCHA
* @author Michael Cramer <michael@bigmichi1.de>
* @license http://www.opensource.org/licenses/bsd-license.php BSD License
* @link http://pear.php.net/package/Text_CAPTCHA
*/
/**
* Interface for Text_CAPTCHA drivers
*
* @category Text
* @package Text_CAPTCHA
* @author Michael Cramer <michael@bigmichi1.de>
* @license http://www.opensource.org/licenses/bsd-license.php BSD License
* @link http://pear.php.net/package/Text_CAPTCHA
*/
interface Text_CAPTCHA_Driver
{
/**
* Clear the internal state of the driver.
*
* @return void
*/
function resetDriver();
/**
* Initialize the driver with the given options.
*
* @param array $options options for the driver as array
*
* @return void
* @throws Text_CAPTCHA_Exception something went wrong during init
*/
function initDriver($options);
/**
* Generate the CAPTCHA.
*
* @return void
* @throws Text_CAPTCHA_Exception something went wrong during creation of CAPTCHA
*/
function createCAPTCHA();
/**
* Generate the phrase for the CAPTCHA.
*
* @return void
* @throws Text_CAPTCHA_Exception something went wrong during creation of phrase
*/
function createPhrase();
}

View File

@@ -0,0 +1,97 @@
<?php
/**
* Base class file for all Text_CAPTCHA drivers.
*
* PHP version 5
*
* @category Text
* @package Text_CAPTCHA
* @author Michael Cramer <michael@bigmichi1.de>
* @license http://www.opensource.org/licenses/bsd-license.php BSD License
* @link http://pear.php.net/package/Text_CAPTCHA
*/
/**
* Base class file for all Text_CAPTCHA drivers.
*
* @category Text
* @package Text_CAPTCHA
* @author Michael Cramer <michael@bigmichi1.de>
* @license http://www.opensource.org/licenses/bsd-license.php BSD License
* @link http://pear.php.net/package/Text_CAPTCHA
*/
abstract class Text_CAPTCHA_Driver_Base implements Text_CAPTCHA_Driver
{
/**
* Captcha
*
* @var object|string
*/
private $_captcha;
/**
* Phrase
*
* @var string
*/
private $_phrase;
/**
* Sets secret CAPTCHA phrase.
* This method sets the CAPTCHA phrase (use null for a random phrase)
*
* @param string $phrase The (new) phrase
*
* @return void
*/
public final function setPhrase($phrase)
{
$this->_phrase = $phrase;
}
/**
* Return secret CAPTCHA phrase
* This method returns the CAPTCHA phrase
*
* @return string secret phrase
*/
public final function getPhrase()
{
return $this->_phrase;
}
/**
* Sets the generated captcha.
*
* @param object|string $captcha the generated captcha
*
* @return void
*/
protected final function setCaptcha($captcha)
{
$this->_captcha = $captcha;
}
/**
* Place holder for the real getCAPTCHA() method
* used by extended classes to return the generated CAPTCHA
* (as an image resource, as an ASCII text, ...)
*
* @return string|object
*/
public final function getCAPTCHA()
{
return $this->_captcha;
}
/**
* Reset the phrase and the CAPTCHA.
*
* @return void
*/
public function resetDriver()
{
$this->setPhrase(null);
$this->setCaptcha(null);
}
}

View File

@@ -0,0 +1,215 @@
<?php
/**
* Equation driver for Text_CAPTCHA.
* Returns simple equations as string, e.g. "9 - 2"
*
* PHP version 5
*
* @category Text
* @package Text_CAPTCHA
* @author Christian Weiske <cweiske@php.net>
* @author Christian Wenz <wenz@php.net>
* @author Michael Cramer <michael@bigmichi1.de>
* @license http://www.opensource.org/licenses/bsd-license.php BSD License
* @link http://pear.php.net/package/Text_CAPTCHA
*/
/**
* Equation driver for Text_CAPTCHA.
* Returns simple equations as string, e.g. "9 - 2"
*
* @category Text
* @package Text_CAPTCHA
* @author Christian Weiske <cweiske@php.net>
* @author Christian Wenz <wenz@php.net>
* @author Michael Cramer <michael@bigmichi1.de>
* @license http://www.opensource.org/licenses/bsd-license.php BSD License
* @link http://pear.php.net/package/Text_CAPTCHA
*/
class Text_CAPTCHA_Driver_Equation extends Text_CAPTCHA_Driver_Base
{
/**
* Operators that may be used in the equation. Two numbers have to be filled in,
* and %s is needed since number2text conversion may be applied and strings
* filled in.
*
* @var array
*/
private $_operators = array(
'%s * %s',
'%s + %s',
'%s - %s',
'min(%s, %s)',
'max(%s, %s)'
);
/**
* Minimal number to use in an equation.
*
* @var int
*/
private $_min = 1;
/**
* Maximum number to use in an equation.
*
* @var int
*/
private $_max = 10;
/**
* Whether numbers shall be converted to text.
*
* @var bool
*/
private $_numbersToText = false;
/**
* This variable holds the locale for Numbers_Words.
*
* @var string
*/
private $_locale = '';
/**
* Complexity of the generated equations.<br>
* 1 - simple ones such as "1 + 10"<br>
* 2 - harder ones such as "(3-2)*(min(5,6))"
*
* @var int
*/
private $_severity = 1;
/**
* Initialize the driver.
*
* @param array $options CAPTCHA options with these keys:<br>
* min minimum numeric value
* max maximum numeric value
* numbersToText boolean for number to text conversion
* locale locale for number to text conversion
* severity number for complexity
*
* @return void
* @throws Text_CAPTCHA_Exception when numbersToText is true, but Number_Words
* package is not available
*/
public function initDriver($options = array())
{
if (isset($options['min'])) {
$this->_min = (int)$options['min'];
} else {
$this->_min = 1;
}
if (isset($options['max'])) {
$this->_max = (int)$options['max'];
} else {
$this->_max = 10;
}
if (isset($options['numbersToText'])) {
$this->_numbersToText = (bool)$options['numbersToText'];
} else {
$this->_numbersToText = false;
}
if (isset($options['locale'])) {
$this->_locale = (string)$options['locale'];
} else {
$this->_locale = '';
}
if (isset($options['severity'])) {
$this->_severity = (int)$options['severity'];
} else {
$this->_severity = 1;
}
if ($this->_numbersToText) {
include_once 'Numbers/Words.php';
if (!class_exists('Numbers_Words')) {
throw new Text_CAPTCHA_Exception('Number_Words package required');
}
}
}
/**
* Create random CAPTCHA equation.
* This method creates a random equation.
*
* @return void
* @throws Text_CAPTCHA_Exception when invalid severity is specified
*/
public function createCAPTCHA()
{
switch ($this->_severity) {
case 1:
list($equation, $phrase) = $this->_createSimpleEquation();
break;
case 2:
list($eq1, $sol1) = $this->_createSimpleEquation();
list($eq2, $sol2) = $this->_createSimpleEquation();
$op3 = $this->_operators[mt_rand(0, count($this->_operators) - 1)];
list(, $phrase) = $this->_solveSimpleEquation($sol1, $sol2, $op3);
$equation = sprintf($op3, '(' . $eq1 . ')', '(' . $eq2 . ')');
break;
default:
throw new Text_CAPTCHA_Exception(
'Equation complexity of ' . $this->_severity . ' not supported'
);
}
$this->setCaptcha($equation);
$this->setPhrase($phrase);
}
/**
* Creates a simple equation of type (number operator number).
*
* @return array Array with equation and solution
*/
private function _createSimpleEquation()
{
$one = mt_rand($this->_min, $this->_max);
$two = mt_rand($this->_min, $this->_max);
$operator = $this->_operators[mt_rand(0, count($this->_operators) - 1)];
return $this->_solveSimpleEquation($one, $two, $operator);
}
/**
* Solves a simple equation with two given numbers and one operator as defined
* in $this->_operators.
* Also converts the numbers to words if required.
*
* @param int $one First number
* @param int $two Second number
* @param string $operator Operator used with those two numbers
*
* @return array Array with equation and solution
*/
private function _solveSimpleEquation($one, $two, $operator)
{
$equation = sprintf($operator, $one, $two);
$function = create_function('', 'return ' . $equation . ';');
if ($this->_numbersToText) {
$numberWords = new Numbers_Words();
$equation = sprintf(
$operator,
$numberWords->toWords($one, $this->_locale),
$numberWords->toWords($two, $this->_locale)
);
}
return array($equation, $function());
}
/**
* Creates the captcha. This method is a placeholder, since the equation is
* created in createCAPTCHA()
*
* @return void
* @see createCAPTCHA()
*/
public function createPhrase()
{
$this->setPhrase(null);
}
}

View File

@@ -0,0 +1,231 @@
<?php
/**
* Require Figlet class for rendering the text.
*
* PHP version 5
*
* @category Text
* @package Text_CAPTCHA
* @author Aaron Wormus <wormus@php.net>
* @author Christian Wenz <wenz@php.net>
* @author Michael Cramer <michael@bigmichi1.de>
* @license http://www.opensource.org/licenses/bsd-license.php BSD License
* @link http://pear.php.net/package/Text_CAPTCHA
*/
/**
* Text_CAPTCHA_Driver_Figlet - Text_CAPTCHA driver Figlet based CAPTCHAs
*
* @category Text
* @package Text_CAPTCHA
* @author Aaron Wormus <wormus@php.net>
* @author Christian Wenz <wenz@php.net>
* @license http://www.opensource.org/licenses/bsd-license.php BSD License
* @link http://pear.php.net/package/Text_CAPTCHA
* @todo define an obfuscation algorithm
*/
class Text_CAPTCHA_Driver_Figlet extends Text_CAPTCHA_Driver_Base
{
/**
* Text_Password options.
*
* @var array
*/
private $_textPasswordOptions;
/**
* Width of CAPTCHA
*
* @var int
*/
private $_width;
/**
* Length of CAPTCHA
*
* @var int
*/
private $_length;
/**
* Figlet font
*
* @var string
*/
private $_font;
/**
* Figlet font
*
* @var array
*/
private $_style = array();
/**
* Output Format
*
* @var string
*/
private $_output;
/**
* init function
*
* Initializes the new Text_CAPTCHA_Driver_Figlet object and creates a GD image
*
* @param array $options CAPTCHA options
*
* @return void
* @throws Text_CAPTCHA_Exception when no options are given
*/
public function initDriver($options = array())
{
if (!empty($options['output'])) {
$this->_output = (string)$options['output'];
} else {
$this->_output = 'html';
}
if (isset($options['width']) && $options['width']) {
$this->_width = (int)$options['width'];
} else {
$this->_width = 200;
}
if (!empty($options['length'])) {
$this->_length = $options['length'];
} else {
$this->_length = 6;
}
if (!isset($options['phrase']) || empty($options['phrase'])) {
$phraseOptions = (isset($options['phraseOptions'])
&& is_array($options['phraseOptions']))
? $options['phraseOptions'] : array();
$this->_textPasswordOptions = $phraseOptions;
} else {
$this->setPhrase($options['phrase']);
}
if (!empty($options['style'])
&& is_array($options['style'])
) {
$this->_style = $options['style'];
}
if (empty($this->_style['padding'])) {
$this->_style['padding'] = '5px';
}
if (!empty($options['font_file'])) {
if (is_array($options['font_file'])) {
$arr = $options['font_file'];
$this->_font = $arr[array_rand($arr)];
} else {
$this->_font = $options['font_file'];
}
}
}
/**
* Create the passphrase.
*
* @return string
*/
public function createPhrase()
{
$options = $this->_textPasswordOptions;
$textPassword = new Text_Password();
if (!is_array($options) || count($options) === 0) {
$this->setPhrase($textPassword->create($this->_length));
} else {
if (count($options) === 1) {
$this->setPhrase($textPassword->create($this->_length, $options[0]));
} else {
$this->setPhrase(
$textPassword->create($this->_length, $options[0], $options[1])
);
}
}
}
/**
* Create CAPTCHA image.
*
* This method creates a CAPTCHA image.
*
* @return void on error
* @throws Text_CAPTCHA_Exception when loading font fails
*/
public function createCAPTCHA()
{
$pear = new PEAR();
$figlet = new Text_Figlet();
if ($pear->isError($figlet->loadFont($this->_font))) {
throw new Text_CAPTCHA_Exception('Error loading Text_Figlet font');
}
$outputString = $figlet->lineEcho($this->getPhrase());
switch ($this->_output) {
case 'text':
$this->setCaptcha($outputString);
break;
case 'html':
$this->setCaptcha($this->_getCAPTCHAAsHTML($outputString));
break;
case 'javascript':
$this->setCaptcha($this->_getCAPTCHAAsJavascript($outputString));
break;
default:
throw new Text_CAPTCHA_Exception('Invalid output option given');
}
}
/**
* Return CAPTCHA as HTML.
*
* This method returns the CAPTCHA as HTML.
*
* @param string $figletOutput output string from Figlet.
*
* @return string HTML Figlet image or PEAR error
*/
private function _getCAPTCHAAsHTML($figletOutput)
{
$charWidth = strpos($figletOutput, "\n");
$data = str_replace("\n", '<br />', $figletOutput);
$textSize = ($this->_width / $charWidth) * 1.4;
$cssOutput = "";
foreach ($this->_style as $key => $value) {
$cssOutput .= "$key: $value;";
}
$htmlOutput = '<div style="font-family: courier;
font-size: ' . $textSize . 'px;
width:' . $this->_width . 'px;
text-align:center;">';
$htmlOutput .= '<div style="' . $cssOutput . 'margin:0px;">
<pre style="padding: 0px; margin: 0px;">' . $data . '</pre></div></div>';
return $htmlOutput;
}
/**
* Return CAPTCHA as Javascript version of HTML.
*
* This method returns the CAPTCHA as a Javascript string.
* I'm not exactly sure what the point of doing this would be.
*
* @param string $figletOutput output string from Figlet.
*
* @return string javascript string or PEAR error
*/
private function _getCAPTCHAAsJavascript($figletOutput)
{
$obfusData = rawurlencode($figletOutput);
$javascript = "<script language=\"javascript\">
document.write(unescape(\"$obfusData\" ) );
</script>";
return $javascript;
}
}

View File

@@ -0,0 +1,289 @@
<?php
/**
* Require Image_Text class for generating the text.
*
* PHP version 5
*
* @category Text
* @package Text_CAPTCHA
* @author Christian Wenz <wenz@php.net>
* @author Michael Cramer <michael@bigmichi1.de>
* @license http://www.opensource.org/licenses/bsd-license.php BSD License
* @link http://pear.php.net/package/Text_CAPTCHA
*/
/**
* Text_CAPTCHA_Driver_Image - Text_CAPTCHA driver graphical CAPTCHAs
*
* Class to create a graphical Turing test
*
* @category Text
* @package Text_CAPTCHA
* @author Christian Wenz <wenz@php.net>
* @author Michael Cramer <michael@bigmichi1.de>
* @license http://www.opensource.org/licenses/bsd-license.php BSD License
* @link http://pear.php.net/package/Text_CAPTCHA
* @todo refine the obfuscation algorithm :-)
* @todo consider removing Image_Text dependency
*/
class Text_CAPTCHA_Driver_Image extends Text_CAPTCHA_Driver_Base
{
/**
* Text_Password options.
*
* @var array
*/
private $_textPasswordOptions;
/**
* Width of CAPTCHA
*
* @var int
*/
private $_width;
/**
* Height of CAPTCHA
*
* @var int
*/
private $_height;
/**
* CAPTCHA output format
*
* @var string
*/
private $_output;
/**
* Further options (here: for Image_Text)
*
* @var array
*/
private $_imageOptions = array(
'font_size' => 24,
'font_path' => './',
'font_file' => 'COUR.TTF',
'text_color' => '#000000',
'lines_color' => '#CACACA',
'background_color' => '#555555',
'antialias' => false
);
/**
* Init function
*
* Initializes the new Text_CAPTCHA_Driver_Image object and creates a GD image
*
* @param array $options CAPTCHA options
*
* @return void
*/
public function initDriver($options = array())
{
if (is_array($options)) {
if (isset($options['width']) && is_int($options['width'])) {
$this->_width = $options['width'];
} else {
$this->_width = 200;
}
if (isset($options['height']) && is_int($options['height'])) {
$this->_height = $options['height'];
} else {
$this->_height = 80;
}
if (!isset($options['phrase']) || empty($options['phrase'])) {
$phraseOptions = (isset($options['phraseOptions'])
&& is_array($options['phraseOptions']))
? $options['phraseOptions'] : array();
$this->_textPasswordOptions = $phraseOptions;
} else {
$this->setPhrase($options['phrase']);
}
if (!isset($options['output']) || empty($options['output'])) {
$this->_output = 'jpeg';
} else {
$this->_output = $options['output'];
}
if (isset($options['imageOptions'])
&& is_array($options['imageOptions'])
&& count($options['imageOptions']) > 0
) {
$this->_imageOptions = array_merge(
$this->_imageOptions, $options['imageOptions']
);
}
}
}
/**
* Create CAPTCHA image.
*
* This method creates a CAPTCHA image.
*
* @return void
* @throws Text_CAPTCHA_Exception when image generation with Image_Text produces
* an error
*/
public function createCAPTCHA()
{
$options['canvas'] = array(
'width' => $this->_width,
'height' => $this->_height
);
$options['width'] = $this->_width - 20;
$options['height'] = $this->_height - 20;
$options['cx'] = ceil(($this->_width) / 2 + 10);
$options['cy'] = ceil(($this->_height) / 2 + 10);
$options['angle'] = rand(0, 30) - 15;
$options['font_size'] = $this->_imageOptions['font_size'];
$options['font_path'] = $this->_imageOptions['font_path'];
$options['font_file'] = $this->_imageOptions['font_file'];
$options['color'] = array($this->_imageOptions['text_color']);
$options['background_color'] = $this->_imageOptions['background_color'];
$options['max_lines'] = 1;
$options['mode'] = 'auto';
do {
$imageText = new Image_Text($this->getPhrase(), $options);
$imageText->init();
$result = $imageText->measurize();
} while ($result === false && --$options['font_size'] > 0);
if ($result === false) {
throw new Text_CAPTCHA_Exception(
'The text provided does not fit in the image dimensions'
);
}
$imageText->render();
$image = $imageText->getImg();
if ($this->_imageOptions['antialias'] && function_exists('imageantialias')) {
imageantialias($image, true);
}
$colors = Image_Text::convertString2RGB(
$this->_imageOptions['lines_color']
);
$linesColor = imagecolorallocate(
$image, $colors['r'], $colors['g'], $colors['b']
);
//some obfuscation
for ($i = 0; $i < 3; $i++) {
$x1 = rand(0, $this->_width - 1);
$y1 = rand(0, round($this->_height / 10, 0));
$x2 = rand(0, round($this->_width / 10, 0));
$y2 = rand(0, $this->_height - 1);
imageline($image, $x1, $y1, $x2, $y2, $linesColor);
$x1 = rand(0, $this->_width - 1);
$y1 = $this->_height - rand(1, round($this->_height / 10, 0));
$x2 = $this->_width - rand(1, round($this->_width / 10, 0));
$y2 = rand(0, $this->_height - 1);
imageline($image, $x1, $y1, $x2, $y2, $linesColor);
$cx = rand(0, $this->_width - 50) + 25;
$cy = rand(0, $this->_height - 50) + 25;
$w = rand(1, 24);
imagearc($image, $cx, $cy, $w, $w, 0, 360, $linesColor);
}
// @todo remove hardcoded value
$this->_output = 'jpg';
if ($this->_output == 'gif' && imagetypes() & IMG_GIF) {
$this->setCaptcha($this->_getCAPTCHAAsGIF($image));
} else if (($this->_output == 'jpg' && imagetypes() & IMG_JPG)
|| ($this->_output == 'jpeg' && imagetypes() & IMG_JPEG)
) {
$this->setCaptcha($this->_getCAPTCHAAsJPEG($image));
} else if ($this->_output == 'png' && imagetypes() & IMG_PNG) {
$this->setCaptcha($this->_getCAPTCHAAsPNG($image));
} else if ($this->_output == 'resource') {
$this->setCaptcha($image);
} else {
throw new Text_CAPTCHA_Exception(
"Unknown or unsupported output type specified"
);
}
imagedestroy($image);
}
/**
* Return CAPTCHA as PNG.
*
* This method returns the CAPTCHA as PNG.
*
* @param resource $image generated image
*
* @return string image contents
*/
private function _getCAPTCHAAsPNG($image)
{
ob_start();
imagepng($image);
$data = ob_get_contents();
ob_end_clean();
return $data;
}
/**
* Return CAPTCHA as JPEG.
*
* This method returns the CAPTCHA as JPEG.
*
* @param resource $image generated image
*
* @return string image contents
*/
public function _getCAPTCHAAsJPEG($image)
{
ob_start();
imagejpeg($image);
$data = ob_get_contents();
ob_end_clean();
return $data;
}
/**
* Return CAPTCHA as GIF.
*
* This method returns the CAPTCHA as GIF.
*
* @param resource $image generated image
*
* @return string image contents
*/
private function _getCAPTCHAAsGIF($image)
{
ob_start();
imagegif($image);
$data = ob_get_contents();
ob_end_clean();
return $data;
}
/**
* Create random CAPTCHA phrase, Image edition (with size check).
*
* This method creates a random phrase, maximum 8 characters or width / 25,
* whatever is smaller.
*
* @return void
*/
public function createPhrase()
{
$len = intval(min(8, $this->_width / 25));
$options = $this->_textPasswordOptions;
$textPassword = new Text_Password();
if (!is_array($options) || count($options) === 0) {
$this->setPhrase($textPassword->create($len));
} else {
if (count($options) === 1) {
$this->setPhrase($textPassword->create($len, $options[0]));
} else {
$this->setPhrase(
$textPassword->create($len, $options[0], $options[1])
);
}
}
}
}

View File

@@ -0,0 +1,268 @@
<?php
/**
* Class used for numeral captchas
*
* PHP version 5
*
* @category Text
* @package Text_CAPTCHA
* @author David Coallier <davidc@agoraproduction.com>
* @author Christian Wenz <wenz@php.net>
* @author Michael Cramer <michael@bigmichi1.de>
* @license http://www.opensource.org/licenses/bsd-license.php BSD License
* @link http://pear.php.net/package/Text_CAPTCHA
*/
/**
* Class used for numeral captchas
*
* This class is intended to be used to generate numeral captchas as such as:
* Example:
* Give me the answer to "54 + 2" to prove that you are human.
*
* @category Text
* @package Text_CAPTCHA
* @author David Coallier <davidc@agoraproduction.com>
* @author Christian Wenz <wenz@php.net>
* @author Michael Cramer <michael@bigmichi1.de>
* @license http://www.opensource.org/licenses/bsd-license.php BSD License
* @link http://pear.php.net/package/Text_CAPTCHA
*/
class Text_CAPTCHA_Driver_Numeral extends Text_CAPTCHA_Driver_Base
{
/**
* This variable holds the minimum range value default set to "1".
*
* @var integer $_minValue The minimum value of the number range.
*/
private $_minValue = 1;
/**
* This variable holds the maximum range value default set to "50".
*
* @var integer $_maxValue The maximum value of the number range.
*/
private $_maxValue = 50;
/**
* The valid operators to use in the numeral captcha. We could use / and * but
* not yet.
*
* @var array $_operators The operations for the captcha.
*/
private $_operators = array('-', '+');
/**
* This variable is basically the operation that we're going to be using in the
* numeral captcha we are about to generate.
*
* @var string $_operator The operation's operator to use.
*/
private $_operator = '';
/**
* This variable holds the first number of the numeral operation we are about to
* generate.
*
* @var integer $_firstNumber The first number of the operation.
*/
private $_firstNumber = 0;
/**
* This variable holds the value of the second variable of the operation we are
* about to generate for the captcha.
*
* @var integer $_secondNumber The second number of the operation.
*/
private $_secondNumber = 0;
/**
* Initialize numeric CAPTCHA.
*
* @param array $options CAPTCHA options with these keys:<br>
* minValue minimum value<br>
* maxValue maximum value
*
* @return void
*/
public function initDriver($options = array())
{
if (isset($options['minValue'])) {
$this->_minValue = (int)$options['minValue'];
} else {
$this->_minValue = 1;
}
if (isset($options['maxValue'])) {
$this->_maxValue = (int)$options['maxValue'];
} else {
$this->_maxValue = 50;
}
if (isset($options['operator'])) {
$this->_operator = $options['operator'];
} else {
$this->_operator = '';
}
if (isset($options['firstValue'])) {
$this->_firstNumber = (int)$options['firstValue'];
} else {
$this->_firstNumber = 0;
}
if (isset($options['secondValue'])) {
$this->_secondNumber = (int)$options['secondValue'];
} else {
$this->_secondNumber = 0;
}
}
/**
* Create the CAPTCHA (the numeral expression).
*
* This function determines a random numeral expression and set the associated
* class properties.
*
* @return void
* @see _generateFirstNumber()
* @see _generateSecondNumber()
* @see _generateOperator()
* @see _generateOperation()
*/
public function createCAPTCHA()
{
if ($this->_firstNumber == 0) {
$this->_firstNumber = $this->_generateNumber();
}
if ($this->_secondNumber == 0) {
$this->_secondNumber = $this->_generateNumber();
}
if (empty($this->_operator)) {
$this->_operator = $this->_operators[array_rand($this->_operators)];
}
$this->_generateOperation();
}
/**
* Set operation.
*
* This variable sets the operation variable by taking the firstNumber,
* secondNumber and operator.
*
* @return void
* @see _operation
* @see _firstNumber
* @see _operator
* @see _secondNumber
*/
private function _setOperation()
{
$this->setCaptcha(
$this->_firstNumber . ' ' . $this->_operator . ' ' . $this->_secondNumber
);
}
/**
* Generate a number.
*
* This function takes the parameters that are in the $this->_maxValue and
* $this->_minValue and get the random number from them using mt_rand().
*
* @return integer Random value between _minValue and _maxValue
* @see _minValue
* @see _maxValue
*/
private function _generateNumber()
{
return mt_rand($this->_minValue, $this->_maxValue);
}
/**
* Adds values.
*
* This function will add the firstNumber and the secondNumber value and then
* call setAnswer to set the answer value.
*
* @return void
* @see _firstNumber
* @see _secondNumber
* @see _setAnswer()
*/
private function _doAdd()
{
$phrase = $this->_firstNumber + $this->_secondNumber;
$this->setPhrase($phrase);
}
/**
* Does a subtract on the values.
*
* This function executes a subtraction on the firstNumber and the secondNumber
* to then call $this->setAnswer to set the answer value.
*
* If the _firstNumber value is smaller than the _secondNumber value then we
* regenerate the first number and regenerate the operation.
*
* @return void
* @see _firstNumber
* @see _secondNumber
* @see _setOperation()
* @see Text_CAPTCHA::setPhrase()
*/
private function _doSubtract()
{
$first = $this->_firstNumber;
$second = $this->_secondNumber;
/**
* Check if firstNumber is smaller than secondNumber
*/
if ($first < $second) {
$this->_firstNumber = $second;
$this->_secondNumber = $first;
$this->_setOperation();
}
$phrase = $this->_firstNumber - $this->_secondNumber;
$this->setPhrase($phrase);
}
/**
* Generate the operation
*
* This function will call the _setOperation() function to set the operation
* string that will be called to display the operation, and call the function
* necessary depending on which operation is set by this->operator.
*
* @return void
* @see _setOperation()
* @see _operator
* @see _doAdd()
* @see _doSubtract()
*/
private function _generateOperation()
{
$this->_setOperation();
switch ($this->_operator) {
case '+':
$this->_doAdd();
break;
case '-':
$this->_doSubtract();
break;
default:
$this->_operator = "+";
$this->_setOperation();
$this->_doAdd();
break;
}
}
/**
* Create random CAPTCHA phrase. This method is a placeholder, since the equation
* is created in createCAPTCHA()
*
* @return string
*/
public function createPhrase()
{
$this->setCaptcha(null);
}
}

View File

@@ -0,0 +1,126 @@
<?php
/**
* Text_CAPTCHA_Driver_Word - Text_CAPTCHA driver word CAPTCHAs
* Class to create a textual Turing test
*
* PHP version 5
*
* @category Text
* @package Text_CAPTCHA
* @author Tobias Schlitt <schlitt@php.net>
* @author Christian Wenz <wenz@php.net>
* @author Michael Cramer <michael@bigmichi1.de>
* @license http://www.opensource.org/licenses/bsd-license.php BSD License
* @link http://pear.php.net/package/Text_CAPTCHA
*/
/**
* Require Numbers_Words class for generating the text.
*
* @category Text
* @package Text_CAPTCHA
* @author Tobias Schlitt <schlitt@php.net>
* @author Christian Wenz <wenz@php.net>
* @author Michael Cramer <michael@bigmichi1.de>
* @license http://www.opensource.org/licenses/bsd-license.php BSD License
* @link http://pear.php.net/package/Text_CAPTCHA
*/
class Text_CAPTCHA_Driver_Word extends Text_CAPTCHA_Driver_Base
{
/**
* Phrase length.
* This variable holds the length of the Word.
*
* @var integer
*/
private $_length;
/**
* Numbers_Words mode.
* This variable holds the mode for Numbers_Words.
*
* @var String
*/
private $_mode;
/**
* Locale
* This variable holds the locale for Numbers_Words
*
* @var string
*/
private $_locale;
/**
* Initializes the new Text_CAPTCHA_Driver_Word object.
*
* @param array $options CAPTCHA options with these keys:<br>
* phrase The "secret word" of the CAPTCHA<br>
* length The number of characters in the phrase<br>
* locale The locale for Numbers_Words<br>
* mode The mode for Numbers_Words
*
* @return void
*/
public function initDriver($options = array())
{
if (isset($options['length']) && is_int($options['length'])) {
$this->_length = $options['length'];
} else {
$this->_length = 4;
}
if (isset($options['phrase']) && !empty($options['phrase'])) {
$this->setPhrase((string)$options['phrase']);
} else {
$this->createPhrase();
}
if (isset($options['mode']) && !empty($options['mode'])) {
$this->_mode = $options['mode'];
} else {
$this->_mode = 'single';
}
if (isset($options['locale']) && !empty($options['locale'])) {
$this->_locale = $options['locale'];
} else {
$this->_locale = 'en_US';
}
}
/**
* Create random CAPTCHA phrase, "Word edition" (numbers only).
* This method creates a random phrase
*
* @return void
*/
public function createPhrase()
{
$phrase = new Text_Password();
$this->setPhrase(
$phrase->create(
$this->_length, 'unpronounceable', 'numeric'
)
);
}
/**
* Place holder for the real _createCAPTCHA() method
* used by extended classes to generate CAPTCHA from phrase
*
* @return void
*/
public function createCAPTCHA()
{
$res = '';
$numberWords = new Numbers_Words();
$phrase = $this->getPhrase();
if ($this->_mode == 'single') {
$phraseArr = str_split($phrase);
for ($i = 0; $i < strlen($phrase); $i++) {
$res .= ' ' . $numberWords->toWords($phraseArr[$i], $this->_locale);
}
} else {
$res = $numberWords->toWords($phrase, $this->_locale);
}
$this->setCaptcha($res);
}
}

View File

@@ -0,0 +1,27 @@
<?php
/**
* Exception for Text_CAPTCHA
*
* PHP version 5
*
* @category Text
* @package Text_CAPTCHA
* @author Christian Weiske <cweiske@php.net>
* @author Christian Wenz <wenz@php.net>
* @author Michael Cramer <michael@bigmichi1.de>
* @license http://www.opensource.org/licenses/bsd-license.php BSD License
* @link http://pear.php.net/package/Text_CAPTCHA
*/
/**
* Exception for Text_CAPTCHA
*
* @category Text
* @package Text_CAPTCHA
* @author Michael Cramer <michael@bigmichi1.de>
* @license http://www.opensource.org/licenses/bsd-license.php BSD License
* @link http://pear.php.net/package/Text_CAPTCHA
*/
class Text_CAPTCHA_Exception extends PEAR_Exception
{
}

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