mirror of
https://github.com/ACSPRI/queXS
synced 2024-04-02 12:12:16 +00:00
Import from DCARF SVN
This commit is contained in:
1762
include/pear/Archive/Tar.php
Normal file
1762
include/pear/Archive/Tar.php
Normal file
File diff suppressed because it is too large
Load Diff
685
include/pear/Calendar/Calendar.php
Normal file
685
include/pear/Calendar/Calendar.php
Normal file
@@ -0,0 +1,685 @@
|
||||
<?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/3_0.txt. |
|
||||
// | If you did not receive a copy of the PHP license and are unable to |
|
||||
// | obtain it through the world-wide-web, please send a note to |
|
||||
// | license@php.net so we can mail you a copy immediately. |
|
||||
// +----------------------------------------------------------------------+
|
||||
// | Authors: Harry Fuecks <hfuecks@phppatterns.com> |
|
||||
// | Lorenzo Alberton <l dot alberton at quipo dot it> |
|
||||
// +----------------------------------------------------------------------+
|
||||
//
|
||||
// $Id: Calendar.php,v 1.3 2005/10/22 10:07:11 quipo Exp $
|
||||
//
|
||||
/**
|
||||
* @package Calendar
|
||||
* @version $Id: Calendar.php,v 1.3 2005/10/22 10:07:11 quipo Exp $
|
||||
*/
|
||||
|
||||
/**
|
||||
* Allows Calendar include path to be redefined
|
||||
*/
|
||||
if (!defined('CALENDAR_ROOT')) {
|
||||
define('CALENDAR_ROOT', 'Calendar'.DIRECTORY_SEPARATOR);
|
||||
}
|
||||
|
||||
/**
|
||||
* Constant which defines the calculation engine to use
|
||||
*/
|
||||
if (!defined('CALENDAR_ENGINE')) {
|
||||
define('CALENDAR_ENGINE', 'UnixTS');
|
||||
}
|
||||
|
||||
/**
|
||||
* Define Calendar Month states
|
||||
*/
|
||||
define('CALENDAR_USE_MONTH', 1);
|
||||
define('CALENDAR_USE_MONTH_WEEKDAYS', 2);
|
||||
define('CALENDAR_USE_MONTH_WEEKS', 3);
|
||||
|
||||
/**
|
||||
* Contains a factory method to return a Singleton instance of a class
|
||||
* implementing the Calendar_Engine_Interface.<br>
|
||||
* <b>Note:</b> this class must be modified to "register" alternative
|
||||
* Calendar_Engines. The engine used can be controlled with the constant
|
||||
* CALENDAR_ENGINE
|
||||
* @see Calendar_Engine_Interface
|
||||
* @package Calendar
|
||||
* @access protected
|
||||
*/
|
||||
class Calendar_Engine_Factory
|
||||
{
|
||||
/**
|
||||
* Returns an instance of the engine
|
||||
* @return object instance of a calendar calculation engine
|
||||
* @access protected
|
||||
*/
|
||||
function & getEngine()
|
||||
{
|
||||
static $engine = false;
|
||||
switch (CALENDAR_ENGINE) {
|
||||
case 'PearDate':
|
||||
$class = 'Calendar_Engine_PearDate';
|
||||
break;
|
||||
case 'UnixTS':
|
||||
default:
|
||||
$class = 'Calendar_Engine_UnixTS';
|
||||
break;
|
||||
}
|
||||
if (!$engine) {
|
||||
if (!class_exists($class)) {
|
||||
require_once CALENDAR_ROOT.'Engine'.DIRECTORY_SEPARATOR.CALENDAR_ENGINE.'.php';
|
||||
}
|
||||
$engine = new $class;
|
||||
}
|
||||
return $engine;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Base class for Calendar API. This class should not be instantiated
|
||||
* directly.
|
||||
* @abstract
|
||||
* @package Calendar
|
||||
*/
|
||||
class Calendar
|
||||
{
|
||||
/**
|
||||
* Instance of class implementing calendar engine interface
|
||||
* @var object
|
||||
* @access private
|
||||
*/
|
||||
var $cE;
|
||||
|
||||
/**
|
||||
* Instance of Calendar_Validator (lazy initialized when isValid() or
|
||||
* getValidor() is called
|
||||
* @var Calendar_Validator
|
||||
* @access private
|
||||
*/
|
||||
var $validator;
|
||||
|
||||
/**
|
||||
* Year for this calendar object e.g. 2003
|
||||
* @access private
|
||||
* @var int
|
||||
*/
|
||||
var $year;
|
||||
|
||||
/**
|
||||
* Month for this calendar object e.g. 9
|
||||
* @access private
|
||||
* @var int
|
||||
*/
|
||||
var $month;
|
||||
|
||||
/**
|
||||
* Day of month for this calendar object e.g. 23
|
||||
* @access private
|
||||
* @var int
|
||||
*/
|
||||
var $day;
|
||||
|
||||
/**
|
||||
* Hour of day for this calendar object e.g. 13
|
||||
* @access private
|
||||
* @var int
|
||||
*/
|
||||
var $hour;
|
||||
|
||||
/**
|
||||
* Minute of hour this calendar object e.g. 46
|
||||
* @access private
|
||||
* @var int
|
||||
*/
|
||||
var $minute;
|
||||
|
||||
/**
|
||||
* Second of minute this calendar object e.g. 34
|
||||
* @access private
|
||||
* @var int
|
||||
*/
|
||||
var $second;
|
||||
|
||||
/**
|
||||
* Marks this calendar object as selected (e.g. 'today')
|
||||
* @access private
|
||||
* @var boolean
|
||||
*/
|
||||
var $selected = false;
|
||||
|
||||
/**
|
||||
* Collection of child calendar objects created from subclasses
|
||||
* of Calendar. Type depends on the object which created them.
|
||||
* @access private
|
||||
* @var array
|
||||
*/
|
||||
var $children = array();
|
||||
|
||||
/**
|
||||
* Constructs the Calendar
|
||||
* @param int year
|
||||
* @param int month
|
||||
* @param int day
|
||||
* @param int hour
|
||||
* @param int minute
|
||||
* @param int second
|
||||
* @access protected
|
||||
*/
|
||||
function Calendar($y = 2000, $m = 1, $d = 1, $h = 0, $i = 0, $s = 0)
|
||||
{
|
||||
static $cE = null;
|
||||
if (!isset($cE)) {
|
||||
$cE = & Calendar_Engine_Factory::getEngine();
|
||||
}
|
||||
$this->cE = & $cE;
|
||||
$this->year = (int)$y;
|
||||
$this->month = (int)$m;
|
||||
$this->day = (int)$d;
|
||||
$this->hour = (int)$h;
|
||||
$this->minute = (int)$i;
|
||||
$this->second = (int)$s;
|
||||
}
|
||||
|
||||
/**
|
||||
* Defines the calendar by a timestamp (Unix or ISO-8601), replacing values
|
||||
* passed to the constructor
|
||||
* @param int|string Unix or ISO-8601 timestamp
|
||||
* @return void
|
||||
* @access public
|
||||
*/
|
||||
function setTimestamp($ts)
|
||||
{
|
||||
$this->year = $this->cE->stampToYear($ts);
|
||||
$this->month = $this->cE->stampToMonth($ts);
|
||||
$this->day = $this->cE->stampToDay($ts);
|
||||
$this->hour = $this->cE->stampToHour($ts);
|
||||
$this->minute = $this->cE->stampToMinute($ts);
|
||||
$this->second = $this->cE->stampToSecond($ts);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a timestamp from the current date / time values. Format of
|
||||
* timestamp depends on Calendar_Engine implementation being used
|
||||
* @return int|string timestamp
|
||||
* @access public
|
||||
*/
|
||||
function getTimestamp()
|
||||
{
|
||||
return $this->cE->dateToStamp(
|
||||
$this->year, $this->month, $this->day,
|
||||
$this->hour, $this->minute, $this->second);
|
||||
}
|
||||
|
||||
/**
|
||||
* Defines calendar object as selected (e.g. for today)
|
||||
* @param boolean state whether Calendar subclass
|
||||
* @return void
|
||||
* @access public
|
||||
*/
|
||||
function setSelected($state = true)
|
||||
{
|
||||
$this->selected = $state;
|
||||
}
|
||||
|
||||
/**
|
||||
* True if the calendar subclass object is selected (e.g. today)
|
||||
* @return boolean
|
||||
* @access public
|
||||
*/
|
||||
function isSelected()
|
||||
{
|
||||
return $this->selected;
|
||||
}
|
||||
|
||||
/**
|
||||
* Adjusts the date (helper method)
|
||||
* @return void
|
||||
* @access public
|
||||
*/
|
||||
function adjust()
|
||||
{
|
||||
$stamp = $this->getTimeStamp();
|
||||
$this->year = $this->cE->stampToYear($stamp);
|
||||
$this->month = $this->cE->stampToMonth($stamp);
|
||||
$this->day = $this->cE->stampToDay($stamp);
|
||||
$this->hour = $this->cE->stampToHour($stamp);
|
||||
$this->minute = $this->cE->stampToMinute($stamp);
|
||||
$this->second = $this->cE->stampToSecond($stamp);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the date as an associative array (helper method)
|
||||
* @param mixed timestamp (leave empty for current timestamp)
|
||||
* @return array
|
||||
* @access public
|
||||
*/
|
||||
function toArray($stamp=null)
|
||||
{
|
||||
if (is_null($stamp)) {
|
||||
$stamp = $this->getTimeStamp();
|
||||
}
|
||||
return array(
|
||||
'year' => $this->cE->stampToYear($stamp),
|
||||
'month' => $this->cE->stampToMonth($stamp),
|
||||
'day' => $this->cE->stampToDay($stamp),
|
||||
'hour' => $this->cE->stampToHour($stamp),
|
||||
'minute' => $this->cE->stampToMinute($stamp),
|
||||
'second' => $this->cE->stampToSecond($stamp)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the value as an associative array (helper method)
|
||||
* @param string type of date object that return value represents
|
||||
* @param string $format ['int' | 'array' | 'timestamp' | 'object']
|
||||
* @param mixed timestamp (depending on Calendar engine being used)
|
||||
* @param int integer default value (i.e. give me the answer quick)
|
||||
* @return mixed
|
||||
* @access private
|
||||
*/
|
||||
function returnValue($returnType, $format, $stamp, $default)
|
||||
{
|
||||
switch (strtolower($format)) {
|
||||
case 'int':
|
||||
return $default;
|
||||
case 'array':
|
||||
return $this->toArray($stamp);
|
||||
break;
|
||||
case 'object':
|
||||
require_once CALENDAR_ROOT.'Factory.php';
|
||||
return Calendar_Factory::createByTimestamp($returnType,$stamp);
|
||||
break;
|
||||
case 'timestamp':
|
||||
default:
|
||||
return $stamp;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Abstract method for building the children of a calendar object.
|
||||
* Implemented by Calendar subclasses
|
||||
* @param array containing Calendar objects to select (optional)
|
||||
* @return boolean
|
||||
* @access public
|
||||
* @abstract
|
||||
*/
|
||||
function build($sDates = array())
|
||||
{
|
||||
require_once 'PEAR.php';
|
||||
PEAR::raiseError(
|
||||
'Calendar::build is abstract', null, PEAR_ERROR_TRIGGER,
|
||||
E_USER_NOTICE, 'Calendar::build()');
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Abstract method for selected data objects called from build
|
||||
* @param array
|
||||
* @return boolean
|
||||
* @access public
|
||||
* @abstract
|
||||
*/
|
||||
function setSelection($sDates)
|
||||
{
|
||||
require_once 'PEAR.php';
|
||||
PEAR::raiseError(
|
||||
'Calendar::setSelection is abstract', null, PEAR_ERROR_TRIGGER,
|
||||
E_USER_NOTICE, 'Calendar::setSelection()');
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Iterator method for fetching child Calendar subclass objects
|
||||
* (e.g. a minute from an hour object). On reaching the end of
|
||||
* the collection, returns false and resets the collection for
|
||||
* further iteratations.
|
||||
* @return mixed either an object subclass of Calendar or false
|
||||
* @access public
|
||||
*/
|
||||
function fetch()
|
||||
{
|
||||
$child = each($this->children);
|
||||
if ($child) {
|
||||
return $child['value'];
|
||||
} else {
|
||||
reset($this->children);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Fetches all child from the current collection of children
|
||||
* @return array
|
||||
* @access public
|
||||
*/
|
||||
function fetchAll()
|
||||
{
|
||||
return $this->children;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the number Calendar subclass objects stored in the internal
|
||||
* collection.
|
||||
* @return int
|
||||
* @access public
|
||||
*/
|
||||
function size()
|
||||
{
|
||||
return count($this->children);
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine whether this date is valid, with the bounds determined by
|
||||
* the Calendar_Engine. The call is passed on to
|
||||
* Calendar_Validator::isValid
|
||||
* @return boolean
|
||||
* @access public
|
||||
*/
|
||||
function isValid()
|
||||
{
|
||||
$validator = & $this->getValidator();
|
||||
return $validator->isValid();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an instance of Calendar_Validator
|
||||
* @return Calendar_Validator
|
||||
* @access public
|
||||
*/
|
||||
function & getValidator()
|
||||
{
|
||||
if (!isset($this->validator)) {
|
||||
require_once CALENDAR_ROOT.'Validator.php';
|
||||
$this->validator = & new Calendar_Validator($this);
|
||||
}
|
||||
return $this->validator;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a reference to the current Calendar_Engine being used. Useful
|
||||
* for Calendar_Table_Helper and Calendar_Validator
|
||||
* @return object implementing Calendar_Engine_Inteface
|
||||
* @access protected
|
||||
*/
|
||||
function & getEngine()
|
||||
{
|
||||
return $this->cE;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the CALENDAR_FIRST_DAY_OF_WEEK constant to the $firstDay value
|
||||
* if the constant is not set yet.
|
||||
* @throws E_USER_WARNING this method throws a WARNING if the
|
||||
* CALENDAR_FIRST_DAY_OF_WEEK constant is already defined and
|
||||
* the $firstDay parameter is set to a different value
|
||||
* @param integer $firstDay first day of the week (0=sunday, 1=monday, ...)
|
||||
* @return integer
|
||||
* @access protected
|
||||
*/
|
||||
function defineFirstDayOfWeek($firstDay = null)
|
||||
{
|
||||
if (defined('CALENDAR_FIRST_DAY_OF_WEEK')) {
|
||||
if (!is_null($firstDay) && ($firstDay != CALENDAR_FIRST_DAY_OF_WEEK)) {
|
||||
$msg = 'CALENDAR_FIRST_DAY_OF_WEEK constant already defined.'
|
||||
.' The $firstDay parameter will be ignored.';
|
||||
trigger_error($msg, E_USER_WARNING);
|
||||
}
|
||||
return CALENDAR_FIRST_DAY_OF_WEEK;
|
||||
}
|
||||
if (is_null($firstDay)) {
|
||||
$firstDay = $this->cE->getFirstDayOfWeek(
|
||||
$this->thisYear(),
|
||||
$this->thisMonth(),
|
||||
$this->thisDay()
|
||||
);
|
||||
}
|
||||
define ('CALENDAR_FIRST_DAY_OF_WEEK', $firstDay);
|
||||
return CALENDAR_FIRST_DAY_OF_WEEK;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the value for the previous year
|
||||
* @param string return value format ['int' | 'timestamp' | 'object' | 'array']
|
||||
* @return int e.g. 2002 or timestamp
|
||||
* @access public
|
||||
*/
|
||||
function prevYear($format = 'int')
|
||||
{
|
||||
$ts = $this->cE->dateToStamp($this->year-1, 1, 1, 0, 0, 0);
|
||||
return $this->returnValue('Year', $format, $ts, $this->year-1);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the value for this year
|
||||
* @param string return value format ['int' | 'timestamp' | 'object' | 'array']
|
||||
* @return int e.g. 2003 or timestamp
|
||||
* @access public
|
||||
*/
|
||||
function thisYear($format = 'int')
|
||||
{
|
||||
$ts = $this->cE->dateToStamp($this->year, 1, 1, 0, 0, 0);
|
||||
return $this->returnValue('Year', $format, $ts, $this->year);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the value for next year
|
||||
* @param string return value format ['int' | 'timestamp' | 'object' | 'array']
|
||||
* @return int e.g. 2004 or timestamp
|
||||
* @access public
|
||||
*/
|
||||
function nextYear($format = 'int')
|
||||
{
|
||||
$ts = $this->cE->dateToStamp($this->year+1, 1, 1, 0, 0, 0);
|
||||
return $this->returnValue('Year', $format, $ts, $this->year+1);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the value for the previous month
|
||||
* @param string return value format ['int' | 'timestamp' | 'object' | 'array']
|
||||
* @return int e.g. 4 or Unix timestamp
|
||||
* @access public
|
||||
*/
|
||||
function prevMonth($format = 'int')
|
||||
{
|
||||
$ts = $this->cE->dateToStamp($this->year, $this->month-1, 1, 0, 0, 0);
|
||||
return $this->returnValue('Month', $format, $ts, $this->cE->stampToMonth($ts));
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the value for this month
|
||||
* @param string return value format ['int' | 'timestamp' | 'object' | 'array']
|
||||
* @return int e.g. 5 or timestamp
|
||||
* @access public
|
||||
*/
|
||||
function thisMonth($format = 'int')
|
||||
{
|
||||
$ts = $this->cE->dateToStamp($this->year, $this->month, 1, 0, 0, 0);
|
||||
return $this->returnValue('Month', $format, $ts, $this->month);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the value for next month
|
||||
* @param string return value format ['int' | 'timestamp' | 'object' | 'array']
|
||||
* @return int e.g. 6 or timestamp
|
||||
* @access public
|
||||
*/
|
||||
function nextMonth($format = 'int')
|
||||
{
|
||||
$ts = $this->cE->dateToStamp($this->year, $this->month+1, 1, 0, 0, 0);
|
||||
return $this->returnValue('Month', $format, $ts, $this->cE->stampToMonth($ts));
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the value for the previous day
|
||||
* @param string return value format ['int' | 'timestamp' | 'object' | 'array']
|
||||
* @return int e.g. 10 or timestamp
|
||||
* @access public
|
||||
*/
|
||||
function prevDay($format = 'int')
|
||||
{
|
||||
$ts = $this->cE->dateToStamp(
|
||||
$this->year, $this->month, $this->day-1, 0, 0, 0);
|
||||
return $this->returnValue('Day', $format, $ts, $this->cE->stampToDay($ts));
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the value for this day
|
||||
* @param string return value format ['int' | 'timestamp' | 'object' | 'array']
|
||||
* @return int e.g. 11 or timestamp
|
||||
* @access public
|
||||
*/
|
||||
function thisDay($format = 'int')
|
||||
{
|
||||
$ts = $this->cE->dateToStamp(
|
||||
$this->year, $this->month, $this->day, 0, 0, 0);
|
||||
return $this->returnValue('Day', $format, $ts, $this->day);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the value for the next day
|
||||
* @param string return value format ['int' | 'timestamp' | 'object' | 'array']
|
||||
* @return int e.g. 12 or timestamp
|
||||
* @access public
|
||||
*/
|
||||
function nextDay($format = 'int')
|
||||
{
|
||||
$ts = $this->cE->dateToStamp(
|
||||
$this->year, $this->month, $this->day+1, 0, 0, 0);
|
||||
return $this->returnValue('Day', $format, $ts, $this->cE->stampToDay($ts));
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the value for the previous hour
|
||||
* @param string return value format ['int' | 'timestamp' | 'object' | 'array']
|
||||
* @return int e.g. 13 or timestamp
|
||||
* @access public
|
||||
*/
|
||||
function prevHour($format = 'int')
|
||||
{
|
||||
$ts = $this->cE->dateToStamp(
|
||||
$this->year, $this->month, $this->day, $this->hour-1, 0, 0);
|
||||
return $this->returnValue('Hour', $format, $ts, $this->cE->stampToHour($ts));
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the value for this hour
|
||||
* @param string return value format ['int' | 'timestamp' | 'object' | 'array']
|
||||
* @return int e.g. 14 or timestamp
|
||||
* @access public
|
||||
*/
|
||||
function thisHour($format = 'int')
|
||||
{
|
||||
$ts = $this->cE->dateToStamp(
|
||||
$this->year, $this->month, $this->day, $this->hour, 0, 0);
|
||||
return $this->returnValue('Hour', $format, $ts, $this->hour);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the value for the next hour
|
||||
* @param string return value format ['int' | 'timestamp' | 'object' | 'array']
|
||||
* @return int e.g. 14 or timestamp
|
||||
* @access public
|
||||
*/
|
||||
function nextHour($format = 'int')
|
||||
{
|
||||
$ts = $this->cE->dateToStamp(
|
||||
$this->year, $this->month, $this->day, $this->hour+1, 0, 0);
|
||||
return $this->returnValue('Hour', $format, $ts, $this->cE->stampToHour($ts));
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the value for the previous minute
|
||||
* @param string return value format ['int' | 'timestamp' | 'object' | 'array']
|
||||
* @return int e.g. 23 or timestamp
|
||||
* @access public
|
||||
*/
|
||||
function prevMinute($format = 'int')
|
||||
{
|
||||
$ts = $this->cE->dateToStamp(
|
||||
$this->year, $this->month, $this->day,
|
||||
$this->hour, $this->minute-1, 0);
|
||||
return $this->returnValue('Minute', $format, $ts, $this->cE->stampToMinute($ts));
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the value for this minute
|
||||
* @param string return value format ['int' | 'timestamp' | 'object' | 'array']
|
||||
* @return int e.g. 24 or timestamp
|
||||
* @access public
|
||||
*/
|
||||
function thisMinute($format = 'int')
|
||||
{
|
||||
$ts = $this->cE->dateToStamp(
|
||||
$this->year, $this->month, $this->day,
|
||||
$this->hour, $this->minute, 0);
|
||||
return $this->returnValue('Minute', $format, $ts, $this->minute);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the value for the next minute
|
||||
* @param string return value format ['int' | 'timestamp' | 'object' | 'array']
|
||||
* @return int e.g. 25 or timestamp
|
||||
* @access public
|
||||
*/
|
||||
function nextMinute($format = 'int')
|
||||
{
|
||||
$ts = $this->cE->dateToStamp(
|
||||
$this->year, $this->month, $this->day,
|
||||
$this->hour, $this->minute+1, 0);
|
||||
return $this->returnValue('Minute', $format, $ts, $this->cE->stampToMinute($ts));
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the value for the previous second
|
||||
* @param string return value format ['int' | 'timestamp' | 'object' | 'array']
|
||||
* @return int e.g. 43 or timestamp
|
||||
* @access public
|
||||
*/
|
||||
function prevSecond($format = 'int')
|
||||
{
|
||||
$ts = $this->cE->dateToStamp(
|
||||
$this->year, $this->month, $this->day,
|
||||
$this->hour, $this->minute, $this->second-1);
|
||||
return $this->returnValue('Second', $format, $ts, $this->cE->stampToSecond($ts));
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the value for this second
|
||||
* @param string return value format ['int' | 'timestamp' | 'object' | 'array']
|
||||
* @return int e.g. 44 or timestamp
|
||||
* @access public
|
||||
*/
|
||||
function thisSecond($format = 'int')
|
||||
{
|
||||
$ts = $this->cE->dateToStamp(
|
||||
$this->year, $this->month, $this->day,
|
||||
$this->hour, $this->minute, $this->second);
|
||||
return $this->returnValue('Second', $format, $ts, $this->second);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the value for the next second
|
||||
* @param string return value format ['int' | 'timestamp' | 'object' | 'array']
|
||||
* @return int e.g. 45 or timestamp
|
||||
* @access public
|
||||
*/
|
||||
function nextSecond($format = 'int')
|
||||
{
|
||||
$ts = $this->cE->dateToStamp(
|
||||
$this->year, $this->month, $this->day,
|
||||
$this->hour, $this->minute, $this->second+1);
|
||||
return $this->returnValue('Second', $format, $ts, $this->cE->stampToSecond($ts));
|
||||
}
|
||||
}
|
||||
?>
|
||||
197
include/pear/Calendar/Day.php
Normal file
197
include/pear/Calendar/Day.php
Normal file
@@ -0,0 +1,197 @@
|
||||
<?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/3_0.txt. |
|
||||
// | If you did not receive a copy of the PHP license and are unable to |
|
||||
// | obtain it through the world-wide-web, please send a note to |
|
||||
// | license@php.net so we can mail you a copy immediately. |
|
||||
// +----------------------------------------------------------------------+
|
||||
// | Authors: Harry Fuecks <hfuecks@phppatterns.com> |
|
||||
// +----------------------------------------------------------------------+
|
||||
//
|
||||
// $Id: Day.php,v 1.1 2004/05/24 22:25:42 quipo Exp $
|
||||
//
|
||||
/**
|
||||
* @package Calendar
|
||||
* @version $Id: Day.php,v 1.1 2004/05/24 22:25:42 quipo Exp $
|
||||
*/
|
||||
|
||||
/**
|
||||
* Allows Calendar include path to be redefined
|
||||
* @ignore
|
||||
*/
|
||||
if (!defined('CALENDAR_ROOT')) {
|
||||
define('CALENDAR_ROOT', 'Calendar'.DIRECTORY_SEPARATOR);
|
||||
}
|
||||
|
||||
/**
|
||||
* Load Calendar base class
|
||||
*/
|
||||
require_once CALENDAR_ROOT.'Calendar.php';
|
||||
|
||||
/**
|
||||
* Represents a Day and builds Hours.
|
||||
* <code>
|
||||
* require_once 'Calendar'.DIRECTORY_SEPARATOR.'Day.php';
|
||||
* $Day = & new Calendar_Day(2003, 10, 21); // Oct 21st 2003
|
||||
* while ($Hour = & $Day->fetch()) {
|
||||
* echo $Hour->thisHour().'<br />';
|
||||
* }
|
||||
* </code>
|
||||
* @package Calendar
|
||||
* @access public
|
||||
*/
|
||||
class Calendar_Day extends Calendar
|
||||
{
|
||||
/**
|
||||
* Marks the Day at the beginning of a week
|
||||
* @access private
|
||||
* @var boolean
|
||||
*/
|
||||
var $first = false;
|
||||
|
||||
/**
|
||||
* Marks the Day at the end of a week
|
||||
* @access private
|
||||
* @var boolean
|
||||
*/
|
||||
var $last = false;
|
||||
|
||||
|
||||
/**
|
||||
* Used for tabular calendars
|
||||
* @access private
|
||||
* @var boolean
|
||||
*/
|
||||
var $empty = false;
|
||||
|
||||
/**
|
||||
* Constructs Calendar_Day
|
||||
* @param int year e.g. 2003
|
||||
* @param int month e.g. 8
|
||||
* @param int day e.g. 15
|
||||
* @access public
|
||||
*/
|
||||
function Calendar_Day($y, $m, $d)
|
||||
{
|
||||
Calendar::Calendar($y, $m, $d);
|
||||
}
|
||||
|
||||
/**
|
||||
* Builds the Hours of the Day
|
||||
* @param array (optional) Caledar_Hour objects representing selected dates
|
||||
* @return boolean
|
||||
* @access public
|
||||
*/
|
||||
function build($sDates = array())
|
||||
{
|
||||
require_once CALENDAR_ROOT.'Hour.php';
|
||||
|
||||
$hID = $this->cE->getHoursInDay($this->year, $this->month, $this->day);
|
||||
for ($i=0; $i < $hID; $i++) {
|
||||
$this->children[$i]=
|
||||
new Calendar_Hour($this->year, $this->month, $this->day, $i);
|
||||
}
|
||||
if (count($sDates) > 0) {
|
||||
$this->setSelection($sDates);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Called from build()
|
||||
* @param array
|
||||
* @return void
|
||||
* @access private
|
||||
*/
|
||||
function setSelection($sDates)
|
||||
{
|
||||
foreach ($sDates as $sDate) {
|
||||
if ($this->year == $sDate->thisYear()
|
||||
&& $this->month == $sDate->thisMonth()
|
||||
&& $this->day == $sDate->thisDay())
|
||||
{
|
||||
$key = (int)$sDate->thisHour();
|
||||
if (isset($this->children[$key])) {
|
||||
$sDate->setSelected();
|
||||
$this->children[$key] = $sDate;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Defines Day object as first in a week
|
||||
* Only used by Calendar_Month_Weekdays::build()
|
||||
* @param boolean state
|
||||
* @return void
|
||||
* @access private
|
||||
*/
|
||||
function setFirst ($state = true)
|
||||
{
|
||||
$this->first = $state;
|
||||
}
|
||||
|
||||
/**
|
||||
* Defines Day object as last in a week
|
||||
* Used only following Calendar_Month_Weekdays::build()
|
||||
* @param boolean state
|
||||
* @return void
|
||||
* @access private
|
||||
*/
|
||||
function setLast($state = true)
|
||||
{
|
||||
$this->last = $state;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if Day object is first in a Week
|
||||
* Only relevant when Day is created by Calendar_Month_Weekdays::build()
|
||||
* @return boolean
|
||||
* @access public
|
||||
*/
|
||||
function isFirst() {
|
||||
return $this->first;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if Day object is last in a Week
|
||||
* Only relevant when Day is created by Calendar_Month_Weekdays::build()
|
||||
* @return boolean
|
||||
* @access public
|
||||
*/
|
||||
function isLast()
|
||||
{
|
||||
return $this->last;
|
||||
}
|
||||
|
||||
/**
|
||||
* Defines Day object as empty
|
||||
* Only used by Calendar_Month_Weekdays::build()
|
||||
* @param boolean state
|
||||
* @return void
|
||||
* @access private
|
||||
*/
|
||||
function setEmpty ($state = true)
|
||||
{
|
||||
$this->empty = $state;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return boolean
|
||||
* @access public
|
||||
*/
|
||||
function isEmpty()
|
||||
{
|
||||
return $this->empty;
|
||||
}
|
||||
}
|
||||
?>
|
||||
558
include/pear/Calendar/Decorator.php
Normal file
558
include/pear/Calendar/Decorator.php
Normal file
@@ -0,0 +1,558 @@
|
||||
<?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/3_0.txt. |
|
||||
// | If you did not receive a copy of the PHP license and are unable to |
|
||||
// | obtain it through the world-wide-web, please send a note to |
|
||||
// | license@php.net so we can mail you a copy immediately. |
|
||||
// +----------------------------------------------------------------------+
|
||||
// | Authors: Harry Fuecks <hfuecks@phppatterns.com> |
|
||||
// +----------------------------------------------------------------------+
|
||||
//
|
||||
// $Id: Decorator.php,v 1.3 2005/10/22 10:29:46 quipo Exp $
|
||||
//
|
||||
/**
|
||||
* @package Calendar
|
||||
* @version $Id: Decorator.php,v 1.3 2005/10/22 10:29:46 quipo Exp $
|
||||
*/
|
||||
/**
|
||||
* Decorates any calendar class.
|
||||
* Create a subclass of this class for your own "decoration".
|
||||
* Used for "selections"
|
||||
* <code>
|
||||
* class DayDecorator extends Calendar_Decorator
|
||||
* {
|
||||
* function thisDay($format = 'int')
|
||||
* {
|
||||
.* $day = parent::thisDay('timestamp');
|
||||
.* return date('D', $day);
|
||||
* }
|
||||
* }
|
||||
* $Day = & new Calendar_Day(2003, 10, 25);
|
||||
* $DayDecorator = & new DayDecorator($Day);
|
||||
* echo $DayDecorator->thisDay(); // Outputs "Sat"
|
||||
* </code>
|
||||
* @abstract
|
||||
* @package Calendar
|
||||
*/
|
||||
class Calendar_Decorator
|
||||
{
|
||||
/**
|
||||
* Subclass of Calendar being decorated
|
||||
* @var object
|
||||
* @access private
|
||||
*/
|
||||
var $calendar;
|
||||
|
||||
/**
|
||||
* Constructs the Calendar_Decorator
|
||||
* @param object subclass to Calendar to decorate
|
||||
*/
|
||||
function Calendar_Decorator(& $calendar)
|
||||
{
|
||||
$this->calendar = & $calendar;
|
||||
}
|
||||
|
||||
/**
|
||||
* Defines the calendar by a Unix timestamp, replacing values
|
||||
* passed to the constructor
|
||||
* @param int Unix timestamp
|
||||
* @return void
|
||||
* @access public
|
||||
*/
|
||||
function setTimestamp($ts)
|
||||
{
|
||||
$this->calendar->setTimestamp($ts);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a timestamp from the current date / time values. Format of
|
||||
* timestamp depends on Calendar_Engine implementation being used
|
||||
* @return int timestamp
|
||||
* @access public
|
||||
*/
|
||||
function getTimestamp()
|
||||
{
|
||||
return $this->calendar->getTimeStamp();
|
||||
}
|
||||
|
||||
/**
|
||||
* Defines calendar object as selected (e.g. for today)
|
||||
* @param boolean state whether Calendar subclass
|
||||
* @return void
|
||||
* @access public
|
||||
*/
|
||||
function setSelected($state = true)
|
||||
{
|
||||
$this->calendar->setSelected($state = true);
|
||||
}
|
||||
|
||||
/**
|
||||
* True if the calendar subclass object is selected (e.g. today)
|
||||
* @return boolean
|
||||
* @access public
|
||||
*/
|
||||
function isSelected()
|
||||
{
|
||||
return $this->calendar->isSelected();
|
||||
}
|
||||
|
||||
/**
|
||||
* Adjusts the date (helper method)
|
||||
* @return void
|
||||
* @access public
|
||||
*/
|
||||
function adjust()
|
||||
{
|
||||
$this->calendar->adjust();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the date as an associative array (helper method)
|
||||
* @param mixed timestamp (leave empty for current timestamp)
|
||||
* @return array
|
||||
* @access public
|
||||
*/
|
||||
function toArray($stamp=null)
|
||||
{
|
||||
return $this->calendar->toArray($stamp);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the value as an associative array (helper method)
|
||||
* @param string type of date object that return value represents
|
||||
* @param string $format ['int' | 'array' | 'timestamp' | 'object']
|
||||
* @param mixed timestamp (depending on Calendar engine being used)
|
||||
* @param int integer default value (i.e. give me the answer quick)
|
||||
* @return mixed
|
||||
* @access private
|
||||
*/
|
||||
function returnValue($returnType, $format, $stamp, $default)
|
||||
{
|
||||
return $this->calendar->returnValue($returnType, $format, $stamp, $default);
|
||||
}
|
||||
|
||||
/**
|
||||
* Defines Day object as first in a week
|
||||
* Only used by Calendar_Month_Weekdays::build()
|
||||
* @param boolean state
|
||||
* @return void
|
||||
* @access private
|
||||
*/
|
||||
function setFirst ($state = true)
|
||||
{
|
||||
if ( method_exists($this->calendar,'setFirst') ) {
|
||||
$this->calendar->setFirst($state);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Defines Day object as last in a week
|
||||
* Used only following Calendar_Month_Weekdays::build()
|
||||
* @param boolean state
|
||||
* @return void
|
||||
* @access private
|
||||
*/
|
||||
function setLast($state = true)
|
||||
{
|
||||
if ( method_exists($this->calendar,'setLast') ) {
|
||||
$this->calendar->setLast($state);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if Day object is first in a Week
|
||||
* Only relevant when Day is created by Calendar_Month_Weekdays::build()
|
||||
* @return boolean
|
||||
* @access public
|
||||
*/
|
||||
function isFirst() {
|
||||
if ( method_exists($this->calendar,'isFirst') ) {
|
||||
return $this->calendar->isFirst();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if Day object is last in a Week
|
||||
* Only relevant when Day is created by Calendar_Month_Weekdays::build()
|
||||
* @return boolean
|
||||
* @access public
|
||||
*/
|
||||
function isLast()
|
||||
{
|
||||
if ( method_exists($this->calendar,'isLast') ) {
|
||||
return $this->calendar->isLast();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Defines Day object as empty
|
||||
* Only used by Calendar_Month_Weekdays::build()
|
||||
* @param boolean state
|
||||
* @return void
|
||||
* @access private
|
||||
*/
|
||||
function setEmpty ($state = true)
|
||||
{
|
||||
if ( method_exists($this->calendar,'setEmpty') ) {
|
||||
$this->calendar->setEmpty($state);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @return boolean
|
||||
* @access public
|
||||
*/
|
||||
function isEmpty()
|
||||
{
|
||||
if ( method_exists($this->calendar,'isEmpty') ) {
|
||||
return $this->calendar->isEmpty();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Build the children
|
||||
* @param array containing Calendar objects to select (optional)
|
||||
* @return boolean
|
||||
* @access public
|
||||
* @abstract
|
||||
*/
|
||||
function build($sDates = array())
|
||||
{
|
||||
$this->calendar->build($sDates);
|
||||
}
|
||||
|
||||
/**
|
||||
* Iterator method for fetching child Calendar subclass objects
|
||||
* (e.g. a minute from an hour object). On reaching the end of
|
||||
* the collection, returns false and resets the collection for
|
||||
* further iteratations.
|
||||
* @return mixed either an object subclass of Calendar or false
|
||||
* @access public
|
||||
*/
|
||||
function fetch()
|
||||
{
|
||||
return $this->calendar->fetch();
|
||||
}
|
||||
|
||||
/**
|
||||
* Fetches all child from the current collection of children
|
||||
* @return array
|
||||
* @access public
|
||||
*/
|
||||
function fetchAll()
|
||||
{
|
||||
return $this->calendar->fetchAll();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the number Calendar subclass objects stored in the internal
|
||||
* collection.
|
||||
* @return int
|
||||
* @access public
|
||||
*/
|
||||
function size()
|
||||
{
|
||||
return $this->calendar->size();
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine whether this date is valid, with the bounds determined by
|
||||
* the Calendar_Engine. The call is passed on to
|
||||
* Calendar_Validator::isValid
|
||||
* @return boolean
|
||||
* @access public
|
||||
*/
|
||||
function isValid()
|
||||
{
|
||||
return $this->calendar->isValid();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an instance of Calendar_Validator
|
||||
* @return Calendar_Validator
|
||||
* @access public
|
||||
*/
|
||||
function & getValidator()
|
||||
{
|
||||
$validator = $this->calendar->getValidator();
|
||||
return $validator;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a reference to the current Calendar_Engine being used. Useful
|
||||
* for Calendar_Table_Helper and Calendar_Validator
|
||||
* @return object implementing Calendar_Engine_Inteface
|
||||
* @access private
|
||||
*/
|
||||
function & getEngine()
|
||||
{
|
||||
return $this->calendar->getEngine();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the value for the previous year
|
||||
* @param string return value format ['int' | 'timestamp' | 'object' | 'array']
|
||||
* @return int e.g. 2002 or timestamp
|
||||
* @access public
|
||||
*/
|
||||
function prevYear($format = 'int')
|
||||
{
|
||||
return $this->calendar->prevYear($format);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the value for this year
|
||||
* @param string return value format ['int' | 'timestamp' | 'object' | 'array']
|
||||
* @return int e.g. 2003 or timestamp
|
||||
* @access public
|
||||
*/
|
||||
function thisYear($format = 'int')
|
||||
{
|
||||
return $this->calendar->thisYear($format);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the value for next year
|
||||
* @param string return value format ['int' | 'timestamp' | 'object' | 'array']
|
||||
* @return int e.g. 2004 or timestamp
|
||||
* @access public
|
||||
*/
|
||||
function nextYear($format = 'int')
|
||||
{
|
||||
return $this->calendar->nextYear($format);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the value for the previous month
|
||||
* @param string return value format ['int' | 'timestamp' | 'object' | 'array']
|
||||
* @return int e.g. 4 or Unix timestamp
|
||||
* @access public
|
||||
*/
|
||||
function prevMonth($format = 'int')
|
||||
{
|
||||
return $this->calendar->prevMonth($format);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the value for this month
|
||||
* @param string return value format ['int' | 'timestamp' | 'object' | 'array']
|
||||
* @return int e.g. 5 or timestamp
|
||||
* @access public
|
||||
*/
|
||||
function thisMonth($format = 'int')
|
||||
{
|
||||
return $this->calendar->thisMonth($format);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the value for next month
|
||||
* @param string return value format ['int' | 'timestamp' | 'object' | 'array']
|
||||
* @return int e.g. 6 or timestamp
|
||||
* @access public
|
||||
*/
|
||||
function nextMonth($format = 'int')
|
||||
{
|
||||
return $this->calendar->nextMonth($format);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the value for the previous week
|
||||
* @param string return value format ['int' | 'timestamp' | 'object' | 'array']
|
||||
* @return int e.g. 4 or Unix timestamp
|
||||
* @access public
|
||||
*/
|
||||
function prevWeek($format = 'n_in_month')
|
||||
{
|
||||
if ( method_exists($this->calendar,'prevWeek') ) {
|
||||
return $this->calendar->prevWeek($format);
|
||||
} else {
|
||||
require_once 'PEAR.php';
|
||||
PEAR::raiseError(
|
||||
'Cannot call prevWeek on Calendar object of type: '.
|
||||
get_class($this->calendar), 133, PEAR_ERROR_TRIGGER,
|
||||
E_USER_NOTICE, 'Calendar_Decorator::prevWeek()');
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the value for this week
|
||||
* @param string return value format ['int' | 'timestamp' | 'object' | 'array']
|
||||
* @return int e.g. 5 or timestamp
|
||||
* @access public
|
||||
*/
|
||||
function thisWeek($format = 'n_in_month')
|
||||
{
|
||||
if ( method_exists($this->calendar,'thisWeek') ) {
|
||||
return $this->calendar->thisWeek($format);
|
||||
} else {
|
||||
require_once 'PEAR.php';
|
||||
PEAR::raiseError(
|
||||
'Cannot call thisWeek on Calendar object of type: '.
|
||||
get_class($this->calendar), 133, PEAR_ERROR_TRIGGER,
|
||||
E_USER_NOTICE, 'Calendar_Decorator::thisWeek()');
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the value for next week
|
||||
* @param string return value format ['int' | 'timestamp' | 'object' | 'array']
|
||||
* @return int e.g. 6 or timestamp
|
||||
* @access public
|
||||
*/
|
||||
function nextWeek($format = 'n_in_month')
|
||||
{
|
||||
if ( method_exists($this->calendar,'nextWeek') ) {
|
||||
return $this->calendar->nextWeek($format);
|
||||
} else {
|
||||
require_once 'PEAR.php';
|
||||
PEAR::raiseError(
|
||||
'Cannot call thisWeek on Calendar object of type: '.
|
||||
get_class($this->calendar), 133, PEAR_ERROR_TRIGGER,
|
||||
E_USER_NOTICE, 'Calendar_Decorator::nextWeek()');
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the value for the previous day
|
||||
* @param string return value format ['int' | 'timestamp' | 'object' | 'array']
|
||||
* @return int e.g. 10 or timestamp
|
||||
* @access public
|
||||
*/
|
||||
function prevDay($format = 'int') {
|
||||
return $this->calendar->prevDay($format);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the value for this day
|
||||
* @param string return value format ['int' | 'timestamp' | 'object' | 'array']
|
||||
* @return int e.g. 11 or timestamp
|
||||
* @access public
|
||||
*/
|
||||
function thisDay($format = 'int')
|
||||
{
|
||||
return $this->calendar->thisDay($format);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the value for the next day
|
||||
* @param string return value format ['int' | 'timestamp' | 'object' | 'array']
|
||||
* @return int e.g. 12 or timestamp
|
||||
* @access public
|
||||
*/
|
||||
function nextDay($format = 'int')
|
||||
{
|
||||
return $this->calendar->nextDay($format);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the value for the previous hour
|
||||
* @param string return value format ['int' | 'timestamp' | 'object' | 'array']
|
||||
* @return int e.g. 13 or timestamp
|
||||
* @access public
|
||||
*/
|
||||
function prevHour($format = 'int')
|
||||
{
|
||||
return $this->calendar->prevHour($format);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the value for this hour
|
||||
* @param string return value format ['int' | 'timestamp' | 'object' | 'array']
|
||||
* @return int e.g. 14 or timestamp
|
||||
* @access public
|
||||
*/
|
||||
function thisHour($format = 'int')
|
||||
{
|
||||
return $this->calendar->thisHour($format);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the value for the next hour
|
||||
* @param string return value format ['int' | 'timestamp' | 'object' | 'array']
|
||||
* @return int e.g. 14 or timestamp
|
||||
* @access public
|
||||
*/
|
||||
function nextHour($format = 'int')
|
||||
{
|
||||
return $this->calendar->nextHour($format);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the value for the previous minute
|
||||
* @param string return value format ['int' | 'timestamp' | 'object' | 'array']
|
||||
* @return int e.g. 23 or timestamp
|
||||
* @access public
|
||||
*/
|
||||
function prevMinute($format = 'int')
|
||||
{
|
||||
return $this->calendar->prevMinute($format);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the value for this minute
|
||||
* @param string return value format ['int' | 'timestamp' | 'object' | 'array']
|
||||
* @return int e.g. 24 or timestamp
|
||||
* @access public
|
||||
*/
|
||||
function thisMinute($format = 'int')
|
||||
{
|
||||
return $this->calendar->thisMinute($format);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the value for the next minute
|
||||
* @param string return value format ['int' | 'timestamp' | 'object' | 'array']
|
||||
* @return int e.g. 25 or timestamp
|
||||
* @access public
|
||||
*/
|
||||
function nextMinute($format = 'int')
|
||||
{
|
||||
return $this->calendar->nextMinute($format);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the value for the previous second
|
||||
* @param string return value format ['int' | 'timestamp' | 'object' | 'array']
|
||||
* @return int e.g. 43 or timestamp
|
||||
* @access public
|
||||
*/
|
||||
function prevSecond($format = 'int')
|
||||
{
|
||||
return $this->calendar->prevSecond($format);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the value for this second
|
||||
* @param string return value format ['int' | 'timestamp' | 'object' | 'array']
|
||||
* @return int e.g. 44 or timestamp
|
||||
* @access public
|
||||
*/
|
||||
function thisSecond($format = 'int')
|
||||
{
|
||||
return $this->calendar->thisSecond($format);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the value for the next second
|
||||
* @param string return value format ['int' | 'timestamp' | 'object' | 'array']
|
||||
* @return int e.g. 45 or timestamp
|
||||
* @access public
|
||||
*/
|
||||
function nextSecond($format = 'int')
|
||||
{
|
||||
return $this->calendar->nextSecond($format);
|
||||
}
|
||||
}
|
||||
?>
|
||||
169
include/pear/Calendar/Decorator/Textual.php
Normal file
169
include/pear/Calendar/Decorator/Textual.php
Normal file
@@ -0,0 +1,169 @@
|
||||
<?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/3_0.txt. |
|
||||
// | If you did not receive a copy of the PHP license and are unable to |
|
||||
// | obtain it through the world-wide-web, please send a note to |
|
||||
// | license@php.net so we can mail you a copy immediately. |
|
||||
// +----------------------------------------------------------------------+
|
||||
// | Authors: Harry Fuecks <hfuecks@phppatterns.com> |
|
||||
// | Lorenzo Alberton <l dot alberton at quipo dot it> |
|
||||
// +----------------------------------------------------------------------+
|
||||
//
|
||||
// $Id: Textual.php,v 1.3 2004/08/16 13:02:44 hfuecks Exp $
|
||||
//
|
||||
/**
|
||||
* @package Calendar
|
||||
* @version $Id: Textual.php,v 1.3 2004/08/16 13:02:44 hfuecks Exp $
|
||||
*/
|
||||
|
||||
/**
|
||||
* Allows Calendar include path to be redefined
|
||||
* @ignore
|
||||
*/
|
||||
if (!defined('CALENDAR_ROOT')) {
|
||||
define('CALENDAR_ROOT', 'Calendar'.DIRECTORY_SEPARATOR);
|
||||
}
|
||||
|
||||
/**
|
||||
* Load Calendar decorator base class
|
||||
*/
|
||||
require_once CALENDAR_ROOT.'Decorator.php';
|
||||
|
||||
/**
|
||||
* Load the Uri utility
|
||||
*/
|
||||
require_once CALENDAR_ROOT.'Util'.DIRECTORY_SEPARATOR.'Textual.php';
|
||||
|
||||
/**
|
||||
* Decorator to help with fetching textual representations of months and
|
||||
* days of the week.
|
||||
* <b>Note:</b> for performance you should prefer Calendar_Util_Textual unless you
|
||||
* have a specific need to use a decorator
|
||||
* @package Calendar
|
||||
* @access public
|
||||
*/
|
||||
class Calendar_Decorator_Textual extends Calendar_Decorator
|
||||
{
|
||||
/**
|
||||
* Constructs Calendar_Decorator_Textual
|
||||
* @param object subclass of Calendar
|
||||
* @access public
|
||||
*/
|
||||
function Calendar_Decorator_Textual(&$Calendar)
|
||||
{
|
||||
parent::Calendar_Decorator($Calendar);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an array of 12 month names (first index = 1)
|
||||
* @param string (optional) format of returned months (one,two,short or long)
|
||||
* @return array
|
||||
* @access public
|
||||
* @static
|
||||
*/
|
||||
function monthNames($format='long')
|
||||
{
|
||||
return Calendar_Util_Textual::monthNames($format);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an array of 7 week day names (first index = 0)
|
||||
* @param string (optional) format of returned days (one,two,short or long)
|
||||
* @return array
|
||||
* @access public
|
||||
* @static
|
||||
*/
|
||||
function weekdayNames($format='long')
|
||||
{
|
||||
return Calendar_Util_Textual::weekdayNames($format);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns textual representation of the previous month of the decorated calendar object
|
||||
* @param string (optional) format of returned months (one,two,short or long)
|
||||
* @return string
|
||||
* @access public
|
||||
*/
|
||||
function prevMonthName($format='long')
|
||||
{
|
||||
return Calendar_Util_Textual::prevMonthName($this->calendar,$format);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns textual representation of the month of the decorated calendar object
|
||||
* @param string (optional) format of returned months (one,two,short or long)
|
||||
* @return string
|
||||
* @access public
|
||||
*/
|
||||
function thisMonthName($format='long')
|
||||
{
|
||||
return Calendar_Util_Textual::thisMonthName($this->calendar,$format);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns textual representation of the next month of the decorated calendar object
|
||||
* @param string (optional) format of returned months (one,two,short or long)
|
||||
* @return string
|
||||
* @access public
|
||||
*/
|
||||
function nextMonthName($format='long')
|
||||
{
|
||||
return Calendar_Util_Textual::nextMonthName($this->calendar,$format);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns textual representation of the previous day of week of the decorated calendar object
|
||||
* @param string (optional) format of returned months (one,two,short or long)
|
||||
* @return string
|
||||
* @access public
|
||||
*/
|
||||
function prevDayName($format='long')
|
||||
{
|
||||
return Calendar_Util_Textual::prevDayName($this->calendar,$format);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns textual representation of the day of week of the decorated calendar object
|
||||
* @param string (optional) format of returned months (one,two,short or long)
|
||||
* @return string
|
||||
* @access public
|
||||
*/
|
||||
function thisDayName($format='long')
|
||||
{
|
||||
return Calendar_Util_Textual::thisDayName($this->calendar,$format);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns textual representation of the next day of week of the decorated calendar object
|
||||
* @param string (optional) format of returned months (one,two,short or long)
|
||||
* @return string
|
||||
* @access public
|
||||
*/
|
||||
function nextDayName($format='long')
|
||||
{
|
||||
return Calendar_Util_Textual::nextDayName($this->calendar,$format);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the days of the week using the order defined in the decorated
|
||||
* calendar object. Only useful for Calendar_Month_Weekdays, Calendar_Month_Weeks
|
||||
* and Calendar_Week. Otherwise the returned array will begin on Sunday
|
||||
* @param string (optional) format of returned months (one,two,short or long)
|
||||
* @return array ordered array of week day names
|
||||
* @access public
|
||||
*/
|
||||
function orderedWeekdays($format='long')
|
||||
{
|
||||
return Calendar_Util_Textual::orderedWeekdays($this->calendar,$format);
|
||||
}
|
||||
}
|
||||
?>
|
||||
151
include/pear/Calendar/Decorator/Uri.php
Normal file
151
include/pear/Calendar/Decorator/Uri.php
Normal file
@@ -0,0 +1,151 @@
|
||||
<?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/3_0.txt. |
|
||||
// | If you did not receive a copy of the PHP license and are unable to |
|
||||
// | obtain it through the world-wide-web, please send a note to |
|
||||
// | license@php.net so we can mail you a copy immediately. |
|
||||
// +----------------------------------------------------------------------+
|
||||
// | Authors: Harry Fuecks <hfuecks@phppatterns.com> |
|
||||
// | Lorenzo Alberton <l dot alberton at quipo dot it> |
|
||||
// +----------------------------------------------------------------------+
|
||||
//
|
||||
// $Id: Uri.php,v 1.3 2004/08/16 09:04:20 hfuecks Exp $
|
||||
//
|
||||
/**
|
||||
* @package Calendar
|
||||
* @version $Id: Uri.php,v 1.3 2004/08/16 09:04:20 hfuecks Exp $
|
||||
*/
|
||||
|
||||
/**
|
||||
* Allows Calendar include path to be redefined
|
||||
* @ignore
|
||||
*/
|
||||
if (!defined('CALENDAR_ROOT')) {
|
||||
define('CALENDAR_ROOT', 'Calendar'.DIRECTORY_SEPARATOR);
|
||||
}
|
||||
|
||||
/**
|
||||
* Load Calendar decorator base class
|
||||
*/
|
||||
require_once CALENDAR_ROOT.'Decorator.php';
|
||||
|
||||
/**
|
||||
* Load the Uri utility
|
||||
*/
|
||||
require_once CALENDAR_ROOT.'Util'.DIRECTORY_SEPARATOR.'Uri.php';
|
||||
|
||||
/**
|
||||
* Decorator to help with building HTML links for navigating the calendar<br />
|
||||
* <b>Note:</b> for performance you should prefer Calendar_Util_Uri unless you
|
||||
* have a specific need to use a decorator
|
||||
* <code>
|
||||
* $Day = new Calendar_Day(2003, 10, 23);
|
||||
* $Uri = & new Calendar_Decorator_Uri($Day);
|
||||
* $Uri->setFragments('year', 'month', 'day');
|
||||
* echo $Uri->getPrev(); // Displays year=2003&month=10&day=22
|
||||
* </code>
|
||||
* @see Calendar_Util_Uri
|
||||
* @package Calendar
|
||||
* @access public
|
||||
*/
|
||||
class Calendar_Decorator_Uri extends Calendar_Decorator
|
||||
{
|
||||
|
||||
/**
|
||||
* @var Calendar_Util_Uri
|
||||
* @access private
|
||||
*/
|
||||
var $Uri;
|
||||
|
||||
/**
|
||||
* Constructs Calendar_Decorator_Uri
|
||||
* @param object subclass of Calendar
|
||||
* @access public
|
||||
*/
|
||||
function Calendar_Decorator_Uri(&$Calendar)
|
||||
{
|
||||
parent::Calendar_Decorator($Calendar);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the URI fragment names
|
||||
* @param string URI fragment for year
|
||||
* @param string (optional) URI fragment for month
|
||||
* @param string (optional) URI fragment for day
|
||||
* @param string (optional) URI fragment for hour
|
||||
* @param string (optional) URI fragment for minute
|
||||
* @param string (optional) URI fragment for second
|
||||
* @return void
|
||||
* @access public
|
||||
*/
|
||||
function setFragments($y, $m=null, $d=null, $h=null, $i=null, $s=null) {
|
||||
$this->Uri = & new Calendar_Util_Uri($y, $m, $d, $h, $i, $s);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the separator string between fragments
|
||||
* @param string separator e.g. /
|
||||
* @return void
|
||||
* @access public
|
||||
*/
|
||||
function setSeparator($separator)
|
||||
{
|
||||
$this->Uri->separator = $separator;
|
||||
}
|
||||
|
||||
/**
|
||||
* Puts Uri decorator into "scalar mode" - URI variable names are not
|
||||
* returned
|
||||
* @param boolean (optional)
|
||||
* @return void
|
||||
* @access public
|
||||
*/
|
||||
function setScalar($state=true)
|
||||
{
|
||||
$this->Uri->scalar = $state;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the URI string for the previous calendar unit
|
||||
* @param string calendar unit to fetch uri for (year,month,week or day etc)
|
||||
* @return string
|
||||
* @access public
|
||||
*/
|
||||
function prev($method)
|
||||
{
|
||||
return $this->Uri->prev($this, $method);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the URI string for the current calendar unit
|
||||
* @param string calendar unit to fetch uri for (year,month,week or day etc)
|
||||
* @return string
|
||||
* @access public
|
||||
*/
|
||||
function this($method)
|
||||
{
|
||||
return $this->Uri->this($this, $method);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the URI string for the next calendar unit
|
||||
* @param string calendar unit to fetch uri for (year,month,week or day etc)
|
||||
* @return string
|
||||
* @access public
|
||||
*/
|
||||
function next($method)
|
||||
{
|
||||
return $this->Uri->next($this, $method);
|
||||
}
|
||||
|
||||
}
|
||||
?>
|
||||
148
include/pear/Calendar/Decorator/Weekday.php
Normal file
148
include/pear/Calendar/Decorator/Weekday.php
Normal file
@@ -0,0 +1,148 @@
|
||||
<?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/3_0.txt. |
|
||||
// | If you did not receive a copy of the PHP license and are unable to |
|
||||
// | obtain it through the world-wide-web, please send a note to |
|
||||
// | license@php.net so we can mail you a copy immediately. |
|
||||
// +----------------------------------------------------------------------+
|
||||
// | Authors: Harry Fuecks <hfuecks@phppatterns.com> |
|
||||
// | Lorenzo Alberton <l dot alberton at quipo dot it> |
|
||||
// +----------------------------------------------------------------------+
|
||||
//
|
||||
// $Id: Weekday.php,v 1.3 2004/08/16 12:25:15 hfuecks Exp $
|
||||
//
|
||||
/**
|
||||
* @package Calendar
|
||||
* @version $Id: Weekday.php,v 1.3 2004/08/16 12:25:15 hfuecks Exp $
|
||||
*/
|
||||
|
||||
/**
|
||||
* Allows Calendar include path to be redefined
|
||||
* @ignore
|
||||
*/
|
||||
if (!defined('CALENDAR_ROOT')) {
|
||||
define('CALENDAR_ROOT', 'Calendar'.DIRECTORY_SEPARATOR);
|
||||
}
|
||||
|
||||
/**
|
||||
* Load Calendar decorator base class
|
||||
*/
|
||||
require_once CALENDAR_ROOT.'Decorator.php';
|
||||
|
||||
/**
|
||||
* Load a Calendar_Day
|
||||
*/
|
||||
require_once CALENDAR_ROOT.'Day.php';
|
||||
/**
|
||||
* Decorator for fetching the day of the week
|
||||
* <code>
|
||||
* $Day = new Calendar_Day(2003, 10, 23);
|
||||
* $Weekday = & new Calendar_Decorator_Weekday($Day);
|
||||
* $Weekday->setFirstDay(0); // Set first day of week to Sunday (default Mon)
|
||||
* echo $Weekday->thisWeekDay(); // Displays 5 - fifth day of week relative to Sun
|
||||
* </code>
|
||||
* @package Calendar
|
||||
* @access public
|
||||
*/
|
||||
class Calendar_Decorator_Weekday extends Calendar_Decorator
|
||||
{
|
||||
/**
|
||||
* First day of week
|
||||
* @var int (default = 1 for Monday)
|
||||
* @access private
|
||||
*/
|
||||
var $firstDay = 1;
|
||||
|
||||
/**
|
||||
* Constructs Calendar_Decorator_Weekday
|
||||
* @param object subclass of Calendar
|
||||
* @access public
|
||||
*/
|
||||
function Calendar_Decorator_Weekday(& $Calendar)
|
||||
{
|
||||
parent::Calendar_Decorator($Calendar);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the first day of the week (0 = Sunday, 1 = Monday (default) etc)
|
||||
* @param int first day of week
|
||||
* @return void
|
||||
* @access public
|
||||
*/
|
||||
function setFirstDay($firstDay) {
|
||||
$this->firstDay = (int)$firstDay;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the previous weekday
|
||||
* @param string (default = 'int') return value format
|
||||
* @return int numeric day of week or timestamp
|
||||
* @access public
|
||||
*/
|
||||
function prevWeekDay($format = 'int')
|
||||
{
|
||||
$ts = $this->calendar->prevDay('timestamp');
|
||||
$Day = new Calendar_Day(2000,1,1);
|
||||
$Day->setTimeStamp($ts);
|
||||
$day = $this->calendar->cE->getDayOfWeek($Day->thisYear(),$Day->thisMonth(),$Day->thisDay());
|
||||
$day = $this->adjustWeekScale($day);
|
||||
return $this->returnValue('Day', $format, $ts, $day);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the current weekday
|
||||
* @param string (default = 'int') return value format
|
||||
* @return int numeric day of week or timestamp
|
||||
* @access public
|
||||
*/
|
||||
function thisWeekDay($format = 'int')
|
||||
{
|
||||
$ts = $this->calendar->thisDay('timestamp');
|
||||
$day = $this->calendar->cE->getDayOfWeek($this->calendar->year,$this->calendar->month,$this->calendar->day);
|
||||
$day = $this->adjustWeekScale($day);
|
||||
return $this->returnValue('Day', $format, $ts, $day);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the next weekday
|
||||
* @param string (default = 'int') return value format
|
||||
* @return int numeric day of week or timestamp
|
||||
* @access public
|
||||
*/
|
||||
function nextWeekDay($format = 'int')
|
||||
{
|
||||
$ts = $this->calendar->nextDay('timestamp');
|
||||
$Day = new Calendar_Day(2000,1,1);
|
||||
$Day->setTimeStamp($ts);
|
||||
$day = $this->calendar->cE->getDayOfWeek($Day->thisYear(),$Day->thisMonth(),$Day->thisDay());
|
||||
$day = $this->adjustWeekScale($day);
|
||||
return $this->returnValue('Day', $format, $ts, $day);
|
||||
}
|
||||
|
||||
/**
|
||||
* Adjusts the day of the week relative to the first day of the week
|
||||
* @param int day of week calendar from Calendar_Engine
|
||||
* @return int day of week adjusted to first day
|
||||
* @access private
|
||||
*/
|
||||
function adjustWeekScale($dayOfWeek) {
|
||||
$dayOfWeek = $dayOfWeek - $this->firstDay;
|
||||
if ( $dayOfWeek >= 0 ) {
|
||||
return $dayOfWeek;
|
||||
} else {
|
||||
return $this->calendar->cE->getDaysInWeek(
|
||||
$this->calendar->year,$this->calendar->month,$this->calendar->day
|
||||
) + $dayOfWeek;
|
||||
}
|
||||
}
|
||||
}
|
||||
?>
|
||||
90
include/pear/Calendar/Decorator/Wrapper.php
Normal file
90
include/pear/Calendar/Decorator/Wrapper.php
Normal file
@@ -0,0 +1,90 @@
|
||||
<?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/3_0.txt. |
|
||||
// | If you did not receive a copy of the PHP license and are unable to |
|
||||
// | obtain it through the world-wide-web, please send a note to |
|
||||
// | license@php.net so we can mail you a copy immediately. |
|
||||
// +----------------------------------------------------------------------+
|
||||
// | Authors: Harry Fuecks <hfuecks@phppatterns.com> |
|
||||
// | Lorenzo Alberton <l dot alberton at quipo dot it> |
|
||||
// +----------------------------------------------------------------------+
|
||||
//
|
||||
// $Id: Wrapper.php,v 1.2 2005/11/03 20:35:03 quipo Exp $
|
||||
//
|
||||
/**
|
||||
* @package Calendar
|
||||
* @version $Id: Wrapper.php,v 1.2 2005/11/03 20:35:03 quipo Exp $
|
||||
*/
|
||||
|
||||
/**
|
||||
* Allows Calendar include path to be redefined
|
||||
* @ignore
|
||||
*/
|
||||
if (!defined('CALENDAR_ROOT')) {
|
||||
define('CALENDAR_ROOT', 'Calendar'.DIRECTORY_SEPARATOR);
|
||||
}
|
||||
|
||||
/**
|
||||
* Load Calendar decorator base class
|
||||
*/
|
||||
require_once CALENDAR_ROOT.'Decorator.php';
|
||||
|
||||
/**
|
||||
* Decorator to help with wrapping built children in another decorator
|
||||
* @package Calendar
|
||||
* @access public
|
||||
*/
|
||||
class Calendar_Decorator_Wrapper extends Calendar_Decorator
|
||||
{
|
||||
/**
|
||||
* Constructs Calendar_Decorator_Wrapper
|
||||
* @param object subclass of Calendar
|
||||
* @access public
|
||||
*/
|
||||
function Calendar_Decorator_Wrapper(&$Calendar)
|
||||
{
|
||||
parent::Calendar_Decorator($Calendar);
|
||||
}
|
||||
|
||||
/**
|
||||
* Wraps objects returned from fetch in the named Decorator class
|
||||
* @param string name of Decorator class to wrap with
|
||||
* @return object instance of named decorator
|
||||
* @access public
|
||||
*/
|
||||
function & fetch($decorator)
|
||||
{
|
||||
$Calendar = parent::fetch();
|
||||
if ($Calendar) {
|
||||
$ret =& new $decorator($Calendar);
|
||||
} else {
|
||||
$ret = false;
|
||||
}
|
||||
return $ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* Wraps the returned calendar objects from fetchAll in the named decorator
|
||||
* @param string name of Decorator class to wrap with
|
||||
* @return array
|
||||
* @access public
|
||||
*/
|
||||
function fetchAll($decorator)
|
||||
{
|
||||
$children = parent::fetchAll();
|
||||
foreach ($children as $key => $Calendar) {
|
||||
$children[$key] = & new $decorator($Calendar);
|
||||
}
|
||||
return $children;
|
||||
}
|
||||
}
|
||||
?>
|
||||
293
include/pear/Calendar/Engine/Interface.php
Normal file
293
include/pear/Calendar/Engine/Interface.php
Normal file
@@ -0,0 +1,293 @@
|
||||
<?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/3_0.txt. |
|
||||
// | If you did not receive a copy of the PHP license and are unable to |
|
||||
// | obtain it through the world-wide-web, please send a note to |
|
||||
// | license@php.net so we can mail you a copy immediately. |
|
||||
// +----------------------------------------------------------------------+
|
||||
// | Authors: Harry Fuecks <hfuecks@phppatterns.com> |
|
||||
// +----------------------------------------------------------------------+
|
||||
//
|
||||
// $Id: Interface.php,v 1.5 2004/08/16 12:29:18 hfuecks Exp $
|
||||
//
|
||||
/**
|
||||
* @package Calendar
|
||||
* @version $Id: Interface.php,v 1.5 2004/08/16 12:29:18 hfuecks Exp $
|
||||
*/
|
||||
/**
|
||||
* The methods the classes implementing the Calendar_Engine must implement.
|
||||
* Note this class is not used but simply to help development
|
||||
* @package Calendar
|
||||
* @access protected
|
||||
*/
|
||||
class Calendar_Engine_Interface
|
||||
{
|
||||
/**
|
||||
* Provides a mechansim to make sure parsing of timestamps
|
||||
* into human dates is only performed once per timestamp.
|
||||
* Typically called "internally" by methods like stampToYear.
|
||||
* Return value can vary, depending on the specific implementation
|
||||
* @param int timestamp (depending on implementation)
|
||||
* @return mixed
|
||||
* @access protected
|
||||
*/
|
||||
function stampCollection($stamp)
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a numeric year given a timestamp
|
||||
* @param int timestamp (depending on implementation)
|
||||
* @return int year (e.g. 2003)
|
||||
* @access protected
|
||||
*/
|
||||
function stampToYear($stamp)
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a numeric month given a timestamp
|
||||
* @param int timestamp (depending on implementation)
|
||||
* @return int month (e.g. 9)
|
||||
* @access protected
|
||||
*/
|
||||
function stampToMonth($stamp)
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a numeric day given a timestamp
|
||||
* @param int timestamp (depending on implementation)
|
||||
* @return int day (e.g. 15)
|
||||
* @access protected
|
||||
*/
|
||||
function stampToDay($stamp)
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a numeric hour given a timestamp
|
||||
* @param int timestamp (depending on implementation)
|
||||
* @return int hour (e.g. 13)
|
||||
* @access protected
|
||||
*/
|
||||
function stampToHour($stamp)
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a numeric minute given a timestamp
|
||||
* @param int timestamp (depending on implementation)
|
||||
* @return int minute (e.g. 34)
|
||||
* @access protected
|
||||
*/
|
||||
function stampToMinute($stamp)
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a numeric second given a timestamp
|
||||
* @param int timestamp (depending on implementation)
|
||||
* @return int second (e.g. 51)
|
||||
* @access protected
|
||||
*/
|
||||
function stampToSecond($stamp)
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a timestamp. Can be worth "caching" generated
|
||||
* timestamps in a static variable, identified by the
|
||||
* params this method accepts, to timestamp will only
|
||||
* be calculated once.
|
||||
* @param int year (e.g. 2003)
|
||||
* @param int month (e.g. 9)
|
||||
* @param int day (e.g. 13)
|
||||
* @param int hour (e.g. 13)
|
||||
* @param int minute (e.g. 34)
|
||||
* @param int second (e.g. 53)
|
||||
* @return int (depends on implementation)
|
||||
* @access protected
|
||||
*/
|
||||
function dateToStamp($y,$m,$d,$h,$i,$s)
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* The upper limit on years that the Calendar Engine can work with
|
||||
* @return int (e.g. 2037)
|
||||
* @access protected
|
||||
*/
|
||||
function getMaxYears()
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* The lower limit on years that the Calendar Engine can work with
|
||||
* @return int (e.g 1902)
|
||||
* @access protected
|
||||
*/
|
||||
function getMinYears()
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the number of months in a year
|
||||
* @param int (optional) year to get months for
|
||||
* @return int (e.g. 12)
|
||||
* @access protected
|
||||
*/
|
||||
function getMonthsInYear($y=null)
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the number of days in a month, given year and month
|
||||
* @param int year (e.g. 2003)
|
||||
* @param int month (e.g. 9)
|
||||
* @return int days in month
|
||||
* @access protected
|
||||
*/
|
||||
function getDaysInMonth($y, $m)
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns numeric representation of the day of the week in a month,
|
||||
* given year and month
|
||||
* @param int year (e.g. 2003)
|
||||
* @param int month (e.g. 9)
|
||||
* @return int
|
||||
* @access protected
|
||||
*/
|
||||
function getFirstDayInMonth ($y, $m)
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the number of days in a week
|
||||
* @param int year (2003)
|
||||
* @param int month (9)
|
||||
* @param int day (4)
|
||||
* @return int (e.g. 7)
|
||||
* @access protected
|
||||
*/
|
||||
function getDaysInWeek($y=NULL, $m=NULL, $d=NULL)
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the number of the week in the year (ISO-8601), given a date
|
||||
* @param int year (2003)
|
||||
* @param int month (9)
|
||||
* @param int day (4)
|
||||
* @return int week number
|
||||
* @access protected
|
||||
*/
|
||||
function getWeekNInYear($y, $m, $d)
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the number of the week in the month, given a date
|
||||
* @param int year (2003)
|
||||
* @param int month (9)
|
||||
* @param int day (4)
|
||||
* @param int first day of the week (default: 1 - monday)
|
||||
* @return int week number
|
||||
* @access protected
|
||||
*/
|
||||
function getWeekNInMonth($y, $m, $d, $firstDay=1)
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the number of weeks in the month
|
||||
* @param int year (2003)
|
||||
* @param int month (9)
|
||||
* @param int first day of the week (default: 1 - monday)
|
||||
* @return int weeks number
|
||||
* @access protected
|
||||
*/
|
||||
function getWeeksInMonth($y, $m)
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the number of the day of the week (0=sunday, 1=monday...)
|
||||
* @param int year (2003)
|
||||
* @param int month (9)
|
||||
* @param int day (4)
|
||||
* @return int weekday number
|
||||
* @access protected
|
||||
*/
|
||||
function getDayOfWeek($y, $m, $d)
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the numeric values of the days of the week.
|
||||
* @param int year (2003)
|
||||
* @param int month (9)
|
||||
* @param int day (4)
|
||||
* @return array list of numeric values of days in week, beginning 0
|
||||
* @access protected
|
||||
*/
|
||||
function getWeekDays($y=NULL, $m=NULL, $d=NULL)
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the default first day of the week as an integer. Must be a
|
||||
* member of the array returned from getWeekDays
|
||||
* @param int year (2003)
|
||||
* @param int month (9)
|
||||
* @param int day (4)
|
||||
* @return int (e.g. 1 for Monday)
|
||||
* @see getWeekDays
|
||||
* @access protected
|
||||
*/
|
||||
function getFirstDayOfWeek($y=NULL, $m=NULL, $d=NULL)
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the number of hours in a day<br>
|
||||
* @param int (optional) day to get hours for
|
||||
* @return int (e.g. 24)
|
||||
* @access protected
|
||||
*/
|
||||
function getHoursInDay($y=null,$m=null,$d=null)
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the number of minutes in an hour
|
||||
* @param int (optional) hour to get minutes for
|
||||
* @return int
|
||||
* @access protected
|
||||
*/
|
||||
function getMinutesInHour($y=null,$m=null,$d=null,$h=null)
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the number of seconds in a minutes
|
||||
* @param int (optional) minute to get seconds for
|
||||
* @return int
|
||||
* @access protected
|
||||
*/
|
||||
function getSecondsInMinute($y=null,$m=null,$d=null,$h=null,$i=null)
|
||||
{
|
||||
}
|
||||
}
|
||||
?>
|
||||
407
include/pear/Calendar/Engine/PearDate.php
Normal file
407
include/pear/Calendar/Engine/PearDate.php
Normal file
@@ -0,0 +1,407 @@
|
||||
<?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/3_0.txt. |
|
||||
// | If you did not receive a copy of the PHP license and are unable to |
|
||||
// | obtain it through the world-wide-web, please send a note to |
|
||||
// | license@php.net so we can mail you a copy immediately. |
|
||||
// +----------------------------------------------------------------------+
|
||||
// | Authors: Lorenzo Alberton <l dot alberton at quipo dot it> |
|
||||
// +----------------------------------------------------------------------+
|
||||
//
|
||||
// $Id: PearDate.php,v 1.8 2004/08/20 20:00:55 quipo Exp $
|
||||
//
|
||||
/**
|
||||
* @package Calendar
|
||||
* @version $Id: PearDate.php,v 1.8 2004/08/20 20:00:55 quipo Exp $
|
||||
*/
|
||||
/**
|
||||
* Load PEAR::Date class
|
||||
*/
|
||||
require_once 'Date.php';
|
||||
|
||||
/**
|
||||
* Performs calendar calculations based on the PEAR::Date class
|
||||
* Timestamps are in the ISO-8601 format (YYYY-MM-DD HH:MM:SS)
|
||||
* @package Calendar
|
||||
* @access protected
|
||||
*/
|
||||
class Calendar_Engine_PearDate /* implements Calendar_Engine_Interface */
|
||||
{
|
||||
/**
|
||||
* Makes sure a given timestamp is only ever parsed once
|
||||
* Uses a static variable to prevent date() being used twice
|
||||
* for a date which is already known
|
||||
* @param mixed Any timestamp format recognized by Pear::Date
|
||||
* @return object Pear::Date object
|
||||
* @access protected
|
||||
*/
|
||||
function stampCollection($stamp)
|
||||
{
|
||||
static $stamps = array();
|
||||
if (!isset($stamps[$stamp])) {
|
||||
$stamps[$stamp] = new Date($stamp);
|
||||
}
|
||||
return $stamps[$stamp];
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a numeric year given a iso-8601 datetime
|
||||
* @param string iso-8601 datetime (YYYY-MM-DD HH:MM:SS)
|
||||
* @return int year (e.g. 2003)
|
||||
* @access protected
|
||||
*/
|
||||
function stampToYear($stamp)
|
||||
{
|
||||
$date = Calendar_Engine_PearDate::stampCollection($stamp);
|
||||
return (int)$date->year;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a numeric month given a iso-8601 datetime
|
||||
* @param string iso-8601 datetime (YYYY-MM-DD HH:MM:SS)
|
||||
* @return int month (e.g. 9)
|
||||
* @access protected
|
||||
*/
|
||||
function stampToMonth($stamp)
|
||||
{
|
||||
$date = Calendar_Engine_PearDate::stampCollection($stamp);
|
||||
return (int)$date->month;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a numeric day given a iso-8601 datetime
|
||||
* @param string iso-8601 datetime (YYYY-MM-DD HH:MM:SS)
|
||||
* @return int day (e.g. 15)
|
||||
* @access protected
|
||||
*/
|
||||
function stampToDay($stamp)
|
||||
{
|
||||
$date = Calendar_Engine_PearDate::stampCollection($stamp);
|
||||
return (int)$date->day;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a numeric hour given a iso-8601 datetime
|
||||
* @param string iso-8601 datetime (YYYY-MM-DD HH:MM:SS)
|
||||
* @return int hour (e.g. 13)
|
||||
* @access protected
|
||||
*/
|
||||
function stampToHour($stamp)
|
||||
{
|
||||
$date = Calendar_Engine_PearDate::stampCollection($stamp);
|
||||
return (int)$date->hour;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a numeric minute given a iso-8601 datetime
|
||||
* @param string iso-8601 datetime (YYYY-MM-DD HH:MM:SS)
|
||||
* @return int minute (e.g. 34)
|
||||
* @access protected
|
||||
*/
|
||||
function stampToMinute($stamp)
|
||||
{
|
||||
$date = Calendar_Engine_PearDate::stampCollection($stamp);
|
||||
return (int)$date->minute;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a numeric second given a iso-8601 datetime
|
||||
* @param string iso-8601 datetime (YYYY-MM-DD HH:MM:SS)
|
||||
* @return int second (e.g. 51)
|
||||
* @access protected
|
||||
*/
|
||||
function stampToSecond($stamp)
|
||||
{
|
||||
$date = Calendar_Engine_PearDate::stampCollection($stamp);
|
||||
return (int)$date->second;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a iso-8601 datetime
|
||||
* @param int year (2003)
|
||||
* @param int month (9)
|
||||
* @param int day (13)
|
||||
* @param int hour (13)
|
||||
* @param int minute (34)
|
||||
* @param int second (53)
|
||||
* @return string iso-8601 datetime
|
||||
* @access protected
|
||||
*/
|
||||
function dateToStamp($y, $m, $d, $h=0, $i=0, $s=0)
|
||||
{
|
||||
$r = array();
|
||||
Calendar_Engine_PearDate::adjustDate($y, $m, $d, $h, $i, $s);
|
||||
$key = $y.$m.$d.$h.$i.$s;
|
||||
if (!isset($r[$key])) {
|
||||
$r[$key] = sprintf("%04d-%02d-%02d %02d:%02d:%02d",
|
||||
$y, $m, $d, $h, $i, $s);
|
||||
}
|
||||
return $r[$key];
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the correct date values (useful for math operations on dates)
|
||||
* @param int year (2003)
|
||||
* @param int month (9)
|
||||
* @param int day (13)
|
||||
* @param int hour (13)
|
||||
* @param int minute (34)
|
||||
* @param int second (53)
|
||||
* @access protected
|
||||
*/
|
||||
function adjustDate(&$y, &$m, &$d, &$h, &$i, &$s)
|
||||
{
|
||||
if ($s < 0) {
|
||||
$m -= floor($s / 60);
|
||||
$s = -$s % 60;
|
||||
}
|
||||
if ($s > 60) {
|
||||
$m += floor($s / 60);
|
||||
$s %= 60;
|
||||
}
|
||||
if ($i < 0) {
|
||||
$h -= floor($i / 60);
|
||||
$i = -$i % 60;
|
||||
}
|
||||
if ($i > 60) {
|
||||
$h += floor($i / 60);
|
||||
$i %= 60;
|
||||
}
|
||||
if ($h < 0) {
|
||||
$d -= floor($h / 24);
|
||||
$h = -$h % 24;
|
||||
}
|
||||
if ($h > 24) {
|
||||
$d += floor($h / 24);
|
||||
$h %= 24;
|
||||
}
|
||||
for(; $m < 1; $y--, $m+=12);
|
||||
for(; $m > 12; $y++, $m-=12);
|
||||
|
||||
while ($d < 1) {
|
||||
if ($m > 1) {
|
||||
$m--;
|
||||
} else {
|
||||
$m = 12;
|
||||
$y--;
|
||||
}
|
||||
$d += Date_Calc::daysInMonth($m, $y);
|
||||
}
|
||||
for ($max_days = Date_Calc::daysInMonth($m, $y); $d > $max_days; ) {
|
||||
$d -= $max_days;
|
||||
if ($m < 12) {
|
||||
$m++;
|
||||
} else {
|
||||
$m = 1;
|
||||
$y++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* The upper limit on years that the Calendar Engine can work with
|
||||
* @return int 9999
|
||||
* @access protected
|
||||
*/
|
||||
function getMaxYears()
|
||||
{
|
||||
return 9999;
|
||||
}
|
||||
|
||||
/**
|
||||
* The lower limit on years that the Calendar Engine can work with
|
||||
* @return int 0
|
||||
* @access protected
|
||||
*/
|
||||
function getMinYears()
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the number of months in a year
|
||||
* @return int (12)
|
||||
* @access protected
|
||||
*/
|
||||
function getMonthsInYear($y=null)
|
||||
{
|
||||
return 12;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the number of days in a month, given year and month
|
||||
* @param int year (2003)
|
||||
* @param int month (9)
|
||||
* @return int days in month
|
||||
* @access protected
|
||||
*/
|
||||
function getDaysInMonth($y, $m)
|
||||
{
|
||||
return (int)Date_Calc::daysInMonth($m, $y);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns numeric representation of the day of the week in a month,
|
||||
* given year and month
|
||||
* @param int year (2003)
|
||||
* @param int month (9)
|
||||
* @return int from 0 to 7
|
||||
* @access protected
|
||||
*/
|
||||
function getFirstDayInMonth($y, $m)
|
||||
{
|
||||
return (int)Date_Calc::dayOfWeek(1, $m, $y);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the number of days in a week
|
||||
* @param int year (2003)
|
||||
* @param int month (9)
|
||||
* @param int day (4)
|
||||
* @return int (7)
|
||||
* @access protected
|
||||
*/
|
||||
function getDaysInWeek($y=NULL, $m=NULL, $d=NULL)
|
||||
{
|
||||
return 7;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the number of the week in the year (ISO-8601), given a date
|
||||
* @param int year (2003)
|
||||
* @param int month (9)
|
||||
* @param int day (4)
|
||||
* @return int week number
|
||||
* @access protected
|
||||
*/
|
||||
function getWeekNInYear($y, $m, $d)
|
||||
{
|
||||
return Date_Calc::weekOfYear($d, $m, $y); //beware, Date_Calc doesn't follow ISO-8601 standard!
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the number of the week in the month, given a date
|
||||
* @param int year (2003)
|
||||
* @param int month (9)
|
||||
* @param int day (4)
|
||||
* @param int first day of the week (default: monday)
|
||||
* @return int week number
|
||||
* @access protected
|
||||
*/
|
||||
function getWeekNInMonth($y, $m, $d, $firstDay=1)
|
||||
{
|
||||
$weekEnd = ($firstDay == 0) ? $this->getDaysInWeek()-1 : $firstDay-1;
|
||||
$end_of_week = (int)Date_Calc::nextDayOfWeek($weekEnd, 1, $m, $y, '%e', true);
|
||||
$w = 1;
|
||||
while ($d > $end_of_week) {
|
||||
++$w;
|
||||
$end_of_week += $this->getDaysInWeek();
|
||||
}
|
||||
return $w;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the number of weeks in the month
|
||||
* @param int year (2003)
|
||||
* @param int month (9)
|
||||
* @param int first day of the week (default: monday)
|
||||
* @return int weeks number
|
||||
* @access protected
|
||||
*/
|
||||
function getWeeksInMonth($y, $m, $firstDay=1)
|
||||
{
|
||||
$FDOM = Date_Calc::firstOfMonthWeekday($m, $y);
|
||||
if ($FDOM == 0) {
|
||||
$FDOM = $this->getDaysInWeek();
|
||||
}
|
||||
if ($FDOM > $firstDay) {
|
||||
$daysInTheFirstWeek = $this->getDaysInWeek() - $FDOM + $firstDay;
|
||||
$weeks = 1;
|
||||
} else {
|
||||
$daysInTheFirstWeek = $firstDay - $FDOM;
|
||||
$weeks = 0;
|
||||
}
|
||||
$daysInTheFirstWeek %= $this->getDaysInWeek();
|
||||
return (int)(ceil(($this->getDaysInMonth($y, $m) - $daysInTheFirstWeek) /
|
||||
$this->getDaysInWeek()) + $weeks);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the number of the day of the week (0=sunday, 1=monday...)
|
||||
* @param int year (2003)
|
||||
* @param int month (9)
|
||||
* @param int day (4)
|
||||
* @return int weekday number
|
||||
* @access protected
|
||||
*/
|
||||
function getDayOfWeek($y, $m, $d)
|
||||
{
|
||||
return Date_Calc::dayOfWeek($d, $m, $y);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a list of integer days of the week beginning 0
|
||||
* @param int year (2003)
|
||||
* @param int month (9)
|
||||
* @param int day (4)
|
||||
* @return array (0, 1, 2, 3, 4, 5, 6) 1 = Monday
|
||||
* @access protected
|
||||
*/
|
||||
function getWeekDays($y=NULL, $m=NULL, $d=NULL)
|
||||
{
|
||||
return array(0, 1, 2, 3, 4, 5, 6);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the default first day of the week
|
||||
* @param int year (2003)
|
||||
* @param int month (9)
|
||||
* @param int day (4)
|
||||
* @return int (default 1 = Monday)
|
||||
* @access protected
|
||||
*/
|
||||
function getFirstDayOfWeek($y=NULL, $m=NULL, $d=NULL)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the number of hours in a day
|
||||
* @return int (24)
|
||||
* @access protected
|
||||
*/
|
||||
function getHoursInDay($y=null,$m=null,$d=null)
|
||||
{
|
||||
return 24;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the number of minutes in an hour
|
||||
* @return int (60)
|
||||
* @access protected
|
||||
*/
|
||||
function getMinutesInHour($y=null,$m=null,$d=null,$h=null)
|
||||
{
|
||||
return 60;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the number of seconds in a minutes
|
||||
* @return int (60)
|
||||
* @access protected
|
||||
*/
|
||||
function getSecondsInMinute($y=null,$m=null,$d=null,$h=null,$i=null)
|
||||
{
|
||||
return 60;
|
||||
}
|
||||
}
|
||||
?>
|
||||
365
include/pear/Calendar/Engine/UnixTS.php
Normal file
365
include/pear/Calendar/Engine/UnixTS.php
Normal file
@@ -0,0 +1,365 @@
|
||||
<?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/3_0.txt. |
|
||||
// | If you did not receive a copy of the PHP license and are unable to |
|
||||
// | obtain it through the world-wide-web, please send a note to |
|
||||
// | license@php.net so we can mail you a copy immediately. |
|
||||
// +----------------------------------------------------------------------+
|
||||
// | Authors: Harry Fuecks <hfuecks@phppatterns.com> |
|
||||
// +----------------------------------------------------------------------+
|
||||
//
|
||||
// $Id: UnixTS.php,v 1.9 2004/08/20 20:00:55 quipo Exp $
|
||||
//
|
||||
/**
|
||||
* @package Calendar
|
||||
* @version $Id: UnixTS.php,v 1.9 2004/08/20 20:00:55 quipo Exp $
|
||||
*/
|
||||
/**
|
||||
* Performs calendar calculations based on the PHP date() function and
|
||||
* Unix timestamps (using PHP's mktime() function).
|
||||
* @package Calendar
|
||||
* @access protected
|
||||
*/
|
||||
class Calendar_Engine_UnixTS /* implements Calendar_Engine_Interface */
|
||||
{
|
||||
/**
|
||||
* Makes sure a given timestamp is only ever parsed once
|
||||
* <pre>
|
||||
* array (
|
||||
* [0] => year (e.g 2003),
|
||||
* [1] => month (e.g 9),
|
||||
* [2] => day (e.g 6),
|
||||
* [3] => hour (e.g 14),
|
||||
* [4] => minute (e.g 34),
|
||||
* [5] => second (e.g 45),
|
||||
* [6] => num days in month (e.g. 31),
|
||||
* [7] => week in year (e.g. 50),
|
||||
* [8] => day in week (e.g. 0 for Sunday)
|
||||
* )
|
||||
* </pre>
|
||||
* Uses a static variable to prevent date() being used twice
|
||||
* for a date which is already known
|
||||
* @param int Unix timestamp
|
||||
* @return array
|
||||
* @access protected
|
||||
*/
|
||||
function stampCollection($stamp)
|
||||
{
|
||||
static $stamps = array();
|
||||
if ( !isset($stamps[$stamp]) ) {
|
||||
$date = @date('Y n j H i s t W w',$stamp);
|
||||
$stamps[$stamp] = sscanf($date, "%d %d %d %d %d %d %d %d %d");
|
||||
}
|
||||
return $stamps[$stamp];
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a numeric year given a timestamp
|
||||
* @param int Unix timestamp
|
||||
* @return int year (e.g. 2003)
|
||||
* @access protected
|
||||
*/
|
||||
function stampToYear($stamp)
|
||||
{
|
||||
$date = Calendar_Engine_UnixTS::stampCollection($stamp);
|
||||
return (int)$date[0];
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a numeric month given a timestamp
|
||||
* @param int Unix timestamp
|
||||
* @return int month (e.g. 9)
|
||||
* @access protected
|
||||
*/
|
||||
function stampToMonth($stamp)
|
||||
{
|
||||
$date = Calendar_Engine_UnixTS::stampCollection($stamp);
|
||||
return (int)$date[1];
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a numeric day given a timestamp
|
||||
* @param int Unix timestamp
|
||||
* @return int day (e.g. 15)
|
||||
* @access protected
|
||||
*/
|
||||
function stampToDay($stamp)
|
||||
{
|
||||
$date = Calendar_Engine_UnixTS::stampCollection($stamp);
|
||||
return (int)$date[2];
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a numeric hour given a timestamp
|
||||
* @param int Unix timestamp
|
||||
* @return int hour (e.g. 13)
|
||||
* @access protected
|
||||
*/
|
||||
function stampToHour($stamp)
|
||||
{
|
||||
$date = Calendar_Engine_UnixTS::stampCollection($stamp);
|
||||
return (int)$date[3];
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a numeric minute given a timestamp
|
||||
* @param int Unix timestamp
|
||||
* @return int minute (e.g. 34)
|
||||
* @access protected
|
||||
*/
|
||||
function stampToMinute($stamp)
|
||||
{
|
||||
$date = Calendar_Engine_UnixTS::stampCollection($stamp);
|
||||
return (int)$date[4];
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a numeric second given a timestamp
|
||||
* @param int Unix timestamp
|
||||
* @return int second (e.g. 51)
|
||||
* @access protected
|
||||
*/
|
||||
function stampToSecond($stamp)
|
||||
{
|
||||
$date = Calendar_Engine_UnixTS::stampCollection($stamp);
|
||||
return (int)$date[5];
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a timestamp
|
||||
* @param int year (2003)
|
||||
* @param int month (9)
|
||||
* @param int day (13)
|
||||
* @param int hour (13)
|
||||
* @param int minute (34)
|
||||
* @param int second (53)
|
||||
* @return int Unix timestamp
|
||||
* @access protected
|
||||
*/
|
||||
function dateToStamp($y, $m, $d, $h=0, $i=0, $s=0)
|
||||
{
|
||||
static $dates = array();
|
||||
if ( !isset($dates[$y][$m][$d][$h][$i][$s]) ) {
|
||||
$dates[$y][$m][$d][$h][$i][$s] = @mktime($h, $i, $s, $m, $d, $y);
|
||||
}
|
||||
return $dates[$y][$m][$d][$h][$i][$s];
|
||||
}
|
||||
|
||||
/**
|
||||
* The upper limit on years that the Calendar Engine can work with
|
||||
* @return int (2037)
|
||||
* @access protected
|
||||
*/
|
||||
function getMaxYears()
|
||||
{
|
||||
return 2037;
|
||||
}
|
||||
|
||||
/**
|
||||
* The lower limit on years that the Calendar Engine can work with
|
||||
* @return int (1970 if it's Windows and 1902 for all other OSs)
|
||||
* @access protected
|
||||
*/
|
||||
function getMinYears()
|
||||
{
|
||||
return $min = strpos(PHP_OS, 'WIN') === false ? 1902 : 1970;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the number of months in a year
|
||||
* @return int (12)
|
||||
* @access protected
|
||||
*/
|
||||
function getMonthsInYear($y=null)
|
||||
{
|
||||
return 12;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the number of days in a month, given year and month
|
||||
* @param int year (2003)
|
||||
* @param int month (9)
|
||||
* @return int days in month
|
||||
* @access protected
|
||||
*/
|
||||
function getDaysInMonth($y, $m)
|
||||
{
|
||||
$stamp = Calendar_Engine_UnixTS::dateToStamp($y,$m,1);
|
||||
$date = Calendar_Engine_UnixTS::stampCollection($stamp);
|
||||
return $date[6];
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns numeric representation of the day of the week in a month,
|
||||
* given year and month
|
||||
* @param int year (2003)
|
||||
* @param int month (9)
|
||||
* @return int from 0 to 6
|
||||
* @access protected
|
||||
*/
|
||||
function getFirstDayInMonth($y, $m)
|
||||
{
|
||||
$stamp = Calendar_Engine_UnixTS::dateToStamp($y,$m,1);
|
||||
$date = Calendar_Engine_UnixTS::stampCollection($stamp);
|
||||
return $date[8];
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the number of days in a week
|
||||
* @param int year (2003)
|
||||
* @param int month (9)
|
||||
* @param int day (4)
|
||||
* @return int (7)
|
||||
* @access protected
|
||||
*/
|
||||
function getDaysInWeek($y=NULL, $m=NULL, $d=NULL)
|
||||
{
|
||||
return 7;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the number of the week in the year (ISO-8601), given a date
|
||||
* @param int year (2003)
|
||||
* @param int month (9)
|
||||
* @param int day (4)
|
||||
* @return int week number
|
||||
* @access protected
|
||||
*/
|
||||
function getWeekNInYear($y, $m, $d)
|
||||
{
|
||||
$stamp = Calendar_Engine_UnixTS::dateToStamp($y,$m,$d);
|
||||
$date = Calendar_Engine_UnixTS::stampCollection($stamp);
|
||||
return $date[7];
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the number of the week in the month, given a date
|
||||
* @param int year (2003)
|
||||
* @param int month (9)
|
||||
* @param int day (4)
|
||||
* @param int first day of the week (default: monday)
|
||||
* @return int week number
|
||||
* @access protected
|
||||
*/
|
||||
function getWeekNInMonth($y, $m, $d, $firstDay=1)
|
||||
{
|
||||
$weekEnd = ($firstDay == 0) ? $this->getDaysInWeek()-1 : $firstDay-1;
|
||||
$end_of_week = 1;
|
||||
while (@date('w', @mktime(0, 0, 0, $m, $end_of_week, $y)) != $weekEnd) {
|
||||
++$end_of_week; //find first weekend of the month
|
||||
}
|
||||
$w = 1;
|
||||
while ($d > $end_of_week) {
|
||||
++$w;
|
||||
$end_of_week += $this->getDaysInWeek();
|
||||
}
|
||||
return $w;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the number of weeks in the month
|
||||
* @param int year (2003)
|
||||
* @param int month (9)
|
||||
* @param int first day of the week (default: monday)
|
||||
* @return int weeks number
|
||||
* @access protected
|
||||
*/
|
||||
function getWeeksInMonth($y, $m, $firstDay=1)
|
||||
{
|
||||
$FDOM = $this->getFirstDayInMonth($y, $m);
|
||||
if ($FDOM == 0) {
|
||||
$FDOM = $this->getDaysInWeek();
|
||||
}
|
||||
if ($FDOM > $firstDay) {
|
||||
$daysInTheFirstWeek = $this->getDaysInWeek() - $FDOM + $firstDay;
|
||||
$weeks = 1;
|
||||
} else {
|
||||
$daysInTheFirstWeek = $firstDay - $FDOM;
|
||||
$weeks = 0;
|
||||
}
|
||||
$daysInTheFirstWeek %= $this->getDaysInWeek();
|
||||
return (int)(ceil(($this->getDaysInMonth($y, $m) - $daysInTheFirstWeek) /
|
||||
$this->getDaysInWeek()) + $weeks);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the number of the day of the week (0=sunday, 1=monday...)
|
||||
* @param int year (2003)
|
||||
* @param int month (9)
|
||||
* @param int day (4)
|
||||
* @return int weekday number
|
||||
* @access protected
|
||||
*/
|
||||
function getDayOfWeek($y, $m, $d)
|
||||
{
|
||||
$stamp = Calendar_Engine_UnixTS::dateToStamp($y,$m,$d);
|
||||
$date = Calendar_Engine_UnixTS::stampCollection($stamp);
|
||||
return $date[8];
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a list of integer days of the week beginning 0
|
||||
* @param int year (2003)
|
||||
* @param int month (9)
|
||||
* @param int day (4)
|
||||
* @return array (0,1,2,3,4,5,6) 1 = Monday
|
||||
* @access protected
|
||||
*/
|
||||
function getWeekDays($y=NULL, $m=NULL, $d=NULL)
|
||||
{
|
||||
return array(0, 1, 2, 3, 4, 5, 6);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the default first day of the week
|
||||
* @param int year (2003)
|
||||
* @param int month (9)
|
||||
* @param int day (4)
|
||||
* @return int (default 1 = Monday)
|
||||
* @access protected
|
||||
*/
|
||||
function getFirstDayOfWeek($y=NULL, $m=NULL, $d=NULL)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the number of hours in a day
|
||||
* @return int (24)
|
||||
* @access protected
|
||||
*/
|
||||
function getHoursInDay($y=null,$m=null,$d=null)
|
||||
{
|
||||
return 24;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the number of minutes in an hour
|
||||
* @return int (60)
|
||||
* @access protected
|
||||
*/
|
||||
function getMinutesInHour($y=null,$m=null,$d=null,$h=null)
|
||||
{
|
||||
return 60;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the number of seconds in a minutes
|
||||
* @return int (60)
|
||||
* @access protected
|
||||
*/
|
||||
function getSecondsInMinute($y=null,$m=null,$d=null,$h=null,$i=null)
|
||||
{
|
||||
return 60;
|
||||
}
|
||||
}
|
||||
?>
|
||||
145
include/pear/Calendar/Factory.php
Normal file
145
include/pear/Calendar/Factory.php
Normal file
@@ -0,0 +1,145 @@
|
||||
<?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/3_0.txt. |
|
||||
// | If you did not receive a copy of the PHP license and are unable to |
|
||||
// | obtain it through the world-wide-web, please send a note to |
|
||||
// | license@php.net so we can mail you a copy immediately. |
|
||||
// +----------------------------------------------------------------------+
|
||||
// | Authors: Harry Fuecks <hfuecks@phppatterns.com> |
|
||||
// | Lorenzo Alberton <l dot alberton at quipo dot it> |
|
||||
// +----------------------------------------------------------------------+
|
||||
//
|
||||
// $Id: Factory.php,v 1.3 2005/10/22 10:08:47 quipo Exp $
|
||||
//
|
||||
/**
|
||||
* @package Calendar
|
||||
* @version $Id: Factory.php,v 1.3 2005/10/22 10:08:47 quipo Exp $
|
||||
*/
|
||||
|
||||
/**
|
||||
* Allows Calendar include path to be redefined
|
||||
* @ignore
|
||||
*/
|
||||
if (!defined('CALENDAR_ROOT')) {
|
||||
define('CALENDAR_ROOT', 'Calendar'.DIRECTORY_SEPARATOR);
|
||||
}
|
||||
|
||||
/**
|
||||
* Load Calendar base class
|
||||
*/
|
||||
require_once CALENDAR_ROOT.'Calendar.php';
|
||||
|
||||
/**
|
||||
* Contains a factory method to return a Singleton instance of a class
|
||||
* implementing the Calendar_Engine_Interface.<br>
|
||||
* For Month objects, to control type of month returned, use CALENDAR_MONTH_STATE
|
||||
* constact e.g.;
|
||||
* <code>
|
||||
* require_once 'Calendar/Factory.php';
|
||||
* define ('CALENDAR_MONTH_STATE',CALENDAR_USE_MONTH_WEEKDAYS); // Use Calendar_Month_Weekdays
|
||||
* // define ('CALENDAR_MONTH_STATE',CALENDAR_USE_MONTH_WEEKS); // Use Calendar_Month_Weeks
|
||||
* // define ('CALENDAR_MONTH_STATE',CALENDAR_USE_MONTH); // Use Calendar_Month
|
||||
* </code>
|
||||
* It defaults to building Calendar_Month objects.<br>
|
||||
* Use the constract CALENDAR_FIRST_DAY_OF_WEEK to control the first day of the week
|
||||
* for Month or Week objects (e.g. 0 = Sunday, 6 = Saturday)
|
||||
* @package Calendar
|
||||
* @access protected
|
||||
*/
|
||||
class Calendar_Factory
|
||||
{
|
||||
/**
|
||||
* Creates a calendar object given the type and units
|
||||
* @param string class of calendar object to create
|
||||
* @param int year
|
||||
* @param int month
|
||||
* @param int day
|
||||
* @param int hour
|
||||
* @param int minute
|
||||
* @param int second
|
||||
* @return object subclass of Calendar
|
||||
* @access public
|
||||
* @static
|
||||
*/
|
||||
function create($type, $y = 2000, $m = 1, $d = 1, $h = 0, $i = 0, $s = 0)
|
||||
{
|
||||
$firstDay = defined('CALENDAR_FIRST_DAY_OF_WEEK') ? CALENDAR_FIRST_DAY_OF_WEEK : 1;
|
||||
switch ($type) {
|
||||
case 'Day':
|
||||
require_once CALENDAR_ROOT.'Day.php';
|
||||
return new Calendar_Day($y,$m,$d);
|
||||
case 'Month':
|
||||
// Set default state for which month type to build
|
||||
if (!defined('CALENDAR_MONTH_STATE')) {
|
||||
define('CALENDAR_MONTH_STATE', CALENDAR_USE_MONTH);
|
||||
}
|
||||
switch (CALENDAR_MONTH_STATE) {
|
||||
case CALENDAR_USE_MONTH_WEEKDAYS:
|
||||
require_once CALENDAR_ROOT.'Month/Weekdays.php';
|
||||
$class = 'Calendar_Month_Weekdays';
|
||||
break;
|
||||
case CALENDAR_USE_MONTH_WEEKS:
|
||||
require_once CALENDAR_ROOT.'Month/Weeks.php';
|
||||
$class = 'Calendar_Month_Weeks';
|
||||
break;
|
||||
case CALENDAR_USE_MONTH:
|
||||
default:
|
||||
require_once CALENDAR_ROOT.'Month.php';
|
||||
$class = 'Calendar_Month';
|
||||
break;
|
||||
}
|
||||
return new $class($y, $m, $firstDay);
|
||||
case 'Week':
|
||||
require_once CALENDAR_ROOT.'Week.php';
|
||||
return new Calendar_Week($y, $m, $d, $firstDay);
|
||||
case 'Hour':
|
||||
require_once CALENDAR_ROOT.'Hour.php';
|
||||
return new Calendar_Hour($y, $m, $d, $h);
|
||||
case 'Minute':
|
||||
require_once CALENDAR_ROOT.'Minute.php';
|
||||
return new Calendar_Minute($y, $m, $d, $h, $i);
|
||||
case 'Second':
|
||||
require_once CALENDAR_ROOT.'Second.php';
|
||||
return new Calendar_Second($y,$m,$d,$h,$i,$s);
|
||||
case 'Year':
|
||||
require_once CALENDAR_ROOT.'Year.php';
|
||||
return new Calendar_Year($y);
|
||||
default:
|
||||
require_once 'PEAR.php';
|
||||
PEAR::raiseError(
|
||||
'Calendar_Factory::create() unrecognised type: '.$type, null, PEAR_ERROR_TRIGGER,
|
||||
E_USER_NOTICE, 'Calendar_Factory::create()');
|
||||
return false;
|
||||
}
|
||||
}
|
||||
/**
|
||||
* Creates an instance of a calendar object, given a type and timestamp
|
||||
* @param string type of object to create
|
||||
* @param mixed timestamp (depending on Calendar engine being used)
|
||||
* @return object subclass of Calendar
|
||||
* @access public
|
||||
* @static
|
||||
*/
|
||||
function & createByTimestamp($type, $stamp)
|
||||
{
|
||||
$cE = & Calendar_Engine_Factory::getEngine();
|
||||
$y = $cE->stampToYear($stamp);
|
||||
$m = $cE->stampToMonth($stamp);
|
||||
$d = $cE->stampToDay($stamp);
|
||||
$h = $cE->stampToHour($stamp);
|
||||
$i = $cE->stampToMinute($stamp);
|
||||
$s = $cE->stampToSecond($stamp);
|
||||
$cal = Calendar_Factory::create($type, $y, $m, $d, $h, $i, $s);
|
||||
return $cal;
|
||||
}
|
||||
}
|
||||
?>
|
||||
113
include/pear/Calendar/Hour.php
Normal file
113
include/pear/Calendar/Hour.php
Normal file
@@ -0,0 +1,113 @@
|
||||
<?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/3_0.txt. |
|
||||
// | If you did not receive a copy of the PHP license and are unable to |
|
||||
// | obtain it through the world-wide-web, please send a note to |
|
||||
// | license@php.net so we can mail you a copy immediately. |
|
||||
// +----------------------------------------------------------------------+
|
||||
// | Authors: Harry Fuecks <hfuecks@phppatterns.com> |
|
||||
// +----------------------------------------------------------------------+
|
||||
//
|
||||
// $Id: Hour.php,v 1.1 2004/05/24 22:25:42 quipo Exp $
|
||||
//
|
||||
/**
|
||||
* @package Calendar
|
||||
* @version $Id: Hour.php,v 1.1 2004/05/24 22:25:42 quipo Exp $
|
||||
*/
|
||||
|
||||
/**
|
||||
* Allows Calendar include path to be redefined
|
||||
* @ignore
|
||||
*/
|
||||
if (!defined('CALENDAR_ROOT')) {
|
||||
define('CALENDAR_ROOT', 'Calendar'.DIRECTORY_SEPARATOR);
|
||||
}
|
||||
|
||||
/**
|
||||
* Load Calendar base class
|
||||
*/
|
||||
require_once CALENDAR_ROOT.'Calendar.php';
|
||||
|
||||
/**
|
||||
* Represents an Hour and builds Minutes
|
||||
* <code>
|
||||
* require_once 'Calendar'.DIRECTORY_SEPARATOR.'Hour.php';
|
||||
* $Hour = & new Calendar_Hour(2003, 10, 21, 15); // Oct 21st 2003, 3pm
|
||||
* $Hour->build(); // Build Calendar_Minute objects
|
||||
* while ($Minute = & $Hour->fetch()) {
|
||||
* echo $Minute->thisMinute().'<br />';
|
||||
* }
|
||||
* </code>
|
||||
* @package Calendar
|
||||
* @access public
|
||||
*/
|
||||
class Calendar_Hour extends Calendar
|
||||
{
|
||||
/**
|
||||
* Constructs Calendar_Hour
|
||||
* @param int year e.g. 2003
|
||||
* @param int month e.g. 5
|
||||
* @param int day e.g. 11
|
||||
* @param int hour e.g. 13
|
||||
* @access public
|
||||
*/
|
||||
function Calendar_Hour($y, $m, $d, $h)
|
||||
{
|
||||
Calendar::Calendar($y, $m, $d, $h);
|
||||
}
|
||||
|
||||
/**
|
||||
* Builds the Minutes in the Hour
|
||||
* @param array (optional) Calendar_Minute objects representing selected dates
|
||||
* @return boolean
|
||||
* @access public
|
||||
*/
|
||||
function build($sDates=array())
|
||||
{
|
||||
require_once CALENDAR_ROOT.'Minute.php';
|
||||
$mIH = $this->cE->getMinutesInHour($this->year, $this->month, $this->day,
|
||||
$this->hour);
|
||||
for ($i=0; $i < $mIH; $i++) {
|
||||
$this->children[$i]=
|
||||
new Calendar_Minute($this->year, $this->month, $this->day,
|
||||
$this->hour, $i);
|
||||
}
|
||||
if (count($sDates) > 0) {
|
||||
$this->setSelection($sDates);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Called from build()
|
||||
* @param array
|
||||
* @return void
|
||||
* @access private
|
||||
*/
|
||||
function setSelection($sDates)
|
||||
{
|
||||
foreach ($sDates as $sDate) {
|
||||
if ($this->year == $sDate->thisYear()
|
||||
&& $this->month == $sDate->thisMonth()
|
||||
&& $this->day == $sDate->thisDay()
|
||||
&& $this->hour == $sDate->thisHour())
|
||||
{
|
||||
$key = (int)$sDate->thisMinute();
|
||||
if (isset($this->children[$key])) {
|
||||
$sDate->setSelected();
|
||||
$this->children[$key] = $sDate;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
?>
|
||||
114
include/pear/Calendar/Minute.php
Normal file
114
include/pear/Calendar/Minute.php
Normal file
@@ -0,0 +1,114 @@
|
||||
<?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/3_0.txt. |
|
||||
// | If you did not receive a copy of the PHP license and are unable to |
|
||||
// | obtain it through the world-wide-web, please send a note to |
|
||||
// | license@php.net so we can mail you a copy immediately. |
|
||||
// +----------------------------------------------------------------------+
|
||||
// | Authors: Harry Fuecks <hfuecks@phppatterns.com> |
|
||||
// +----------------------------------------------------------------------+
|
||||
//
|
||||
// $Id: Minute.php,v 1.1 2004/05/24 22:25:42 quipo Exp $
|
||||
//
|
||||
/**
|
||||
* @package Calendar
|
||||
* @version $Id: Minute.php,v 1.1 2004/05/24 22:25:42 quipo Exp $
|
||||
*/
|
||||
|
||||
/**
|
||||
* Allows Calendar include path to be redefined
|
||||
* @ignore
|
||||
*/
|
||||
if (!defined('CALENDAR_ROOT')) {
|
||||
define('CALENDAR_ROOT', 'Calendar'.DIRECTORY_SEPARATOR);
|
||||
}
|
||||
|
||||
/**
|
||||
* Load Calendar base class
|
||||
*/
|
||||
require_once CALENDAR_ROOT.'Calendar.php';
|
||||
|
||||
/**
|
||||
* Represents a Minute and builds Seconds
|
||||
* <code>
|
||||
* require_once 'Calendar'.DIRECTORY_SEPARATOR.'Minute.php';
|
||||
* $Minute = & new Calendar_Minute(2003, 10, 21, 15, 31); // Oct 21st 2003, 3:31pm
|
||||
* $Minute->build(); // Build Calendar_Second objects
|
||||
* while ($Second = & $Minute->fetch()) {
|
||||
* echo $Second->thisSecond().'<br />';
|
||||
* }
|
||||
* </code>
|
||||
* @package Calendar
|
||||
* @access public
|
||||
*/
|
||||
class Calendar_Minute extends Calendar
|
||||
{
|
||||
/**
|
||||
* Constructs Minute
|
||||
* @param int year e.g. 2003
|
||||
* @param int month e.g. 5
|
||||
* @param int day e.g. 11
|
||||
* @param int hour e.g. 13
|
||||
* @param int minute e.g. 31
|
||||
* @access public
|
||||
*/
|
||||
function Calendar_Minute($y, $m, $d, $h, $i)
|
||||
{
|
||||
Calendar::Calendar($y, $m, $d, $h, $i);
|
||||
}
|
||||
|
||||
/**
|
||||
* Builds the Calendar_Second objects
|
||||
* @param array (optional) Calendar_Second objects representing selected dates
|
||||
* @return boolean
|
||||
* @access public
|
||||
*/
|
||||
function build($sDates=array())
|
||||
{
|
||||
require_once CALENDAR_ROOT.'Second.php';
|
||||
$sIM = $this->cE->getSecondsInMinute($this->year, $this->month,
|
||||
$this->day, $this->hour, $this->minute);
|
||||
for ($i=0; $i < $sIM; $i++) {
|
||||
$this->children[$i] = new Calendar_Second($this->year, $this->month,
|
||||
$this->day, $this->hour, $this->minute, $i);
|
||||
}
|
||||
if (count($sDates) > 0) {
|
||||
$this->setSelection($sDates);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Called from build()
|
||||
* @param array
|
||||
* @return void
|
||||
* @access private
|
||||
*/
|
||||
function setSelection($sDates)
|
||||
{
|
||||
foreach ($sDates as $sDate) {
|
||||
if ($this->year == $sDate->thisYear()
|
||||
&& $this->month == $sDate->thisMonth()
|
||||
&& $this->day == $sDate->thisDay()
|
||||
&& $this->hour == $sDate->thisHour()
|
||||
&& $this->minute == $sDate->thisMinute())
|
||||
{
|
||||
$key = (int)$sDate->thisSecond();
|
||||
if (isset($this->children[$key])) {
|
||||
$sDate->setSelected();
|
||||
$this->children[$key] = $sDate;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
?>
|
||||
114
include/pear/Calendar/Month.php
Normal file
114
include/pear/Calendar/Month.php
Normal file
@@ -0,0 +1,114 @@
|
||||
<?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/3_0.txt. |
|
||||
// | If you did not receive a copy of the PHP license and are unable to |
|
||||
// | obtain it through the world-wide-web, please send a note to |
|
||||
// | license@php.net so we can mail you a copy immediately. |
|
||||
// +----------------------------------------------------------------------+
|
||||
// | Authors: Harry Fuecks <hfuecks@phppatterns.com> |
|
||||
// +----------------------------------------------------------------------+
|
||||
//
|
||||
// $Id: Month.php,v 1.3 2005/10/22 10:10:26 quipo Exp $
|
||||
//
|
||||
/**
|
||||
* @package Calendar
|
||||
* @version $Id: Month.php,v 1.3 2005/10/22 10:10:26 quipo Exp $
|
||||
*/
|
||||
|
||||
/**
|
||||
* Allows Calendar include path to be redefined
|
||||
* @ignore
|
||||
*/
|
||||
if (!defined('CALENDAR_ROOT')) {
|
||||
define('CALENDAR_ROOT', 'Calendar'.DIRECTORY_SEPARATOR);
|
||||
}
|
||||
|
||||
/**
|
||||
* Load Calendar base class
|
||||
*/
|
||||
require_once CALENDAR_ROOT.'Calendar.php';
|
||||
|
||||
/**
|
||||
* Represents a Month and builds Days
|
||||
* <code>
|
||||
* require_once 'Calendar/Month.php';
|
||||
* $Month = & new Calendar_Month(2003, 10); // Oct 2003
|
||||
* $Month->build(); // Build Calendar_Day objects
|
||||
* while ($Day = & $Month->fetch()) {
|
||||
* echo $Day->thisDay().'<br />';
|
||||
* }
|
||||
* </code>
|
||||
* @package Calendar
|
||||
* @access public
|
||||
*/
|
||||
class Calendar_Month extends Calendar
|
||||
{
|
||||
/**
|
||||
* Constructs Calendar_Month
|
||||
* @param int $y year e.g. 2003
|
||||
* @param int $m month e.g. 5
|
||||
* @param int $firstDay first day of the week [optional]
|
||||
* @access public
|
||||
*/
|
||||
function Calendar_Month($y, $m, $firstDay=null)
|
||||
{
|
||||
Calendar::Calendar($y, $m);
|
||||
$this->firstDay = $this->defineFirstDayOfWeek($firstDay);
|
||||
}
|
||||
|
||||
/**
|
||||
* Builds Day objects for this Month. Creates as many Calendar_Day objects
|
||||
* as there are days in the month
|
||||
* @param array (optional) Calendar_Day objects representing selected dates
|
||||
* @return boolean
|
||||
* @access public
|
||||
*/
|
||||
function build($sDates=array())
|
||||
{
|
||||
require_once CALENDAR_ROOT.'Day.php';
|
||||
$daysInMonth = $this->cE->getDaysInMonth($this->year, $this->month);
|
||||
for ($i=1; $i<=$daysInMonth; $i++) {
|
||||
$this->children[$i] = new Calendar_Day($this->year, $this->month, $i);
|
||||
}
|
||||
if (count($sDates) > 0) {
|
||||
$this->setSelection($sDates);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Called from build()
|
||||
* @param array
|
||||
* @return void
|
||||
* @access private
|
||||
*/
|
||||
function setSelection($sDates)
|
||||
{
|
||||
foreach ($sDates as $sDate) {
|
||||
if ($this->year == $sDate->thisYear()
|
||||
&& $this->month == $sDate->thisMonth()
|
||||
) {
|
||||
$key = $sDate->thisDay();
|
||||
if (isset($this->children[$key])) {
|
||||
$sDate->setSelected();
|
||||
$class = strtolower(get_class($sDate));
|
||||
if ($class == 'calendar_day' || $class == 'calendar_decorator') {
|
||||
$sDate->setFirst($this->children[$key]->isFirst());
|
||||
$sDate->setLast($this->children[$key]->isLast());
|
||||
}
|
||||
$this->children[$key] = $sDate;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
?>
|
||||
189
include/pear/Calendar/Month/Weekdays.php
Normal file
189
include/pear/Calendar/Month/Weekdays.php
Normal file
@@ -0,0 +1,189 @@
|
||||
<?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/3_0.txt. |
|
||||
// | If you did not receive a copy of the PHP license and are unable to |
|
||||
// | obtain it through the world-wide-web, please send a note to |
|
||||
// | license@php.net so we can mail you a copy immediately. |
|
||||
// +----------------------------------------------------------------------+
|
||||
// | Authors: Harry Fuecks <hfuecks@phppatterns.com> |
|
||||
// +----------------------------------------------------------------------+
|
||||
//
|
||||
// $Id: Weekdays.php,v 1.4 2005/10/22 10:28:49 quipo Exp $
|
||||
//
|
||||
/**
|
||||
* @package Calendar
|
||||
* @version $Id: Weekdays.php,v 1.4 2005/10/22 10:28:49 quipo Exp $
|
||||
*/
|
||||
|
||||
/**
|
||||
* Allows Calendar include path to be redefined
|
||||
* @ignore
|
||||
*/
|
||||
if (!defined('CALENDAR_ROOT')) {
|
||||
define('CALENDAR_ROOT', 'Calendar'.DIRECTORY_SEPARATOR);
|
||||
}
|
||||
|
||||
/**
|
||||
* Load Calendar base class
|
||||
*/
|
||||
require_once CALENDAR_ROOT.'Calendar.php';
|
||||
|
||||
/**
|
||||
* Load base month
|
||||
*/
|
||||
require_once CALENDAR_ROOT.'Month.php';
|
||||
|
||||
/**
|
||||
* Represents a Month and builds Days in tabular form<br>
|
||||
* <code>
|
||||
* require_once 'Calendar/Month/Weekdays.php';
|
||||
* $Month = & new Calendar_Month_Weekdays(2003, 10); // Oct 2003
|
||||
* $Month->build(); // Build Calendar_Day objects
|
||||
* while ($Day = & $Month->fetch()) {
|
||||
* if ($Day->isFirst()) {
|
||||
* echo '<tr>';
|
||||
* }
|
||||
* if ($Day->isEmpty()) {
|
||||
* echo '<td> </td>';
|
||||
* } else {
|
||||
* echo '<td>'.$Day->thisDay().'</td>';
|
||||
* }
|
||||
* if ($Day->isLast()) {
|
||||
* echo '</tr>';
|
||||
* }
|
||||
* }
|
||||
* </code>
|
||||
* @package Calendar
|
||||
* @access public
|
||||
*/
|
||||
class Calendar_Month_Weekdays extends Calendar_Month
|
||||
{
|
||||
/**
|
||||
* Instance of Calendar_Table_Helper
|
||||
* @var Calendar_Table_Helper
|
||||
* @access private
|
||||
*/
|
||||
var $tableHelper;
|
||||
|
||||
/**
|
||||
* First day of the week
|
||||
* @access private
|
||||
* @var string
|
||||
*/
|
||||
var $firstDay;
|
||||
|
||||
/**
|
||||
* Constructs Calendar_Month_Weekdays
|
||||
* @param int year e.g. 2003
|
||||
* @param int month e.g. 5
|
||||
* @param int (optional) first day of week (e.g. 0 for Sunday, 2 for Tuesday etc.)
|
||||
* @access public
|
||||
*/
|
||||
function Calendar_Month_Weekdays($y, $m, $firstDay=null)
|
||||
{
|
||||
Calendar_Month::Calendar_Month($y, $m, $firstDay);
|
||||
}
|
||||
|
||||
/**
|
||||
* Builds Day objects in tabular form, to allow display of calendar month
|
||||
* with empty cells if the first day of the week does not fall on the first
|
||||
* day of the month.
|
||||
* @see Calendar_Day::isEmpty()
|
||||
* @see Calendar_Day_Base::isFirst()
|
||||
* @see Calendar_Day_Base::isLast()
|
||||
* @param array (optional) Calendar_Day objects representing selected dates
|
||||
* @return boolean
|
||||
* @access public
|
||||
*/
|
||||
function build($sDates=array())
|
||||
{
|
||||
require_once CALENDAR_ROOT.'Table/Helper.php';
|
||||
$this->tableHelper = & new Calendar_Table_Helper($this, $this->firstDay);
|
||||
Calendar_Month::build($sDates);
|
||||
$this->buildEmptyDaysBefore();
|
||||
$this->shiftDays();
|
||||
$this->buildEmptyDaysAfter();
|
||||
$this->setWeekMarkers();
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Prepends empty days before the real days in the month
|
||||
* @return void
|
||||
* @access private
|
||||
*/
|
||||
function buildEmptyDaysBefore()
|
||||
{
|
||||
$eBefore = $this->tableHelper->getEmptyDaysBefore();
|
||||
for ($i=0; $i < $eBefore; $i++) {
|
||||
$stamp = $this->cE->dateToStamp($this->year, $this->month, -$i);
|
||||
$Day = new Calendar_Day(
|
||||
$this->cE->stampToYear($stamp),
|
||||
$this->cE->stampToMonth($stamp),
|
||||
$this->cE->stampToDay($stamp));
|
||||
$Day->setEmpty();
|
||||
$Day->adjust();
|
||||
array_unshift($this->children, $Day);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Shifts the array of children forward, if necessary
|
||||
* @return void
|
||||
* @access private
|
||||
*/
|
||||
function shiftDays()
|
||||
{
|
||||
if (isset ($this->children[0])) {
|
||||
array_unshift($this->children, null);
|
||||
unset($this->children[0]);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Appends empty days after the real days in the month
|
||||
* @return void
|
||||
* @access private
|
||||
*/
|
||||
function buildEmptyDaysAfter()
|
||||
{
|
||||
$eAfter = $this->tableHelper->getEmptyDaysAfter();
|
||||
$sDOM = $this->tableHelper->getNumTableDaysInMonth();
|
||||
for ($i = 1; $i <= $sDOM-$eAfter; $i++) {
|
||||
$Day = new Calendar_Day($this->year, $this->month+1, $i);
|
||||
$Day->setEmpty();
|
||||
$Day->adjust();
|
||||
array_push($this->children, $Day);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the "markers" for the beginning and of a of week, in the
|
||||
* built Calendar_Day children
|
||||
* @return void
|
||||
* @access private
|
||||
*/
|
||||
function setWeekMarkers()
|
||||
{
|
||||
$dIW = $this->cE->getDaysInWeek(
|
||||
$this->thisYear(),
|
||||
$this->thisMonth(),
|
||||
$this->thisDay()
|
||||
);
|
||||
$sDOM = $this->tableHelper->getNumTableDaysInMonth();
|
||||
for ($i=1; $i <= $sDOM; $i+= $dIW) {
|
||||
$this->children[$i]->setFirst();
|
||||
$this->children[$i+($dIW-1)]->setLast();
|
||||
}
|
||||
}
|
||||
}
|
||||
?>
|
||||
139
include/pear/Calendar/Month/Weeks.php
Normal file
139
include/pear/Calendar/Month/Weeks.php
Normal file
@@ -0,0 +1,139 @@
|
||||
<?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/3_0.txt. |
|
||||
// | If you did not receive a copy of the PHP license and are unable to |
|
||||
// | obtain it through the world-wide-web, please send a note to |
|
||||
// | license@php.net so we can mail you a copy immediately. |
|
||||
// +----------------------------------------------------------------------+
|
||||
// | Authors: Harry Fuecks <hfuecks@phppatterns.com> |
|
||||
// | Lorenzo Alberton <l dot alberton at quipo dot it> |
|
||||
// +----------------------------------------------------------------------+
|
||||
//
|
||||
// $Id: Weeks.php,v 1.3 2005/10/22 10:28:49 quipo Exp $
|
||||
//
|
||||
/**
|
||||
* @package Calendar
|
||||
* @version $Id: Weeks.php,v 1.3 2005/10/22 10:28:49 quipo Exp $
|
||||
*/
|
||||
|
||||
/**
|
||||
* Allows Calendar include path to be redefined
|
||||
* @ignore
|
||||
*/
|
||||
if (!defined('CALENDAR_ROOT')) {
|
||||
define('CALENDAR_ROOT', 'Calendar'.DIRECTORY_SEPARATOR);
|
||||
}
|
||||
|
||||
/**
|
||||
* Load Calendar base class
|
||||
*/
|
||||
require_once CALENDAR_ROOT.'Calendar.php';
|
||||
|
||||
/**
|
||||
* Load base month
|
||||
*/
|
||||
require_once CALENDAR_ROOT.'Month.php';
|
||||
|
||||
/**
|
||||
* Represents a Month and builds Weeks
|
||||
* <code>
|
||||
* require_once 'Calendar'.DIRECTORY_SEPARATOR.'Month'.DIRECTORY_SEPARATOR.'Weeks.php';
|
||||
* $Month = & new Calendar_Month_Weeks(2003, 10); // Oct 2003
|
||||
* $Month->build(); // Build Calendar_Day objects
|
||||
* while ($Week = & $Month->fetch()) {
|
||||
* echo $Week->thisWeek().'<br />';
|
||||
* }
|
||||
* </code>
|
||||
* @package Calendar
|
||||
* @access public
|
||||
*/
|
||||
class Calendar_Month_Weeks extends Calendar_Month
|
||||
{
|
||||
/**
|
||||
* Instance of Calendar_Table_Helper
|
||||
* @var Calendar_Table_Helper
|
||||
* @access private
|
||||
*/
|
||||
var $tableHelper;
|
||||
|
||||
/**
|
||||
* First day of the week
|
||||
* @access private
|
||||
* @var string
|
||||
*/
|
||||
var $firstDay;
|
||||
|
||||
/**
|
||||
* Constructs Calendar_Month_Weeks
|
||||
* @param int year e.g. 2003
|
||||
* @param int month e.g. 5
|
||||
* @param int (optional) first day of week (e.g. 0 for Sunday, 2 for Tuesday etc.)
|
||||
* @access public
|
||||
*/
|
||||
function Calendar_Month_Weeks($y, $m, $firstDay=null)
|
||||
{
|
||||
Calendar_Month::Calendar_Month($y, $m, $firstDay);
|
||||
}
|
||||
|
||||
/**
|
||||
* Builds Calendar_Week objects for the Month. Note that Calendar_Week
|
||||
* builds Calendar_Day object in tabular form (with Calendar_Day->empty)
|
||||
* @param array (optional) Calendar_Week objects representing selected dates
|
||||
* @return boolean
|
||||
* @access public
|
||||
*/
|
||||
function build($sDates=array())
|
||||
{
|
||||
require_once CALENDAR_ROOT.'Table/Helper.php';
|
||||
$this->tableHelper = & new Calendar_Table_Helper($this, $this->firstDay);
|
||||
require_once CALENDAR_ROOT.'Week.php';
|
||||
$numWeeks = $this->tableHelper->getNumWeeks();
|
||||
for ($i=1, $d=1; $i<=$numWeeks; $i++,
|
||||
$d+=$this->cE->getDaysInWeek(
|
||||
$this->thisYear(),
|
||||
$this->thisMonth(),
|
||||
$this->thisDay()) ) {
|
||||
$this->children[$i] = new Calendar_Week(
|
||||
$this->year, $this->month, $d, $this->tableHelper->getFirstDay());
|
||||
}
|
||||
//used to set empty days
|
||||
$this->children[1]->setFirst(true);
|
||||
$this->children[$numWeeks]->setLast(true);
|
||||
|
||||
// Handle selected weeks here
|
||||
if (count($sDates) > 0) {
|
||||
$this->setSelection($sDates);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Called from build()
|
||||
* @param array
|
||||
* @return void
|
||||
* @access private
|
||||
*/
|
||||
function setSelection($sDates)
|
||||
{
|
||||
foreach ($sDates as $sDate) {
|
||||
if ($this->year == $sDate->thisYear()
|
||||
&& $this->month == $sDate->thisMonth())
|
||||
{
|
||||
$key = $sDate->thisWeek('n_in_month');
|
||||
if (isset($this->children[$key])) {
|
||||
$this->children[$key]->setSelected();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
?>
|
||||
98
include/pear/Calendar/Second.php
Normal file
98
include/pear/Calendar/Second.php
Normal file
@@ -0,0 +1,98 @@
|
||||
<?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/3_0.txt. |
|
||||
// | If you did not receive a copy of the PHP license and are unable to |
|
||||
// | obtain it through the world-wide-web, please send a note to |
|
||||
// | license@php.net so we can mail you a copy immediately. |
|
||||
// +----------------------------------------------------------------------+
|
||||
// | Authors: Harry Fuecks <hfuecks@phppatterns.com> |
|
||||
// +----------------------------------------------------------------------+
|
||||
//
|
||||
// $Id: Second.php,v 1.1 2004/05/24 22:25:42 quipo Exp $
|
||||
//
|
||||
/**
|
||||
* @package Calendar
|
||||
* @version $Id: Second.php,v 1.1 2004/05/24 22:25:42 quipo Exp $
|
||||
*/
|
||||
|
||||
/**
|
||||
* Allows Calendar include path to be redefined
|
||||
* @ignore
|
||||
*/
|
||||
if (!defined('CALENDAR_ROOT')) {
|
||||
define('CALENDAR_ROOT', 'Calendar'.DIRECTORY_SEPARATOR);
|
||||
}
|
||||
|
||||
/**
|
||||
* Load Calendar base class
|
||||
*/
|
||||
require_once CALENDAR_ROOT.'Calendar.php';
|
||||
|
||||
/**
|
||||
* Represents a Second<br />
|
||||
* <b>Note:</b> Seconds do not build other objects
|
||||
* so related methods are overridden to return NULL
|
||||
* @package Calendar
|
||||
*/
|
||||
class Calendar_Second extends Calendar
|
||||
{
|
||||
/**
|
||||
* Constructs Second
|
||||
* @param int year e.g. 2003
|
||||
* @param int month e.g. 5
|
||||
* @param int day e.g. 11
|
||||
* @param int hour e.g. 13
|
||||
* @param int minute e.g. 31
|
||||
* @param int second e.g. 45
|
||||
*/
|
||||
function Calendar_Second($y, $m, $d, $h, $i, $s)
|
||||
{
|
||||
Calendar::Calendar($y, $m, $d, $h, $i, $s);
|
||||
}
|
||||
|
||||
/**
|
||||
* Overwrite build
|
||||
* @return NULL
|
||||
*/
|
||||
function build()
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Overwrite fetch
|
||||
* @return NULL
|
||||
*/
|
||||
function fetch()
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Overwrite fetchAll
|
||||
* @return NULL
|
||||
*/
|
||||
function fetchAll()
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Overwrite size
|
||||
* @return NULL
|
||||
*/
|
||||
function size()
|
||||
{
|
||||
return null;
|
||||
}
|
||||
}
|
||||
?>
|
||||
280
include/pear/Calendar/Table/Helper.php
Normal file
280
include/pear/Calendar/Table/Helper.php
Normal file
@@ -0,0 +1,280 @@
|
||||
<?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/3_0.txt. |
|
||||
// | If you did not receive a copy of the PHP license and are unable to |
|
||||
// | obtain it through the world-wide-web, please send a note to |
|
||||
// | license@php.net so we can mail you a copy immediately. |
|
||||
// +----------------------------------------------------------------------+
|
||||
// | Authors: Harry Fuecks <hfuecks@phppatterns.com> |
|
||||
// +----------------------------------------------------------------------+
|
||||
//
|
||||
// $Id: Helper.php,v 1.5 2005/10/22 09:51:53 quipo Exp $
|
||||
//
|
||||
/**
|
||||
* @package Calendar
|
||||
* @version $Id: Helper.php,v 1.5 2005/10/22 09:51:53 quipo Exp $
|
||||
*/
|
||||
|
||||
/**
|
||||
* Used by Calendar_Month_Weekdays, Calendar_Month_Weeks and Calendar_Week to
|
||||
* help with building the calendar in tabular form
|
||||
* @package Calendar
|
||||
* @access protected
|
||||
*/
|
||||
class Calendar_Table_Helper
|
||||
{
|
||||
/**
|
||||
* Instance of the Calendar object being helped.
|
||||
* @var object
|
||||
* @access private
|
||||
*/
|
||||
var $calendar;
|
||||
|
||||
/**
|
||||
* Instance of the Calendar_Engine
|
||||
* @var object
|
||||
* @access private
|
||||
*/
|
||||
var $cE;
|
||||
|
||||
/**
|
||||
* First day of the week
|
||||
* @access private
|
||||
* @var string
|
||||
*/
|
||||
var $firstDay;
|
||||
|
||||
/**
|
||||
* The seven days of the week named
|
||||
* @access private
|
||||
* @var array
|
||||
*/
|
||||
var $weekDays;
|
||||
|
||||
/**
|
||||
* Days of the week ordered with $firstDay at the beginning
|
||||
* @access private
|
||||
* @var array
|
||||
*/
|
||||
var $daysOfWeek = array();
|
||||
|
||||
/**
|
||||
* Days of the month built from days of the week
|
||||
* @access private
|
||||
* @var array
|
||||
*/
|
||||
var $daysOfMonth = array();
|
||||
|
||||
/**
|
||||
* Number of weeks in month
|
||||
* @var int
|
||||
* @access private
|
||||
*/
|
||||
var $numWeeks = null;
|
||||
|
||||
/**
|
||||
* Number of emtpy days before real days begin in month
|
||||
* @var int
|
||||
* @access private
|
||||
*/
|
||||
var $emptyBefore = 0;
|
||||
|
||||
/**
|
||||
* Constructs Calendar_Table_Helper
|
||||
* @param object Calendar_Month_Weekdays, Calendar_Month_Weeks, Calendar_Week
|
||||
* @param int (optional) first day of the week e.g. 1 for Monday
|
||||
* @access protected
|
||||
*/
|
||||
function Calendar_Table_Helper(& $calendar, $firstDay=null)
|
||||
{
|
||||
$this->calendar = & $calendar;
|
||||
$this->cE = & $calendar->getEngine();
|
||||
if (is_null($firstDay)) {
|
||||
$firstDay = $this->cE->getFirstDayOfWeek(
|
||||
$this->calendar->thisYear(),
|
||||
$this->calendar->thisMonth(),
|
||||
$this->calendar->thisDay()
|
||||
);
|
||||
}
|
||||
$this->firstDay = $firstDay;
|
||||
$this->setFirstDay();
|
||||
$this->setDaysOfMonth();
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs $this->daysOfWeek based on $this->firstDay
|
||||
* @return void
|
||||
* @access private
|
||||
*/
|
||||
function setFirstDay()
|
||||
{
|
||||
$weekDays = $this->cE->getWeekDays(
|
||||
$this->calendar->thisYear(),
|
||||
$this->calendar->thisMonth(),
|
||||
$this->calendar->thisDay()
|
||||
);
|
||||
$endDays = array();
|
||||
$tmpDays = array();
|
||||
$begin = false;
|
||||
foreach ($weekDays as $day) {
|
||||
if ($begin) {
|
||||
$endDays[] = $day;
|
||||
} else if ($day === $this->firstDay) {
|
||||
$begin = true;
|
||||
$endDays[] = $day;
|
||||
} else {
|
||||
$tmpDays[] = $day;
|
||||
}
|
||||
}
|
||||
$this->daysOfWeek = array_merge($endDays, $tmpDays);
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs $this->daysOfMonth
|
||||
* @return void
|
||||
* @access private
|
||||
*/
|
||||
function setDaysOfMonth()
|
||||
{
|
||||
$this->daysOfMonth = $this->daysOfWeek;
|
||||
$daysInMonth = $this->cE->getDaysInMonth(
|
||||
$this->calendar->thisYear(), $this->calendar->thisMonth());
|
||||
$firstDayInMonth = $this->cE->getFirstDayInMonth(
|
||||
$this->calendar->thisYear(), $this->calendar->thisMonth());
|
||||
$this->emptyBefore=0;
|
||||
foreach ($this->daysOfMonth as $dayOfWeek) {
|
||||
if ($firstDayInMonth == $dayOfWeek) {
|
||||
break;
|
||||
}
|
||||
$this->emptyBefore++;
|
||||
}
|
||||
$this->numWeeks = ceil(
|
||||
($daysInMonth + $this->emptyBefore)
|
||||
/
|
||||
$this->cE->getDaysInWeek(
|
||||
$this->calendar->thisYear(),
|
||||
$this->calendar->thisMonth(),
|
||||
$this->calendar->thisDay()
|
||||
)
|
||||
);
|
||||
for ($i=1; $i < $this->numWeeks; $i++) {
|
||||
$this->daysOfMonth =
|
||||
array_merge($this->daysOfMonth, $this->daysOfWeek);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the first day of the month
|
||||
* @see Calendar_Engine_Interface::getFirstDayOfWeek()
|
||||
* @return int
|
||||
* @access protected
|
||||
*/
|
||||
function getFirstDay()
|
||||
{
|
||||
return $this->firstDay;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the order array of days in a week
|
||||
* @return int
|
||||
* @access protected
|
||||
*/
|
||||
function getDaysOfWeek()
|
||||
{
|
||||
return $this->daysOfWeek;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the number of tabular weeks in a month
|
||||
* @return int
|
||||
* @access protected
|
||||
*/
|
||||
function getNumWeeks()
|
||||
{
|
||||
return $this->numWeeks;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the number of real days + empty days
|
||||
* @return int
|
||||
* @access protected
|
||||
*/
|
||||
function getNumTableDaysInMonth()
|
||||
{
|
||||
return count($this->daysOfMonth);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the number of empty days before the real days begin
|
||||
* @return int
|
||||
* @access protected
|
||||
*/
|
||||
function getEmptyDaysBefore()
|
||||
{
|
||||
return $this->emptyBefore;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the index of the last real day in the month
|
||||
* @todo Potential performance optimization with static
|
||||
* @return int
|
||||
* @access protected
|
||||
*/
|
||||
function getEmptyDaysAfter()
|
||||
{
|
||||
// Causes bug when displaying more than one month
|
||||
// static $index;
|
||||
// if (!isset($index)) {
|
||||
$index = $this->getEmptyDaysBefore() + $this->cE->getDaysInMonth(
|
||||
$this->calendar->thisYear(), $this->calendar->thisMonth());
|
||||
// }
|
||||
return $index;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the index of the last real day in the month, relative to the
|
||||
* beginning of the tabular week it is part of
|
||||
* @return int
|
||||
* @access protected
|
||||
*/
|
||||
function getEmptyDaysAfterOffset()
|
||||
{
|
||||
$eAfter = $this->getEmptyDaysAfter();
|
||||
return $eAfter - (
|
||||
$this->cE->getDaysInWeek(
|
||||
$this->calendar->thisYear(),
|
||||
$this->calendar->thisMonth(),
|
||||
$this->calendar->thisDay()
|
||||
) * ($this->numWeeks-1) );
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the timestamp of the first day of the current week
|
||||
*/
|
||||
function getWeekStart($y, $m, $d, $firstDay=1)
|
||||
{
|
||||
$dow = $this->cE->getDayOfWeek($y, $m, $d);
|
||||
if ($dow > $firstDay) {
|
||||
$d -= ($dow - $firstDay);
|
||||
}
|
||||
if ($dow < $firstDay) {
|
||||
$d -= (
|
||||
$this->cE->getDaysInWeek(
|
||||
$this->calendar->thisYear(),
|
||||
$this->calendar->thisMonth(),
|
||||
$this->calendar->thisDay()
|
||||
) - $firstDay + $dow);
|
||||
}
|
||||
return $this->cE->dateToStamp($y, $m, $d);
|
||||
}
|
||||
}
|
||||
?>
|
||||
239
include/pear/Calendar/Util/Textual.php
Normal file
239
include/pear/Calendar/Util/Textual.php
Normal file
@@ -0,0 +1,239 @@
|
||||
<?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/3_0.txt. |
|
||||
// | If you did not receive a copy of the PHP license and are unable to |
|
||||
// | obtain it through the world-wide-web, please send a note to |
|
||||
// | license@php.net so we can mail you a copy immediately. |
|
||||
// +----------------------------------------------------------------------+
|
||||
// | Authors: Harry Fuecks <hfuecks@phppatterns.com> |
|
||||
// | Lorenzo Alberton <l dot alberton at quipo dot it> |
|
||||
// +----------------------------------------------------------------------+
|
||||
//
|
||||
// $Id: Textual.php,v 1.2 2004/08/16 13:13:09 hfuecks Exp $
|
||||
//
|
||||
/**
|
||||
* @package Calendar
|
||||
* @version $Id: Textual.php,v 1.2 2004/08/16 13:13:09 hfuecks Exp $
|
||||
*/
|
||||
|
||||
/**
|
||||
* Allows Calendar include path to be redefined
|
||||
* @ignore
|
||||
*/
|
||||
if (!defined('CALENDAR_ROOT')) {
|
||||
define('CALENDAR_ROOT', 'Calendar'.DIRECTORY_SEPARATOR);
|
||||
}
|
||||
|
||||
/**
|
||||
* Load Calendar decorator base class
|
||||
*/
|
||||
require_once CALENDAR_ROOT.'Decorator.php';
|
||||
|
||||
/**
|
||||
* Static utlities to help with fetching textual representations of months and
|
||||
* days of the week.
|
||||
* @package Calendar
|
||||
* @access public
|
||||
*/
|
||||
class Calendar_Util_Textual
|
||||
{
|
||||
|
||||
/**
|
||||
* Returns an array of 12 month names (first index = 1)
|
||||
* @param string (optional) format of returned months (one,two,short or long)
|
||||
* @return array
|
||||
* @access public
|
||||
* @static
|
||||
*/
|
||||
function monthNames($format='long')
|
||||
{
|
||||
$formats = array('one'=>'%b', 'two'=>'%b', 'short'=>'%b', 'long'=>'%B');
|
||||
if (!array_key_exists($format,$formats)) {
|
||||
$format = 'long';
|
||||
}
|
||||
$months = array();
|
||||
for ($i=1; $i<=12; $i++) {
|
||||
$stamp = mktime(0, 0, 0, $i, 1, 2003);
|
||||
$month = strftime($formats[$format], $stamp);
|
||||
switch($format) {
|
||||
case 'one':
|
||||
$month = substr($month, 0, 1);
|
||||
break;
|
||||
case 'two':
|
||||
$month = substr($month, 0, 2);
|
||||
break;
|
||||
}
|
||||
$months[$i] = $month;
|
||||
}
|
||||
return $months;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an array of 7 week day names (first index = 0)
|
||||
* @param string (optional) format of returned days (one,two,short or long)
|
||||
* @return array
|
||||
* @access public
|
||||
* @static
|
||||
*/
|
||||
function weekdayNames($format='long')
|
||||
{
|
||||
$formats = array('one'=>'%a', 'two'=>'%a', 'short'=>'%a', 'long'=>'%A');
|
||||
if (!array_key_exists($format,$formats)) {
|
||||
$format = 'long';
|
||||
}
|
||||
$days = array();
|
||||
for ($i=0; $i<=6; $i++) {
|
||||
$stamp = mktime(0, 0, 0, 11, $i+2, 2003);
|
||||
$day = strftime($formats[$format], $stamp);
|
||||
switch($format) {
|
||||
case 'one':
|
||||
$day = substr($day, 0, 1);
|
||||
break;
|
||||
case 'two':
|
||||
$day = substr($day, 0, 2);
|
||||
break;
|
||||
}
|
||||
$days[$i] = $day;
|
||||
}
|
||||
return $days;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns textual representation of the previous month of the decorated calendar object
|
||||
* @param object subclass of Calendar e.g. Calendar_Month
|
||||
* @param string (optional) format of returned months (one,two,short or long)
|
||||
* @return string
|
||||
* @access public
|
||||
* @static
|
||||
*/
|
||||
function prevMonthName($Calendar, $format='long')
|
||||
{
|
||||
$months = Calendar_Util_Textual::monthNames($format);
|
||||
return $months[$Calendar->prevMonth()];
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns textual representation of the month of the decorated calendar object
|
||||
* @param object subclass of Calendar e.g. Calendar_Month
|
||||
* @param string (optional) format of returned months (one,two,short or long)
|
||||
* @return string
|
||||
* @access public
|
||||
* @static
|
||||
*/
|
||||
function thisMonthName($Calendar, $format='long')
|
||||
{
|
||||
$months = Calendar_Util_Textual::monthNames($format);
|
||||
return $months[$Calendar->thisMonth()];
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns textual representation of the next month of the decorated calendar object
|
||||
* @param object subclass of Calendar e.g. Calendar_Month
|
||||
* @param string (optional) format of returned months (one,two,short or long)
|
||||
* @return string
|
||||
* @access public
|
||||
* @static
|
||||
*/
|
||||
function nextMonthName($Calendar, $format='long')
|
||||
{
|
||||
$months = Calendar_Util_Textual::monthNames($format);
|
||||
return $months[$Calendar->nextMonth()];
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns textual representation of the previous day of week of the decorated calendar object
|
||||
* <b>Note:</b> Requires PEAR::Date
|
||||
* @param object subclass of Calendar e.g. Calendar_Month
|
||||
* @param string (optional) format of returned months (one,two,short or long)
|
||||
* @return string
|
||||
* @access public
|
||||
* @static
|
||||
*/
|
||||
function prevDayName($Calendar, $format='long')
|
||||
{
|
||||
$days = Calendar_Util_Textual::weekdayNames($format);
|
||||
$stamp = $Calendar->prevDay('timestamp');
|
||||
$cE = $Calendar->getEngine();
|
||||
require_once 'Date/Calc.php';
|
||||
$day = Date_Calc::dayOfWeek($cE->stampToDay($stamp),
|
||||
$cE->stampToMonth($stamp), $cE->stampToYear($stamp));
|
||||
return $days[$day];
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns textual representation of the day of week of the decorated calendar object
|
||||
* <b>Note:</b> Requires PEAR::Date
|
||||
* @param object subclass of Calendar e.g. Calendar_Month
|
||||
* @param string (optional) format of returned months (one,two,short or long)
|
||||
* @return string
|
||||
* @access public
|
||||
* @static
|
||||
*/
|
||||
function thisDayName($Calendar, $format='long')
|
||||
{
|
||||
$days = Calendar_Util_Textual::weekdayNames($format);
|
||||
require_once 'Date/Calc.php';
|
||||
$day = Date_Calc::dayOfWeek($Calendar->thisDay(), $Calendar->thisMonth(), $Calendar->thisYear());
|
||||
return $days[$day];
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns textual representation of the next day of week of the decorated calendar object
|
||||
* @param object subclass of Calendar e.g. Calendar_Month
|
||||
* @param string (optional) format of returned months (one,two,short or long)
|
||||
* @return string
|
||||
* @access public
|
||||
* @static
|
||||
*/
|
||||
function nextDayName($Calendar, $format='long')
|
||||
{
|
||||
$days = Calendar_Util_Textual::weekdayNames($format);
|
||||
$stamp = $Calendar->nextDay('timestamp');
|
||||
$cE = $Calendar->getEngine();
|
||||
require_once 'Date/Calc.php';
|
||||
$day = Date_Calc::dayOfWeek($cE->stampToDay($stamp),
|
||||
$cE->stampToMonth($stamp), $cE->stampToYear($stamp));
|
||||
return $days[$day];
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the days of the week using the order defined in the decorated
|
||||
* calendar object. Only useful for Calendar_Month_Weekdays, Calendar_Month_Weeks
|
||||
* and Calendar_Week. Otherwise the returned array will begin on Sunday
|
||||
* @param object subclass of Calendar e.g. Calendar_Month
|
||||
* @param string (optional) format of returned months (one,two,short or long)
|
||||
* @return array ordered array of week day names
|
||||
* @access public
|
||||
* @static
|
||||
*/
|
||||
function orderedWeekdays($Calendar, $format='long')
|
||||
{
|
||||
$days = Calendar_Util_Textual::weekdayNames($format);
|
||||
|
||||
// Not so good - need methods to access this information perhaps...
|
||||
if (isset($Calendar->tableHelper)) {
|
||||
$ordereddays = $Calendar->tableHelper->daysOfWeek;
|
||||
} else {
|
||||
$ordereddays = array(0, 1, 2, 3, 4, 5, 6);
|
||||
}
|
||||
|
||||
$ordereddays = array_flip($ordereddays);
|
||||
$i = 0;
|
||||
$returndays = array();
|
||||
foreach ($ordereddays as $key => $value) {
|
||||
$returndays[$i] = $days[$key];
|
||||
$i++;
|
||||
}
|
||||
return $returndays;
|
||||
}
|
||||
}
|
||||
?>
|
||||
169
include/pear/Calendar/Util/Uri.php
Normal file
169
include/pear/Calendar/Util/Uri.php
Normal file
@@ -0,0 +1,169 @@
|
||||
<?php
|
||||
/* vim: set expandtab tabstop=4 shiftwidth=4: */
|
||||
//
|
||||
// +----------------------------------------------------------------------+
|
||||
// | PHP |
|
||||
// +----------------------------------------------------------------------+
|
||||
// | 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/3_0.txt. |
|
||||
// | If you did not receive a copy of the PHP license and are unable to |
|
||||
// | obtain it through the world-wide-web, please send a note to |
|
||||
// | license@php.net so we can mail you a copy immediately. |
|
||||
// +----------------------------------------------------------------------+
|
||||
// | Authors: Harry Fuecks <hfuecks@phppatterns.com> |
|
||||
// | Lorenzo Alberton <l dot alberton at quipo dot it> |
|
||||
// +----------------------------------------------------------------------+
|
||||
//
|
||||
// $Id: Uri.php,v 1.1 2004/08/16 09:03:55 hfuecks Exp $
|
||||
//
|
||||
/**
|
||||
* @package Calendar
|
||||
* @version $Id: Uri.php,v 1.1 2004/08/16 09:03:55 hfuecks Exp $
|
||||
*/
|
||||
|
||||
/**
|
||||
* Utility to help building HTML links for navigating the calendar<br />
|
||||
* <code>
|
||||
* $Day = new Calendar_Day(2003, 10, 23);
|
||||
* $Uri = & new Calendar_Util_Uri('year', 'month', 'day');
|
||||
* echo $Uri->prev($Day,'month'); // Displays year=2003&month=10
|
||||
* echo $Uri->prev($Day,'day'); // Displays year=2003&month=10&day=22
|
||||
* $Uri->seperator = '/';
|
||||
* $Uri->scalar = true;
|
||||
* echo $Uri->prev($Day,'month'); // Displays 2003/10
|
||||
* echo $Uri->prev($Day,'day'); // Displays 2003/10/22
|
||||
* </code>
|
||||
* @package Calendar
|
||||
* @access public
|
||||
*/
|
||||
class Calendar_Util_Uri
|
||||
{
|
||||
/**
|
||||
* Uri fragments for year, month, day etc.
|
||||
* @var array
|
||||
* @access private
|
||||
*/
|
||||
var $uris = array();
|
||||
|
||||
/**
|
||||
* String to separate fragments with.
|
||||
* Set to just & for HTML.
|
||||
* For a scalar URL you might use / as the seperator
|
||||
* @var string (default XHTML &)
|
||||
* @access public
|
||||
*/
|
||||
var $separator = '&';
|
||||
|
||||
/**
|
||||
* To output a "scalar" string - variable names omitted.
|
||||
* Used for urls like index.php/2004/8/12
|
||||
* @var boolean (default false)
|
||||
* @access public
|
||||
*/
|
||||
var $scalar = false;
|
||||
|
||||
/**
|
||||
* Constructs Calendar_Decorator_Uri
|
||||
* The term "fragment" means <i>name</i> of a calendar GET variables in the URL
|
||||
* @param string URI fragment for year
|
||||
* @param string (optional) URI fragment for month
|
||||
* @param string (optional) URI fragment for day
|
||||
* @param string (optional) URI fragment for hour
|
||||
* @param string (optional) URI fragment for minute
|
||||
* @param string (optional) URI fragment for second
|
||||
* @access public
|
||||
*/
|
||||
function Calendar_Util_Uri($y, $m=null, $d=null, $h=null, $i=null, $s=null)
|
||||
{
|
||||
$this->setFragments($y, $m, $d, $h, $i, $s);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the URI fragment names
|
||||
* @param string URI fragment for year
|
||||
* @param string (optional) URI fragment for month
|
||||
* @param string (optional) URI fragment for day
|
||||
* @param string (optional) URI fragment for hour
|
||||
* @param string (optional) URI fragment for minute
|
||||
* @param string (optional) URI fragment for second
|
||||
* @return void
|
||||
* @access public
|
||||
*/
|
||||
function setFragments($y, $m=null, $d=null, $h=null, $i=null, $s=null) {
|
||||
if (!is_null($y)) $this->uris['Year'] = $y;
|
||||
if (!is_null($m)) $this->uris['Month'] = $m;
|
||||
if (!is_null($d)) $this->uris['Day'] = $d;
|
||||
if (!is_null($h)) $this->uris['Hour'] = $h;
|
||||
if (!is_null($i)) $this->uris['Minute'] = $i;
|
||||
if (!is_null($s)) $this->uris['Second'] = $s;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the URI string for the previous calendar unit
|
||||
* @param object subclassed from Calendar e.g. Calendar_Month
|
||||
* @param string calendar unit ( must be year, month, week, day, hour, minute or second)
|
||||
* @return string
|
||||
* @access public
|
||||
*/
|
||||
function prev($Calendar, $unit)
|
||||
{
|
||||
$method = 'prev'.$unit;
|
||||
$stamp = $Calendar->{$method}('timestamp');
|
||||
return $this->buildUriString($Calendar, $method, $stamp);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the URI string for the current calendar unit
|
||||
* @param object subclassed from Calendar e.g. Calendar_Month
|
||||
* @param string calendar unit ( must be year, month, week, day, hour, minute or second)
|
||||
* @return string
|
||||
* @access public
|
||||
*/
|
||||
function this($Calendar, $unit)
|
||||
{
|
||||
$method = 'this'.$unit;
|
||||
$stamp = $Calendar->{$method}('timestamp');
|
||||
return $this->buildUriString($Calendar, $method, $stamp);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the URI string for the next calendar unit
|
||||
* @param object subclassed from Calendar e.g. Calendar_Month
|
||||
* @param string calendar unit ( must be year, month, week, day, hour, minute or second)
|
||||
* @return string
|
||||
* @access public
|
||||
*/
|
||||
function next($Calendar, $unit)
|
||||
{
|
||||
$method = 'next'.$unit;
|
||||
$stamp = $Calendar->{$method}('timestamp');
|
||||
return $this->buildUriString($Calendar, $method, $stamp);
|
||||
}
|
||||
|
||||
/**
|
||||
* Build the URI string
|
||||
* @param string method substring
|
||||
* @param int timestamp
|
||||
* @return string build uri string
|
||||
* @access private
|
||||
*/
|
||||
function buildUriString($Calendar, $method, $stamp)
|
||||
{
|
||||
$uriString = '';
|
||||
$cE = & $Calendar->getEngine();
|
||||
$separator = '';
|
||||
foreach ($this->uris as $unit => $uri) {
|
||||
$call = 'stampTo'.$unit;
|
||||
$uriString .= $separator;
|
||||
if (!$this->scalar) $uriString .= $uri.'=';
|
||||
$uriString .= $cE->{$call}($stamp);
|
||||
$separator = $this->separator;
|
||||
}
|
||||
return $uriString;
|
||||
}
|
||||
}
|
||||
?>
|
||||
335
include/pear/Calendar/Validator.php
Normal file
335
include/pear/Calendar/Validator.php
Normal file
@@ -0,0 +1,335 @@
|
||||
<?php
|
||||
/* vim: set expandtab tabstop=4 shiftwidth=4: */
|
||||
//
|
||||
// +----------------------------------------------------------------------+
|
||||
// | PHP Version 4 |
|
||||
// +----------------------------------------------------------------------+
|
||||
// | Copyright (c) 1997-2002 The PHP Group |
|
||||
// +----------------------------------------------------------------------+
|
||||
// | This source file is subject to version 2.02 of the PHP license, |
|
||||
// | that is bundled with this package in the file LICENSE, and is |
|
||||
// | available at through the world-wide-web at |
|
||||
// | http://www.php.net/license/3_0.txt. |
|
||||
// | If you did not receive a copy of the PHP license and are unable to |
|
||||
// | obtain it through the world-wide-web, please send a note to |
|
||||
// | license@php.net so we can mail you a copy immediately. |
|
||||
// +----------------------------------------------------------------------+
|
||||
// | Authors: Harry Fuecks <hfuecks@phppatterns.com> |
|
||||
// +----------------------------------------------------------------------+
|
||||
//
|
||||
// $Id: Validator.php,v 1.1 2004/05/24 22:25:42 quipo Exp $
|
||||
//
|
||||
/**
|
||||
* @package Calendar
|
||||
* @version $Id: Validator.php,v 1.1 2004/05/24 22:25:42 quipo Exp $
|
||||
*/
|
||||
|
||||
/**
|
||||
* Validation Error Messages
|
||||
*/
|
||||
if (!defined('CALENDAR_VALUE_TOOSMALL')) {
|
||||
define('CALENDAR_VALUE_TOOSMALL', 'Too small: min = ');
|
||||
}
|
||||
if (!defined('CALENDAR_VALUE_TOOLARGE')) {
|
||||
define('CALENDAR_VALUE_TOOLARGE', 'Too large: max = ');
|
||||
}
|
||||
|
||||
/**
|
||||
* Used to validate any given Calendar date object. Instances of this class
|
||||
* can be obtained from any data object using the getValidator method
|
||||
* @see Calendar::getValidator()
|
||||
* @package Calendar
|
||||
* @access public
|
||||
*/
|
||||
class Calendar_Validator
|
||||
{
|
||||
/**
|
||||
* Instance of the Calendar date object to validate
|
||||
* @var object
|
||||
* @access private
|
||||
*/
|
||||
var $calendar;
|
||||
|
||||
/**
|
||||
* Instance of the Calendar_Engine
|
||||
* @var object
|
||||
* @access private
|
||||
*/
|
||||
var $cE;
|
||||
|
||||
/**
|
||||
* Array of errors for validation failures
|
||||
* @var array
|
||||
* @access private
|
||||
*/
|
||||
var $errors = array();
|
||||
|
||||
/**
|
||||
* Constructs Calendar_Validator
|
||||
* @param object subclass of Calendar
|
||||
* @access public
|
||||
*/
|
||||
function Calendar_Validator(& $calendar)
|
||||
{
|
||||
$this->calendar = & $calendar;
|
||||
$this->cE = & $calendar->getEngine();
|
||||
}
|
||||
|
||||
/**
|
||||
* Calls all the other isValidXXX() methods in the validator
|
||||
* @return boolean
|
||||
* @access public
|
||||
*/
|
||||
function isValid()
|
||||
{
|
||||
$checks = array('isValidYear', 'isValidMonth', 'isValidDay',
|
||||
'isValidHour', 'isValidMinute', 'isValidSecond');
|
||||
$valid = true;
|
||||
foreach ($checks as $check) {
|
||||
if (!$this->{$check}()) {
|
||||
$valid = false;
|
||||
}
|
||||
}
|
||||
return $valid;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check whether this is a valid year
|
||||
* @return boolean
|
||||
* @access public
|
||||
*/
|
||||
function isValidYear()
|
||||
{
|
||||
$y = $this->calendar->thisYear();
|
||||
$min = $this->cE->getMinYears();
|
||||
if ($min > $y) {
|
||||
$this->errors[] = new Calendar_Validation_Error(
|
||||
'Year', $y, CALENDAR_VALUE_TOOSMALL.$min);
|
||||
return false;
|
||||
}
|
||||
$max = $this->cE->getMaxYears();
|
||||
if ($y > $max) {
|
||||
$this->errors[] = new Calendar_Validation_Error(
|
||||
'Year', $y, CALENDAR_VALUE_TOOLARGE.$max);
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check whether this is a valid month
|
||||
* @return boolean
|
||||
* @access public
|
||||
*/
|
||||
function isValidMonth()
|
||||
{
|
||||
$m = $this->calendar->thisMonth();
|
||||
$min = 1;
|
||||
if ($min > $m) {
|
||||
$this->errors[] = new Calendar_Validation_Error(
|
||||
'Month', $m, CALENDAR_VALUE_TOOSMALL.$min);
|
||||
return false;
|
||||
}
|
||||
$max = $this->cE->getMonthsInYear($this->calendar->thisYear());
|
||||
if ($m > $max) {
|
||||
$this->errors[] = new Calendar_Validation_Error(
|
||||
'Month', $m, CALENDAR_VALUE_TOOLARGE.$max);
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check whether this is a valid day
|
||||
* @return boolean
|
||||
* @access public
|
||||
*/
|
||||
function isValidDay()
|
||||
{
|
||||
$d = $this->calendar->thisDay();
|
||||
$min = 1;
|
||||
if ($min > $d) {
|
||||
$this->errors[] = new Calendar_Validation_Error(
|
||||
'Day', $d, CALENDAR_VALUE_TOOSMALL.$min);
|
||||
return false;
|
||||
}
|
||||
$max = $this->cE->getDaysInMonth(
|
||||
$this->calendar->thisYear(), $this->calendar->thisMonth());
|
||||
if ($d > $max) {
|
||||
$this->errors[] = new Calendar_Validation_Error(
|
||||
'Day', $d, CALENDAR_VALUE_TOOLARGE.$max);
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check whether this is a valid hour
|
||||
* @return boolean
|
||||
* @access public
|
||||
*/
|
||||
function isValidHour()
|
||||
{
|
||||
$h = $this->calendar->thisHour();
|
||||
$min = 0;
|
||||
if ($min > $h) {
|
||||
$this->errors[] = new Calendar_Validation_Error(
|
||||
'Hour', $h, CALENDAR_VALUE_TOOSMALL.$min);
|
||||
return false;
|
||||
}
|
||||
$max = ($this->cE->getHoursInDay($this->calendar->thisDay())-1);
|
||||
if ($h > $max) {
|
||||
$this->errors[] = new Calendar_Validation_Error(
|
||||
'Hour', $h, CALENDAR_VALUE_TOOLARGE.$max);
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check whether this is a valid minute
|
||||
* @return boolean
|
||||
* @access public
|
||||
*/
|
||||
function isValidMinute()
|
||||
{
|
||||
$i = $this->calendar->thisMinute();
|
||||
$min = 0;
|
||||
if ($min > $i) {
|
||||
$this->errors[] = new Calendar_Validation_Error(
|
||||
'Minute', $i, CALENDAR_VALUE_TOOSMALL.$min);
|
||||
return false;
|
||||
}
|
||||
$max = ($this->cE->getMinutesInHour($this->calendar->thisHour())-1);
|
||||
if ($i > $max) {
|
||||
$this->errors[] = new Calendar_Validation_Error(
|
||||
'Minute', $i, CALENDAR_VALUE_TOOLARGE.$max);
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check whether this is a valid second
|
||||
* @return boolean
|
||||
* @access public
|
||||
*/
|
||||
function isValidSecond()
|
||||
{
|
||||
$s = $this->calendar->thisSecond();
|
||||
$min = 0;
|
||||
if ($min > $s) {
|
||||
$this->errors[] = new Calendar_Validation_Error(
|
||||
'Second', $s, CALENDAR_VALUE_TOOSMALL.$min);
|
||||
return false;
|
||||
}
|
||||
$max = ($this->cE->getSecondsInMinute($this->calendar->thisMinute())-1);
|
||||
if ($s > $max) {
|
||||
$this->errors[] = new Calendar_Validation_Error(
|
||||
'Second', $s, CALENDAR_VALUE_TOOLARGE.$max);
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Iterates over any validation errors
|
||||
* @return mixed either Calendar_Validation_Error or false
|
||||
* @access public
|
||||
*/
|
||||
function fetch()
|
||||
{
|
||||
$error = each ($this->errors);
|
||||
if ($error) {
|
||||
return $error['value'];
|
||||
} else {
|
||||
reset($this->errors);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* For Validation Error messages
|
||||
* @see Calendar::fetch()
|
||||
* @package Calendar
|
||||
* @access public
|
||||
*/
|
||||
class Calendar_Validation_Error
|
||||
{
|
||||
/**
|
||||
* Date unit (e.g. month,hour,second) which failed test
|
||||
* @var string
|
||||
* @access private
|
||||
*/
|
||||
var $unit;
|
||||
|
||||
/**
|
||||
* Value of unit which failed test
|
||||
* @var int
|
||||
* @access private
|
||||
*/
|
||||
var $value;
|
||||
|
||||
/**
|
||||
* Validation error message
|
||||
* @var string
|
||||
* @access private
|
||||
*/
|
||||
var $message;
|
||||
|
||||
/**
|
||||
* Constructs Calendar_Validation_Error
|
||||
* @param string Date unit (e.g. month,hour,second)
|
||||
* @param int Value of unit which failed test
|
||||
* @param string Validation error message
|
||||
* @access protected
|
||||
*/
|
||||
function Calendar_Validation_Error($unit,$value,$message)
|
||||
{
|
||||
$this->unit = $unit;
|
||||
$this->value = $value;
|
||||
$this->message = $message;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the Date unit
|
||||
* @return string
|
||||
* @access public
|
||||
*/
|
||||
function getUnit()
|
||||
{
|
||||
return $this->unit;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the value of the unit
|
||||
* @return int
|
||||
* @access public
|
||||
*/
|
||||
function getValue()
|
||||
{
|
||||
return $this->value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the validation error message
|
||||
* @return string
|
||||
* @access public
|
||||
*/
|
||||
function getMessage()
|
||||
{
|
||||
return $this->message;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a string containing the unit, value and error message
|
||||
* @return string
|
||||
* @access public
|
||||
*/
|
||||
function toString ()
|
||||
{
|
||||
return $this->unit.' = '.$this->value.' ['.$this->message.']';
|
||||
}
|
||||
}
|
||||
?>
|
||||
394
include/pear/Calendar/Week.php
Normal file
394
include/pear/Calendar/Week.php
Normal file
@@ -0,0 +1,394 @@
|
||||
<?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/3_0.txt. |
|
||||
// | If you did not receive a copy of the PHP license and are unable to |
|
||||
// | obtain it through the world-wide-web, please send a note to |
|
||||
// | license@php.net so we can mail you a copy immediately. |
|
||||
// +----------------------------------------------------------------------+
|
||||
// | Authors: Harry Fuecks <hfuecks@phppatterns.com> |
|
||||
// | Lorenzo Alberton <l dot alberton at quipo dot it> |
|
||||
// +----------------------------------------------------------------------+
|
||||
//
|
||||
// $Id: Week.php,v 1.7 2005/10/22 10:26:49 quipo Exp $
|
||||
//
|
||||
/**
|
||||
* @package Calendar
|
||||
* @version $Id: Week.php,v 1.7 2005/10/22 10:26:49 quipo Exp $
|
||||
*/
|
||||
|
||||
/**
|
||||
* Allows Calendar include path to be redefined
|
||||
* @ignore
|
||||
*/
|
||||
if (!defined('CALENDAR_ROOT')) {
|
||||
define('CALENDAR_ROOT', 'Calendar'.DIRECTORY_SEPARATOR);
|
||||
}
|
||||
|
||||
/**
|
||||
* Load Calendar base class
|
||||
*/
|
||||
require_once CALENDAR_ROOT.'Calendar.php';
|
||||
|
||||
/**
|
||||
* Represents a Week and builds Days in tabular format<br>
|
||||
* <code>
|
||||
* require_once 'Calendar'.DIRECTORY_SEPARATOR.'Week.php';
|
||||
* $Week = & new Calendar_Week(2003, 10, 1); Oct 2003, 1st tabular week
|
||||
* echo '<tr>';
|
||||
* while ($Day = & $Week->fetch()) {
|
||||
* if ($Day->isEmpty()) {
|
||||
* echo '<td> </td>';
|
||||
* } else {
|
||||
* echo '<td>'.$Day->thisDay().'</td>';
|
||||
* }
|
||||
* }
|
||||
* echo '</tr>';
|
||||
* </code>
|
||||
* @package Calendar
|
||||
* @access public
|
||||
*/
|
||||
class Calendar_Week extends Calendar
|
||||
{
|
||||
/**
|
||||
* Instance of Calendar_Table_Helper
|
||||
* @var Calendar_Table_Helper
|
||||
* @access private
|
||||
*/
|
||||
var $tableHelper;
|
||||
|
||||
/**
|
||||
* Stores the timestamp of the first day of this week
|
||||
* @access private
|
||||
* @var object
|
||||
*/
|
||||
var $thisWeek;
|
||||
|
||||
/**
|
||||
* Stores the timestamp of first day of previous week
|
||||
* @access private
|
||||
* @var object
|
||||
*/
|
||||
var $prevWeek;
|
||||
|
||||
/**
|
||||
* Stores the timestamp of first day of next week
|
||||
* @access private
|
||||
* @var object
|
||||
*/
|
||||
var $nextWeek;
|
||||
|
||||
/**
|
||||
* Used by build() to set empty days
|
||||
* @access private
|
||||
* @var boolean
|
||||
*/
|
||||
var $firstWeek = false;
|
||||
|
||||
/**
|
||||
* Used by build() to set empty days
|
||||
* @access private
|
||||
* @var boolean
|
||||
*/
|
||||
var $lastWeek = false;
|
||||
|
||||
/**
|
||||
* First day of the week (0=sunday, 1=monday...)
|
||||
* @access private
|
||||
* @var boolean
|
||||
*/
|
||||
var $firstDay = 1;
|
||||
|
||||
/**
|
||||
* Constructs Week
|
||||
* @param int year e.g. 2003
|
||||
* @param int month e.g. 5
|
||||
* @param int a day of the desired week
|
||||
* @param int (optional) first day of week (e.g. 0 for Sunday, 2 for Tuesday etc.)
|
||||
* @access public
|
||||
*/
|
||||
function Calendar_Week($y, $m, $d, $firstDay=null)
|
||||
{
|
||||
require_once CALENDAR_ROOT.'Table/Helper.php';
|
||||
Calendar::Calendar($y, $m, $d);
|
||||
$this->firstDay = $this->defineFirstDayOfWeek($firstDay);
|
||||
$this->tableHelper = & new Calendar_Table_Helper($this, $this->firstDay);
|
||||
$this->thisWeek = $this->tableHelper->getWeekStart($y, $m, $d, $this->firstDay);
|
||||
$this->prevWeek = $this->tableHelper->getWeekStart($y, $m, $d - $this->cE->getDaysInWeek(
|
||||
$this->thisYear(),
|
||||
$this->thisMonth(),
|
||||
$this->thisDay()), $this->firstDay);
|
||||
$this->nextWeek = $this->tableHelper->getWeekStart($y, $m, $d + $this->cE->getDaysInWeek(
|
||||
$this->thisYear(),
|
||||
$this->thisMonth(),
|
||||
$this->thisDay()), $this->firstDay);
|
||||
}
|
||||
|
||||
/**
|
||||
* Defines the calendar by a timestamp (Unix or ISO-8601), replacing values
|
||||
* passed to the constructor
|
||||
* @param int|string Unix or ISO-8601 timestamp
|
||||
* @return void
|
||||
* @access public
|
||||
*/
|
||||
function setTimestamp($ts)
|
||||
{
|
||||
parent::setTimestamp($ts);
|
||||
$this->thisWeek = $this->tableHelper->getWeekStart(
|
||||
$this->year, $this->month, $this->day, $this->firstDay
|
||||
);
|
||||
$this->prevWeek = $this->tableHelper->getWeekStart(
|
||||
$this->year, $this->month, $this->day - $this->cE->getDaysInWeek(
|
||||
$this->thisYear(),
|
||||
$this->thisMonth(),
|
||||
$this->thisDay()), $this->firstDay
|
||||
);
|
||||
$this->nextWeek = $this->tableHelper->getWeekStart(
|
||||
$this->year, $this->month, $this->day + $this->cE->getDaysInWeek(
|
||||
$this->thisYear(),
|
||||
$this->thisMonth(),
|
||||
$this->thisDay()), $this->firstDay
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Builds Calendar_Day objects for this Week
|
||||
* @param array (optional) Calendar_Day objects representing selected dates
|
||||
* @return boolean
|
||||
* @access public
|
||||
*/
|
||||
function build($sDates = array())
|
||||
{
|
||||
require_once CALENDAR_ROOT.'Day.php';
|
||||
$year = $this->cE->stampToYear($this->thisWeek);
|
||||
$month = $this->cE->stampToMonth($this->thisWeek);
|
||||
$day = $this->cE->stampToDay($this->thisWeek);
|
||||
$end = $this->cE->getDaysInWeek(
|
||||
$this->thisYear(),
|
||||
$this->thisMonth(),
|
||||
$this->thisDay()
|
||||
);
|
||||
|
||||
for ($i=1; $i <= $end; $i++) {
|
||||
$stamp = $this->cE->dateToStamp($year, $month, $day++);
|
||||
$this->children[$i] = new Calendar_Day(
|
||||
$this->cE->stampToYear($stamp),
|
||||
$this->cE->stampToMonth($stamp),
|
||||
$this->cE->stampToDay($stamp));
|
||||
}
|
||||
|
||||
//set empty days (@see Calendar_Month_Weeks::build())
|
||||
if ($this->firstWeek) {
|
||||
$eBefore = $this->tableHelper->getEmptyDaysBefore();
|
||||
for ($i=1; $i <= $eBefore; $i++) {
|
||||
$this->children[$i]->setEmpty();
|
||||
}
|
||||
}
|
||||
if ($this->lastWeek) {
|
||||
$eAfter = $this->tableHelper->getEmptyDaysAfterOffset();
|
||||
for ($i = $eAfter+1; $i <= $end; $i++) {
|
||||
$this->children[$i]->setEmpty();
|
||||
}
|
||||
}
|
||||
|
||||
if (count($sDates) > 0) {
|
||||
$this->setSelection($sDates);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param boolean
|
||||
* @return void
|
||||
* @access private
|
||||
*/
|
||||
function setFirst($state=true)
|
||||
{
|
||||
$this->firstWeek = $state;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param boolean
|
||||
* @return void
|
||||
* @access private
|
||||
*/
|
||||
function setLast($state=true)
|
||||
{
|
||||
$this->lastWeek = $state;
|
||||
}
|
||||
|
||||
/**
|
||||
* Called from build()
|
||||
* @param array
|
||||
* @return void
|
||||
* @access private
|
||||
*/
|
||||
function setSelection($sDates)
|
||||
{
|
||||
foreach ($sDates as $sDate) {
|
||||
foreach ($this->children as $key => $child) {
|
||||
if ($child->thisDay() == $sDate->thisDay() &&
|
||||
$child->thisMonth() == $sDate->thisMonth() &&
|
||||
$child->thisYear() == $sDate->thisYear()
|
||||
) {
|
||||
$this->children[$key] = $sDate;
|
||||
$this->children[$key]->setSelected();
|
||||
}
|
||||
}
|
||||
}
|
||||
reset($this->children);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the value of the previous week, according to the requested format
|
||||
*
|
||||
* @param string $format ['timestamp' | 'n_in_month' | 'n_in_year' | 'array']
|
||||
* @return mixed
|
||||
* @access public
|
||||
*/
|
||||
function prevWeek($format = 'n_in_month')
|
||||
{
|
||||
switch (strtolower($format)) {
|
||||
case 'int':
|
||||
case 'n_in_month':
|
||||
return ($this->firstWeek) ? null : $this->thisWeek('n_in_month') -1;
|
||||
break;
|
||||
case 'n_in_year':
|
||||
return $this->cE->getWeekNInYear(
|
||||
$this->cE->stampToYear($this->prevWeek),
|
||||
$this->cE->stampToMonth($this->prevWeek),
|
||||
$this->cE->stampToDay($this->prevWeek));
|
||||
break;
|
||||
case 'array':
|
||||
return $this->toArray($this->prevWeek);
|
||||
break;
|
||||
case 'object':
|
||||
require_once CALENDAR_ROOT.'Factory.php';
|
||||
return Calendar_Factory::createByTimestamp('Week', $this->prevWeek);
|
||||
break;
|
||||
case 'timestamp':
|
||||
default:
|
||||
return $this->prevWeek;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the value of the current week, according to the requested format
|
||||
*
|
||||
* @param string $format ['timestamp' | 'n_in_month' | 'n_in_year' | 'array']
|
||||
* @return mixed
|
||||
* @access public
|
||||
*/
|
||||
function thisWeek($format = 'n_in_month')
|
||||
{
|
||||
switch (strtolower($format)) {
|
||||
case 'int':
|
||||
case 'n_in_month':
|
||||
if ($this->firstWeek) {
|
||||
return 1;
|
||||
}
|
||||
if ($this->lastWeek) {
|
||||
return $this->cE->getWeeksInMonth(
|
||||
$this->thisYear(),
|
||||
$this->thisMonth(),
|
||||
$this->firstDay);
|
||||
}
|
||||
return $this->cE->getWeekNInMonth(
|
||||
$this->thisYear(),
|
||||
$this->thisMonth(),
|
||||
$this->thisDay(),
|
||||
$this->firstDay);
|
||||
break;
|
||||
case 'n_in_year':
|
||||
return $this->cE->getWeekNInYear(
|
||||
$this->cE->stampToYear($this->thisWeek),
|
||||
$this->cE->stampToMonth($this->thisWeek),
|
||||
$this->cE->stampToDay($this->thisWeek));
|
||||
break;
|
||||
case 'array':
|
||||
return $this->toArray($this->thisWeek);
|
||||
break;
|
||||
case 'object':
|
||||
require_once CALENDAR_ROOT.'Factory.php';
|
||||
return Calendar_Factory::createByTimestamp('Week', $this->thisWeek);
|
||||
break;
|
||||
case 'timestamp':
|
||||
default:
|
||||
return $this->thisWeek;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the value of the following week, according to the requested format
|
||||
*
|
||||
* @param string $format ['timestamp' | 'n_in_month' | 'n_in_year' | 'array']
|
||||
* @return mixed
|
||||
* @access public
|
||||
*/
|
||||
function nextWeek($format = 'n_in_month')
|
||||
{
|
||||
switch (strtolower($format)) {
|
||||
case 'int':
|
||||
case 'n_in_month':
|
||||
return ($this->lastWeek) ? null : $this->thisWeek('n_in_month') +1;
|
||||
break;
|
||||
case 'n_in_year':
|
||||
return $this->cE->getWeekNInYear(
|
||||
$this->cE->stampToYear($this->nextWeek),
|
||||
$this->cE->stampToMonth($this->nextWeek),
|
||||
$this->cE->stampToDay($this->nextWeek));
|
||||
break;
|
||||
case 'array':
|
||||
return $this->toArray($this->nextWeek);
|
||||
break;
|
||||
case 'object':
|
||||
require_once CALENDAR_ROOT.'Factory.php';
|
||||
return Calendar_Factory::createByTimestamp('Week', $this->nextWeek);
|
||||
break;
|
||||
case 'timestamp':
|
||||
default:
|
||||
return $this->nextWeek;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the instance of Calendar_Table_Helper.
|
||||
* Called from Calendar_Validator::isValidWeek
|
||||
* @return Calendar_Table_Helper
|
||||
* @access protected
|
||||
*/
|
||||
function & getHelper()
|
||||
{
|
||||
return $this->tableHelper;
|
||||
}
|
||||
|
||||
/**
|
||||
* Makes sure theres a value for $this->day
|
||||
* @return void
|
||||
* @access private
|
||||
*/
|
||||
function findFirstDay()
|
||||
{
|
||||
if (!count($this->children) > 0) {
|
||||
$this->build();
|
||||
foreach ($this->children as $Day) {
|
||||
if (!$Day->isEmpty()) {
|
||||
$this->day = $Day->thisDay();
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
?>
|
||||
113
include/pear/Calendar/Year.php
Normal file
113
include/pear/Calendar/Year.php
Normal file
@@ -0,0 +1,113 @@
|
||||
<?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/3_0.txt. |
|
||||
// | If you did not receive a copy of the PHP license and are unable to |
|
||||
// | obtain it through the world-wide-web, please send a note to |
|
||||
// | license@php.net so we can mail you a copy immediately. |
|
||||
// +----------------------------------------------------------------------+
|
||||
// | Authors: Harry Fuecks <hfuecks@phppatterns.com> |
|
||||
// +----------------------------------------------------------------------+
|
||||
//
|
||||
// $Id: Year.php,v 1.4 2005/10/22 10:25:39 quipo Exp $
|
||||
//
|
||||
/**
|
||||
* @package Calendar
|
||||
* @version $Id: Year.php,v 1.4 2005/10/22 10:25:39 quipo Exp $
|
||||
*/
|
||||
|
||||
/**
|
||||
* Allows Calendar include path to be redefined
|
||||
* @ignore
|
||||
*/
|
||||
if (!defined('CALENDAR_ROOT')) {
|
||||
define('CALENDAR_ROOT', 'Calendar'.DIRECTORY_SEPARATOR);
|
||||
}
|
||||
|
||||
/**
|
||||
* Load Calendar base class
|
||||
*/
|
||||
require_once CALENDAR_ROOT.'Calendar.php';
|
||||
|
||||
/**
|
||||
* Represents a Year and builds Months<br>
|
||||
* <code>
|
||||
* require_once 'Calendar'.DIRECTORY_SEPARATOR.'Year.php';
|
||||
* $Year = & new Calendar_Year(2003, 10, 21); // 21st Oct 2003
|
||||
* $Year->build(); // Build Calendar_Month objects
|
||||
* while ($Month = & $Year->fetch()) {
|
||||
* echo $Month->thisMonth().'<br />';
|
||||
* }
|
||||
* </code>
|
||||
* @package Calendar
|
||||
* @access public
|
||||
*/
|
||||
class Calendar_Year extends Calendar
|
||||
{
|
||||
/**
|
||||
* Constructs Calendar_Year
|
||||
* @param int year e.g. 2003
|
||||
* @access public
|
||||
*/
|
||||
function Calendar_Year($y)
|
||||
{
|
||||
Calendar::Calendar($y);
|
||||
}
|
||||
|
||||
/**
|
||||
* Builds the Months of the Year.<br>
|
||||
* <b>Note:</b> by defining the constant CALENDAR_MONTH_STATE you can
|
||||
* control what class of Calendar_Month is built e.g.;
|
||||
* <code>
|
||||
* require_once 'Calendar/Calendar_Year.php';
|
||||
* define ('CALENDAR_MONTH_STATE',CALENDAR_USE_MONTH_WEEKDAYS); // Use Calendar_Month_Weekdays
|
||||
* // define ('CALENDAR_MONTH_STATE',CALENDAR_USE_MONTH_WEEKS); // Use Calendar_Month_Weeks
|
||||
* // define ('CALENDAR_MONTH_STATE',CALENDAR_USE_MONTH); // Use Calendar_Month
|
||||
* </code>
|
||||
* It defaults to building Calendar_Month objects.
|
||||
* @param array (optional) array of Calendar_Month objects representing selected dates
|
||||
* @param int (optional) first day of week (e.g. 0 for Sunday, 2 for Tuesday etc.)
|
||||
* @return boolean
|
||||
* @access public
|
||||
*/
|
||||
function build($sDates = array(), $firstDay = null)
|
||||
{
|
||||
require_once CALENDAR_ROOT.'Factory.php';
|
||||
$this->firstDay = $this->defineFirstDayOfWeek($firstDay);
|
||||
$monthsInYear = $this->cE->getMonthsInYear($this->thisYear());
|
||||
for ($i=1; $i <= $monthsInYear; $i++) {
|
||||
$this->children[$i] = Calendar_Factory::create('Month', $this->year, $i);
|
||||
}
|
||||
if (count($sDates) > 0) {
|
||||
$this->setSelection($sDates);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Called from build()
|
||||
* @param array
|
||||
* @return void
|
||||
* @access private
|
||||
*/
|
||||
function setSelection($sDates) {
|
||||
foreach ($sDates as $sDate) {
|
||||
if ($this->year == $sDate->thisYear()) {
|
||||
$key = $sDate->thisMonth();
|
||||
if (isset($this->children[$key])) {
|
||||
$sDate->setSelected();
|
||||
$this->children[$key] = $sDate;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
?>
|
||||
251
include/pear/Console/Getopt.php
Normal file
251
include/pear/Console/Getopt.php
Normal file
@@ -0,0 +1,251 @@
|
||||
<?php
|
||||
/* vim: set expandtab tabstop=4 shiftwidth=4: */
|
||||
// +----------------------------------------------------------------------+
|
||||
// | PHP Version 4 |
|
||||
// +----------------------------------------------------------------------+
|
||||
// | Copyright (c) 1997-2003 The PHP Group |
|
||||
// +----------------------------------------------------------------------+
|
||||
// | This source file is subject to version 3.0 of the PHP license, |
|
||||
// | that is bundled with this package in the file LICENSE, and is |
|
||||
// | available through the world-wide-web at the following url: |
|
||||
// | 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 world-wide-web, please send a note to |
|
||||
// | license@php.net so we can mail you a copy immediately. |
|
||||
// +----------------------------------------------------------------------+
|
||||
// | Author: Andrei Zmievski <andrei@php.net> |
|
||||
// +----------------------------------------------------------------------+
|
||||
//
|
||||
// $Id: Getopt.php,v 1.21.4.7 2003/12/05 21:57:01 andrei Exp $
|
||||
|
||||
require_once 'PEAR.php';
|
||||
|
||||
/**
|
||||
* Command-line options parsing class.
|
||||
*
|
||||
* @author Andrei Zmievski <andrei@php.net>
|
||||
*
|
||||
*/
|
||||
class Console_Getopt {
|
||||
/**
|
||||
* Parses the command-line options.
|
||||
*
|
||||
* The first parameter to this function should be the list of command-line
|
||||
* arguments without the leading reference to the running program.
|
||||
*
|
||||
* The second parameter is a string of allowed short options. Each of the
|
||||
* option letters can be followed by a colon ':' to specify that the option
|
||||
* requires an argument, or a double colon '::' to specify that the option
|
||||
* takes an optional argument.
|
||||
*
|
||||
* The third argument is an optional array of allowed long options. The
|
||||
* leading '--' should not be included in the option name. Options that
|
||||
* require an argument should be followed by '=', and options that take an
|
||||
* option argument should be followed by '=='.
|
||||
*
|
||||
* The return value is an array of two elements: the list of parsed
|
||||
* options and the list of non-option command-line arguments. Each entry in
|
||||
* the list of parsed options is a pair of elements - the first one
|
||||
* specifies the option, and the second one specifies the option argument,
|
||||
* if there was one.
|
||||
*
|
||||
* Long and short options can be mixed.
|
||||
*
|
||||
* Most of the semantics of this function are based on GNU getopt_long().
|
||||
*
|
||||
* @param array $args an array of command-line arguments
|
||||
* @param string $short_options specifies the list of allowed short options
|
||||
* @param array $long_options specifies the list of allowed long options
|
||||
*
|
||||
* @return array two-element array containing the list of parsed options and
|
||||
* the non-option arguments
|
||||
*
|
||||
* @access public
|
||||
*
|
||||
*/
|
||||
function getopt2($args, $short_options, $long_options = null)
|
||||
{
|
||||
return Console_Getopt::doGetopt(2, $args, $short_options, $long_options);
|
||||
}
|
||||
|
||||
/**
|
||||
* This function expects $args to start with the script name (POSIX-style).
|
||||
* Preserved for backwards compatibility.
|
||||
* @see getopt2()
|
||||
*/
|
||||
function getopt($args, $short_options, $long_options = null)
|
||||
{
|
||||
return Console_Getopt::doGetopt(1, $args, $short_options, $long_options);
|
||||
}
|
||||
|
||||
/**
|
||||
* The actual implementation of the argument parsing code.
|
||||
*/
|
||||
function doGetopt($version, $args, $short_options, $long_options = null)
|
||||
{
|
||||
// in case you pass directly readPHPArgv() as the first arg
|
||||
if (PEAR::isError($args)) {
|
||||
return $args;
|
||||
}
|
||||
if (empty($args)) {
|
||||
return array(array(), array());
|
||||
}
|
||||
$opts = array();
|
||||
$non_opts = array();
|
||||
|
||||
settype($args, 'array');
|
||||
|
||||
if ($long_options) {
|
||||
sort($long_options);
|
||||
}
|
||||
|
||||
/*
|
||||
* Preserve backwards compatibility with callers that relied on
|
||||
* erroneous POSIX fix.
|
||||
*/
|
||||
if ($version < 2) {
|
||||
if (isset($args[0]{0}) && $args[0]{0} != '-') {
|
||||
array_shift($args);
|
||||
}
|
||||
}
|
||||
|
||||
reset($args);
|
||||
while (list($i, $arg) = each($args)) {
|
||||
|
||||
/* The special element '--' means explicit end of
|
||||
options. Treat the rest of the arguments as non-options
|
||||
and end the loop. */
|
||||
if ($arg == '--') {
|
||||
$non_opts = array_merge($non_opts, array_slice($args, $i + 1));
|
||||
break;
|
||||
}
|
||||
|
||||
if ($arg{0} != '-' || (strlen($arg) > 1 && $arg{1} == '-' && !$long_options)) {
|
||||
$non_opts = array_merge($non_opts, array_slice($args, $i));
|
||||
break;
|
||||
} elseif (strlen($arg) > 1 && $arg{1} == '-') {
|
||||
$error = Console_Getopt::_parseLongOption(substr($arg, 2), $long_options, $opts, $args);
|
||||
if (PEAR::isError($error))
|
||||
return $error;
|
||||
} else {
|
||||
$error = Console_Getopt::_parseShortOption(substr($arg, 1), $short_options, $opts, $args);
|
||||
if (PEAR::isError($error))
|
||||
return $error;
|
||||
}
|
||||
}
|
||||
|
||||
return array($opts, $non_opts);
|
||||
}
|
||||
|
||||
/**
|
||||
* @access private
|
||||
*
|
||||
*/
|
||||
function _parseShortOption($arg, $short_options, &$opts, &$args)
|
||||
{
|
||||
for ($i = 0; $i < strlen($arg); $i++) {
|
||||
$opt = $arg{$i};
|
||||
$opt_arg = null;
|
||||
|
||||
/* Try to find the short option in the specifier string. */
|
||||
if (($spec = strstr($short_options, $opt)) === false || $arg{$i} == ':')
|
||||
{
|
||||
return PEAR::raiseError("Console_Getopt: unrecognized option -- $opt");
|
||||
}
|
||||
|
||||
if (strlen($spec) > 1 && $spec{1} == ':') {
|
||||
if (strlen($spec) > 2 && $spec{2} == ':') {
|
||||
if ($i + 1 < strlen($arg)) {
|
||||
/* Option takes an optional argument. Use the remainder of
|
||||
the arg string if there is anything left. */
|
||||
$opts[] = array($opt, substr($arg, $i + 1));
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
/* Option requires an argument. Use the remainder of the arg
|
||||
string if there is anything left. */
|
||||
if ($i + 1 < strlen($arg)) {
|
||||
$opts[] = array($opt, substr($arg, $i + 1));
|
||||
break;
|
||||
} else if (list(, $opt_arg) = each($args))
|
||||
/* Else use the next argument. */;
|
||||
else
|
||||
return PEAR::raiseError("Console_Getopt: option requires an argument -- $opt");
|
||||
}
|
||||
}
|
||||
|
||||
$opts[] = array($opt, $opt_arg);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @access private
|
||||
*
|
||||
*/
|
||||
function _parseLongOption($arg, $long_options, &$opts, &$args)
|
||||
{
|
||||
@list($opt, $opt_arg) = explode('=', $arg);
|
||||
$opt_len = strlen($opt);
|
||||
|
||||
for ($i = 0; $i < count($long_options); $i++) {
|
||||
$long_opt = $long_options[$i];
|
||||
$opt_start = substr($long_opt, 0, $opt_len);
|
||||
|
||||
/* Option doesn't match. Go on to the next one. */
|
||||
if ($opt_start != $opt)
|
||||
continue;
|
||||
|
||||
$opt_rest = substr($long_opt, $opt_len);
|
||||
|
||||
/* Check that the options uniquely matches one of the allowed
|
||||
options. */
|
||||
if ($opt_rest != '' && $opt{0} != '=' &&
|
||||
$i + 1 < count($long_options) &&
|
||||
$opt == substr($long_options[$i+1], 0, $opt_len)) {
|
||||
return PEAR::raiseError("Console_Getopt: option --$opt is ambiguous");
|
||||
}
|
||||
|
||||
if (substr($long_opt, -1) == '=') {
|
||||
if (substr($long_opt, -2) != '==') {
|
||||
/* Long option requires an argument.
|
||||
Take the next argument if one wasn't specified. */;
|
||||
if (!strlen($opt_arg) && !(list(, $opt_arg) = each($args))) {
|
||||
return PEAR::raiseError("Console_Getopt: option --$opt requires an argument");
|
||||
}
|
||||
}
|
||||
} else if ($opt_arg) {
|
||||
return PEAR::raiseError("Console_Getopt: option --$opt doesn't allow an argument");
|
||||
}
|
||||
|
||||
$opts[] = array('--' . $opt, $opt_arg);
|
||||
return;
|
||||
}
|
||||
|
||||
return PEAR::raiseError("Console_Getopt: unrecognized option --$opt");
|
||||
}
|
||||
|
||||
/**
|
||||
* Safely read the $argv PHP array across different PHP configurations.
|
||||
* Will take care on register_globals and register_argc_argv ini directives
|
||||
*
|
||||
* @access public
|
||||
* @return mixed the $argv PHP array or PEAR error if not registered
|
||||
*/
|
||||
function readPHPArgv()
|
||||
{
|
||||
global $argv;
|
||||
if (!is_array($argv)) {
|
||||
if (!@is_array($_SERVER['argv'])) {
|
||||
if (!@is_array($GLOBALS['HTTP_SERVER_VARS']['argv'])) {
|
||||
return PEAR::raiseError("Console_Getopt: Could not read cmd args (register_argc_argv=Off?)");
|
||||
}
|
||||
return $GLOBALS['HTTP_SERVER_VARS']['argv'];
|
||||
}
|
||||
return $_SERVER['argv'];
|
||||
}
|
||||
return $argv;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
?>
|
||||
1388
include/pear/DB.php
Normal file
1388
include/pear/DB.php
Normal file
File diff suppressed because it is too large
Load Diff
2157
include/pear/DB/common.php
Normal file
2157
include/pear/DB/common.php
Normal file
File diff suppressed because it is too large
Load Diff
510
include/pear/DB/dbase.php
Normal file
510
include/pear/DB/dbase.php
Normal file
@@ -0,0 +1,510 @@
|
||||
<?php
|
||||
|
||||
/* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4: */
|
||||
|
||||
/**
|
||||
* The PEAR DB driver for PHP's dbase extension
|
||||
* for interacting with dBase databases
|
||||
*
|
||||
* 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 Database
|
||||
* @package DB
|
||||
* @author Tomas V.V. Cox <cox@idecnet.com>
|
||||
* @author Daniel Convissor <danielc@php.net>
|
||||
* @copyright 1997-2005 The PHP Group
|
||||
* @license http://www.php.net/license/3_0.txt PHP License 3.0
|
||||
* @version CVS: $Id: dbase.php,v 1.39 2005/02/19 23:25:25 danielc Exp $
|
||||
* @link http://pear.php.net/package/DB
|
||||
*/
|
||||
|
||||
/**
|
||||
* Obtain the DB_common class so it can be extended from
|
||||
*/
|
||||
require_once 'DB/common.php';
|
||||
|
||||
/**
|
||||
* The methods PEAR DB uses to interact with PHP's dbase extension
|
||||
* for interacting with dBase databases
|
||||
*
|
||||
* These methods overload the ones declared in DB_common.
|
||||
*
|
||||
* @category Database
|
||||
* @package DB
|
||||
* @author Tomas V.V. Cox <cox@idecnet.com>
|
||||
* @author Daniel Convissor <danielc@php.net>
|
||||
* @copyright 1997-2005 The PHP Group
|
||||
* @license http://www.php.net/license/3_0.txt PHP License 3.0
|
||||
* @version Release: @package_version@
|
||||
* @link http://pear.php.net/package/DB
|
||||
*/
|
||||
class DB_dbase extends DB_common
|
||||
{
|
||||
// {{{ properties
|
||||
|
||||
/**
|
||||
* The DB driver type (mysql, oci8, odbc, etc.)
|
||||
* @var string
|
||||
*/
|
||||
var $phptype = 'dbase';
|
||||
|
||||
/**
|
||||
* The database syntax variant to be used (db2, access, etc.), if any
|
||||
* @var string
|
||||
*/
|
||||
var $dbsyntax = 'dbase';
|
||||
|
||||
/**
|
||||
* The capabilities of this DB implementation
|
||||
*
|
||||
* The 'new_link' element contains the PHP version that first provided
|
||||
* new_link support for this DBMS. Contains false if it's unsupported.
|
||||
*
|
||||
* Meaning of the 'limit' element:
|
||||
* + 'emulate' = emulate with fetch row by number
|
||||
* + 'alter' = alter the query
|
||||
* + false = skip rows
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
var $features = array(
|
||||
'limit' => false,
|
||||
'new_link' => false,
|
||||
'numrows' => true,
|
||||
'pconnect' => false,
|
||||
'prepare' => false,
|
||||
'ssl' => false,
|
||||
'transactions' => false,
|
||||
);
|
||||
|
||||
/**
|
||||
* A mapping of native error codes to DB error codes
|
||||
* @var array
|
||||
*/
|
||||
var $errorcode_map = array(
|
||||
);
|
||||
|
||||
/**
|
||||
* The raw database connection created by PHP
|
||||
* @var resource
|
||||
*/
|
||||
var $connection;
|
||||
|
||||
/**
|
||||
* The DSN information for connecting to a database
|
||||
* @var array
|
||||
*/
|
||||
var $dsn = array();
|
||||
|
||||
|
||||
/**
|
||||
* A means of emulating result resources
|
||||
* @var array
|
||||
*/
|
||||
var $res_row = array();
|
||||
|
||||
/**
|
||||
* The quantity of results so far
|
||||
*
|
||||
* For emulating result resources.
|
||||
*
|
||||
* @var integer
|
||||
*/
|
||||
var $result = 0;
|
||||
|
||||
/**
|
||||
* Maps dbase data type id's to human readable strings
|
||||
*
|
||||
* The human readable values are based on the output of PHP's
|
||||
* dbase_get_header_info() function.
|
||||
*
|
||||
* @var array
|
||||
* @since Property available since Release 1.7.0
|
||||
*/
|
||||
var $types = array(
|
||||
'C' => 'character',
|
||||
'D' => 'date',
|
||||
'L' => 'boolean',
|
||||
'M' => 'memo',
|
||||
'N' => 'number',
|
||||
);
|
||||
|
||||
|
||||
// }}}
|
||||
// {{{ constructor
|
||||
|
||||
/**
|
||||
* This constructor calls <kbd>$this->DB_common()</kbd>
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
function DB_dbase()
|
||||
{
|
||||
$this->DB_common();
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ connect()
|
||||
|
||||
/**
|
||||
* Connect to the database and create it if it doesn't exist
|
||||
*
|
||||
* Don't call this method directly. Use DB::connect() instead.
|
||||
*
|
||||
* PEAR DB's dbase driver supports the following extra DSN options:
|
||||
* + mode An integer specifying the read/write mode to use
|
||||
* (0 = read only, 1 = write only, 2 = read/write).
|
||||
* Available since PEAR DB 1.7.0.
|
||||
* + fields An array of arrays that PHP's dbase_create() function needs
|
||||
* to create a new database. This information is used if the
|
||||
* dBase file specified in the "database" segment of the DSN
|
||||
* does not exist. For more info, see the PHP manual's
|
||||
* {@link http://php.net/dbase_create dbase_create()} page.
|
||||
* Available since PEAR DB 1.7.0.
|
||||
*
|
||||
* Example of how to connect and establish a new dBase file if necessary:
|
||||
* <code>
|
||||
* require_once 'DB.php';
|
||||
*
|
||||
* $dsn = array(
|
||||
* 'phptype' => 'dbase',
|
||||
* 'database' => '/path/and/name/of/dbase/file',
|
||||
* 'mode' => 2,
|
||||
* 'fields' => array(
|
||||
* array('a', 'N', 5, 0),
|
||||
* array('b', 'C', 40),
|
||||
* array('c', 'C', 255),
|
||||
* array('d', 'C', 20),
|
||||
* ),
|
||||
* );
|
||||
* $options = array(
|
||||
* 'debug' => 2,
|
||||
* 'portability' => DB_PORTABILITY_ALL,
|
||||
* );
|
||||
*
|
||||
* $db =& DB::connect($dsn, $options);
|
||||
* if (PEAR::isError($db)) {
|
||||
* die($db->getMessage());
|
||||
* }
|
||||
* </code>
|
||||
*
|
||||
* @param array $dsn the data source name
|
||||
* @param bool $persistent should the connection be persistent?
|
||||
*
|
||||
* @return int DB_OK on success. A DB_Error object on failure.
|
||||
*/
|
||||
function connect($dsn, $persistent = false)
|
||||
{
|
||||
if (!PEAR::loadExtension('dbase')) {
|
||||
return $this->raiseError(DB_ERROR_EXTENSION_NOT_FOUND);
|
||||
}
|
||||
|
||||
$this->dsn = $dsn;
|
||||
if ($dsn['dbsyntax']) {
|
||||
$this->dbsyntax = $dsn['dbsyntax'];
|
||||
}
|
||||
|
||||
/*
|
||||
* Turn track_errors on for entire script since $php_errormsg
|
||||
* is the only way to find errors from the dbase extension.
|
||||
*/
|
||||
ini_set('track_errors', 1);
|
||||
$php_errormsg = '';
|
||||
|
||||
if (!file_exists($dsn['database'])) {
|
||||
$this->dsn['mode'] = 2;
|
||||
if (empty($dsn['fields']) || !is_array($dsn['fields'])) {
|
||||
return $this->raiseError(DB_ERROR_CONNECT_FAILED,
|
||||
null, null, null,
|
||||
'the dbase file does not exist and '
|
||||
. 'it could not be created because '
|
||||
. 'the "fields" element of the DSN '
|
||||
. 'is not properly set');
|
||||
}
|
||||
$this->connection = @dbase_create($dsn['database'],
|
||||
$dsn['fields']);
|
||||
if (!$this->connection) {
|
||||
return $this->raiseError(DB_ERROR_CONNECT_FAILED,
|
||||
null, null, null,
|
||||
'the dbase file does not exist and '
|
||||
. 'the attempt to create it failed: '
|
||||
. $php_errormsg);
|
||||
}
|
||||
} else {
|
||||
if (!isset($this->dsn['mode'])) {
|
||||
$this->dsn['mode'] = 0;
|
||||
}
|
||||
$this->connection = @dbase_open($dsn['database'],
|
||||
$this->dsn['mode']);
|
||||
if (!$this->connection) {
|
||||
return $this->raiseError(DB_ERROR_CONNECT_FAILED,
|
||||
null, null, null,
|
||||
$php_errormsg);
|
||||
}
|
||||
}
|
||||
return DB_OK;
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ disconnect()
|
||||
|
||||
/**
|
||||
* Disconnects from the database server
|
||||
*
|
||||
* @return bool TRUE on success, FALSE on failure
|
||||
*/
|
||||
function disconnect()
|
||||
{
|
||||
$ret = @dbase_close($this->connection);
|
||||
$this->connection = null;
|
||||
return $ret;
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ &query()
|
||||
|
||||
function &query($query = null)
|
||||
{
|
||||
// emulate result resources
|
||||
$this->res_row[(int)$this->result] = 0;
|
||||
$tmp =& new DB_result($this, $this->result++);
|
||||
return $tmp;
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ fetchInto()
|
||||
|
||||
/**
|
||||
* Places a row from the result set into the given array
|
||||
*
|
||||
* Formating of the array and the data therein are configurable.
|
||||
* See DB_result::fetchInto() for more information.
|
||||
*
|
||||
* This method is not meant to be called directly. Use
|
||||
* DB_result::fetchInto() instead. It can't be declared "protected"
|
||||
* because DB_result is a separate object.
|
||||
*
|
||||
* @param resource $result the query result resource
|
||||
* @param array $arr the referenced array to put the data in
|
||||
* @param int $fetchmode how the resulting array should be indexed
|
||||
* @param int $rownum the row number to fetch (0 = first row)
|
||||
*
|
||||
* @return mixed DB_OK on success, NULL when the end of a result set is
|
||||
* reached or on failure
|
||||
*
|
||||
* @see DB_result::fetchInto()
|
||||
*/
|
||||
function fetchInto($result, &$arr, $fetchmode, $rownum = null)
|
||||
{
|
||||
if ($rownum === null) {
|
||||
$rownum = $this->res_row[(int)$result]++;
|
||||
}
|
||||
if ($fetchmode & DB_FETCHMODE_ASSOC) {
|
||||
$arr = @dbase_get_record_with_names($this->connection, $rownum);
|
||||
if ($this->options['portability'] & DB_PORTABILITY_LOWERCASE && $arr) {
|
||||
$arr = array_change_key_case($arr, CASE_LOWER);
|
||||
}
|
||||
} else {
|
||||
$arr = @dbase_get_record($this->connection, $rownum);
|
||||
}
|
||||
if (!$arr) {
|
||||
return null;
|
||||
}
|
||||
if ($this->options['portability'] & DB_PORTABILITY_RTRIM) {
|
||||
$this->_rtrimArrayValues($arr);
|
||||
}
|
||||
if ($this->options['portability'] & DB_PORTABILITY_NULL_TO_EMPTY) {
|
||||
$this->_convertNullArrayValuesToEmpty($arr);
|
||||
}
|
||||
return DB_OK;
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ numCols()
|
||||
|
||||
/**
|
||||
* Gets the number of columns in a result set
|
||||
*
|
||||
* This method is not meant to be called directly. Use
|
||||
* DB_result::numCols() instead. It can't be declared "protected"
|
||||
* because DB_result is a separate object.
|
||||
*
|
||||
* @param resource $result PHP's query result resource
|
||||
*
|
||||
* @return int the number of columns. A DB_Error object on failure.
|
||||
*
|
||||
* @see DB_result::numCols()
|
||||
*/
|
||||
function numCols($foo)
|
||||
{
|
||||
return @dbase_numfields($this->connection);
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ numRows()
|
||||
|
||||
/**
|
||||
* Gets the number of rows in a result set
|
||||
*
|
||||
* This method is not meant to be called directly. Use
|
||||
* DB_result::numRows() instead. It can't be declared "protected"
|
||||
* because DB_result is a separate object.
|
||||
*
|
||||
* @param resource $result PHP's query result resource
|
||||
*
|
||||
* @return int the number of rows. A DB_Error object on failure.
|
||||
*
|
||||
* @see DB_result::numRows()
|
||||
*/
|
||||
function numRows($foo)
|
||||
{
|
||||
return @dbase_numrecords($this->connection);
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ quoteSmart()
|
||||
|
||||
/**
|
||||
* Formats input so it can be safely used in a query
|
||||
*
|
||||
* @param mixed $in the data to be formatted
|
||||
*
|
||||
* @return mixed the formatted data. The format depends on the input's
|
||||
* PHP type:
|
||||
* + null = the string <samp>NULL</samp>
|
||||
* + boolean = <samp>T</samp> if true or
|
||||
* <samp>F</samp> if false. Use the <kbd>Logical</kbd>
|
||||
* data type.
|
||||
* + integer or double = the unquoted number
|
||||
* + other (including strings and numeric strings) =
|
||||
* the data with single quotes escaped by preceeding
|
||||
* single quotes then the whole string is encapsulated
|
||||
* between single quotes
|
||||
*
|
||||
* @see DB_common::quoteSmart()
|
||||
* @since Method available since Release 1.6.0
|
||||
*/
|
||||
function quoteSmart($in)
|
||||
{
|
||||
if (is_int($in) || is_double($in)) {
|
||||
return $in;
|
||||
} elseif (is_bool($in)) {
|
||||
return $in ? 'T' : 'F';
|
||||
} elseif (is_null($in)) {
|
||||
return 'NULL';
|
||||
} else {
|
||||
return "'" . $this->escapeSimple($in) . "'";
|
||||
}
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ tableInfo()
|
||||
|
||||
/**
|
||||
* Returns information about the current database
|
||||
*
|
||||
* @param mixed $result THIS IS UNUSED IN DBASE. The current database
|
||||
* is examined regardless of what is provided here.
|
||||
* @param int $mode a valid tableInfo mode
|
||||
*
|
||||
* @return array an associative array with the information requested.
|
||||
* A DB_Error object on failure.
|
||||
*
|
||||
* @see DB_common::tableInfo()
|
||||
* @since Method available since Release 1.7.0
|
||||
*/
|
||||
function tableInfo($result = null, $mode = null)
|
||||
{
|
||||
if (function_exists('dbase_get_header_info')) {
|
||||
$id = @dbase_get_header_info($this->connection);
|
||||
if (!$id && $php_errormsg) {
|
||||
return $this->raiseError(DB_ERROR,
|
||||
null, null, null,
|
||||
$php_errormsg);
|
||||
}
|
||||
} else {
|
||||
/*
|
||||
* This segment for PHP 4 is loosely based on code by
|
||||
* Hadi Rusiah <deegos@yahoo.com> in the comments on
|
||||
* the dBase reference page in the PHP manual.
|
||||
*/
|
||||
$db = @fopen($this->dsn['database'], 'r');
|
||||
if (!$db) {
|
||||
return $this->raiseError(DB_ERROR_CONNECT_FAILED,
|
||||
null, null, null,
|
||||
$php_errormsg);
|
||||
}
|
||||
|
||||
$id = array();
|
||||
$i = 0;
|
||||
|
||||
$line = fread($db, 32);
|
||||
while (!feof($db)) {
|
||||
$line = fread($db, 32);
|
||||
if (substr($line, 0, 1) == chr(13)) {
|
||||
break;
|
||||
} else {
|
||||
$pos = strpos(substr($line, 0, 10), chr(0));
|
||||
$pos = ($pos == 0 ? 10 : $pos);
|
||||
$id[$i] = array(
|
||||
'name' => substr($line, 0, $pos),
|
||||
'type' => $this->types[substr($line, 11, 1)],
|
||||
'length' => ord(substr($line, 16, 1)),
|
||||
'precision' => ord(substr($line, 17, 1)),
|
||||
);
|
||||
}
|
||||
$i++;
|
||||
}
|
||||
|
||||
fclose($db);
|
||||
}
|
||||
|
||||
if ($this->options['portability'] & DB_PORTABILITY_LOWERCASE) {
|
||||
$case_func = 'strtolower';
|
||||
} else {
|
||||
$case_func = 'strval';
|
||||
}
|
||||
|
||||
$res = array();
|
||||
$count = count($id);
|
||||
|
||||
if ($mode) {
|
||||
$res['num_fields'] = $count;
|
||||
}
|
||||
|
||||
for ($i = 0; $i < $count; $i++) {
|
||||
$res[$i] = array(
|
||||
'table' => $this->dsn['database'],
|
||||
'name' => $case_func($id[$i]['name']),
|
||||
'type' => $id[$i]['type'],
|
||||
'len' => $id[$i]['length'],
|
||||
'flags' => ''
|
||||
);
|
||||
if ($mode & DB_TABLEINFO_ORDER) {
|
||||
$res['order'][$res[$i]['name']] = $i;
|
||||
}
|
||||
if ($mode & DB_TABLEINFO_ORDERTABLE) {
|
||||
$res['ordertable'][$res[$i]['table']][$res[$i]['name']] = $i;
|
||||
}
|
||||
}
|
||||
|
||||
return $res;
|
||||
}
|
||||
|
||||
// }}}
|
||||
}
|
||||
|
||||
/*
|
||||
* Local variables:
|
||||
* tab-width: 4
|
||||
* c-basic-offset: 4
|
||||
* End:
|
||||
*/
|
||||
|
||||
?>
|
||||
770
include/pear/DB/fbsql.php
Normal file
770
include/pear/DB/fbsql.php
Normal file
@@ -0,0 +1,770 @@
|
||||
<?php
|
||||
|
||||
/* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4: */
|
||||
|
||||
/**
|
||||
* The PEAR DB driver for PHP's fbsql extension
|
||||
* for interacting with FrontBase databases
|
||||
*
|
||||
* 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 Database
|
||||
* @package DB
|
||||
* @author Frank M. Kromann <frank@frontbase.com>
|
||||
* @author Daniel Convissor <danielc@php.net>
|
||||
* @copyright 1997-2005 The PHP Group
|
||||
* @license http://www.php.net/license/3_0.txt PHP License 3.0
|
||||
* @version CVS: $Id: fbsql.php,v 1.82 2005/03/04 23:12:36 danielc Exp $
|
||||
* @link http://pear.php.net/package/DB
|
||||
*/
|
||||
|
||||
/**
|
||||
* Obtain the DB_common class so it can be extended from
|
||||
*/
|
||||
require_once 'DB/common.php';
|
||||
|
||||
/**
|
||||
* The methods PEAR DB uses to interact with PHP's fbsql extension
|
||||
* for interacting with FrontBase databases
|
||||
*
|
||||
* These methods overload the ones declared in DB_common.
|
||||
*
|
||||
* @category Database
|
||||
* @package DB
|
||||
* @author Frank M. Kromann <frank@frontbase.com>
|
||||
* @author Daniel Convissor <danielc@php.net>
|
||||
* @copyright 1997-2005 The PHP Group
|
||||
* @license http://www.php.net/license/3_0.txt PHP License 3.0
|
||||
* @version Release: @package_version@
|
||||
* @link http://pear.php.net/package/DB
|
||||
* @since Class functional since Release 1.7.0
|
||||
*/
|
||||
class DB_fbsql extends DB_common
|
||||
{
|
||||
// {{{ properties
|
||||
|
||||
/**
|
||||
* The DB driver type (mysql, oci8, odbc, etc.)
|
||||
* @var string
|
||||
*/
|
||||
var $phptype = 'fbsql';
|
||||
|
||||
/**
|
||||
* The database syntax variant to be used (db2, access, etc.), if any
|
||||
* @var string
|
||||
*/
|
||||
var $dbsyntax = 'fbsql';
|
||||
|
||||
/**
|
||||
* The capabilities of this DB implementation
|
||||
*
|
||||
* The 'new_link' element contains the PHP version that first provided
|
||||
* new_link support for this DBMS. Contains false if it's unsupported.
|
||||
*
|
||||
* Meaning of the 'limit' element:
|
||||
* + 'emulate' = emulate with fetch row by number
|
||||
* + 'alter' = alter the query
|
||||
* + false = skip rows
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
var $features = array(
|
||||
'limit' => 'alter',
|
||||
'new_link' => false,
|
||||
'numrows' => true,
|
||||
'pconnect' => true,
|
||||
'prepare' => false,
|
||||
'ssl' => false,
|
||||
'transactions' => true,
|
||||
);
|
||||
|
||||
/**
|
||||
* A mapping of native error codes to DB error codes
|
||||
* @var array
|
||||
*/
|
||||
var $errorcode_map = array(
|
||||
22 => DB_ERROR_SYNTAX,
|
||||
85 => DB_ERROR_ALREADY_EXISTS,
|
||||
108 => DB_ERROR_SYNTAX,
|
||||
116 => DB_ERROR_NOSUCHTABLE,
|
||||
124 => DB_ERROR_VALUE_COUNT_ON_ROW,
|
||||
215 => DB_ERROR_NOSUCHFIELD,
|
||||
217 => DB_ERROR_INVALID_NUMBER,
|
||||
226 => DB_ERROR_NOSUCHFIELD,
|
||||
231 => DB_ERROR_INVALID,
|
||||
239 => DB_ERROR_TRUNCATED,
|
||||
251 => DB_ERROR_SYNTAX,
|
||||
266 => DB_ERROR_NOT_FOUND,
|
||||
357 => DB_ERROR_CONSTRAINT_NOT_NULL,
|
||||
358 => DB_ERROR_CONSTRAINT,
|
||||
360 => DB_ERROR_CONSTRAINT,
|
||||
361 => DB_ERROR_CONSTRAINT,
|
||||
);
|
||||
|
||||
/**
|
||||
* The raw database connection created by PHP
|
||||
* @var resource
|
||||
*/
|
||||
var $connection;
|
||||
|
||||
/**
|
||||
* The DSN information for connecting to a database
|
||||
* @var array
|
||||
*/
|
||||
var $dsn = array();
|
||||
|
||||
|
||||
// }}}
|
||||
// {{{ constructor
|
||||
|
||||
/**
|
||||
* This constructor calls <kbd>$this->DB_common()</kbd>
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
function DB_fbsql()
|
||||
{
|
||||
$this->DB_common();
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ connect()
|
||||
|
||||
/**
|
||||
* Connect to the database server, log in and open the database
|
||||
*
|
||||
* Don't call this method directly. Use DB::connect() instead.
|
||||
*
|
||||
* @param array $dsn the data source name
|
||||
* @param bool $persistent should the connection be persistent?
|
||||
*
|
||||
* @return int DB_OK on success. A DB_Error object on failure.
|
||||
*/
|
||||
function connect($dsn, $persistent = false)
|
||||
{
|
||||
if (!PEAR::loadExtension('fbsql')) {
|
||||
return $this->raiseError(DB_ERROR_EXTENSION_NOT_FOUND);
|
||||
}
|
||||
|
||||
$this->dsn = $dsn;
|
||||
if ($dsn['dbsyntax']) {
|
||||
$this->dbsyntax = $dsn['dbsyntax'];
|
||||
}
|
||||
|
||||
$params = array(
|
||||
$dsn['hostspec'] ? $dsn['hostspec'] : 'localhost',
|
||||
$dsn['username'] ? $dsn['username'] : null,
|
||||
$dsn['password'] ? $dsn['password'] : null,
|
||||
);
|
||||
|
||||
$connect_function = $persistent ? 'fbsql_pconnect' : 'fbsql_connect';
|
||||
|
||||
$ini = ini_get('track_errors');
|
||||
$php_errormsg = '';
|
||||
if ($ini) {
|
||||
$this->connection = @call_user_func_array($connect_function,
|
||||
$params);
|
||||
} else {
|
||||
ini_set('track_errors', 1);
|
||||
$this->connection = @call_user_func_array($connect_function,
|
||||
$params);
|
||||
ini_set('track_errors', $ini);
|
||||
}
|
||||
|
||||
if (!$this->connection) {
|
||||
return $this->raiseError(DB_ERROR_CONNECT_FAILED,
|
||||
null, null, null,
|
||||
$php_errormsg);
|
||||
}
|
||||
|
||||
if ($dsn['database']) {
|
||||
if (!@fbsql_select_db($dsn['database'], $this->connection)) {
|
||||
return $this->fbsqlRaiseError();
|
||||
}
|
||||
}
|
||||
|
||||
return DB_OK;
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ disconnect()
|
||||
|
||||
/**
|
||||
* Disconnects from the database server
|
||||
*
|
||||
* @return bool TRUE on success, FALSE on failure
|
||||
*/
|
||||
function disconnect()
|
||||
{
|
||||
$ret = @fbsql_close($this->connection);
|
||||
$this->connection = null;
|
||||
return $ret;
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ simpleQuery()
|
||||
|
||||
/**
|
||||
* Sends a query to the database server
|
||||
*
|
||||
* @param string the SQL query string
|
||||
*
|
||||
* @return mixed + a PHP result resrouce for successful SELECT queries
|
||||
* + the DB_OK constant for other successful queries
|
||||
* + a DB_Error object on failure
|
||||
*/
|
||||
function simpleQuery($query)
|
||||
{
|
||||
$this->last_query = $query;
|
||||
$query = $this->modifyQuery($query);
|
||||
$result = @fbsql_query("$query;", $this->connection);
|
||||
if (!$result) {
|
||||
return $this->fbsqlRaiseError();
|
||||
}
|
||||
// Determine which queries that should return data, and which
|
||||
// should return an error code only.
|
||||
if (DB::isManip($query)) {
|
||||
return DB_OK;
|
||||
}
|
||||
return $result;
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ nextResult()
|
||||
|
||||
/**
|
||||
* Move the internal fbsql result pointer to the next available result
|
||||
*
|
||||
* @param a valid fbsql result resource
|
||||
*
|
||||
* @access public
|
||||
*
|
||||
* @return true if a result is available otherwise return false
|
||||
*/
|
||||
function nextResult($result)
|
||||
{
|
||||
return @fbsql_next_result($result);
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ fetchInto()
|
||||
|
||||
/**
|
||||
* Places a row from the result set into the given array
|
||||
*
|
||||
* Formating of the array and the data therein are configurable.
|
||||
* See DB_result::fetchInto() for more information.
|
||||
*
|
||||
* This method is not meant to be called directly. Use
|
||||
* DB_result::fetchInto() instead. It can't be declared "protected"
|
||||
* because DB_result is a separate object.
|
||||
*
|
||||
* @param resource $result the query result resource
|
||||
* @param array $arr the referenced array to put the data in
|
||||
* @param int $fetchmode how the resulting array should be indexed
|
||||
* @param int $rownum the row number to fetch (0 = first row)
|
||||
*
|
||||
* @return mixed DB_OK on success, NULL when the end of a result set is
|
||||
* reached or on failure
|
||||
*
|
||||
* @see DB_result::fetchInto()
|
||||
*/
|
||||
function fetchInto($result, &$arr, $fetchmode, $rownum = null)
|
||||
{
|
||||
if ($rownum !== null) {
|
||||
if (!@fbsql_data_seek($result, $rownum)) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
if ($fetchmode & DB_FETCHMODE_ASSOC) {
|
||||
$arr = @fbsql_fetch_array($result, FBSQL_ASSOC);
|
||||
if ($this->options['portability'] & DB_PORTABILITY_LOWERCASE && $arr) {
|
||||
$arr = array_change_key_case($arr, CASE_LOWER);
|
||||
}
|
||||
} else {
|
||||
$arr = @fbsql_fetch_row($result);
|
||||
}
|
||||
if (!$arr) {
|
||||
return null;
|
||||
}
|
||||
if ($this->options['portability'] & DB_PORTABILITY_RTRIM) {
|
||||
$this->_rtrimArrayValues($arr);
|
||||
}
|
||||
if ($this->options['portability'] & DB_PORTABILITY_NULL_TO_EMPTY) {
|
||||
$this->_convertNullArrayValuesToEmpty($arr);
|
||||
}
|
||||
return DB_OK;
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ freeResult()
|
||||
|
||||
/**
|
||||
* Deletes the result set and frees the memory occupied by the result set
|
||||
*
|
||||
* This method is not meant to be called directly. Use
|
||||
* DB_result::free() instead. It can't be declared "protected"
|
||||
* because DB_result is a separate object.
|
||||
*
|
||||
* @param resource $result PHP's query result resource
|
||||
*
|
||||
* @return bool TRUE on success, FALSE if $result is invalid
|
||||
*
|
||||
* @see DB_result::free()
|
||||
*/
|
||||
function freeResult($result)
|
||||
{
|
||||
return @fbsql_free_result($result);
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ autoCommit()
|
||||
|
||||
/**
|
||||
* Enables or disables automatic commits
|
||||
*
|
||||
* @param bool $onoff true turns it on, false turns it off
|
||||
*
|
||||
* @return int DB_OK on success. A DB_Error object if the driver
|
||||
* doesn't support auto-committing transactions.
|
||||
*/
|
||||
function autoCommit($onoff=false)
|
||||
{
|
||||
if ($onoff) {
|
||||
$this->query("SET COMMIT TRUE");
|
||||
} else {
|
||||
$this->query("SET COMMIT FALSE");
|
||||
}
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ commit()
|
||||
|
||||
/**
|
||||
* Commits the current transaction
|
||||
*
|
||||
* @return int DB_OK on success. A DB_Error object on failure.
|
||||
*/
|
||||
function commit()
|
||||
{
|
||||
@fbsql_commit();
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ rollback()
|
||||
|
||||
/**
|
||||
* Reverts the current transaction
|
||||
*
|
||||
* @return int DB_OK on success. A DB_Error object on failure.
|
||||
*/
|
||||
function rollback()
|
||||
{
|
||||
@fbsql_rollback();
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ numCols()
|
||||
|
||||
/**
|
||||
* Gets the number of columns in a result set
|
||||
*
|
||||
* This method is not meant to be called directly. Use
|
||||
* DB_result::numCols() instead. It can't be declared "protected"
|
||||
* because DB_result is a separate object.
|
||||
*
|
||||
* @param resource $result PHP's query result resource
|
||||
*
|
||||
* @return int the number of columns. A DB_Error object on failure.
|
||||
*
|
||||
* @see DB_result::numCols()
|
||||
*/
|
||||
function numCols($result)
|
||||
{
|
||||
$cols = @fbsql_num_fields($result);
|
||||
if (!$cols) {
|
||||
return $this->fbsqlRaiseError();
|
||||
}
|
||||
return $cols;
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ numRows()
|
||||
|
||||
/**
|
||||
* Gets the number of rows in a result set
|
||||
*
|
||||
* This method is not meant to be called directly. Use
|
||||
* DB_result::numRows() instead. It can't be declared "protected"
|
||||
* because DB_result is a separate object.
|
||||
*
|
||||
* @param resource $result PHP's query result resource
|
||||
*
|
||||
* @return int the number of rows. A DB_Error object on failure.
|
||||
*
|
||||
* @see DB_result::numRows()
|
||||
*/
|
||||
function numRows($result)
|
||||
{
|
||||
$rows = @fbsql_num_rows($result);
|
||||
if ($rows === null) {
|
||||
return $this->fbsqlRaiseError();
|
||||
}
|
||||
return $rows;
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ affectedRows()
|
||||
|
||||
/**
|
||||
* Determines the number of rows affected by a data maniuplation query
|
||||
*
|
||||
* 0 is returned for queries that don't manipulate data.
|
||||
*
|
||||
* @return int the number of rows. A DB_Error object on failure.
|
||||
*/
|
||||
function affectedRows()
|
||||
{
|
||||
if (DB::isManip($this->last_query)) {
|
||||
$result = @fbsql_affected_rows($this->connection);
|
||||
} else {
|
||||
$result = 0;
|
||||
}
|
||||
return $result;
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ nextId()
|
||||
|
||||
/**
|
||||
* Returns the next free id in a sequence
|
||||
*
|
||||
* @param string $seq_name name of the sequence
|
||||
* @param boolean $ondemand when true, the seqence is automatically
|
||||
* created if it does not exist
|
||||
*
|
||||
* @return int the next id number in the sequence.
|
||||
* A DB_Error object on failure.
|
||||
*
|
||||
* @see DB_common::nextID(), DB_common::getSequenceName(),
|
||||
* DB_fbsql::createSequence(), DB_fbsql::dropSequence()
|
||||
*/
|
||||
function nextId($seq_name, $ondemand = true)
|
||||
{
|
||||
$seqname = $this->getSequenceName($seq_name);
|
||||
do {
|
||||
$repeat = 0;
|
||||
$this->pushErrorHandling(PEAR_ERROR_RETURN);
|
||||
$result = $this->query('SELECT UNIQUE FROM ' . $seqname);
|
||||
$this->popErrorHandling();
|
||||
if ($ondemand && DB::isError($result) &&
|
||||
$result->getCode() == DB_ERROR_NOSUCHTABLE) {
|
||||
$repeat = 1;
|
||||
$result = $this->createSequence($seq_name);
|
||||
if (DB::isError($result)) {
|
||||
return $result;
|
||||
}
|
||||
} else {
|
||||
$repeat = 0;
|
||||
}
|
||||
} while ($repeat);
|
||||
if (DB::isError($result)) {
|
||||
return $this->fbsqlRaiseError();
|
||||
}
|
||||
$result->fetchInto($tmp, DB_FETCHMODE_ORDERED);
|
||||
return $tmp[0];
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new sequence
|
||||
*
|
||||
* @param string $seq_name name of the new sequence
|
||||
*
|
||||
* @return int DB_OK on success. A DB_Error object on failure.
|
||||
*
|
||||
* @see DB_common::createSequence(), DB_common::getSequenceName(),
|
||||
* DB_fbsql::nextID(), DB_fbsql::dropSequence()
|
||||
*/
|
||||
function createSequence($seq_name)
|
||||
{
|
||||
$seqname = $this->getSequenceName($seq_name);
|
||||
$res = $this->query('CREATE TABLE ' . $seqname
|
||||
. ' (id INTEGER NOT NULL,'
|
||||
. ' PRIMARY KEY(id))');
|
||||
if ($res) {
|
||||
$res = $this->query('SET UNIQUE = 0 FOR ' . $seqname);
|
||||
}
|
||||
return $res;
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ dropSequence()
|
||||
|
||||
/**
|
||||
* Deletes a sequence
|
||||
*
|
||||
* @param string $seq_name name of the sequence to be deleted
|
||||
*
|
||||
* @return int DB_OK on success. A DB_Error object on failure.
|
||||
*
|
||||
* @see DB_common::dropSequence(), DB_common::getSequenceName(),
|
||||
* DB_fbsql::nextID(), DB_fbsql::createSequence()
|
||||
*/
|
||||
function dropSequence($seq_name)
|
||||
{
|
||||
return $this->query('DROP TABLE ' . $this->getSequenceName($seq_name)
|
||||
. ' RESTRICT');
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ modifyLimitQuery()
|
||||
|
||||
/**
|
||||
* Adds LIMIT clauses to a query string according to current DBMS standards
|
||||
*
|
||||
* @param string $query the query to modify
|
||||
* @param int $from the row to start to fetching (0 = the first row)
|
||||
* @param int $count the numbers of rows to fetch
|
||||
* @param mixed $params array, string or numeric data to be used in
|
||||
* execution of the statement. Quantity of items
|
||||
* passed must match quantity of placeholders in
|
||||
* query: meaning 1 placeholder for non-array
|
||||
* parameters or 1 placeholder per array element.
|
||||
*
|
||||
* @return string the query string with LIMIT clauses added
|
||||
*
|
||||
* @access protected
|
||||
*/
|
||||
function modifyLimitQuery($query, $from, $count, $params = array())
|
||||
{
|
||||
if (DB::isManip($query)) {
|
||||
return preg_replace('/^([\s(])*SELECT/i',
|
||||
"\\1SELECT TOP($count)", $query);
|
||||
} else {
|
||||
return preg_replace('/([\s(])*SELECT/i',
|
||||
"\\1SELECT TOP($from, $count)", $query);
|
||||
}
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ quoteSmart()
|
||||
|
||||
/**
|
||||
* Formats input so it can be safely used in a query
|
||||
*
|
||||
* @param mixed $in the data to be formatted
|
||||
*
|
||||
* @return mixed the formatted data. The format depends on the input's
|
||||
* PHP type:
|
||||
* + null = the string <samp>NULL</samp>
|
||||
* + boolean = string <samp>TRUE</samp> or <samp>FALSE</samp>
|
||||
* + integer or double = the unquoted number
|
||||
* + other (including strings and numeric strings) =
|
||||
* the data escaped according to FrontBase's settings
|
||||
* then encapsulated between single quotes
|
||||
*
|
||||
* @see DB_common::quoteSmart()
|
||||
* @since Method available since Release 1.6.0
|
||||
*/
|
||||
function quoteSmart($in)
|
||||
{
|
||||
if (is_int($in) || is_double($in)) {
|
||||
return $in;
|
||||
} elseif (is_bool($in)) {
|
||||
return $in ? 'TRUE' : 'FALSE';
|
||||
} elseif (is_null($in)) {
|
||||
return 'NULL';
|
||||
} else {
|
||||
return "'" . $this->escapeSimple($in) . "'";
|
||||
}
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ fbsqlRaiseError()
|
||||
|
||||
/**
|
||||
* Produces a DB_Error object regarding the current problem
|
||||
*
|
||||
* @param int $errno if the error is being manually raised pass a
|
||||
* DB_ERROR* constant here. If this isn't passed
|
||||
* the error information gathered from the DBMS.
|
||||
*
|
||||
* @return object the DB_Error object
|
||||
*
|
||||
* @see DB_common::raiseError(),
|
||||
* DB_fbsql::errorNative(), DB_common::errorCode()
|
||||
*/
|
||||
function fbsqlRaiseError($errno = null)
|
||||
{
|
||||
if ($errno === null) {
|
||||
$errno = $this->errorCode(fbsql_errno($this->connection));
|
||||
}
|
||||
return $this->raiseError($errno, null, null, null,
|
||||
@fbsql_error($this->connection));
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ errorNative()
|
||||
|
||||
/**
|
||||
* Gets the DBMS' native error code produced by the last query
|
||||
*
|
||||
* @return int the DBMS' error code
|
||||
*/
|
||||
function errorNative()
|
||||
{
|
||||
return @fbsql_errno($this->connection);
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ tableInfo()
|
||||
|
||||
/**
|
||||
* Returns information about a table or a result set
|
||||
*
|
||||
* @param object|string $result DB_result object from a query or a
|
||||
* string containing the name of a table.
|
||||
* While this also accepts a query result
|
||||
* resource identifier, this behavior is
|
||||
* deprecated.
|
||||
* @param int $mode a valid tableInfo mode
|
||||
*
|
||||
* @return array an associative array with the information requested.
|
||||
* A DB_Error object on failure.
|
||||
*
|
||||
* @see DB_common::tableInfo()
|
||||
*/
|
||||
function tableInfo($result, $mode = null)
|
||||
{
|
||||
if (is_string($result)) {
|
||||
/*
|
||||
* Probably received a table name.
|
||||
* Create a result resource identifier.
|
||||
*/
|
||||
$id = @fbsql_list_fields($this->dsn['database'],
|
||||
$result, $this->connection);
|
||||
$got_string = true;
|
||||
} elseif (isset($result->result)) {
|
||||
/*
|
||||
* Probably received a result object.
|
||||
* Extract the result resource identifier.
|
||||
*/
|
||||
$id = $result->result;
|
||||
$got_string = false;
|
||||
} else {
|
||||
/*
|
||||
* Probably received a result resource identifier.
|
||||
* Copy it.
|
||||
* Deprecated. Here for compatibility only.
|
||||
*/
|
||||
$id = $result;
|
||||
$got_string = false;
|
||||
}
|
||||
|
||||
if (!is_resource($id)) {
|
||||
return $this->fbsqlRaiseError(DB_ERROR_NEED_MORE_DATA);
|
||||
}
|
||||
|
||||
if ($this->options['portability'] & DB_PORTABILITY_LOWERCASE) {
|
||||
$case_func = 'strtolower';
|
||||
} else {
|
||||
$case_func = 'strval';
|
||||
}
|
||||
|
||||
$count = @fbsql_num_fields($id);
|
||||
$res = array();
|
||||
|
||||
if ($mode) {
|
||||
$res['num_fields'] = $count;
|
||||
}
|
||||
|
||||
for ($i = 0; $i < $count; $i++) {
|
||||
$res[$i] = array(
|
||||
'table' => $case_func(@fbsql_field_table($id, $i)),
|
||||
'name' => $case_func(@fbsql_field_name($id, $i)),
|
||||
'type' => @fbsql_field_type($id, $i),
|
||||
'len' => @fbsql_field_len($id, $i),
|
||||
'flags' => @fbsql_field_flags($id, $i),
|
||||
);
|
||||
if ($mode & DB_TABLEINFO_ORDER) {
|
||||
$res['order'][$res[$i]['name']] = $i;
|
||||
}
|
||||
if ($mode & DB_TABLEINFO_ORDERTABLE) {
|
||||
$res['ordertable'][$res[$i]['table']][$res[$i]['name']] = $i;
|
||||
}
|
||||
}
|
||||
|
||||
// free the result only if we were called on a table
|
||||
if ($got_string) {
|
||||
@fbsql_free_result($id);
|
||||
}
|
||||
return $res;
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ getSpecialQuery()
|
||||
|
||||
/**
|
||||
* Obtains the query string needed for listing a given type of objects
|
||||
*
|
||||
* @param string $type the kind of objects you want to retrieve
|
||||
*
|
||||
* @return string the SQL query string or null if the driver doesn't
|
||||
* support the object type requested
|
||||
*
|
||||
* @access protected
|
||||
* @see DB_common::getListOf()
|
||||
*/
|
||||
function getSpecialQuery($type)
|
||||
{
|
||||
switch ($type) {
|
||||
case 'tables':
|
||||
return 'SELECT "table_name" FROM information_schema.tables'
|
||||
. ' t0, information_schema.schemata t1'
|
||||
. ' WHERE t0.schema_pk=t1.schema_pk AND'
|
||||
. ' "table_type" = \'BASE TABLE\''
|
||||
. ' AND "schema_name" = current_schema';
|
||||
case 'views':
|
||||
return 'SELECT "table_name" FROM information_schema.tables'
|
||||
. ' t0, information_schema.schemata t1'
|
||||
. ' WHERE t0.schema_pk=t1.schema_pk AND'
|
||||
. ' "table_type" = \'VIEW\''
|
||||
. ' AND "schema_name" = current_schema';
|
||||
case 'users':
|
||||
return 'SELECT "user_name" from information_schema.users';
|
||||
case 'functions':
|
||||
return 'SELECT "routine_name" FROM'
|
||||
. ' information_schema.psm_routines'
|
||||
. ' t0, information_schema.schemata t1'
|
||||
. ' WHERE t0.schema_pk=t1.schema_pk'
|
||||
. ' AND "routine_kind"=\'FUNCTION\''
|
||||
. ' AND "schema_name" = current_schema';
|
||||
case 'procedures':
|
||||
return 'SELECT "routine_name" FROM'
|
||||
. ' information_schema.psm_routines'
|
||||
. ' t0, information_schema.schemata t1'
|
||||
. ' WHERE t0.schema_pk=t1.schema_pk'
|
||||
. ' AND "routine_kind"=\'PROCEDURE\''
|
||||
. ' AND "schema_name" = current_schema';
|
||||
default:
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
// }}}
|
||||
}
|
||||
|
||||
/*
|
||||
* Local variables:
|
||||
* tab-width: 4
|
||||
* c-basic-offset: 4
|
||||
* End:
|
||||
*/
|
||||
|
||||
?>
|
||||
1071
include/pear/DB/ibase.php
Normal file
1071
include/pear/DB/ibase.php
Normal file
File diff suppressed because it is too large
Load Diff
681
include/pear/DB/ifx.php
Normal file
681
include/pear/DB/ifx.php
Normal file
@@ -0,0 +1,681 @@
|
||||
<?php
|
||||
|
||||
/* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4: */
|
||||
|
||||
/**
|
||||
* The PEAR DB driver for PHP's ifx extension
|
||||
* for interacting with Informix databases
|
||||
*
|
||||
* 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 Database
|
||||
* @package DB
|
||||
* @author Tomas V.V.Cox <cox@idecnet.com>
|
||||
* @author Daniel Convissor <danielc@php.net>
|
||||
* @copyright 1997-2005 The PHP Group
|
||||
* @license http://www.php.net/license/3_0.txt PHP License 3.0
|
||||
* @version CVS: $Id: ifx.php,v 1.70 2005/02/20 00:44:48 danielc Exp $
|
||||
* @link http://pear.php.net/package/DB
|
||||
*/
|
||||
|
||||
/**
|
||||
* Obtain the DB_common class so it can be extended from
|
||||
*/
|
||||
require_once 'DB/common.php';
|
||||
|
||||
/**
|
||||
* The methods PEAR DB uses to interact with PHP's ifx extension
|
||||
* for interacting with Informix databases
|
||||
*
|
||||
* These methods overload the ones declared in DB_common.
|
||||
*
|
||||
* More info on Informix errors can be found at:
|
||||
* http://www.informix.com/answers/english/ierrors.htm
|
||||
*
|
||||
* TODO:
|
||||
* - set needed env Informix vars on connect
|
||||
* - implement native prepare/execute
|
||||
*
|
||||
* @category Database
|
||||
* @package DB
|
||||
* @author Tomas V.V.Cox <cox@idecnet.com>
|
||||
* @author Daniel Convissor <danielc@php.net>
|
||||
* @copyright 1997-2005 The PHP Group
|
||||
* @license http://www.php.net/license/3_0.txt PHP License 3.0
|
||||
* @version Release: @package_version@
|
||||
* @link http://pear.php.net/package/DB
|
||||
*/
|
||||
class DB_ifx extends DB_common
|
||||
{
|
||||
// {{{ properties
|
||||
|
||||
/**
|
||||
* The DB driver type (mysql, oci8, odbc, etc.)
|
||||
* @var string
|
||||
*/
|
||||
var $phptype = 'ifx';
|
||||
|
||||
/**
|
||||
* The database syntax variant to be used (db2, access, etc.), if any
|
||||
* @var string
|
||||
*/
|
||||
var $dbsyntax = 'ifx';
|
||||
|
||||
/**
|
||||
* The capabilities of this DB implementation
|
||||
*
|
||||
* The 'new_link' element contains the PHP version that first provided
|
||||
* new_link support for this DBMS. Contains false if it's unsupported.
|
||||
*
|
||||
* Meaning of the 'limit' element:
|
||||
* + 'emulate' = emulate with fetch row by number
|
||||
* + 'alter' = alter the query
|
||||
* + false = skip rows
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
var $features = array(
|
||||
'limit' => 'emulate',
|
||||
'new_link' => false,
|
||||
'numrows' => 'emulate',
|
||||
'pconnect' => true,
|
||||
'prepare' => false,
|
||||
'ssl' => false,
|
||||
'transactions' => true,
|
||||
);
|
||||
|
||||
/**
|
||||
* A mapping of native error codes to DB error codes
|
||||
* @var array
|
||||
*/
|
||||
var $errorcode_map = array(
|
||||
'-201' => DB_ERROR_SYNTAX,
|
||||
'-206' => DB_ERROR_NOSUCHTABLE,
|
||||
'-217' => DB_ERROR_NOSUCHFIELD,
|
||||
'-236' => DB_ERROR_VALUE_COUNT_ON_ROW,
|
||||
'-239' => DB_ERROR_CONSTRAINT,
|
||||
'-253' => DB_ERROR_SYNTAX,
|
||||
'-292' => DB_ERROR_CONSTRAINT_NOT_NULL,
|
||||
'-310' => DB_ERROR_ALREADY_EXISTS,
|
||||
'-316' => DB_ERROR_ALREADY_EXISTS,
|
||||
'-319' => DB_ERROR_NOT_FOUND,
|
||||
'-329' => DB_ERROR_NODBSELECTED,
|
||||
'-346' => DB_ERROR_CONSTRAINT,
|
||||
'-386' => DB_ERROR_CONSTRAINT_NOT_NULL,
|
||||
'-391' => DB_ERROR_CONSTRAINT_NOT_NULL,
|
||||
'-554' => DB_ERROR_SYNTAX,
|
||||
'-691' => DB_ERROR_CONSTRAINT,
|
||||
'-692' => DB_ERROR_CONSTRAINT,
|
||||
'-703' => DB_ERROR_CONSTRAINT_NOT_NULL,
|
||||
'-1204' => DB_ERROR_INVALID_DATE,
|
||||
'-1205' => DB_ERROR_INVALID_DATE,
|
||||
'-1206' => DB_ERROR_INVALID_DATE,
|
||||
'-1209' => DB_ERROR_INVALID_DATE,
|
||||
'-1210' => DB_ERROR_INVALID_DATE,
|
||||
'-1212' => DB_ERROR_INVALID_DATE,
|
||||
'-1213' => DB_ERROR_INVALID_NUMBER,
|
||||
);
|
||||
|
||||
/**
|
||||
* The raw database connection created by PHP
|
||||
* @var resource
|
||||
*/
|
||||
var $connection;
|
||||
|
||||
/**
|
||||
* The DSN information for connecting to a database
|
||||
* @var array
|
||||
*/
|
||||
var $dsn = array();
|
||||
|
||||
|
||||
/**
|
||||
* Should data manipulation queries be committed automatically?
|
||||
* @var bool
|
||||
* @access private
|
||||
*/
|
||||
var $autocommit = true;
|
||||
|
||||
/**
|
||||
* The quantity of transactions begun
|
||||
*
|
||||
* {@internal While this is private, it can't actually be designated
|
||||
* private in PHP 5 because it is directly accessed in the test suite.}}
|
||||
*
|
||||
* @var integer
|
||||
* @access private
|
||||
*/
|
||||
var $transaction_opcount = 0;
|
||||
|
||||
/**
|
||||
* The number of rows affected by a data manipulation query
|
||||
* @var integer
|
||||
* @access private
|
||||
*/
|
||||
var $affected = 0;
|
||||
|
||||
|
||||
// }}}
|
||||
// {{{ constructor
|
||||
|
||||
/**
|
||||
* This constructor calls <kbd>$this->DB_common()</kbd>
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
function DB_ifx()
|
||||
{
|
||||
$this->DB_common();
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ connect()
|
||||
|
||||
/**
|
||||
* Connect to the database server, log in and open the database
|
||||
*
|
||||
* Don't call this method directly. Use DB::connect() instead.
|
||||
*
|
||||
* @param array $dsn the data source name
|
||||
* @param bool $persistent should the connection be persistent?
|
||||
*
|
||||
* @return int DB_OK on success. A DB_Error object on failure.
|
||||
*/
|
||||
function connect($dsn, $persistent = false)
|
||||
{
|
||||
if (!PEAR::loadExtension('informix') &&
|
||||
!PEAR::loadExtension('Informix'))
|
||||
{
|
||||
return $this->raiseError(DB_ERROR_EXTENSION_NOT_FOUND);
|
||||
}
|
||||
|
||||
$this->dsn = $dsn;
|
||||
if ($dsn['dbsyntax']) {
|
||||
$this->dbsyntax = $dsn['dbsyntax'];
|
||||
}
|
||||
|
||||
$dbhost = $dsn['hostspec'] ? '@' . $dsn['hostspec'] : '';
|
||||
$dbname = $dsn['database'] ? $dsn['database'] . $dbhost : '';
|
||||
$user = $dsn['username'] ? $dsn['username'] : '';
|
||||
$pw = $dsn['password'] ? $dsn['password'] : '';
|
||||
|
||||
$connect_function = $persistent ? 'ifx_pconnect' : 'ifx_connect';
|
||||
|
||||
$this->connection = @$connect_function($dbname, $user, $pw);
|
||||
if (!is_resource($this->connection)) {
|
||||
return $this->ifxRaiseError(DB_ERROR_CONNECT_FAILED);
|
||||
}
|
||||
return DB_OK;
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ disconnect()
|
||||
|
||||
/**
|
||||
* Disconnects from the database server
|
||||
*
|
||||
* @return bool TRUE on success, FALSE on failure
|
||||
*/
|
||||
function disconnect()
|
||||
{
|
||||
$ret = @ifx_close($this->connection);
|
||||
$this->connection = null;
|
||||
return $ret;
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ simpleQuery()
|
||||
|
||||
/**
|
||||
* Sends a query to the database server
|
||||
*
|
||||
* @param string the SQL query string
|
||||
*
|
||||
* @return mixed + a PHP result resrouce for successful SELECT queries
|
||||
* + the DB_OK constant for other successful queries
|
||||
* + a DB_Error object on failure
|
||||
*/
|
||||
function simpleQuery($query)
|
||||
{
|
||||
$ismanip = DB::isManip($query);
|
||||
$this->last_query = $query;
|
||||
$this->affected = null;
|
||||
if (preg_match('/(SELECT)/i', $query)) { //TESTME: Use !DB::isManip()?
|
||||
// the scroll is needed for fetching absolute row numbers
|
||||
// in a select query result
|
||||
$result = @ifx_query($query, $this->connection, IFX_SCROLL);
|
||||
} else {
|
||||
if (!$this->autocommit && $ismanip) {
|
||||
if ($this->transaction_opcount == 0) {
|
||||
$result = @ifx_query('BEGIN WORK', $this->connection);
|
||||
if (!$result) {
|
||||
return $this->ifxRaiseError();
|
||||
}
|
||||
}
|
||||
$this->transaction_opcount++;
|
||||
}
|
||||
$result = @ifx_query($query, $this->connection);
|
||||
}
|
||||
if (!$result) {
|
||||
return $this->ifxRaiseError();
|
||||
}
|
||||
$this->affected = @ifx_affected_rows($result);
|
||||
// Determine which queries should return data, and which
|
||||
// should return an error code only.
|
||||
if (preg_match('/(SELECT)/i', $query)) {
|
||||
return $result;
|
||||
}
|
||||
// XXX Testme: free results inside a transaction
|
||||
// may cause to stop it and commit the work?
|
||||
|
||||
// Result has to be freed even with a insert or update
|
||||
@ifx_free_result($result);
|
||||
|
||||
return DB_OK;
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ nextResult()
|
||||
|
||||
/**
|
||||
* Move the internal ifx result pointer to the next available result
|
||||
*
|
||||
* @param a valid fbsql result resource
|
||||
*
|
||||
* @access public
|
||||
*
|
||||
* @return true if a result is available otherwise return false
|
||||
*/
|
||||
function nextResult($result)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ affectedRows()
|
||||
|
||||
/**
|
||||
* Determines the number of rows affected by a data maniuplation query
|
||||
*
|
||||
* 0 is returned for queries that don't manipulate data.
|
||||
*
|
||||
* @return int the number of rows. A DB_Error object on failure.
|
||||
*/
|
||||
function affectedRows()
|
||||
{
|
||||
if (DB::isManip($this->last_query)) {
|
||||
return $this->affected;
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ fetchInto()
|
||||
|
||||
/**
|
||||
* Places a row from the result set into the given array
|
||||
*
|
||||
* Formating of the array and the data therein are configurable.
|
||||
* See DB_result::fetchInto() for more information.
|
||||
*
|
||||
* This method is not meant to be called directly. Use
|
||||
* DB_result::fetchInto() instead. It can't be declared "protected"
|
||||
* because DB_result is a separate object.
|
||||
*
|
||||
* @param resource $result the query result resource
|
||||
* @param array $arr the referenced array to put the data in
|
||||
* @param int $fetchmode how the resulting array should be indexed
|
||||
* @param int $rownum the row number to fetch (0 = first row)
|
||||
*
|
||||
* @return mixed DB_OK on success, NULL when the end of a result set is
|
||||
* reached or on failure
|
||||
*
|
||||
* @see DB_result::fetchInto()
|
||||
*/
|
||||
function fetchInto($result, &$arr, $fetchmode, $rownum = null)
|
||||
{
|
||||
if (($rownum !== null) && ($rownum < 0)) {
|
||||
return null;
|
||||
}
|
||||
if ($rownum === null) {
|
||||
/*
|
||||
* Even though fetch_row() should return the next row if
|
||||
* $rownum is null, it doesn't in all cases. Bug 598.
|
||||
*/
|
||||
$rownum = 'NEXT';
|
||||
} else {
|
||||
// Index starts at row 1, unlike most DBMS's starting at 0.
|
||||
$rownum++;
|
||||
}
|
||||
if (!$arr = @ifx_fetch_row($result, $rownum)) {
|
||||
return null;
|
||||
}
|
||||
if ($fetchmode !== DB_FETCHMODE_ASSOC) {
|
||||
$i=0;
|
||||
$order = array();
|
||||
foreach ($arr as $val) {
|
||||
$order[$i++] = $val;
|
||||
}
|
||||
$arr = $order;
|
||||
} elseif ($fetchmode == DB_FETCHMODE_ASSOC &&
|
||||
$this->options['portability'] & DB_PORTABILITY_LOWERCASE)
|
||||
{
|
||||
$arr = array_change_key_case($arr, CASE_LOWER);
|
||||
}
|
||||
if ($this->options['portability'] & DB_PORTABILITY_RTRIM) {
|
||||
$this->_rtrimArrayValues($arr);
|
||||
}
|
||||
if ($this->options['portability'] & DB_PORTABILITY_NULL_TO_EMPTY) {
|
||||
$this->_convertNullArrayValuesToEmpty($arr);
|
||||
}
|
||||
return DB_OK;
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ numCols()
|
||||
|
||||
/**
|
||||
* Gets the number of columns in a result set
|
||||
*
|
||||
* This method is not meant to be called directly. Use
|
||||
* DB_result::numCols() instead. It can't be declared "protected"
|
||||
* because DB_result is a separate object.
|
||||
*
|
||||
* @param resource $result PHP's query result resource
|
||||
*
|
||||
* @return int the number of columns. A DB_Error object on failure.
|
||||
*
|
||||
* @see DB_result::numCols()
|
||||
*/
|
||||
function numCols($result)
|
||||
{
|
||||
if (!$cols = @ifx_num_fields($result)) {
|
||||
return $this->ifxRaiseError();
|
||||
}
|
||||
return $cols;
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ freeResult()
|
||||
|
||||
/**
|
||||
* Deletes the result set and frees the memory occupied by the result set
|
||||
*
|
||||
* This method is not meant to be called directly. Use
|
||||
* DB_result::free() instead. It can't be declared "protected"
|
||||
* because DB_result is a separate object.
|
||||
*
|
||||
* @param resource $result PHP's query result resource
|
||||
*
|
||||
* @return bool TRUE on success, FALSE if $result is invalid
|
||||
*
|
||||
* @see DB_result::free()
|
||||
*/
|
||||
function freeResult($result)
|
||||
{
|
||||
return @ifx_free_result($result);
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ autoCommit()
|
||||
|
||||
/**
|
||||
* Enables or disables automatic commits
|
||||
*
|
||||
* @param bool $onoff true turns it on, false turns it off
|
||||
*
|
||||
* @return int DB_OK on success. A DB_Error object if the driver
|
||||
* doesn't support auto-committing transactions.
|
||||
*/
|
||||
function autoCommit($onoff = true)
|
||||
{
|
||||
// XXX if $this->transaction_opcount > 0, we should probably
|
||||
// issue a warning here.
|
||||
$this->autocommit = $onoff ? true : false;
|
||||
return DB_OK;
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ commit()
|
||||
|
||||
/**
|
||||
* Commits the current transaction
|
||||
*
|
||||
* @return int DB_OK on success. A DB_Error object on failure.
|
||||
*/
|
||||
function commit()
|
||||
{
|
||||
if ($this->transaction_opcount > 0) {
|
||||
$result = @ifx_query('COMMIT WORK', $this->connection);
|
||||
$this->transaction_opcount = 0;
|
||||
if (!$result) {
|
||||
return $this->ifxRaiseError();
|
||||
}
|
||||
}
|
||||
return DB_OK;
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ rollback()
|
||||
|
||||
/**
|
||||
* Reverts the current transaction
|
||||
*
|
||||
* @return int DB_OK on success. A DB_Error object on failure.
|
||||
*/
|
||||
function rollback()
|
||||
{
|
||||
if ($this->transaction_opcount > 0) {
|
||||
$result = @ifx_query('ROLLBACK WORK', $this->connection);
|
||||
$this->transaction_opcount = 0;
|
||||
if (!$result) {
|
||||
return $this->ifxRaiseError();
|
||||
}
|
||||
}
|
||||
return DB_OK;
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ ifxRaiseError()
|
||||
|
||||
/**
|
||||
* Produces a DB_Error object regarding the current problem
|
||||
*
|
||||
* @param int $errno if the error is being manually raised pass a
|
||||
* DB_ERROR* constant here. If this isn't passed
|
||||
* the error information gathered from the DBMS.
|
||||
*
|
||||
* @return object the DB_Error object
|
||||
*
|
||||
* @see DB_common::raiseError(),
|
||||
* DB_ifx::errorNative(), DB_ifx::errorCode()
|
||||
*/
|
||||
function ifxRaiseError($errno = null)
|
||||
{
|
||||
if ($errno === null) {
|
||||
$errno = $this->errorCode(ifx_error());
|
||||
}
|
||||
return $this->raiseError($errno, null, null, null,
|
||||
$this->errorNative());
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ errorNative()
|
||||
|
||||
/**
|
||||
* Gets the DBMS' native error code and message produced by the last query
|
||||
*
|
||||
* @return string the DBMS' error code and message
|
||||
*/
|
||||
function errorNative()
|
||||
{
|
||||
return @ifx_error() . ' ' . @ifx_errormsg();
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ errorCode()
|
||||
|
||||
/**
|
||||
* Maps native error codes to DB's portable ones.
|
||||
*
|
||||
* Requires that the DB implementation's constructor fills
|
||||
* in the <var>$errorcode_map</var> property.
|
||||
*
|
||||
* @param string $nativecode error code returned by the database
|
||||
* @return int a portable DB error code, or DB_ERROR if this DB
|
||||
* implementation has no mapping for the given error code.
|
||||
*/
|
||||
function errorCode($nativecode)
|
||||
{
|
||||
if (ereg('SQLCODE=(.*)]', $nativecode, $match)) {
|
||||
$code = $match[1];
|
||||
if (isset($this->errorcode_map[$code])) {
|
||||
return $this->errorcode_map[$code];
|
||||
}
|
||||
}
|
||||
return DB_ERROR;
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ tableInfo()
|
||||
|
||||
/**
|
||||
* Returns information about a table or a result set
|
||||
*
|
||||
* NOTE: only supports 'table' if <var>$result</var> is a table name.
|
||||
*
|
||||
* If analyzing a query result and the result has duplicate field names,
|
||||
* an error will be raised saying
|
||||
* <samp>can't distinguish duplicate field names</samp>.
|
||||
*
|
||||
* @param object|string $result DB_result object from a query or a
|
||||
* string containing the name of a table.
|
||||
* While this also accepts a query result
|
||||
* resource identifier, this behavior is
|
||||
* deprecated.
|
||||
* @param int $mode a valid tableInfo mode
|
||||
*
|
||||
* @return array an associative array with the information requested.
|
||||
* A DB_Error object on failure.
|
||||
*
|
||||
* @see DB_common::tableInfo()
|
||||
* @since Method available since Release 1.6.0
|
||||
*/
|
||||
function tableInfo($result, $mode = null)
|
||||
{
|
||||
if (is_string($result)) {
|
||||
/*
|
||||
* Probably received a table name.
|
||||
* Create a result resource identifier.
|
||||
*/
|
||||
$id = @ifx_query("SELECT * FROM $result WHERE 1=0",
|
||||
$this->connection);
|
||||
$got_string = true;
|
||||
} elseif (isset($result->result)) {
|
||||
/*
|
||||
* Probably received a result object.
|
||||
* Extract the result resource identifier.
|
||||
*/
|
||||
$id = $result->result;
|
||||
$got_string = false;
|
||||
} else {
|
||||
/*
|
||||
* Probably received a result resource identifier.
|
||||
* Copy it.
|
||||
*/
|
||||
$id = $result;
|
||||
$got_string = false;
|
||||
}
|
||||
|
||||
if (!is_resource($id)) {
|
||||
return $this->ifxRaiseError(DB_ERROR_NEED_MORE_DATA);
|
||||
}
|
||||
|
||||
$flds = @ifx_fieldproperties($id);
|
||||
$count = @ifx_num_fields($id);
|
||||
|
||||
if (count($flds) != $count) {
|
||||
return $this->raiseError("can't distinguish duplicate field names");
|
||||
}
|
||||
|
||||
if ($this->options['portability'] & DB_PORTABILITY_LOWERCASE) {
|
||||
$case_func = 'strtolower';
|
||||
} else {
|
||||
$case_func = 'strval';
|
||||
}
|
||||
|
||||
$i = 0;
|
||||
$res = array();
|
||||
|
||||
if ($mode) {
|
||||
$res['num_fields'] = $count;
|
||||
}
|
||||
|
||||
foreach ($flds as $key => $value) {
|
||||
$props = explode(';', $value);
|
||||
$res[$i] = array(
|
||||
'table' => $got_string ? $case_func($result) : '',
|
||||
'name' => $case_func($key),
|
||||
'type' => $props[0],
|
||||
'len' => $props[1],
|
||||
'flags' => $props[4] == 'N' ? 'not_null' : '',
|
||||
);
|
||||
if ($mode & DB_TABLEINFO_ORDER) {
|
||||
$res['order'][$res[$i]['name']] = $i;
|
||||
}
|
||||
if ($mode & DB_TABLEINFO_ORDERTABLE) {
|
||||
$res['ordertable'][$res[$i]['table']][$res[$i]['name']] = $i;
|
||||
}
|
||||
$i++;
|
||||
}
|
||||
|
||||
// free the result only if we were called on a table
|
||||
if ($got_string) {
|
||||
@ifx_free_result($id);
|
||||
}
|
||||
return $res;
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ getSpecialQuery()
|
||||
|
||||
/**
|
||||
* Obtains the query string needed for listing a given type of objects
|
||||
*
|
||||
* @param string $type the kind of objects you want to retrieve
|
||||
*
|
||||
* @return string the SQL query string or null if the driver doesn't
|
||||
* support the object type requested
|
||||
*
|
||||
* @access protected
|
||||
* @see DB_common::getListOf()
|
||||
*/
|
||||
function getSpecialQuery($type)
|
||||
{
|
||||
switch ($type) {
|
||||
case 'tables':
|
||||
return 'SELECT tabname FROM systables WHERE tabid >= 100';
|
||||
default:
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
// }}}
|
||||
|
||||
}
|
||||
|
||||
/*
|
||||
* Local variables:
|
||||
* tab-width: 4
|
||||
* c-basic-offset: 4
|
||||
* End:
|
||||
*/
|
||||
|
||||
?>
|
||||
810
include/pear/DB/msql.php
Normal file
810
include/pear/DB/msql.php
Normal file
@@ -0,0 +1,810 @@
|
||||
<?php
|
||||
|
||||
/* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4: */
|
||||
|
||||
/**
|
||||
* The PEAR DB driver for PHP's msql extension
|
||||
* for interacting with Mini SQL databases
|
||||
*
|
||||
* PHP's mSQL extension did weird things with NULL values prior to PHP
|
||||
* 4.3.11 and 5.0.4. Make sure your version of PHP meets or exceeds
|
||||
* those versions.
|
||||
*
|
||||
* 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 Database
|
||||
* @package DB
|
||||
* @author Daniel Convissor <danielc@php.net>
|
||||
* @copyright 1997-2005 The PHP Group
|
||||
* @license http://www.php.net/license/3_0.txt PHP License 3.0
|
||||
* @version CVS: $Id: msql.php,v 1.57 2005/02/22 07:26:46 danielc Exp $
|
||||
* @link http://pear.php.net/package/DB
|
||||
*/
|
||||
|
||||
/**
|
||||
* Obtain the DB_common class so it can be extended from
|
||||
*/
|
||||
require_once 'DB/common.php';
|
||||
|
||||
/**
|
||||
* The methods PEAR DB uses to interact with PHP's msql extension
|
||||
* for interacting with Mini SQL databases
|
||||
*
|
||||
* These methods overload the ones declared in DB_common.
|
||||
*
|
||||
* PHP's mSQL extension did weird things with NULL values prior to PHP
|
||||
* 4.3.11 and 5.0.4. Make sure your version of PHP meets or exceeds
|
||||
* those versions.
|
||||
*
|
||||
* @category Database
|
||||
* @package DB
|
||||
* @author Daniel Convissor <danielc@php.net>
|
||||
* @copyright 1997-2005 The PHP Group
|
||||
* @license http://www.php.net/license/3_0.txt PHP License 3.0
|
||||
* @version Release: @package_version@
|
||||
* @link http://pear.php.net/package/DB
|
||||
* @since Class not functional until Release 1.7.0
|
||||
*/
|
||||
class DB_msql extends DB_common
|
||||
{
|
||||
// {{{ properties
|
||||
|
||||
/**
|
||||
* The DB driver type (mysql, oci8, odbc, etc.)
|
||||
* @var string
|
||||
*/
|
||||
var $phptype = 'msql';
|
||||
|
||||
/**
|
||||
* The database syntax variant to be used (db2, access, etc.), if any
|
||||
* @var string
|
||||
*/
|
||||
var $dbsyntax = 'msql';
|
||||
|
||||
/**
|
||||
* The capabilities of this DB implementation
|
||||
*
|
||||
* The 'new_link' element contains the PHP version that first provided
|
||||
* new_link support for this DBMS. Contains false if it's unsupported.
|
||||
*
|
||||
* Meaning of the 'limit' element:
|
||||
* + 'emulate' = emulate with fetch row by number
|
||||
* + 'alter' = alter the query
|
||||
* + false = skip rows
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
var $features = array(
|
||||
'limit' => 'emulate',
|
||||
'new_link' => false,
|
||||
'numrows' => true,
|
||||
'pconnect' => true,
|
||||
'prepare' => false,
|
||||
'ssl' => false,
|
||||
'transactions' => false,
|
||||
);
|
||||
|
||||
/**
|
||||
* A mapping of native error codes to DB error codes
|
||||
* @var array
|
||||
*/
|
||||
var $errorcode_map = array(
|
||||
);
|
||||
|
||||
/**
|
||||
* The raw database connection created by PHP
|
||||
* @var resource
|
||||
*/
|
||||
var $connection;
|
||||
|
||||
/**
|
||||
* The DSN information for connecting to a database
|
||||
* @var array
|
||||
*/
|
||||
var $dsn = array();
|
||||
|
||||
|
||||
/**
|
||||
* The query result resource created by PHP
|
||||
*
|
||||
* Used to make affectedRows() work. Only contains the result for
|
||||
* data manipulation queries. Contains false for other queries.
|
||||
*
|
||||
* @var resource
|
||||
* @access private
|
||||
*/
|
||||
var $_result;
|
||||
|
||||
|
||||
// }}}
|
||||
// {{{ constructor
|
||||
|
||||
/**
|
||||
* This constructor calls <kbd>$this->DB_common()</kbd>
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
function DB_msql()
|
||||
{
|
||||
$this->DB_common();
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ connect()
|
||||
|
||||
/**
|
||||
* Connect to the database server, log in and open the database
|
||||
*
|
||||
* Don't call this method directly. Use DB::connect() instead.
|
||||
*
|
||||
* Example of how to connect:
|
||||
* <code>
|
||||
* require_once 'DB.php';
|
||||
*
|
||||
* // $dsn = 'msql://hostname/dbname'; // use a TCP connection
|
||||
* $dsn = 'msql:///dbname'; // use a socket
|
||||
* $options = array(
|
||||
* 'portability' => DB_PORTABILITY_ALL,
|
||||
* );
|
||||
*
|
||||
* $db =& DB::connect($dsn, $options);
|
||||
* if (PEAR::isError($db)) {
|
||||
* die($db->getMessage());
|
||||
* }
|
||||
* </code>
|
||||
*
|
||||
* @param array $dsn the data source name
|
||||
* @param bool $persistent should the connection be persistent?
|
||||
*
|
||||
* @return int DB_OK on success. A DB_Error object on failure.
|
||||
*/
|
||||
function connect($dsn, $persistent = false)
|
||||
{
|
||||
if (!PEAR::loadExtension('msql')) {
|
||||
return $this->raiseError(DB_ERROR_EXTENSION_NOT_FOUND);
|
||||
}
|
||||
|
||||
$this->dsn = $dsn;
|
||||
if ($dsn['dbsyntax']) {
|
||||
$this->dbsyntax = $dsn['dbsyntax'];
|
||||
}
|
||||
|
||||
$params = array();
|
||||
if ($dsn['hostspec']) {
|
||||
$params[] = $dsn['port']
|
||||
? $dsn['hostspec'] . ',' . $dsn['port']
|
||||
: $dsn['hostspec'];
|
||||
}
|
||||
|
||||
$connect_function = $persistent ? 'msql_pconnect' : 'msql_connect';
|
||||
|
||||
$ini = ini_get('track_errors');
|
||||
$php_errormsg = '';
|
||||
if ($ini) {
|
||||
$this->connection = @call_user_func_array($connect_function,
|
||||
$params);
|
||||
} else {
|
||||
ini_set('track_errors', 1);
|
||||
$this->connection = @call_user_func_array($connect_function,
|
||||
$params);
|
||||
ini_set('track_errors', $ini);
|
||||
}
|
||||
|
||||
if (!$this->connection) {
|
||||
if (($err = @msql_error()) != '') {
|
||||
return $this->raiseError(DB_ERROR_CONNECT_FAILED,
|
||||
null, null, null,
|
||||
$err);
|
||||
} else {
|
||||
return $this->raiseError(DB_ERROR_CONNECT_FAILED,
|
||||
null, null, null,
|
||||
$php_errormsg);
|
||||
}
|
||||
}
|
||||
|
||||
if (!@msql_select_db($dsn['database'], $this->connection)) {
|
||||
return $this->msqlRaiseError();
|
||||
}
|
||||
return DB_OK;
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ disconnect()
|
||||
|
||||
/**
|
||||
* Disconnects from the database server
|
||||
*
|
||||
* @return bool TRUE on success, FALSE on failure
|
||||
*/
|
||||
function disconnect()
|
||||
{
|
||||
$ret = @msql_close($this->connection);
|
||||
$this->connection = null;
|
||||
return $ret;
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ simpleQuery()
|
||||
|
||||
/**
|
||||
* Sends a query to the database server
|
||||
*
|
||||
* @param string the SQL query string
|
||||
*
|
||||
* @return mixed + a PHP result resrouce for successful SELECT queries
|
||||
* + the DB_OK constant for other successful queries
|
||||
* + a DB_Error object on failure
|
||||
*/
|
||||
function simpleQuery($query)
|
||||
{
|
||||
$this->last_query = $query;
|
||||
$query = $this->modifyQuery($query);
|
||||
$result = @msql_query($query, $this->connection);
|
||||
if (!$result) {
|
||||
return $this->msqlRaiseError();
|
||||
}
|
||||
// Determine which queries that should return data, and which
|
||||
// should return an error code only.
|
||||
if (DB::isManip($query)) {
|
||||
$this->_result = $result;
|
||||
return DB_OK;
|
||||
} else {
|
||||
$this->_result = false;
|
||||
return $result;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// }}}
|
||||
// {{{ nextResult()
|
||||
|
||||
/**
|
||||
* Move the internal msql result pointer to the next available result
|
||||
*
|
||||
* @param a valid fbsql result resource
|
||||
*
|
||||
* @access public
|
||||
*
|
||||
* @return true if a result is available otherwise return false
|
||||
*/
|
||||
function nextResult($result)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ fetchInto()
|
||||
|
||||
/**
|
||||
* Places a row from the result set into the given array
|
||||
*
|
||||
* Formating of the array and the data therein are configurable.
|
||||
* See DB_result::fetchInto() for more information.
|
||||
*
|
||||
* This method is not meant to be called directly. Use
|
||||
* DB_result::fetchInto() instead. It can't be declared "protected"
|
||||
* because DB_result is a separate object.
|
||||
*
|
||||
* PHP's mSQL extension did weird things with NULL values prior to PHP
|
||||
* 4.3.11 and 5.0.4. Make sure your version of PHP meets or exceeds
|
||||
* those versions.
|
||||
*
|
||||
* @param resource $result the query result resource
|
||||
* @param array $arr the referenced array to put the data in
|
||||
* @param int $fetchmode how the resulting array should be indexed
|
||||
* @param int $rownum the row number to fetch (0 = first row)
|
||||
*
|
||||
* @return mixed DB_OK on success, NULL when the end of a result set is
|
||||
* reached or on failure
|
||||
*
|
||||
* @see DB_result::fetchInto()
|
||||
*/
|
||||
function fetchInto($result, &$arr, $fetchmode, $rownum = null)
|
||||
{
|
||||
if ($rownum !== null) {
|
||||
if (!@msql_data_seek($result, $rownum)) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
if ($fetchmode & DB_FETCHMODE_ASSOC) {
|
||||
$arr = @msql_fetch_array($result, MSQL_ASSOC);
|
||||
if ($this->options['portability'] & DB_PORTABILITY_LOWERCASE && $arr) {
|
||||
$arr = array_change_key_case($arr, CASE_LOWER);
|
||||
}
|
||||
} else {
|
||||
$arr = @msql_fetch_row($result);
|
||||
}
|
||||
if (!$arr) {
|
||||
return null;
|
||||
}
|
||||
if ($this->options['portability'] & DB_PORTABILITY_RTRIM) {
|
||||
$this->_rtrimArrayValues($arr);
|
||||
}
|
||||
if ($this->options['portability'] & DB_PORTABILITY_NULL_TO_EMPTY) {
|
||||
$this->_convertNullArrayValuesToEmpty($arr);
|
||||
}
|
||||
return DB_OK;
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ freeResult()
|
||||
|
||||
/**
|
||||
* Deletes the result set and frees the memory occupied by the result set
|
||||
*
|
||||
* This method is not meant to be called directly. Use
|
||||
* DB_result::free() instead. It can't be declared "protected"
|
||||
* because DB_result is a separate object.
|
||||
*
|
||||
* @param resource $result PHP's query result resource
|
||||
*
|
||||
* @return bool TRUE on success, FALSE if $result is invalid
|
||||
*
|
||||
* @see DB_result::free()
|
||||
*/
|
||||
function freeResult($result)
|
||||
{
|
||||
return @msql_free_result($result);
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ numCols()
|
||||
|
||||
/**
|
||||
* Gets the number of columns in a result set
|
||||
*
|
||||
* This method is not meant to be called directly. Use
|
||||
* DB_result::numCols() instead. It can't be declared "protected"
|
||||
* because DB_result is a separate object.
|
||||
*
|
||||
* @param resource $result PHP's query result resource
|
||||
*
|
||||
* @return int the number of columns. A DB_Error object on failure.
|
||||
*
|
||||
* @see DB_result::numCols()
|
||||
*/
|
||||
function numCols($result)
|
||||
{
|
||||
$cols = @msql_num_fields($result);
|
||||
if (!$cols) {
|
||||
return $this->msqlRaiseError();
|
||||
}
|
||||
return $cols;
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ numRows()
|
||||
|
||||
/**
|
||||
* Gets the number of rows in a result set
|
||||
*
|
||||
* This method is not meant to be called directly. Use
|
||||
* DB_result::numRows() instead. It can't be declared "protected"
|
||||
* because DB_result is a separate object.
|
||||
*
|
||||
* @param resource $result PHP's query result resource
|
||||
*
|
||||
* @return int the number of rows. A DB_Error object on failure.
|
||||
*
|
||||
* @see DB_result::numRows()
|
||||
*/
|
||||
function numRows($result)
|
||||
{
|
||||
$rows = @msql_num_rows($result);
|
||||
if ($rows === false) {
|
||||
return $this->msqlRaiseError();
|
||||
}
|
||||
return $rows;
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ affected()
|
||||
|
||||
/**
|
||||
* Determines the number of rows affected by a data maniuplation query
|
||||
*
|
||||
* 0 is returned for queries that don't manipulate data.
|
||||
*
|
||||
* @return int the number of rows. A DB_Error object on failure.
|
||||
*/
|
||||
function affectedRows()
|
||||
{
|
||||
if (!$this->_result) {
|
||||
return 0;
|
||||
}
|
||||
return msql_affected_rows($this->_result);
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ nextId()
|
||||
|
||||
/**
|
||||
* Returns the next free id in a sequence
|
||||
*
|
||||
* @param string $seq_name name of the sequence
|
||||
* @param boolean $ondemand when true, the seqence is automatically
|
||||
* created if it does not exist
|
||||
*
|
||||
* @return int the next id number in the sequence.
|
||||
* A DB_Error object on failure.
|
||||
*
|
||||
* @see DB_common::nextID(), DB_common::getSequenceName(),
|
||||
* DB_msql::createSequence(), DB_msql::dropSequence()
|
||||
*/
|
||||
function nextId($seq_name, $ondemand = true)
|
||||
{
|
||||
$seqname = $this->getSequenceName($seq_name);
|
||||
$repeat = false;
|
||||
do {
|
||||
$this->pushErrorHandling(PEAR_ERROR_RETURN);
|
||||
$result =& $this->query("SELECT _seq FROM ${seqname}");
|
||||
$this->popErrorHandling();
|
||||
if ($ondemand && DB::isError($result) &&
|
||||
$result->getCode() == DB_ERROR_NOSUCHTABLE) {
|
||||
$repeat = true;
|
||||
$this->pushErrorHandling(PEAR_ERROR_RETURN);
|
||||
$result = $this->createSequence($seq_name);
|
||||
$this->popErrorHandling();
|
||||
if (DB::isError($result)) {
|
||||
return $this->raiseError($result);
|
||||
}
|
||||
} else {
|
||||
$repeat = false;
|
||||
}
|
||||
} while ($repeat);
|
||||
if (DB::isError($result)) {
|
||||
return $this->raiseError($result);
|
||||
}
|
||||
$arr = $result->fetchRow(DB_FETCHMODE_ORDERED);
|
||||
$result->free();
|
||||
return $arr[0];
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ createSequence()
|
||||
|
||||
/**
|
||||
* Creates a new sequence
|
||||
*
|
||||
* Also creates a new table to associate the sequence with. Uses
|
||||
* a separate table to ensure portability with other drivers.
|
||||
*
|
||||
* @param string $seq_name name of the new sequence
|
||||
*
|
||||
* @return int DB_OK on success. A DB_Error object on failure.
|
||||
*
|
||||
* @see DB_common::createSequence(), DB_common::getSequenceName(),
|
||||
* DB_msql::nextID(), DB_msql::dropSequence()
|
||||
*/
|
||||
function createSequence($seq_name)
|
||||
{
|
||||
$seqname = $this->getSequenceName($seq_name);
|
||||
$res = $this->query('CREATE TABLE ' . $seqname
|
||||
. ' (id INTEGER NOT NULL)');
|
||||
if (DB::isError($res)) {
|
||||
return $res;
|
||||
}
|
||||
$res = $this->query("CREATE SEQUENCE ON ${seqname}");
|
||||
return $res;
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ dropSequence()
|
||||
|
||||
/**
|
||||
* Deletes a sequence
|
||||
*
|
||||
* @param string $seq_name name of the sequence to be deleted
|
||||
*
|
||||
* @return int DB_OK on success. A DB_Error object on failure.
|
||||
*
|
||||
* @see DB_common::dropSequence(), DB_common::getSequenceName(),
|
||||
* DB_msql::nextID(), DB_msql::createSequence()
|
||||
*/
|
||||
function dropSequence($seq_name)
|
||||
{
|
||||
return $this->query('DROP TABLE ' . $this->getSequenceName($seq_name));
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ quoteIdentifier()
|
||||
|
||||
/**
|
||||
* mSQL does not support delimited identifiers
|
||||
*
|
||||
* @param string $str the identifier name to be quoted
|
||||
*
|
||||
* @return object a DB_Error object
|
||||
*
|
||||
* @see DB_common::quoteIdentifier()
|
||||
* @since Method available since Release 1.7.0
|
||||
*/
|
||||
function quoteIdentifier($str)
|
||||
{
|
||||
return $this->raiseError(DB_ERROR_UNSUPPORTED);
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ escapeSimple()
|
||||
|
||||
/**
|
||||
* Escapes a string according to the current DBMS's standards
|
||||
*
|
||||
* @param string $str the string to be escaped
|
||||
*
|
||||
* @return string the escaped string
|
||||
*
|
||||
* @see DB_common::quoteSmart()
|
||||
* @since Method available since Release 1.7.0
|
||||
*/
|
||||
function escapeSimple($str)
|
||||
{
|
||||
return addslashes($str);
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ msqlRaiseError()
|
||||
|
||||
/**
|
||||
* Produces a DB_Error object regarding the current problem
|
||||
*
|
||||
* @param int $errno if the error is being manually raised pass a
|
||||
* DB_ERROR* constant here. If this isn't passed
|
||||
* the error information gathered from the DBMS.
|
||||
*
|
||||
* @return object the DB_Error object
|
||||
*
|
||||
* @see DB_common::raiseError(),
|
||||
* DB_msql::errorNative(), DB_msql::errorCode()
|
||||
*/
|
||||
function msqlRaiseError($errno = null)
|
||||
{
|
||||
$native = $this->errorNative();
|
||||
if ($errno === null) {
|
||||
$errno = $this->errorCode($native);
|
||||
}
|
||||
return $this->raiseError($errno, null, null, null, $native);
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ errorNative()
|
||||
|
||||
/**
|
||||
* Gets the DBMS' native error message produced by the last query
|
||||
*
|
||||
* @return string the DBMS' error message
|
||||
*/
|
||||
function errorNative()
|
||||
{
|
||||
return @msql_error();
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ errorCode()
|
||||
|
||||
/**
|
||||
* Determines PEAR::DB error code from the database's text error message
|
||||
*
|
||||
* @param string $errormsg the error message returned from the database
|
||||
*
|
||||
* @return integer the error number from a DB_ERROR* constant
|
||||
*/
|
||||
function errorCode($errormsg)
|
||||
{
|
||||
static $error_regexps;
|
||||
if (!isset($error_regexps)) {
|
||||
$error_regexps = array(
|
||||
'/^Access to database denied/i'
|
||||
=> DB_ERROR_ACCESS_VIOLATION,
|
||||
'/^Bad index name/i'
|
||||
=> DB_ERROR_ALREADY_EXISTS,
|
||||
'/^Bad order field/i'
|
||||
=> DB_ERROR_SYNTAX,
|
||||
'/^Bad type for comparison/i'
|
||||
=> DB_ERROR_SYNTAX,
|
||||
'/^Can\'t perform LIKE on/i'
|
||||
=> DB_ERROR_SYNTAX,
|
||||
'/^Can\'t use TEXT fields in LIKE comparison/i'
|
||||
=> DB_ERROR_SYNTAX,
|
||||
'/^Couldn\'t create temporary table/i'
|
||||
=> DB_ERROR_CANNOT_CREATE,
|
||||
'/^Error creating table file/i'
|
||||
=> DB_ERROR_CANNOT_CREATE,
|
||||
'/^Field .* cannot be null$/i'
|
||||
=> DB_ERROR_CONSTRAINT_NOT_NULL,
|
||||
'/^Index (field|condition) .* cannot be null$/i'
|
||||
=> DB_ERROR_SYNTAX,
|
||||
'/^Invalid date format/i'
|
||||
=> DB_ERROR_INVALID_DATE,
|
||||
'/^Invalid time format/i'
|
||||
=> DB_ERROR_INVALID,
|
||||
'/^Literal value for .* is wrong type$/i'
|
||||
=> DB_ERROR_INVALID_NUMBER,
|
||||
'/^No Database Selected/i'
|
||||
=> DB_ERROR_NODBSELECTED,
|
||||
'/^No value specified for field/i'
|
||||
=> DB_ERROR_VALUE_COUNT_ON_ROW,
|
||||
'/^Non unique value for unique index/i'
|
||||
=> DB_ERROR_CONSTRAINT,
|
||||
'/^Out of memory for temporary table/i'
|
||||
=> DB_ERROR_CANNOT_CREATE,
|
||||
'/^Permission denied/i'
|
||||
=> DB_ERROR_ACCESS_VIOLATION,
|
||||
'/^Reference to un-selected table/i'
|
||||
=> DB_ERROR_SYNTAX,
|
||||
'/^syntax error/i'
|
||||
=> DB_ERROR_SYNTAX,
|
||||
'/^Table .* exists$/i'
|
||||
=> DB_ERROR_ALREADY_EXISTS,
|
||||
'/^Unknown database/i'
|
||||
=> DB_ERROR_NOSUCHDB,
|
||||
'/^Unknown field/i'
|
||||
=> DB_ERROR_NOSUCHFIELD,
|
||||
'/^Unknown (index|system variable)/i'
|
||||
=> DB_ERROR_NOT_FOUND,
|
||||
'/^Unknown table/i'
|
||||
=> DB_ERROR_NOSUCHTABLE,
|
||||
'/^Unqualified field/i'
|
||||
=> DB_ERROR_SYNTAX,
|
||||
);
|
||||
}
|
||||
|
||||
foreach ($error_regexps as $regexp => $code) {
|
||||
if (preg_match($regexp, $errormsg)) {
|
||||
return $code;
|
||||
}
|
||||
}
|
||||
return DB_ERROR;
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ tableInfo()
|
||||
|
||||
/**
|
||||
* Returns information about a table or a result set
|
||||
*
|
||||
* @param object|string $result DB_result object from a query or a
|
||||
* string containing the name of a table.
|
||||
* While this also accepts a query result
|
||||
* resource identifier, this behavior is
|
||||
* deprecated.
|
||||
* @param int $mode a valid tableInfo mode
|
||||
*
|
||||
* @return array an associative array with the information requested.
|
||||
* A DB_Error object on failure.
|
||||
*
|
||||
* @see DB_common::setOption()
|
||||
*/
|
||||
function tableInfo($result, $mode = null)
|
||||
{
|
||||
if (is_string($result)) {
|
||||
/*
|
||||
* Probably received a table name.
|
||||
* Create a result resource identifier.
|
||||
*/
|
||||
$id = @msql_query("SELECT * FROM $result",
|
||||
$this->connection);
|
||||
$got_string = true;
|
||||
} elseif (isset($result->result)) {
|
||||
/*
|
||||
* Probably received a result object.
|
||||
* Extract the result resource identifier.
|
||||
*/
|
||||
$id = $result->result;
|
||||
$got_string = false;
|
||||
} else {
|
||||
/*
|
||||
* Probably received a result resource identifier.
|
||||
* Copy it.
|
||||
* Deprecated. Here for compatibility only.
|
||||
*/
|
||||
$id = $result;
|
||||
$got_string = false;
|
||||
}
|
||||
|
||||
if (!is_resource($id)) {
|
||||
return $this->raiseError(DB_ERROR_NEED_MORE_DATA);
|
||||
}
|
||||
|
||||
if ($this->options['portability'] & DB_PORTABILITY_LOWERCASE) {
|
||||
$case_func = 'strtolower';
|
||||
} else {
|
||||
$case_func = 'strval';
|
||||
}
|
||||
|
||||
$count = @msql_num_fields($id);
|
||||
$res = array();
|
||||
|
||||
if ($mode) {
|
||||
$res['num_fields'] = $count;
|
||||
}
|
||||
|
||||
for ($i = 0; $i < $count; $i++) {
|
||||
$tmp = @msql_fetch_field($id);
|
||||
|
||||
$flags = '';
|
||||
if ($tmp->not_null) {
|
||||
$flags .= 'not_null ';
|
||||
}
|
||||
if ($tmp->unique) {
|
||||
$flags .= 'unique_key ';
|
||||
}
|
||||
$flags = trim($flags);
|
||||
|
||||
$res[$i] = array(
|
||||
'table' => $case_func($tmp->table),
|
||||
'name' => $case_func($tmp->name),
|
||||
'type' => $tmp->type,
|
||||
'len' => msql_field_len($id, $i),
|
||||
'flags' => $flags,
|
||||
);
|
||||
|
||||
if ($mode & DB_TABLEINFO_ORDER) {
|
||||
$res['order'][$res[$i]['name']] = $i;
|
||||
}
|
||||
if ($mode & DB_TABLEINFO_ORDERTABLE) {
|
||||
$res['ordertable'][$res[$i]['table']][$res[$i]['name']] = $i;
|
||||
}
|
||||
}
|
||||
|
||||
// free the result only if we were called on a table
|
||||
if ($got_string) {
|
||||
@msql_free_result($id);
|
||||
}
|
||||
return $res;
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ getSpecialQuery()
|
||||
|
||||
/**
|
||||
* Obtain a list of a given type of objects
|
||||
*
|
||||
* @param string $type the kind of objects you want to retrieve
|
||||
*
|
||||
* @return array the array containing the list of objects requested
|
||||
*
|
||||
* @access protected
|
||||
* @see DB_common::getListOf()
|
||||
*/
|
||||
function getSpecialQuery($type)
|
||||
{
|
||||
switch ($type) {
|
||||
case 'databases':
|
||||
$id = @msql_list_dbs($this->connection);
|
||||
break;
|
||||
case 'tables':
|
||||
$id = @msql_list_tables($this->dsn['database'],
|
||||
$this->connection);
|
||||
break;
|
||||
default:
|
||||
return null;
|
||||
}
|
||||
if (!$id) {
|
||||
return $this->msqlRaiseError();
|
||||
}
|
||||
$out = array();
|
||||
while ($row = @msql_fetch_row($id)) {
|
||||
$out[] = $row[0];
|
||||
}
|
||||
return $out;
|
||||
}
|
||||
|
||||
// }}}
|
||||
|
||||
}
|
||||
|
||||
/*
|
||||
* Local variables:
|
||||
* tab-width: 4
|
||||
* c-basic-offset: 4
|
||||
* End:
|
||||
*/
|
||||
|
||||
?>
|
||||
914
include/pear/DB/mssql.php
Normal file
914
include/pear/DB/mssql.php
Normal file
@@ -0,0 +1,914 @@
|
||||
<?php
|
||||
|
||||
/* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4: */
|
||||
|
||||
/**
|
||||
* The PEAR DB driver for PHP's mssql extension
|
||||
* for interacting with Microsoft SQL Server databases
|
||||
*
|
||||
* 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 Database
|
||||
* @package DB
|
||||
* @author Sterling Hughes <sterling@php.net>
|
||||
* @author Daniel Convissor <danielc@php.net>
|
||||
* @copyright 1997-2005 The PHP Group
|
||||
* @license http://www.php.net/license/3_0.txt PHP License 3.0
|
||||
* @version CVS: $Id: mssql.php,v 1.83 2005/03/07 18:24:51 danielc Exp $
|
||||
* @link http://pear.php.net/package/DB
|
||||
*/
|
||||
|
||||
/**
|
||||
* Obtain the DB_common class so it can be extended from
|
||||
*/
|
||||
require_once 'DB/common.php';
|
||||
|
||||
/**
|
||||
* The methods PEAR DB uses to interact with PHP's mssql extension
|
||||
* for interacting with Microsoft SQL Server databases
|
||||
*
|
||||
* These methods overload the ones declared in DB_common.
|
||||
*
|
||||
* @category Database
|
||||
* @package DB
|
||||
* @author Sterling Hughes <sterling@php.net>
|
||||
* @author Daniel Convissor <danielc@php.net>
|
||||
* @copyright 1997-2005 The PHP Group
|
||||
* @license http://www.php.net/license/3_0.txt PHP License 3.0
|
||||
* @version Release: @package_version@
|
||||
* @link http://pear.php.net/package/DB
|
||||
*/
|
||||
class DB_mssql extends DB_common
|
||||
{
|
||||
// {{{ properties
|
||||
|
||||
/**
|
||||
* The DB driver type (mysql, oci8, odbc, etc.)
|
||||
* @var string
|
||||
*/
|
||||
var $phptype = 'mssql';
|
||||
|
||||
/**
|
||||
* The database syntax variant to be used (db2, access, etc.), if any
|
||||
* @var string
|
||||
*/
|
||||
var $dbsyntax = 'mssql';
|
||||
|
||||
/**
|
||||
* The capabilities of this DB implementation
|
||||
*
|
||||
* The 'new_link' element contains the PHP version that first provided
|
||||
* new_link support for this DBMS. Contains false if it's unsupported.
|
||||
*
|
||||
* Meaning of the 'limit' element:
|
||||
* + 'emulate' = emulate with fetch row by number
|
||||
* + 'alter' = alter the query
|
||||
* + false = skip rows
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
var $features = array(
|
||||
'limit' => 'emulate',
|
||||
'new_link' => false,
|
||||
'numrows' => true,
|
||||
'pconnect' => true,
|
||||
'prepare' => false,
|
||||
'ssl' => false,
|
||||
'transactions' => true,
|
||||
);
|
||||
|
||||
/**
|
||||
* A mapping of native error codes to DB error codes
|
||||
* @var array
|
||||
*/
|
||||
// XXX Add here error codes ie: 'S100E' => DB_ERROR_SYNTAX
|
||||
var $errorcode_map = array(
|
||||
110 => DB_ERROR_VALUE_COUNT_ON_ROW,
|
||||
155 => DB_ERROR_NOSUCHFIELD,
|
||||
170 => DB_ERROR_SYNTAX,
|
||||
207 => DB_ERROR_NOSUCHFIELD,
|
||||
208 => DB_ERROR_NOSUCHTABLE,
|
||||
245 => DB_ERROR_INVALID_NUMBER,
|
||||
515 => DB_ERROR_CONSTRAINT_NOT_NULL,
|
||||
547 => DB_ERROR_CONSTRAINT,
|
||||
1913 => DB_ERROR_ALREADY_EXISTS,
|
||||
2627 => DB_ERROR_CONSTRAINT,
|
||||
2714 => DB_ERROR_ALREADY_EXISTS,
|
||||
3701 => DB_ERROR_NOSUCHTABLE,
|
||||
8134 => DB_ERROR_DIVZERO,
|
||||
);
|
||||
|
||||
/**
|
||||
* The raw database connection created by PHP
|
||||
* @var resource
|
||||
*/
|
||||
var $connection;
|
||||
|
||||
/**
|
||||
* The DSN information for connecting to a database
|
||||
* @var array
|
||||
*/
|
||||
var $dsn = array();
|
||||
|
||||
|
||||
/**
|
||||
* Should data manipulation queries be committed automatically?
|
||||
* @var bool
|
||||
* @access private
|
||||
*/
|
||||
var $autocommit = true;
|
||||
|
||||
/**
|
||||
* The quantity of transactions begun
|
||||
*
|
||||
* {@internal While this is private, it can't actually be designated
|
||||
* private in PHP 5 because it is directly accessed in the test suite.}}
|
||||
*
|
||||
* @var integer
|
||||
* @access private
|
||||
*/
|
||||
var $transaction_opcount = 0;
|
||||
|
||||
/**
|
||||
* The database specified in the DSN
|
||||
*
|
||||
* It's a fix to allow calls to different databases in the same script.
|
||||
*
|
||||
* @var string
|
||||
* @access private
|
||||
*/
|
||||
var $_db = null;
|
||||
|
||||
|
||||
// }}}
|
||||
// {{{ constructor
|
||||
|
||||
/**
|
||||
* This constructor calls <kbd>$this->DB_common()</kbd>
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
function DB_mssql()
|
||||
{
|
||||
$this->DB_common();
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ connect()
|
||||
|
||||
/**
|
||||
* Connect to the database server, log in and open the database
|
||||
*
|
||||
* Don't call this method directly. Use DB::connect() instead.
|
||||
*
|
||||
* @param array $dsn the data source name
|
||||
* @param bool $persistent should the connection be persistent?
|
||||
*
|
||||
* @return int DB_OK on success. A DB_Error object on failure.
|
||||
*/
|
||||
function connect($dsn, $persistent = false)
|
||||
{
|
||||
if (!PEAR::loadExtension('mssql') && !PEAR::loadExtension('sybase')
|
||||
&& !PEAR::loadExtension('sybase_ct'))
|
||||
{
|
||||
return $this->raiseError(DB_ERROR_EXTENSION_NOT_FOUND);
|
||||
}
|
||||
|
||||
$this->dsn = $dsn;
|
||||
if ($dsn['dbsyntax']) {
|
||||
$this->dbsyntax = $dsn['dbsyntax'];
|
||||
}
|
||||
|
||||
$params = array(
|
||||
$dsn['hostspec'] ? $dsn['hostspec'] : 'localhost',
|
||||
$dsn['username'] ? $dsn['username'] : null,
|
||||
$dsn['password'] ? $dsn['password'] : null,
|
||||
);
|
||||
if ($dsn['port']) {
|
||||
$params[0] .= ((substr(PHP_OS, 0, 3) == 'WIN') ? ',' : ':')
|
||||
. $dsn['port'];
|
||||
}
|
||||
|
||||
$connect_function = $persistent ? 'mssql_pconnect' : 'mssql_connect';
|
||||
|
||||
$this->connection = @call_user_func_array($connect_function, $params);
|
||||
|
||||
if (!$this->connection) {
|
||||
return $this->raiseError(DB_ERROR_CONNECT_FAILED,
|
||||
null, null, null,
|
||||
@mssql_get_last_message());
|
||||
}
|
||||
if ($dsn['database']) {
|
||||
if (!@mssql_select_db($dsn['database'], $this->connection)) {
|
||||
return $this->raiseError(DB_ERROR_NODBSELECTED,
|
||||
null, null, null,
|
||||
@mssql_get_last_message());
|
||||
}
|
||||
$this->_db = $dsn['database'];
|
||||
}
|
||||
return DB_OK;
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ disconnect()
|
||||
|
||||
/**
|
||||
* Disconnects from the database server
|
||||
*
|
||||
* @return bool TRUE on success, FALSE on failure
|
||||
*/
|
||||
function disconnect()
|
||||
{
|
||||
$ret = @mssql_close($this->connection);
|
||||
$this->connection = null;
|
||||
return $ret;
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ simpleQuery()
|
||||
|
||||
/**
|
||||
* Sends a query to the database server
|
||||
*
|
||||
* @param string the SQL query string
|
||||
*
|
||||
* @return mixed + a PHP result resrouce for successful SELECT queries
|
||||
* + the DB_OK constant for other successful queries
|
||||
* + a DB_Error object on failure
|
||||
*/
|
||||
function simpleQuery($query)
|
||||
{
|
||||
$ismanip = DB::isManip($query);
|
||||
$this->last_query = $query;
|
||||
if (!@mssql_select_db($this->_db, $this->connection)) {
|
||||
return $this->mssqlRaiseError(DB_ERROR_NODBSELECTED);
|
||||
}
|
||||
$query = $this->modifyQuery($query);
|
||||
if (!$this->autocommit && $ismanip) {
|
||||
if ($this->transaction_opcount == 0) {
|
||||
$result = @mssql_query('BEGIN TRAN', $this->connection);
|
||||
if (!$result) {
|
||||
return $this->mssqlRaiseError();
|
||||
}
|
||||
}
|
||||
$this->transaction_opcount++;
|
||||
}
|
||||
$result = @mssql_query($query, $this->connection);
|
||||
if (!$result) {
|
||||
return $this->mssqlRaiseError();
|
||||
}
|
||||
// Determine which queries that should return data, and which
|
||||
// should return an error code only.
|
||||
return $ismanip ? DB_OK : $result;
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ nextResult()
|
||||
|
||||
/**
|
||||
* Move the internal mssql result pointer to the next available result
|
||||
*
|
||||
* @param a valid fbsql result resource
|
||||
*
|
||||
* @access public
|
||||
*
|
||||
* @return true if a result is available otherwise return false
|
||||
*/
|
||||
function nextResult($result)
|
||||
{
|
||||
return @mssql_next_result($result);
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ fetchInto()
|
||||
|
||||
/**
|
||||
* Places a row from the result set into the given array
|
||||
*
|
||||
* Formating of the array and the data therein are configurable.
|
||||
* See DB_result::fetchInto() for more information.
|
||||
*
|
||||
* This method is not meant to be called directly. Use
|
||||
* DB_result::fetchInto() instead. It can't be declared "protected"
|
||||
* because DB_result is a separate object.
|
||||
*
|
||||
* @param resource $result the query result resource
|
||||
* @param array $arr the referenced array to put the data in
|
||||
* @param int $fetchmode how the resulting array should be indexed
|
||||
* @param int $rownum the row number to fetch (0 = first row)
|
||||
*
|
||||
* @return mixed DB_OK on success, NULL when the end of a result set is
|
||||
* reached or on failure
|
||||
*
|
||||
* @see DB_result::fetchInto()
|
||||
*/
|
||||
function fetchInto($result, &$arr, $fetchmode, $rownum = null)
|
||||
{
|
||||
if ($rownum !== null) {
|
||||
if (!@mssql_data_seek($result, $rownum)) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
if ($fetchmode & DB_FETCHMODE_ASSOC) {
|
||||
$arr = @mssql_fetch_array($result, MSSQL_ASSOC);
|
||||
if ($this->options['portability'] & DB_PORTABILITY_LOWERCASE && $arr) {
|
||||
$arr = array_change_key_case($arr, CASE_LOWER);
|
||||
}
|
||||
} else {
|
||||
$arr = @mssql_fetch_row($result);
|
||||
}
|
||||
if (!$arr) {
|
||||
return null;
|
||||
}
|
||||
if ($this->options['portability'] & DB_PORTABILITY_RTRIM) {
|
||||
$this->_rtrimArrayValues($arr);
|
||||
}
|
||||
if ($this->options['portability'] & DB_PORTABILITY_NULL_TO_EMPTY) {
|
||||
$this->_convertNullArrayValuesToEmpty($arr);
|
||||
}
|
||||
return DB_OK;
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ freeResult()
|
||||
|
||||
/**
|
||||
* Deletes the result set and frees the memory occupied by the result set
|
||||
*
|
||||
* This method is not meant to be called directly. Use
|
||||
* DB_result::free() instead. It can't be declared "protected"
|
||||
* because DB_result is a separate object.
|
||||
*
|
||||
* @param resource $result PHP's query result resource
|
||||
*
|
||||
* @return bool TRUE on success, FALSE if $result is invalid
|
||||
*
|
||||
* @see DB_result::free()
|
||||
*/
|
||||
function freeResult($result)
|
||||
{
|
||||
return @mssql_free_result($result);
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ numCols()
|
||||
|
||||
/**
|
||||
* Gets the number of columns in a result set
|
||||
*
|
||||
* This method is not meant to be called directly. Use
|
||||
* DB_result::numCols() instead. It can't be declared "protected"
|
||||
* because DB_result is a separate object.
|
||||
*
|
||||
* @param resource $result PHP's query result resource
|
||||
*
|
||||
* @return int the number of columns. A DB_Error object on failure.
|
||||
*
|
||||
* @see DB_result::numCols()
|
||||
*/
|
||||
function numCols($result)
|
||||
{
|
||||
$cols = @mssql_num_fields($result);
|
||||
if (!$cols) {
|
||||
return $this->mssqlRaiseError();
|
||||
}
|
||||
return $cols;
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ numRows()
|
||||
|
||||
/**
|
||||
* Gets the number of rows in a result set
|
||||
*
|
||||
* This method is not meant to be called directly. Use
|
||||
* DB_result::numRows() instead. It can't be declared "protected"
|
||||
* because DB_result is a separate object.
|
||||
*
|
||||
* @param resource $result PHP's query result resource
|
||||
*
|
||||
* @return int the number of rows. A DB_Error object on failure.
|
||||
*
|
||||
* @see DB_result::numRows()
|
||||
*/
|
||||
function numRows($result)
|
||||
{
|
||||
$rows = @mssql_num_rows($result);
|
||||
if ($rows === false) {
|
||||
return $this->mssqlRaiseError();
|
||||
}
|
||||
return $rows;
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ autoCommit()
|
||||
|
||||
/**
|
||||
* Enables or disables automatic commits
|
||||
*
|
||||
* @param bool $onoff true turns it on, false turns it off
|
||||
*
|
||||
* @return int DB_OK on success. A DB_Error object if the driver
|
||||
* doesn't support auto-committing transactions.
|
||||
*/
|
||||
function autoCommit($onoff = false)
|
||||
{
|
||||
// XXX if $this->transaction_opcount > 0, we should probably
|
||||
// issue a warning here.
|
||||
$this->autocommit = $onoff ? true : false;
|
||||
return DB_OK;
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ commit()
|
||||
|
||||
/**
|
||||
* Commits the current transaction
|
||||
*
|
||||
* @return int DB_OK on success. A DB_Error object on failure.
|
||||
*/
|
||||
function commit()
|
||||
{
|
||||
if ($this->transaction_opcount > 0) {
|
||||
if (!@mssql_select_db($this->_db, $this->connection)) {
|
||||
return $this->mssqlRaiseError(DB_ERROR_NODBSELECTED);
|
||||
}
|
||||
$result = @mssql_query('COMMIT TRAN', $this->connection);
|
||||
$this->transaction_opcount = 0;
|
||||
if (!$result) {
|
||||
return $this->mssqlRaiseError();
|
||||
}
|
||||
}
|
||||
return DB_OK;
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ rollback()
|
||||
|
||||
/**
|
||||
* Reverts the current transaction
|
||||
*
|
||||
* @return int DB_OK on success. A DB_Error object on failure.
|
||||
*/
|
||||
function rollback()
|
||||
{
|
||||
if ($this->transaction_opcount > 0) {
|
||||
if (!@mssql_select_db($this->_db, $this->connection)) {
|
||||
return $this->mssqlRaiseError(DB_ERROR_NODBSELECTED);
|
||||
}
|
||||
$result = @mssql_query('ROLLBACK TRAN', $this->connection);
|
||||
$this->transaction_opcount = 0;
|
||||
if (!$result) {
|
||||
return $this->mssqlRaiseError();
|
||||
}
|
||||
}
|
||||
return DB_OK;
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ affectedRows()
|
||||
|
||||
/**
|
||||
* Determines the number of rows affected by a data maniuplation query
|
||||
*
|
||||
* 0 is returned for queries that don't manipulate data.
|
||||
*
|
||||
* @return int the number of rows. A DB_Error object on failure.
|
||||
*/
|
||||
function affectedRows()
|
||||
{
|
||||
if (DB::isManip($this->last_query)) {
|
||||
$res = @mssql_query('select @@rowcount', $this->connection);
|
||||
if (!$res) {
|
||||
return $this->mssqlRaiseError();
|
||||
}
|
||||
$ar = @mssql_fetch_row($res);
|
||||
if (!$ar) {
|
||||
$result = 0;
|
||||
} else {
|
||||
@mssql_free_result($res);
|
||||
$result = $ar[0];
|
||||
}
|
||||
} else {
|
||||
$result = 0;
|
||||
}
|
||||
return $result;
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ nextId()
|
||||
|
||||
/**
|
||||
* Returns the next free id in a sequence
|
||||
*
|
||||
* @param string $seq_name name of the sequence
|
||||
* @param boolean $ondemand when true, the seqence is automatically
|
||||
* created if it does not exist
|
||||
*
|
||||
* @return int the next id number in the sequence.
|
||||
* A DB_Error object on failure.
|
||||
*
|
||||
* @see DB_common::nextID(), DB_common::getSequenceName(),
|
||||
* DB_mssql::createSequence(), DB_mssql::dropSequence()
|
||||
*/
|
||||
function nextId($seq_name, $ondemand = true)
|
||||
{
|
||||
$seqname = $this->getSequenceName($seq_name);
|
||||
if (!@mssql_select_db($this->_db, $this->connection)) {
|
||||
return $this->mssqlRaiseError(DB_ERROR_NODBSELECTED);
|
||||
}
|
||||
$repeat = 0;
|
||||
do {
|
||||
$this->pushErrorHandling(PEAR_ERROR_RETURN);
|
||||
$result = $this->query("INSERT INTO $seqname (vapor) VALUES (0)");
|
||||
$this->popErrorHandling();
|
||||
if ($ondemand && DB::isError($result) &&
|
||||
($result->getCode() == DB_ERROR || $result->getCode() == DB_ERROR_NOSUCHTABLE))
|
||||
{
|
||||
$repeat = 1;
|
||||
$result = $this->createSequence($seq_name);
|
||||
if (DB::isError($result)) {
|
||||
return $this->raiseError($result);
|
||||
}
|
||||
} elseif (!DB::isError($result)) {
|
||||
$result =& $this->query("SELECT @@IDENTITY FROM $seqname");
|
||||
$repeat = 0;
|
||||
} else {
|
||||
$repeat = false;
|
||||
}
|
||||
} while ($repeat);
|
||||
if (DB::isError($result)) {
|
||||
return $this->raiseError($result);
|
||||
}
|
||||
$result = $result->fetchRow(DB_FETCHMODE_ORDERED);
|
||||
return $result[0];
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new sequence
|
||||
*
|
||||
* @param string $seq_name name of the new sequence
|
||||
*
|
||||
* @return int DB_OK on success. A DB_Error object on failure.
|
||||
*
|
||||
* @see DB_common::createSequence(), DB_common::getSequenceName(),
|
||||
* DB_mssql::nextID(), DB_mssql::dropSequence()
|
||||
*/
|
||||
function createSequence($seq_name)
|
||||
{
|
||||
return $this->query('CREATE TABLE '
|
||||
. $this->getSequenceName($seq_name)
|
||||
. ' ([id] [int] IDENTITY (1, 1) NOT NULL,'
|
||||
. ' [vapor] [int] NULL)');
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ dropSequence()
|
||||
|
||||
/**
|
||||
* Deletes a sequence
|
||||
*
|
||||
* @param string $seq_name name of the sequence to be deleted
|
||||
*
|
||||
* @return int DB_OK on success. A DB_Error object on failure.
|
||||
*
|
||||
* @see DB_common::dropSequence(), DB_common::getSequenceName(),
|
||||
* DB_mssql::nextID(), DB_mssql::createSequence()
|
||||
*/
|
||||
function dropSequence($seq_name)
|
||||
{
|
||||
return $this->query('DROP TABLE ' . $this->getSequenceName($seq_name));
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ quoteIdentifier()
|
||||
|
||||
/**
|
||||
* Quotes a string so it can be safely used as a table or column name
|
||||
*
|
||||
* @param string $str identifier name to be quoted
|
||||
*
|
||||
* @return string quoted identifier string
|
||||
*
|
||||
* @see DB_common::quoteIdentifier()
|
||||
* @since Method available since Release 1.6.0
|
||||
*/
|
||||
function quoteIdentifier($str)
|
||||
{
|
||||
return '[' . str_replace(']', ']]', $str) . ']';
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ mssqlRaiseError()
|
||||
|
||||
/**
|
||||
* Produces a DB_Error object regarding the current problem
|
||||
*
|
||||
* @param int $errno if the error is being manually raised pass a
|
||||
* DB_ERROR* constant here. If this isn't passed
|
||||
* the error information gathered from the DBMS.
|
||||
*
|
||||
* @return object the DB_Error object
|
||||
*
|
||||
* @see DB_common::raiseError(),
|
||||
* DB_mssql::errorNative(), DB_mssql::errorCode()
|
||||
*/
|
||||
function mssqlRaiseError($code = null)
|
||||
{
|
||||
$message = @mssql_get_last_message();
|
||||
if (!$code) {
|
||||
$code = $this->errorNative();
|
||||
}
|
||||
return $this->raiseError($this->errorCode($code, $message),
|
||||
null, null, null, "$code - $message");
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ errorNative()
|
||||
|
||||
/**
|
||||
* Gets the DBMS' native error code produced by the last query
|
||||
*
|
||||
* @return int the DBMS' error code
|
||||
*/
|
||||
function errorNative()
|
||||
{
|
||||
$res = @mssql_query('select @@ERROR as ErrorCode', $this->connection);
|
||||
if (!$res) {
|
||||
return DB_ERROR;
|
||||
}
|
||||
$row = @mssql_fetch_row($res);
|
||||
return $row[0];
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ errorCode()
|
||||
|
||||
/**
|
||||
* Determines PEAR::DB error code from mssql's native codes.
|
||||
*
|
||||
* If <var>$nativecode</var> isn't known yet, it will be looked up.
|
||||
*
|
||||
* @param mixed $nativecode mssql error code, if known
|
||||
* @return integer an error number from a DB error constant
|
||||
* @see errorNative()
|
||||
*/
|
||||
function errorCode($nativecode = null, $msg = '')
|
||||
{
|
||||
if (!$nativecode) {
|
||||
$nativecode = $this->errorNative();
|
||||
}
|
||||
if (isset($this->errorcode_map[$nativecode])) {
|
||||
if ($nativecode == 3701
|
||||
&& preg_match('/Cannot drop the index/i', $msg))
|
||||
{
|
||||
return DB_ERROR_NOT_FOUND;
|
||||
}
|
||||
return $this->errorcode_map[$nativecode];
|
||||
} else {
|
||||
return DB_ERROR;
|
||||
}
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ tableInfo()
|
||||
|
||||
/**
|
||||
* Returns information about a table or a result set
|
||||
*
|
||||
* NOTE: only supports 'table' and 'flags' if <var>$result</var>
|
||||
* is a table name.
|
||||
*
|
||||
* @param object|string $result DB_result object from a query or a
|
||||
* string containing the name of a table.
|
||||
* While this also accepts a query result
|
||||
* resource identifier, this behavior is
|
||||
* deprecated.
|
||||
* @param int $mode a valid tableInfo mode
|
||||
*
|
||||
* @return array an associative array with the information requested.
|
||||
* A DB_Error object on failure.
|
||||
*
|
||||
* @see DB_common::tableInfo()
|
||||
*/
|
||||
function tableInfo($result, $mode = null)
|
||||
{
|
||||
if (is_string($result)) {
|
||||
/*
|
||||
* Probably received a table name.
|
||||
* Create a result resource identifier.
|
||||
*/
|
||||
if (!@mssql_select_db($this->_db, $this->connection)) {
|
||||
return $this->mssqlRaiseError(DB_ERROR_NODBSELECTED);
|
||||
}
|
||||
$id = @mssql_query("SELECT * FROM $result WHERE 1=0",
|
||||
$this->connection);
|
||||
$got_string = true;
|
||||
} elseif (isset($result->result)) {
|
||||
/*
|
||||
* Probably received a result object.
|
||||
* Extract the result resource identifier.
|
||||
*/
|
||||
$id = $result->result;
|
||||
$got_string = false;
|
||||
} else {
|
||||
/*
|
||||
* Probably received a result resource identifier.
|
||||
* Copy it.
|
||||
* Deprecated. Here for compatibility only.
|
||||
*/
|
||||
$id = $result;
|
||||
$got_string = false;
|
||||
}
|
||||
|
||||
if (!is_resource($id)) {
|
||||
return $this->mssqlRaiseError(DB_ERROR_NEED_MORE_DATA);
|
||||
}
|
||||
|
||||
if ($this->options['portability'] & DB_PORTABILITY_LOWERCASE) {
|
||||
$case_func = 'strtolower';
|
||||
} else {
|
||||
$case_func = 'strval';
|
||||
}
|
||||
|
||||
$count = @mssql_num_fields($id);
|
||||
$res = array();
|
||||
|
||||
if ($mode) {
|
||||
$res['num_fields'] = $count;
|
||||
}
|
||||
|
||||
for ($i = 0; $i < $count; $i++) {
|
||||
$res[$i] = array(
|
||||
'table' => $got_string ? $case_func($result) : '',
|
||||
'name' => $case_func(@mssql_field_name($id, $i)),
|
||||
'type' => @mssql_field_type($id, $i),
|
||||
'len' => @mssql_field_length($id, $i),
|
||||
// We only support flags for table
|
||||
'flags' => $got_string
|
||||
? $this->_mssql_field_flags($result,
|
||||
@mssql_field_name($id, $i))
|
||||
: '',
|
||||
);
|
||||
if ($mode & DB_TABLEINFO_ORDER) {
|
||||
$res['order'][$res[$i]['name']] = $i;
|
||||
}
|
||||
if ($mode & DB_TABLEINFO_ORDERTABLE) {
|
||||
$res['ordertable'][$res[$i]['table']][$res[$i]['name']] = $i;
|
||||
}
|
||||
}
|
||||
|
||||
// free the result only if we were called on a table
|
||||
if ($got_string) {
|
||||
@mssql_free_result($id);
|
||||
}
|
||||
return $res;
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ _mssql_field_flags()
|
||||
|
||||
/**
|
||||
* Get a column's flags
|
||||
*
|
||||
* Supports "not_null", "primary_key",
|
||||
* "auto_increment" (mssql identity), "timestamp" (mssql timestamp),
|
||||
* "unique_key" (mssql unique index, unique check or primary_key) and
|
||||
* "multiple_key" (multikey index)
|
||||
*
|
||||
* mssql timestamp is NOT similar to the mysql timestamp so this is maybe
|
||||
* not useful at all - is the behaviour of mysql_field_flags that primary
|
||||
* keys are alway unique? is the interpretation of multiple_key correct?
|
||||
*
|
||||
* @param string $table the table name
|
||||
* @param string $column the field name
|
||||
*
|
||||
* @return string the flags
|
||||
*
|
||||
* @access private
|
||||
* @author Joern Barthel <j_barthel@web.de>
|
||||
*/
|
||||
function _mssql_field_flags($table, $column)
|
||||
{
|
||||
static $tableName = null;
|
||||
static $flags = array();
|
||||
|
||||
if ($table != $tableName) {
|
||||
|
||||
$flags = array();
|
||||
$tableName = $table;
|
||||
|
||||
// get unique and primary keys
|
||||
$res = $this->getAll("EXEC SP_HELPINDEX[$table]", DB_FETCHMODE_ASSOC);
|
||||
|
||||
foreach ($res as $val) {
|
||||
$keys = explode(', ', $val['index_keys']);
|
||||
|
||||
if (sizeof($keys) > 1) {
|
||||
foreach ($keys as $key) {
|
||||
$this->_add_flag($flags[$key], 'multiple_key');
|
||||
}
|
||||
}
|
||||
|
||||
if (strpos($val['index_description'], 'primary key')) {
|
||||
foreach ($keys as $key) {
|
||||
$this->_add_flag($flags[$key], 'primary_key');
|
||||
}
|
||||
} elseif (strpos($val['index_description'], 'unique')) {
|
||||
foreach ($keys as $key) {
|
||||
$this->_add_flag($flags[$key], 'unique_key');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// get auto_increment, not_null and timestamp
|
||||
$res = $this->getAll("EXEC SP_COLUMNS[$table]", DB_FETCHMODE_ASSOC);
|
||||
|
||||
foreach ($res as $val) {
|
||||
$val = array_change_key_case($val, CASE_LOWER);
|
||||
if ($val['nullable'] == '0') {
|
||||
$this->_add_flag($flags[$val['column_name']], 'not_null');
|
||||
}
|
||||
if (strpos($val['type_name'], 'identity')) {
|
||||
$this->_add_flag($flags[$val['column_name']], 'auto_increment');
|
||||
}
|
||||
if (strpos($val['type_name'], 'timestamp')) {
|
||||
$this->_add_flag($flags[$val['column_name']], 'timestamp');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (array_key_exists($column, $flags)) {
|
||||
return(implode(' ', $flags[$column]));
|
||||
}
|
||||
return '';
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ _add_flag()
|
||||
|
||||
/**
|
||||
* Adds a string to the flags array if the flag is not yet in there
|
||||
* - if there is no flag present the array is created
|
||||
*
|
||||
* @param array &$array the reference to the flag-array
|
||||
* @param string $value the flag value
|
||||
*
|
||||
* @return void
|
||||
*
|
||||
* @access private
|
||||
* @author Joern Barthel <j_barthel@web.de>
|
||||
*/
|
||||
function _add_flag(&$array, $value)
|
||||
{
|
||||
if (!is_array($array)) {
|
||||
$array = array($value);
|
||||
} elseif (!in_array($value, $array)) {
|
||||
array_push($array, $value);
|
||||
}
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ getSpecialQuery()
|
||||
|
||||
/**
|
||||
* Obtains the query string needed for listing a given type of objects
|
||||
*
|
||||
* @param string $type the kind of objects you want to retrieve
|
||||
*
|
||||
* @return string the SQL query string or null if the driver doesn't
|
||||
* support the object type requested
|
||||
*
|
||||
* @access protected
|
||||
* @see DB_common::getListOf()
|
||||
*/
|
||||
function getSpecialQuery($type)
|
||||
{
|
||||
switch ($type) {
|
||||
case 'tables':
|
||||
return "SELECT name FROM sysobjects WHERE type = 'U'"
|
||||
. ' ORDER BY name';
|
||||
case 'views':
|
||||
return "SELECT name FROM sysobjects WHERE type = 'V'";
|
||||
default:
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
// }}}
|
||||
}
|
||||
|
||||
/*
|
||||
* Local variables:
|
||||
* tab-width: 4
|
||||
* c-basic-offset: 4
|
||||
* End:
|
||||
*/
|
||||
|
||||
?>
|
||||
1034
include/pear/DB/mysql.php
Normal file
1034
include/pear/DB/mysql.php
Normal file
File diff suppressed because it is too large
Load Diff
1076
include/pear/DB/mysqli.php
Normal file
1076
include/pear/DB/mysqli.php
Normal file
File diff suppressed because it is too large
Load Diff
1117
include/pear/DB/oci8.php
Normal file
1117
include/pear/DB/oci8.php
Normal file
File diff suppressed because it is too large
Load Diff
883
include/pear/DB/odbc.php
Normal file
883
include/pear/DB/odbc.php
Normal file
@@ -0,0 +1,883 @@
|
||||
<?php
|
||||
|
||||
/* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4: */
|
||||
|
||||
/**
|
||||
* The PEAR DB driver for PHP's odbc extension
|
||||
* for interacting with databases via ODBC connections
|
||||
*
|
||||
* 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 Database
|
||||
* @package DB
|
||||
* @author Stig Bakken <ssb@php.net>
|
||||
* @author Daniel Convissor <danielc@php.net>
|
||||
* @copyright 1997-2005 The PHP Group
|
||||
* @license http://www.php.net/license/3_0.txt PHP License 3.0
|
||||
* @version CVS: $Id: odbc.php,v 1.78 2005/02/28 01:42:17 danielc Exp $
|
||||
* @link http://pear.php.net/package/DB
|
||||
*/
|
||||
|
||||
/**
|
||||
* Obtain the DB_common class so it can be extended from
|
||||
*/
|
||||
require_once 'DB/common.php';
|
||||
|
||||
/**
|
||||
* The methods PEAR DB uses to interact with PHP's odbc extension
|
||||
* for interacting with databases via ODBC connections
|
||||
*
|
||||
* These methods overload the ones declared in DB_common.
|
||||
*
|
||||
* More info on ODBC errors could be found here:
|
||||
* http://msdn.microsoft.com/library/default.asp?url=/library/en-us/trblsql/tr_err_odbc_5stz.asp
|
||||
*
|
||||
* @category Database
|
||||
* @package DB
|
||||
* @author Stig Bakken <ssb@php.net>
|
||||
* @author Daniel Convissor <danielc@php.net>
|
||||
* @copyright 1997-2005 The PHP Group
|
||||
* @license http://www.php.net/license/3_0.txt PHP License 3.0
|
||||
* @version Release: @package_version@
|
||||
* @link http://pear.php.net/package/DB
|
||||
*/
|
||||
class DB_odbc extends DB_common
|
||||
{
|
||||
// {{{ properties
|
||||
|
||||
/**
|
||||
* The DB driver type (mysql, oci8, odbc, etc.)
|
||||
* @var string
|
||||
*/
|
||||
var $phptype = 'odbc';
|
||||
|
||||
/**
|
||||
* The database syntax variant to be used (db2, access, etc.), if any
|
||||
* @var string
|
||||
*/
|
||||
var $dbsyntax = 'sql92';
|
||||
|
||||
/**
|
||||
* The capabilities of this DB implementation
|
||||
*
|
||||
* The 'new_link' element contains the PHP version that first provided
|
||||
* new_link support for this DBMS. Contains false if it's unsupported.
|
||||
*
|
||||
* Meaning of the 'limit' element:
|
||||
* + 'emulate' = emulate with fetch row by number
|
||||
* + 'alter' = alter the query
|
||||
* + false = skip rows
|
||||
*
|
||||
* NOTE: The feature set of the following drivers are different than
|
||||
* the default:
|
||||
* + solid: 'transactions' = true
|
||||
* + navision: 'limit' = false
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
var $features = array(
|
||||
'limit' => 'emulate',
|
||||
'new_link' => false,
|
||||
'numrows' => true,
|
||||
'pconnect' => true,
|
||||
'prepare' => false,
|
||||
'ssl' => false,
|
||||
'transactions' => false,
|
||||
);
|
||||
|
||||
/**
|
||||
* A mapping of native error codes to DB error codes
|
||||
* @var array
|
||||
*/
|
||||
var $errorcode_map = array(
|
||||
'01004' => DB_ERROR_TRUNCATED,
|
||||
'07001' => DB_ERROR_MISMATCH,
|
||||
'21S01' => DB_ERROR_VALUE_COUNT_ON_ROW,
|
||||
'21S02' => DB_ERROR_MISMATCH,
|
||||
'22001' => DB_ERROR_INVALID,
|
||||
'22003' => DB_ERROR_INVALID_NUMBER,
|
||||
'22005' => DB_ERROR_INVALID_NUMBER,
|
||||
'22008' => DB_ERROR_INVALID_DATE,
|
||||
'22012' => DB_ERROR_DIVZERO,
|
||||
'23000' => DB_ERROR_CONSTRAINT,
|
||||
'23502' => DB_ERROR_CONSTRAINT_NOT_NULL,
|
||||
'23503' => DB_ERROR_CONSTRAINT,
|
||||
'23504' => DB_ERROR_CONSTRAINT,
|
||||
'23505' => DB_ERROR_CONSTRAINT,
|
||||
'24000' => DB_ERROR_INVALID,
|
||||
'34000' => DB_ERROR_INVALID,
|
||||
'37000' => DB_ERROR_SYNTAX,
|
||||
'42000' => DB_ERROR_SYNTAX,
|
||||
'42601' => DB_ERROR_SYNTAX,
|
||||
'IM001' => DB_ERROR_UNSUPPORTED,
|
||||
'S0000' => DB_ERROR_NOSUCHTABLE,
|
||||
'S0001' => DB_ERROR_ALREADY_EXISTS,
|
||||
'S0002' => DB_ERROR_NOSUCHTABLE,
|
||||
'S0011' => DB_ERROR_ALREADY_EXISTS,
|
||||
'S0012' => DB_ERROR_NOT_FOUND,
|
||||
'S0021' => DB_ERROR_ALREADY_EXISTS,
|
||||
'S0022' => DB_ERROR_NOSUCHFIELD,
|
||||
'S1009' => DB_ERROR_INVALID,
|
||||
'S1090' => DB_ERROR_INVALID,
|
||||
'S1C00' => DB_ERROR_NOT_CAPABLE,
|
||||
);
|
||||
|
||||
/**
|
||||
* The raw database connection created by PHP
|
||||
* @var resource
|
||||
*/
|
||||
var $connection;
|
||||
|
||||
/**
|
||||
* The DSN information for connecting to a database
|
||||
* @var array
|
||||
*/
|
||||
var $dsn = array();
|
||||
|
||||
|
||||
/**
|
||||
* The number of rows affected by a data manipulation query
|
||||
* @var integer
|
||||
* @access private
|
||||
*/
|
||||
var $affected = 0;
|
||||
|
||||
|
||||
// }}}
|
||||
// {{{ constructor
|
||||
|
||||
/**
|
||||
* This constructor calls <kbd>$this->DB_common()</kbd>
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
function DB_odbc()
|
||||
{
|
||||
$this->DB_common();
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ connect()
|
||||
|
||||
/**
|
||||
* Connect to the database server, log in and open the database
|
||||
*
|
||||
* Don't call this method directly. Use DB::connect() instead.
|
||||
*
|
||||
* PEAR DB's odbc driver supports the following extra DSN options:
|
||||
* + cursor The type of cursor to be used for this connection.
|
||||
*
|
||||
* @param array $dsn the data source name
|
||||
* @param bool $persistent should the connection be persistent?
|
||||
*
|
||||
* @return int DB_OK on success. A DB_Error object on failure.
|
||||
*/
|
||||
function connect($dsn, $persistent = false)
|
||||
{
|
||||
if (!PEAR::loadExtension('odbc')) {
|
||||
return $this->raiseError(DB_ERROR_EXTENSION_NOT_FOUND);
|
||||
}
|
||||
|
||||
$this->dsn = $dsn;
|
||||
if ($dsn['dbsyntax']) {
|
||||
$this->dbsyntax = $dsn['dbsyntax'];
|
||||
}
|
||||
switch ($this->dbsyntax) {
|
||||
case 'access':
|
||||
case 'db2':
|
||||
case 'solid':
|
||||
$this->features['transactions'] = true;
|
||||
break;
|
||||
case 'navision':
|
||||
$this->features['limit'] = false;
|
||||
}
|
||||
|
||||
/*
|
||||
* This is hear for backwards compatibility. Should have been using
|
||||
* 'database' all along, but prior to 1.6.0RC3 'hostspec' was used.
|
||||
*/
|
||||
if ($dsn['database']) {
|
||||
$odbcdsn = $dsn['database'];
|
||||
} elseif ($dsn['hostspec']) {
|
||||
$odbcdsn = $dsn['hostspec'];
|
||||
} else {
|
||||
$odbcdsn = 'localhost';
|
||||
}
|
||||
|
||||
$connect_function = $persistent ? 'odbc_pconnect' : 'odbc_connect';
|
||||
|
||||
if (empty($dsn['cursor'])) {
|
||||
$this->connection = @$connect_function($odbcdsn, $dsn['username'],
|
||||
$dsn['password']);
|
||||
} else {
|
||||
$this->connection = @$connect_function($odbcdsn, $dsn['username'],
|
||||
$dsn['password'],
|
||||
$dsn['cursor']);
|
||||
}
|
||||
|
||||
if (!is_resource($this->connection)) {
|
||||
return $this->raiseError(DB_ERROR_CONNECT_FAILED,
|
||||
null, null, null,
|
||||
$this->errorNative());
|
||||
}
|
||||
return DB_OK;
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ disconnect()
|
||||
|
||||
/**
|
||||
* Disconnects from the database server
|
||||
*
|
||||
* @return bool TRUE on success, FALSE on failure
|
||||
*/
|
||||
function disconnect()
|
||||
{
|
||||
$err = @odbc_close($this->connection);
|
||||
$this->connection = null;
|
||||
return $err;
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ simpleQuery()
|
||||
|
||||
/**
|
||||
* Sends a query to the database server
|
||||
*
|
||||
* @param string the SQL query string
|
||||
*
|
||||
* @return mixed + a PHP result resrouce for successful SELECT queries
|
||||
* + the DB_OK constant for other successful queries
|
||||
* + a DB_Error object on failure
|
||||
*/
|
||||
function simpleQuery($query)
|
||||
{
|
||||
$this->last_query = $query;
|
||||
$query = $this->modifyQuery($query);
|
||||
$result = @odbc_exec($this->connection, $query);
|
||||
if (!$result) {
|
||||
return $this->odbcRaiseError(); // XXX ERRORMSG
|
||||
}
|
||||
// Determine which queries that should return data, and which
|
||||
// should return an error code only.
|
||||
if (DB::isManip($query)) {
|
||||
$this->affected = $result; // For affectedRows()
|
||||
return DB_OK;
|
||||
}
|
||||
$this->affected = 0;
|
||||
return $result;
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ nextResult()
|
||||
|
||||
/**
|
||||
* Move the internal odbc result pointer to the next available result
|
||||
*
|
||||
* @param a valid fbsql result resource
|
||||
*
|
||||
* @access public
|
||||
*
|
||||
* @return true if a result is available otherwise return false
|
||||
*/
|
||||
function nextResult($result)
|
||||
{
|
||||
return @odbc_next_result($result);
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ fetchInto()
|
||||
|
||||
/**
|
||||
* Places a row from the result set into the given array
|
||||
*
|
||||
* Formating of the array and the data therein are configurable.
|
||||
* See DB_result::fetchInto() for more information.
|
||||
*
|
||||
* This method is not meant to be called directly. Use
|
||||
* DB_result::fetchInto() instead. It can't be declared "protected"
|
||||
* because DB_result is a separate object.
|
||||
*
|
||||
* @param resource $result the query result resource
|
||||
* @param array $arr the referenced array to put the data in
|
||||
* @param int $fetchmode how the resulting array should be indexed
|
||||
* @param int $rownum the row number to fetch (0 = first row)
|
||||
*
|
||||
* @return mixed DB_OK on success, NULL when the end of a result set is
|
||||
* reached or on failure
|
||||
*
|
||||
* @see DB_result::fetchInto()
|
||||
*/
|
||||
function fetchInto($result, &$arr, $fetchmode, $rownum = null)
|
||||
{
|
||||
$arr = array();
|
||||
if ($rownum !== null) {
|
||||
$rownum++; // ODBC first row is 1
|
||||
if (version_compare(phpversion(), '4.2.0', 'ge')) {
|
||||
$cols = @odbc_fetch_into($result, $arr, $rownum);
|
||||
} else {
|
||||
$cols = @odbc_fetch_into($result, $rownum, $arr);
|
||||
}
|
||||
} else {
|
||||
$cols = @odbc_fetch_into($result, $arr);
|
||||
}
|
||||
if (!$cols) {
|
||||
return null;
|
||||
}
|
||||
if ($fetchmode !== DB_FETCHMODE_ORDERED) {
|
||||
for ($i = 0; $i < count($arr); $i++) {
|
||||
$colName = @odbc_field_name($result, $i+1);
|
||||
$a[$colName] = $arr[$i];
|
||||
}
|
||||
if ($this->options['portability'] & DB_PORTABILITY_LOWERCASE) {
|
||||
$a = array_change_key_case($a, CASE_LOWER);
|
||||
}
|
||||
$arr = $a;
|
||||
}
|
||||
if ($this->options['portability'] & DB_PORTABILITY_RTRIM) {
|
||||
$this->_rtrimArrayValues($arr);
|
||||
}
|
||||
if ($this->options['portability'] & DB_PORTABILITY_NULL_TO_EMPTY) {
|
||||
$this->_convertNullArrayValuesToEmpty($arr);
|
||||
}
|
||||
return DB_OK;
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ freeResult()
|
||||
|
||||
/**
|
||||
* Deletes the result set and frees the memory occupied by the result set
|
||||
*
|
||||
* This method is not meant to be called directly. Use
|
||||
* DB_result::free() instead. It can't be declared "protected"
|
||||
* because DB_result is a separate object.
|
||||
*
|
||||
* @param resource $result PHP's query result resource
|
||||
*
|
||||
* @return bool TRUE on success, FALSE if $result is invalid
|
||||
*
|
||||
* @see DB_result::free()
|
||||
*/
|
||||
function freeResult($result)
|
||||
{
|
||||
return @odbc_free_result($result);
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ numCols()
|
||||
|
||||
/**
|
||||
* Gets the number of columns in a result set
|
||||
*
|
||||
* This method is not meant to be called directly. Use
|
||||
* DB_result::numCols() instead. It can't be declared "protected"
|
||||
* because DB_result is a separate object.
|
||||
*
|
||||
* @param resource $result PHP's query result resource
|
||||
*
|
||||
* @return int the number of columns. A DB_Error object on failure.
|
||||
*
|
||||
* @see DB_result::numCols()
|
||||
*/
|
||||
function numCols($result)
|
||||
{
|
||||
$cols = @odbc_num_fields($result);
|
||||
if (!$cols) {
|
||||
return $this->odbcRaiseError();
|
||||
}
|
||||
return $cols;
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ affectedRows()
|
||||
|
||||
/**
|
||||
* Determines the number of rows affected by a data maniuplation query
|
||||
*
|
||||
* 0 is returned for queries that don't manipulate data.
|
||||
*
|
||||
* @return int the number of rows. A DB_Error object on failure.
|
||||
*/
|
||||
function affectedRows()
|
||||
{
|
||||
if (empty($this->affected)) { // In case of SELECT stms
|
||||
return 0;
|
||||
}
|
||||
$nrows = @odbc_num_rows($this->affected);
|
||||
if ($nrows == -1) {
|
||||
return $this->odbcRaiseError();
|
||||
}
|
||||
return $nrows;
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ numRows()
|
||||
|
||||
/**
|
||||
* Gets the number of rows in a result set
|
||||
*
|
||||
* Not all ODBC drivers support this functionality. If they don't
|
||||
* a DB_Error object for DB_ERROR_UNSUPPORTED is returned.
|
||||
*
|
||||
* This method is not meant to be called directly. Use
|
||||
* DB_result::numRows() instead. It can't be declared "protected"
|
||||
* because DB_result is a separate object.
|
||||
*
|
||||
* @param resource $result PHP's query result resource
|
||||
*
|
||||
* @return int the number of rows. A DB_Error object on failure.
|
||||
*
|
||||
* @see DB_result::numRows()
|
||||
*/
|
||||
function numRows($result)
|
||||
{
|
||||
$nrows = @odbc_num_rows($result);
|
||||
if ($nrows == -1) {
|
||||
return $this->odbcRaiseError(DB_ERROR_UNSUPPORTED);
|
||||
}
|
||||
if ($nrows === false) {
|
||||
return $this->odbcRaiseError();
|
||||
}
|
||||
return $nrows;
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ quoteIdentifier()
|
||||
|
||||
/**
|
||||
* Quotes a string so it can be safely used as a table or column name
|
||||
*
|
||||
* Use 'mssql' as the dbsyntax in the DB DSN only if you've unchecked
|
||||
* "Use ANSI quoted identifiers" when setting up the ODBC data source.
|
||||
*
|
||||
* @param string $str identifier name to be quoted
|
||||
*
|
||||
* @return string quoted identifier string
|
||||
*
|
||||
* @see DB_common::quoteIdentifier()
|
||||
* @since Method available since Release 1.6.0
|
||||
*/
|
||||
function quoteIdentifier($str)
|
||||
{
|
||||
switch ($this->dsn['dbsyntax']) {
|
||||
case 'access':
|
||||
return '[' . $str . ']';
|
||||
case 'mssql':
|
||||
case 'sybase':
|
||||
return '[' . str_replace(']', ']]', $str) . ']';
|
||||
case 'mysql':
|
||||
case 'mysqli':
|
||||
return '`' . $str . '`';
|
||||
default:
|
||||
return '"' . str_replace('"', '""', $str) . '"';
|
||||
}
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ quote()
|
||||
|
||||
/**
|
||||
* @deprecated Deprecated in release 1.6.0
|
||||
* @internal
|
||||
*/
|
||||
function quote($str)
|
||||
{
|
||||
return $this->quoteSmart($str);
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ nextId()
|
||||
|
||||
/**
|
||||
* Returns the next free id in a sequence
|
||||
*
|
||||
* @param string $seq_name name of the sequence
|
||||
* @param boolean $ondemand when true, the seqence is automatically
|
||||
* created if it does not exist
|
||||
*
|
||||
* @return int the next id number in the sequence.
|
||||
* A DB_Error object on failure.
|
||||
*
|
||||
* @see DB_common::nextID(), DB_common::getSequenceName(),
|
||||
* DB_odbc::createSequence(), DB_odbc::dropSequence()
|
||||
*/
|
||||
function nextId($seq_name, $ondemand = true)
|
||||
{
|
||||
$seqname = $this->getSequenceName($seq_name);
|
||||
$repeat = 0;
|
||||
do {
|
||||
$this->pushErrorHandling(PEAR_ERROR_RETURN);
|
||||
$result = $this->query("update ${seqname} set id = id + 1");
|
||||
$this->popErrorHandling();
|
||||
if ($ondemand && DB::isError($result) &&
|
||||
$result->getCode() == DB_ERROR_NOSUCHTABLE) {
|
||||
$repeat = 1;
|
||||
$this->pushErrorHandling(PEAR_ERROR_RETURN);
|
||||
$result = $this->createSequence($seq_name);
|
||||
$this->popErrorHandling();
|
||||
if (DB::isError($result)) {
|
||||
return $this->raiseError($result);
|
||||
}
|
||||
$result = $this->query("insert into ${seqname} (id) values(0)");
|
||||
} else {
|
||||
$repeat = 0;
|
||||
}
|
||||
} while ($repeat);
|
||||
|
||||
if (DB::isError($result)) {
|
||||
return $this->raiseError($result);
|
||||
}
|
||||
|
||||
$result = $this->query("select id from ${seqname}");
|
||||
if (DB::isError($result)) {
|
||||
return $result;
|
||||
}
|
||||
|
||||
$row = $result->fetchRow(DB_FETCHMODE_ORDERED);
|
||||
if (DB::isError($row || !$row)) {
|
||||
return $row;
|
||||
}
|
||||
|
||||
return $row[0];
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new sequence
|
||||
*
|
||||
* @param string $seq_name name of the new sequence
|
||||
*
|
||||
* @return int DB_OK on success. A DB_Error object on failure.
|
||||
*
|
||||
* @see DB_common::createSequence(), DB_common::getSequenceName(),
|
||||
* DB_odbc::nextID(), DB_odbc::dropSequence()
|
||||
*/
|
||||
function createSequence($seq_name)
|
||||
{
|
||||
return $this->query('CREATE TABLE '
|
||||
. $this->getSequenceName($seq_name)
|
||||
. ' (id integer NOT NULL,'
|
||||
. ' PRIMARY KEY(id))');
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ dropSequence()
|
||||
|
||||
/**
|
||||
* Deletes a sequence
|
||||
*
|
||||
* @param string $seq_name name of the sequence to be deleted
|
||||
*
|
||||
* @return int DB_OK on success. A DB_Error object on failure.
|
||||
*
|
||||
* @see DB_common::dropSequence(), DB_common::getSequenceName(),
|
||||
* DB_odbc::nextID(), DB_odbc::createSequence()
|
||||
*/
|
||||
function dropSequence($seq_name)
|
||||
{
|
||||
return $this->query('DROP TABLE ' . $this->getSequenceName($seq_name));
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ autoCommit()
|
||||
|
||||
/**
|
||||
* Enables or disables automatic commits
|
||||
*
|
||||
* @param bool $onoff true turns it on, false turns it off
|
||||
*
|
||||
* @return int DB_OK on success. A DB_Error object if the driver
|
||||
* doesn't support auto-committing transactions.
|
||||
*/
|
||||
function autoCommit($onoff = false)
|
||||
{
|
||||
if (!@odbc_autocommit($this->connection, $onoff)) {
|
||||
return $this->odbcRaiseError();
|
||||
}
|
||||
return DB_OK;
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ commit()
|
||||
|
||||
/**
|
||||
* Commits the current transaction
|
||||
*
|
||||
* @return int DB_OK on success. A DB_Error object on failure.
|
||||
*/
|
||||
function commit()
|
||||
{
|
||||
if (!@odbc_commit($this->connection)) {
|
||||
return $this->odbcRaiseError();
|
||||
}
|
||||
return DB_OK;
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ rollback()
|
||||
|
||||
/**
|
||||
* Reverts the current transaction
|
||||
*
|
||||
* @return int DB_OK on success. A DB_Error object on failure.
|
||||
*/
|
||||
function rollback()
|
||||
{
|
||||
if (!@odbc_rollback($this->connection)) {
|
||||
return $this->odbcRaiseError();
|
||||
}
|
||||
return DB_OK;
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ odbcRaiseError()
|
||||
|
||||
/**
|
||||
* Produces a DB_Error object regarding the current problem
|
||||
*
|
||||
* @param int $errno if the error is being manually raised pass a
|
||||
* DB_ERROR* constant here. If this isn't passed
|
||||
* the error information gathered from the DBMS.
|
||||
*
|
||||
* @return object the DB_Error object
|
||||
*
|
||||
* @see DB_common::raiseError(),
|
||||
* DB_odbc::errorNative(), DB_common::errorCode()
|
||||
*/
|
||||
function odbcRaiseError($errno = null)
|
||||
{
|
||||
if ($errno === null) {
|
||||
switch ($this->dbsyntax) {
|
||||
case 'access':
|
||||
if ($this->options['portability'] & DB_PORTABILITY_ERRORS) {
|
||||
$this->errorcode_map['07001'] = DB_ERROR_NOSUCHFIELD;
|
||||
} else {
|
||||
// Doing this in case mode changes during runtime.
|
||||
$this->errorcode_map['07001'] = DB_ERROR_MISMATCH;
|
||||
}
|
||||
|
||||
$native_code = odbc_error($this->connection);
|
||||
|
||||
// S1000 is for "General Error." Let's be more specific.
|
||||
if ($native_code == 'S1000') {
|
||||
$errormsg = odbc_errormsg($this->connection);
|
||||
static $error_regexps;
|
||||
if (!isset($error_regexps)) {
|
||||
$error_regexps = array(
|
||||
'/includes related records.$/i' => DB_ERROR_CONSTRAINT,
|
||||
'/cannot contain a Null value/i' => DB_ERROR_CONSTRAINT_NOT_NULL,
|
||||
);
|
||||
}
|
||||
foreach ($error_regexps as $regexp => $code) {
|
||||
if (preg_match($regexp, $errormsg)) {
|
||||
return $this->raiseError($code,
|
||||
null, null, null,
|
||||
$native_code . ' ' . $errormsg);
|
||||
}
|
||||
}
|
||||
$errno = DB_ERROR;
|
||||
} else {
|
||||
$errno = $this->errorCode($native_code);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
$errno = $this->errorCode(odbc_error($this->connection));
|
||||
}
|
||||
}
|
||||
return $this->raiseError($errno, null, null, null,
|
||||
$this->errorNative());
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ errorNative()
|
||||
|
||||
/**
|
||||
* Gets the DBMS' native error code and message produced by the last query
|
||||
*
|
||||
* @return string the DBMS' error code and message
|
||||
*/
|
||||
function errorNative()
|
||||
{
|
||||
if (!is_resource($this->connection)) {
|
||||
return @odbc_error() . ' ' . @odbc_errormsg();
|
||||
}
|
||||
return @odbc_error($this->connection) . ' ' . @odbc_errormsg($this->connection);
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ tableInfo()
|
||||
|
||||
/**
|
||||
* Returns information about a table or a result set
|
||||
*
|
||||
* @param object|string $result DB_result object from a query or a
|
||||
* string containing the name of a table.
|
||||
* While this also accepts a query result
|
||||
* resource identifier, this behavior is
|
||||
* deprecated.
|
||||
* @param int $mode a valid tableInfo mode
|
||||
*
|
||||
* @return array an associative array with the information requested.
|
||||
* A DB_Error object on failure.
|
||||
*
|
||||
* @see DB_common::tableInfo()
|
||||
* @since Method available since Release 1.7.0
|
||||
*/
|
||||
function tableInfo($result, $mode = null)
|
||||
{
|
||||
if (is_string($result)) {
|
||||
/*
|
||||
* Probably received a table name.
|
||||
* Create a result resource identifier.
|
||||
*/
|
||||
$id = @odbc_exec($this->connection, "SELECT * FROM $result");
|
||||
if (!$id) {
|
||||
return $this->odbcRaiseError();
|
||||
}
|
||||
$got_string = true;
|
||||
} elseif (isset($result->result)) {
|
||||
/*
|
||||
* Probably received a result object.
|
||||
* Extract the result resource identifier.
|
||||
*/
|
||||
$id = $result->result;
|
||||
$got_string = false;
|
||||
} else {
|
||||
/*
|
||||
* Probably received a result resource identifier.
|
||||
* Copy it.
|
||||
* Deprecated. Here for compatibility only.
|
||||
*/
|
||||
$id = $result;
|
||||
$got_string = false;
|
||||
}
|
||||
|
||||
if (!is_resource($id)) {
|
||||
return $this->odbcRaiseError(DB_ERROR_NEED_MORE_DATA);
|
||||
}
|
||||
|
||||
if ($this->options['portability'] & DB_PORTABILITY_LOWERCASE) {
|
||||
$case_func = 'strtolower';
|
||||
} else {
|
||||
$case_func = 'strval';
|
||||
}
|
||||
|
||||
$count = @odbc_num_fields($id);
|
||||
$res = array();
|
||||
|
||||
if ($mode) {
|
||||
$res['num_fields'] = $count;
|
||||
}
|
||||
|
||||
for ($i = 0; $i < $count; $i++) {
|
||||
$col = $i + 1;
|
||||
$res[$i] = array(
|
||||
'table' => $got_string ? $case_func($result) : '',
|
||||
'name' => $case_func(@odbc_field_name($id, $col)),
|
||||
'type' => @odbc_field_type($id, $col),
|
||||
'len' => @odbc_field_len($id, $col),
|
||||
'flags' => '',
|
||||
);
|
||||
if ($mode & DB_TABLEINFO_ORDER) {
|
||||
$res['order'][$res[$i]['name']] = $i;
|
||||
}
|
||||
if ($mode & DB_TABLEINFO_ORDERTABLE) {
|
||||
$res['ordertable'][$res[$i]['table']][$res[$i]['name']] = $i;
|
||||
}
|
||||
}
|
||||
|
||||
// free the result only if we were called on a table
|
||||
if ($got_string) {
|
||||
@odbc_free_result($id);
|
||||
}
|
||||
return $res;
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ getSpecialQuery()
|
||||
|
||||
/**
|
||||
* Obtains the query string needed for listing a given type of objects
|
||||
*
|
||||
* Thanks to symbol1@gmail.com and Philippe.Jausions@11abacus.com.
|
||||
*
|
||||
* @param string $type the kind of objects you want to retrieve
|
||||
*
|
||||
* @return string the list of objects requested
|
||||
*
|
||||
* @access protected
|
||||
* @see DB_common::getListOf()
|
||||
* @since Method available since Release 1.7.0
|
||||
*/
|
||||
function getSpecialQuery($type)
|
||||
{
|
||||
switch ($type) {
|
||||
case 'databases':
|
||||
if (!function_exists('odbc_data_source')) {
|
||||
return null;
|
||||
}
|
||||
$res = @odbc_data_source($this->connection, SQL_FETCH_FIRST);
|
||||
if (is_array($res)) {
|
||||
$out = array($res['server']);
|
||||
while($res = @odbc_data_source($this->connection,
|
||||
SQL_FETCH_NEXT))
|
||||
{
|
||||
$out[] = $res['server'];
|
||||
}
|
||||
return $out;
|
||||
} else {
|
||||
return $this->odbcRaiseError();
|
||||
}
|
||||
break;
|
||||
case 'tables':
|
||||
case 'schema.tables':
|
||||
$keep = 'TABLE';
|
||||
break;
|
||||
case 'views':
|
||||
$keep = 'VIEW';
|
||||
break;
|
||||
default:
|
||||
return null;
|
||||
}
|
||||
|
||||
/*
|
||||
* Removing non-conforming items in the while loop rather than
|
||||
* in the odbc_tables() call because some backends choke on this:
|
||||
* odbc_tables($this->connection, '', '', '', 'TABLE')
|
||||
*/
|
||||
$res = @odbc_tables($this->connection);
|
||||
if (!$res) {
|
||||
return $this->odbcRaiseError();
|
||||
}
|
||||
$out = array();
|
||||
while ($row = odbc_fetch_array($res)) {
|
||||
if ($row['TABLE_TYPE'] != $keep) {
|
||||
continue;
|
||||
}
|
||||
if ($type == 'schema.tables') {
|
||||
$out[] = $row['TABLE_SCHEM'] . '.' . $row['TABLE_NAME'];
|
||||
} else {
|
||||
$out[] = $row['TABLE_NAME'];
|
||||
}
|
||||
}
|
||||
return $out;
|
||||
}
|
||||
|
||||
// }}}
|
||||
|
||||
}
|
||||
|
||||
/*
|
||||
* Local variables:
|
||||
* tab-width: 4
|
||||
* c-basic-offset: 4
|
||||
* End:
|
||||
*/
|
||||
|
||||
?>
|
||||
1097
include/pear/DB/pgsql.php
Normal file
1097
include/pear/DB/pgsql.php
Normal file
File diff suppressed because it is too large
Load Diff
942
include/pear/DB/sqlite.php
Normal file
942
include/pear/DB/sqlite.php
Normal file
@@ -0,0 +1,942 @@
|
||||
<?php
|
||||
|
||||
/* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4: */
|
||||
|
||||
/**
|
||||
* The PEAR DB driver for PHP's sqlite extension
|
||||
* for interacting with SQLite databases
|
||||
*
|
||||
* 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 Database
|
||||
* @package DB
|
||||
* @author Urs Gehrig <urs@circle.ch>
|
||||
* @author Mika Tuupola <tuupola@appelsiini.net>
|
||||
* @author Daniel Convissor <danielc@php.net>
|
||||
* @copyright 1997-2005 The PHP Group
|
||||
* @license http://www.php.net/license/3_0.txt PHP License 3.0 3.0
|
||||
* @version CVS: $Id: sqlite.php,v 1.109 2005/03/10 01:22:48 danielc Exp $
|
||||
* @link http://pear.php.net/package/DB
|
||||
*/
|
||||
|
||||
/**
|
||||
* Obtain the DB_common class so it can be extended from
|
||||
*/
|
||||
require_once 'DB/common.php';
|
||||
|
||||
/**
|
||||
* The methods PEAR DB uses to interact with PHP's sqlite extension
|
||||
* for interacting with SQLite databases
|
||||
*
|
||||
* These methods overload the ones declared in DB_common.
|
||||
*
|
||||
* NOTICE: This driver needs PHP's track_errors ini setting to be on.
|
||||
* It is automatically turned on when connecting to the database.
|
||||
* Make sure your scripts don't turn it off.
|
||||
*
|
||||
* @category Database
|
||||
* @package DB
|
||||
* @author Urs Gehrig <urs@circle.ch>
|
||||
* @author Mika Tuupola <tuupola@appelsiini.net>
|
||||
* @author Daniel Convissor <danielc@php.net>
|
||||
* @copyright 1997-2005 The PHP Group
|
||||
* @license http://www.php.net/license/3_0.txt PHP License 3.0 3.0
|
||||
* @version Release: @package_version@
|
||||
* @link http://pear.php.net/package/DB
|
||||
*/
|
||||
class DB_sqlite extends DB_common
|
||||
{
|
||||
// {{{ properties
|
||||
|
||||
/**
|
||||
* The DB driver type (mysql, oci8, odbc, etc.)
|
||||
* @var string
|
||||
*/
|
||||
var $phptype = 'sqlite';
|
||||
|
||||
/**
|
||||
* The database syntax variant to be used (db2, access, etc.), if any
|
||||
* @var string
|
||||
*/
|
||||
var $dbsyntax = 'sqlite';
|
||||
|
||||
/**
|
||||
* The capabilities of this DB implementation
|
||||
*
|
||||
* The 'new_link' element contains the PHP version that first provided
|
||||
* new_link support for this DBMS. Contains false if it's unsupported.
|
||||
*
|
||||
* Meaning of the 'limit' element:
|
||||
* + 'emulate' = emulate with fetch row by number
|
||||
* + 'alter' = alter the query
|
||||
* + false = skip rows
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
var $features = array(
|
||||
'limit' => 'alter',
|
||||
'new_link' => false,
|
||||
'numrows' => true,
|
||||
'pconnect' => true,
|
||||
'prepare' => false,
|
||||
'ssl' => false,
|
||||
'transactions' => false,
|
||||
);
|
||||
|
||||
/**
|
||||
* A mapping of native error codes to DB error codes
|
||||
*
|
||||
* {@internal Error codes according to sqlite_exec. See the online
|
||||
* manual at http://sqlite.org/c_interface.html for info.
|
||||
* This error handling based on sqlite_exec is not yet implemented.}}
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
var $errorcode_map = array(
|
||||
);
|
||||
|
||||
/**
|
||||
* The raw database connection created by PHP
|
||||
* @var resource
|
||||
*/
|
||||
var $connection;
|
||||
|
||||
/**
|
||||
* The DSN information for connecting to a database
|
||||
* @var array
|
||||
*/
|
||||
var $dsn = array();
|
||||
|
||||
|
||||
/**
|
||||
* SQLite data types
|
||||
*
|
||||
* @link http://www.sqlite.org/datatypes.html
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
var $keywords = array (
|
||||
'BLOB' => '',
|
||||
'BOOLEAN' => '',
|
||||
'CHARACTER' => '',
|
||||
'CLOB' => '',
|
||||
'FLOAT' => '',
|
||||
'INTEGER' => '',
|
||||
'KEY' => '',
|
||||
'NATIONAL' => '',
|
||||
'NUMERIC' => '',
|
||||
'NVARCHAR' => '',
|
||||
'PRIMARY' => '',
|
||||
'TEXT' => '',
|
||||
'TIMESTAMP' => '',
|
||||
'UNIQUE' => '',
|
||||
'VARCHAR' => '',
|
||||
'VARYING' => '',
|
||||
);
|
||||
|
||||
/**
|
||||
* The most recent error message from $php_errormsg
|
||||
* @var string
|
||||
* @access private
|
||||
*/
|
||||
var $_lasterror = '';
|
||||
|
||||
|
||||
// }}}
|
||||
// {{{ constructor
|
||||
|
||||
/**
|
||||
* This constructor calls <kbd>$this->DB_common()</kbd>
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
function DB_sqlite()
|
||||
{
|
||||
$this->DB_common();
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ connect()
|
||||
|
||||
/**
|
||||
* Connect to the database server, log in and open the database
|
||||
*
|
||||
* Don't call this method directly. Use DB::connect() instead.
|
||||
*
|
||||
* PEAR DB's sqlite driver supports the following extra DSN options:
|
||||
* + mode The permissions for the database file, in four digit
|
||||
* chmod octal format (eg "0600").
|
||||
*
|
||||
* Example of connecting to a database in read-only mode:
|
||||
* <code>
|
||||
* require_once 'DB.php';
|
||||
*
|
||||
* $dsn = 'sqlite:///path/and/name/of/db/file?mode=0400';
|
||||
* $options = array(
|
||||
* 'portability' => DB_PORTABILITY_ALL,
|
||||
* );
|
||||
*
|
||||
* $db =& DB::connect($dsn, $options);
|
||||
* if (PEAR::isError($db)) {
|
||||
* die($db->getMessage());
|
||||
* }
|
||||
* </code>
|
||||
*
|
||||
* @param array $dsn the data source name
|
||||
* @param bool $persistent should the connection be persistent?
|
||||
*
|
||||
* @return int DB_OK on success. A DB_Error object on failure.
|
||||
*/
|
||||
function connect($dsn, $persistent = false)
|
||||
{
|
||||
if (!PEAR::loadExtension('sqlite')) {
|
||||
return $this->raiseError(DB_ERROR_EXTENSION_NOT_FOUND);
|
||||
}
|
||||
|
||||
$this->dsn = $dsn;
|
||||
if ($dsn['dbsyntax']) {
|
||||
$this->dbsyntax = $dsn['dbsyntax'];
|
||||
}
|
||||
|
||||
if ($dsn['database']) {
|
||||
if (!file_exists($dsn['database'])) {
|
||||
if (!touch($dsn['database'])) {
|
||||
return $this->sqliteRaiseError(DB_ERROR_NOT_FOUND);
|
||||
}
|
||||
if (!isset($dsn['mode']) ||
|
||||
!is_numeric($dsn['mode']))
|
||||
{
|
||||
$mode = 0644;
|
||||
} else {
|
||||
$mode = octdec($dsn['mode']);
|
||||
}
|
||||
if (!chmod($dsn['database'], $mode)) {
|
||||
return $this->sqliteRaiseError(DB_ERROR_NOT_FOUND);
|
||||
}
|
||||
if (!file_exists($dsn['database'])) {
|
||||
return $this->sqliteRaiseError(DB_ERROR_NOT_FOUND);
|
||||
}
|
||||
}
|
||||
if (!is_file($dsn['database'])) {
|
||||
return $this->sqliteRaiseError(DB_ERROR_INVALID);
|
||||
}
|
||||
if (!is_readable($dsn['database'])) {
|
||||
return $this->sqliteRaiseError(DB_ERROR_ACCESS_VIOLATION);
|
||||
}
|
||||
} else {
|
||||
return $this->sqliteRaiseError(DB_ERROR_ACCESS_VIOLATION);
|
||||
}
|
||||
|
||||
$connect_function = $persistent ? 'sqlite_popen' : 'sqlite_open';
|
||||
|
||||
// track_errors must remain on for simpleQuery()
|
||||
ini_set('track_errors', 1);
|
||||
$php_errormsg = '';
|
||||
|
||||
if (!$this->connection = @$connect_function($dsn['database'])) {
|
||||
return $this->raiseError(DB_ERROR_NODBSELECTED,
|
||||
null, null, null,
|
||||
$php_errormsg);
|
||||
}
|
||||
return DB_OK;
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ disconnect()
|
||||
|
||||
/**
|
||||
* Disconnects from the database server
|
||||
*
|
||||
* @return bool TRUE on success, FALSE on failure
|
||||
*/
|
||||
function disconnect()
|
||||
{
|
||||
$ret = @sqlite_close($this->connection);
|
||||
$this->connection = null;
|
||||
return $ret;
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ simpleQuery()
|
||||
|
||||
/**
|
||||
* Sends a query to the database server
|
||||
*
|
||||
* NOTICE: This method needs PHP's track_errors ini setting to be on.
|
||||
* It is automatically turned on when connecting to the database.
|
||||
* Make sure your scripts don't turn it off.
|
||||
*
|
||||
* @param string the SQL query string
|
||||
*
|
||||
* @return mixed + a PHP result resrouce for successful SELECT queries
|
||||
* + the DB_OK constant for other successful queries
|
||||
* + a DB_Error object on failure
|
||||
*/
|
||||
function simpleQuery($query)
|
||||
{
|
||||
$ismanip = DB::isManip($query);
|
||||
$this->last_query = $query;
|
||||
$query = $this->modifyQuery($query);
|
||||
|
||||
$php_errormsg = '';
|
||||
|
||||
$result = @sqlite_query($query, $this->connection);
|
||||
$this->_lasterror = $php_errormsg ? $php_errormsg : '';
|
||||
|
||||
$this->result = $result;
|
||||
if (!$this->result) {
|
||||
return $this->sqliteRaiseError(null);
|
||||
}
|
||||
|
||||
// sqlite_query() seems to allways return a resource
|
||||
// so cant use that. Using $ismanip instead
|
||||
if (!$ismanip) {
|
||||
$numRows = $this->numRows($result);
|
||||
if (is_object($numRows)) {
|
||||
// we've got PEAR_Error
|
||||
return $numRows;
|
||||
}
|
||||
return $result;
|
||||
}
|
||||
return DB_OK;
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ nextResult()
|
||||
|
||||
/**
|
||||
* Move the internal sqlite result pointer to the next available result
|
||||
*
|
||||
* @param resource $result the valid sqlite result resource
|
||||
*
|
||||
* @return bool true if a result is available otherwise return false
|
||||
*/
|
||||
function nextResult($result)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ fetchInto()
|
||||
|
||||
/**
|
||||
* Places a row from the result set into the given array
|
||||
*
|
||||
* Formating of the array and the data therein are configurable.
|
||||
* See DB_result::fetchInto() for more information.
|
||||
*
|
||||
* This method is not meant to be called directly. Use
|
||||
* DB_result::fetchInto() instead. It can't be declared "protected"
|
||||
* because DB_result is a separate object.
|
||||
*
|
||||
* @param resource $result the query result resource
|
||||
* @param array $arr the referenced array to put the data in
|
||||
* @param int $fetchmode how the resulting array should be indexed
|
||||
* @param int $rownum the row number to fetch (0 = first row)
|
||||
*
|
||||
* @return mixed DB_OK on success, NULL when the end of a result set is
|
||||
* reached or on failure
|
||||
*
|
||||
* @see DB_result::fetchInto()
|
||||
*/
|
||||
function fetchInto($result, &$arr, $fetchmode, $rownum = null)
|
||||
{
|
||||
if ($rownum !== null) {
|
||||
if (!@sqlite_seek($this->result, $rownum)) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
if ($fetchmode & DB_FETCHMODE_ASSOC) {
|
||||
$arr = @sqlite_fetch_array($result, SQLITE_ASSOC);
|
||||
if ($this->options['portability'] & DB_PORTABILITY_LOWERCASE && $arr) {
|
||||
$arr = array_change_key_case($arr, CASE_LOWER);
|
||||
}
|
||||
} else {
|
||||
$arr = @sqlite_fetch_array($result, SQLITE_NUM);
|
||||
}
|
||||
if (!$arr) {
|
||||
return null;
|
||||
}
|
||||
if ($this->options['portability'] & DB_PORTABILITY_RTRIM) {
|
||||
/*
|
||||
* Even though this DBMS already trims output, we do this because
|
||||
* a field might have intentional whitespace at the end that
|
||||
* gets removed by DB_PORTABILITY_RTRIM under another driver.
|
||||
*/
|
||||
$this->_rtrimArrayValues($arr);
|
||||
}
|
||||
if ($this->options['portability'] & DB_PORTABILITY_NULL_TO_EMPTY) {
|
||||
$this->_convertNullArrayValuesToEmpty($arr);
|
||||
}
|
||||
return DB_OK;
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ freeResult()
|
||||
|
||||
/**
|
||||
* Deletes the result set and frees the memory occupied by the result set
|
||||
*
|
||||
* This method is not meant to be called directly. Use
|
||||
* DB_result::free() instead. It can't be declared "protected"
|
||||
* because DB_result is a separate object.
|
||||
*
|
||||
* @param resource $result PHP's query result resource
|
||||
*
|
||||
* @return bool TRUE on success, FALSE if $result is invalid
|
||||
*
|
||||
* @see DB_result::free()
|
||||
*/
|
||||
function freeResult(&$result)
|
||||
{
|
||||
// XXX No native free?
|
||||
if (!is_resource($result)) {
|
||||
return false;
|
||||
}
|
||||
$result = null;
|
||||
return true;
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ numCols()
|
||||
|
||||
/**
|
||||
* Gets the number of columns in a result set
|
||||
*
|
||||
* This method is not meant to be called directly. Use
|
||||
* DB_result::numCols() instead. It can't be declared "protected"
|
||||
* because DB_result is a separate object.
|
||||
*
|
||||
* @param resource $result PHP's query result resource
|
||||
*
|
||||
* @return int the number of columns. A DB_Error object on failure.
|
||||
*
|
||||
* @see DB_result::numCols()
|
||||
*/
|
||||
function numCols($result)
|
||||
{
|
||||
$cols = @sqlite_num_fields($result);
|
||||
if (!$cols) {
|
||||
return $this->sqliteRaiseError();
|
||||
}
|
||||
return $cols;
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ numRows()
|
||||
|
||||
/**
|
||||
* Gets the number of rows in a result set
|
||||
*
|
||||
* This method is not meant to be called directly. Use
|
||||
* DB_result::numRows() instead. It can't be declared "protected"
|
||||
* because DB_result is a separate object.
|
||||
*
|
||||
* @param resource $result PHP's query result resource
|
||||
*
|
||||
* @return int the number of rows. A DB_Error object on failure.
|
||||
*
|
||||
* @see DB_result::numRows()
|
||||
*/
|
||||
function numRows($result)
|
||||
{
|
||||
$rows = @sqlite_num_rows($result);
|
||||
if ($rows === null) {
|
||||
return $this->sqliteRaiseError();
|
||||
}
|
||||
return $rows;
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ affected()
|
||||
|
||||
/**
|
||||
* Determines the number of rows affected by a data maniuplation query
|
||||
*
|
||||
* 0 is returned for queries that don't manipulate data.
|
||||
*
|
||||
* @return int the number of rows. A DB_Error object on failure.
|
||||
*/
|
||||
function affectedRows()
|
||||
{
|
||||
return @sqlite_changes($this->connection);
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ dropSequence()
|
||||
|
||||
/**
|
||||
* Deletes a sequence
|
||||
*
|
||||
* @param string $seq_name name of the sequence to be deleted
|
||||
*
|
||||
* @return int DB_OK on success. A DB_Error object on failure.
|
||||
*
|
||||
* @see DB_common::dropSequence(), DB_common::getSequenceName(),
|
||||
* DB_sqlite::nextID(), DB_sqlite::createSequence()
|
||||
*/
|
||||
function dropSequence($seq_name)
|
||||
{
|
||||
return $this->query('DROP TABLE ' . $this->getSequenceName($seq_name));
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new sequence
|
||||
*
|
||||
* @param string $seq_name name of the new sequence
|
||||
*
|
||||
* @return int DB_OK on success. A DB_Error object on failure.
|
||||
*
|
||||
* @see DB_common::createSequence(), DB_common::getSequenceName(),
|
||||
* DB_sqlite::nextID(), DB_sqlite::dropSequence()
|
||||
*/
|
||||
function createSequence($seq_name)
|
||||
{
|
||||
$seqname = $this->getSequenceName($seq_name);
|
||||
$query = 'CREATE TABLE ' . $seqname .
|
||||
' (id INTEGER UNSIGNED PRIMARY KEY) ';
|
||||
$result = $this->query($query);
|
||||
if (DB::isError($result)) {
|
||||
return($result);
|
||||
}
|
||||
$query = "CREATE TRIGGER ${seqname}_cleanup AFTER INSERT ON $seqname
|
||||
BEGIN
|
||||
DELETE FROM $seqname WHERE id<LAST_INSERT_ROWID();
|
||||
END ";
|
||||
$result = $this->query($query);
|
||||
if (DB::isError($result)) {
|
||||
return($result);
|
||||
}
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ nextId()
|
||||
|
||||
/**
|
||||
* Returns the next free id in a sequence
|
||||
*
|
||||
* @param string $seq_name name of the sequence
|
||||
* @param boolean $ondemand when true, the seqence is automatically
|
||||
* created if it does not exist
|
||||
*
|
||||
* @return int the next id number in the sequence.
|
||||
* A DB_Error object on failure.
|
||||
*
|
||||
* @see DB_common::nextID(), DB_common::getSequenceName(),
|
||||
* DB_sqlite::createSequence(), DB_sqlite::dropSequence()
|
||||
*/
|
||||
function nextId($seq_name, $ondemand = true)
|
||||
{
|
||||
$seqname = $this->getSequenceName($seq_name);
|
||||
|
||||
do {
|
||||
$repeat = 0;
|
||||
$this->pushErrorHandling(PEAR_ERROR_RETURN);
|
||||
$result = $this->query("INSERT INTO $seqname (id) VALUES (NULL)");
|
||||
$this->popErrorHandling();
|
||||
if ($result === DB_OK) {
|
||||
$id = @sqlite_last_insert_rowid($this->connection);
|
||||
if ($id != 0) {
|
||||
return $id;
|
||||
}
|
||||
} elseif ($ondemand && DB::isError($result) &&
|
||||
$result->getCode() == DB_ERROR_NOSUCHTABLE)
|
||||
{
|
||||
$result = $this->createSequence($seq_name);
|
||||
if (DB::isError($result)) {
|
||||
return $this->raiseError($result);
|
||||
} else {
|
||||
$repeat = 1;
|
||||
}
|
||||
}
|
||||
} while ($repeat);
|
||||
|
||||
return $this->raiseError($result);
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ getDbFileStats()
|
||||
|
||||
/**
|
||||
* Get the file stats for the current database
|
||||
*
|
||||
* Possible arguments are dev, ino, mode, nlink, uid, gid, rdev, size,
|
||||
* atime, mtime, ctime, blksize, blocks or a numeric key between
|
||||
* 0 and 12.
|
||||
*
|
||||
* @param string $arg the array key for stats()
|
||||
*
|
||||
* @return mixed an array on an unspecified key, integer on a passed
|
||||
* arg and false at a stats error
|
||||
*/
|
||||
function getDbFileStats($arg = '')
|
||||
{
|
||||
$stats = stat($this->dsn['database']);
|
||||
if ($stats == false) {
|
||||
return false;
|
||||
}
|
||||
if (is_array($stats)) {
|
||||
if (is_numeric($arg)) {
|
||||
if (((int)$arg <= 12) & ((int)$arg >= 0)) {
|
||||
return false;
|
||||
}
|
||||
return $stats[$arg ];
|
||||
}
|
||||
if (array_key_exists(trim($arg), $stats)) {
|
||||
return $stats[$arg ];
|
||||
}
|
||||
}
|
||||
return $stats;
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ escapeSimple()
|
||||
|
||||
/**
|
||||
* Escapes a string according to the current DBMS's standards
|
||||
*
|
||||
* In SQLite, this makes things safe for inserts/updates, but may
|
||||
* cause problems when performing text comparisons against columns
|
||||
* containing binary data. See the
|
||||
* {@link http://php.net/sqlite_escape_string PHP manual} for more info.
|
||||
*
|
||||
* @param string $str the string to be escaped
|
||||
*
|
||||
* @return string the escaped string
|
||||
*
|
||||
* @since Method available since Release 1.6.1
|
||||
* @see DB_common::escapeSimple()
|
||||
*/
|
||||
function escapeSimple($str)
|
||||
{
|
||||
return @sqlite_escape_string($str);
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ modifyLimitQuery()
|
||||
|
||||
/**
|
||||
* Adds LIMIT clauses to a query string according to current DBMS standards
|
||||
*
|
||||
* @param string $query the query to modify
|
||||
* @param int $from the row to start to fetching (0 = the first row)
|
||||
* @param int $count the numbers of rows to fetch
|
||||
* @param mixed $params array, string or numeric data to be used in
|
||||
* execution of the statement. Quantity of items
|
||||
* passed must match quantity of placeholders in
|
||||
* query: meaning 1 placeholder for non-array
|
||||
* parameters or 1 placeholder per array element.
|
||||
*
|
||||
* @return string the query string with LIMIT clauses added
|
||||
*
|
||||
* @access protected
|
||||
*/
|
||||
function modifyLimitQuery($query, $from, $count, $params = array())
|
||||
{
|
||||
return "$query LIMIT $count OFFSET $from";
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ modifyQuery()
|
||||
|
||||
/**
|
||||
* Changes a query string for various DBMS specific reasons
|
||||
*
|
||||
* This little hack lets you know how many rows were deleted
|
||||
* when running a "DELETE FROM table" query. Only implemented
|
||||
* if the DB_PORTABILITY_DELETE_COUNT portability option is on.
|
||||
*
|
||||
* @param string $query the query string to modify
|
||||
*
|
||||
* @return string the modified query string
|
||||
*
|
||||
* @access protected
|
||||
* @see DB_common::setOption()
|
||||
*/
|
||||
function modifyQuery($query)
|
||||
{
|
||||
if ($this->options['portability'] & DB_PORTABILITY_DELETE_COUNT) {
|
||||
if (preg_match('/^\s*DELETE\s+FROM\s+(\S+)\s*$/i', $query)) {
|
||||
$query = preg_replace('/^\s*DELETE\s+FROM\s+(\S+)\s*$/',
|
||||
'DELETE FROM \1 WHERE 1=1', $query);
|
||||
}
|
||||
}
|
||||
return $query;
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ sqliteRaiseError()
|
||||
|
||||
/**
|
||||
* Produces a DB_Error object regarding the current problem
|
||||
*
|
||||
* @param int $errno if the error is being manually raised pass a
|
||||
* DB_ERROR* constant here. If this isn't passed
|
||||
* the error information gathered from the DBMS.
|
||||
*
|
||||
* @return object the DB_Error object
|
||||
*
|
||||
* @see DB_common::raiseError(),
|
||||
* DB_sqlite::errorNative(), DB_sqlite::errorCode()
|
||||
*/
|
||||
function sqliteRaiseError($errno = null)
|
||||
{
|
||||
$native = $this->errorNative();
|
||||
if ($errno === null) {
|
||||
$errno = $this->errorCode($native);
|
||||
}
|
||||
|
||||
$errorcode = @sqlite_last_error($this->connection);
|
||||
$userinfo = "$errorcode ** $this->last_query";
|
||||
|
||||
return $this->raiseError($errno, null, null, $userinfo, $native);
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ errorNative()
|
||||
|
||||
/**
|
||||
* Gets the DBMS' native error message produced by the last query
|
||||
*
|
||||
* {@internal This is used to retrieve more meaningfull error messages
|
||||
* because sqlite_last_error() does not provide adequate info.}}
|
||||
*
|
||||
* @return string the DBMS' error message
|
||||
*/
|
||||
function errorNative()
|
||||
{
|
||||
return $this->_lasterror;
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ errorCode()
|
||||
|
||||
/**
|
||||
* Determines PEAR::DB error code from the database's text error message
|
||||
*
|
||||
* @param string $errormsg the error message returned from the database
|
||||
*
|
||||
* @return integer the DB error number
|
||||
*/
|
||||
function errorCode($errormsg)
|
||||
{
|
||||
static $error_regexps;
|
||||
if (!isset($error_regexps)) {
|
||||
$error_regexps = array(
|
||||
'/^no such table:/' => DB_ERROR_NOSUCHTABLE,
|
||||
'/^no such index:/' => DB_ERROR_NOT_FOUND,
|
||||
'/^(table|index) .* already exists$/' => DB_ERROR_ALREADY_EXISTS,
|
||||
'/PRIMARY KEY must be unique/i' => DB_ERROR_CONSTRAINT,
|
||||
'/is not unique/' => DB_ERROR_CONSTRAINT,
|
||||
'/columns .* are not unique/i' => DB_ERROR_CONSTRAINT,
|
||||
'/uniqueness constraint failed/' => DB_ERROR_CONSTRAINT,
|
||||
'/may not be NULL/' => DB_ERROR_CONSTRAINT_NOT_NULL,
|
||||
'/^no such column:/' => DB_ERROR_NOSUCHFIELD,
|
||||
'/column not present in both tables/i' => DB_ERROR_NOSUCHFIELD,
|
||||
'/^near ".*": syntax error$/' => DB_ERROR_SYNTAX,
|
||||
'/[0-9]+ values for [0-9]+ columns/i' => DB_ERROR_VALUE_COUNT_ON_ROW,
|
||||
);
|
||||
}
|
||||
foreach ($error_regexps as $regexp => $code) {
|
||||
if (preg_match($regexp, $errormsg)) {
|
||||
return $code;
|
||||
}
|
||||
}
|
||||
// Fall back to DB_ERROR if there was no mapping.
|
||||
return DB_ERROR;
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ tableInfo()
|
||||
|
||||
/**
|
||||
* Returns information about a table
|
||||
*
|
||||
* @param string $result a string containing the name of a table
|
||||
* @param int $mode a valid tableInfo mode
|
||||
*
|
||||
* @return array an associative array with the information requested.
|
||||
* A DB_Error object on failure.
|
||||
*
|
||||
* @see DB_common::tableInfo()
|
||||
* @since Method available since Release 1.7.0
|
||||
*/
|
||||
function tableInfo($result, $mode = null)
|
||||
{
|
||||
if (is_string($result)) {
|
||||
/*
|
||||
* Probably received a table name.
|
||||
* Create a result resource identifier.
|
||||
*/
|
||||
$id = @sqlite_array_query($this->connection,
|
||||
"PRAGMA table_info('$result');",
|
||||
SQLITE_ASSOC);
|
||||
$got_string = true;
|
||||
} else {
|
||||
$this->last_query = '';
|
||||
return $this->raiseError(DB_ERROR_NOT_CAPABLE, null, null, null,
|
||||
'This DBMS can not obtain tableInfo' .
|
||||
' from result sets');
|
||||
}
|
||||
|
||||
if ($this->options['portability'] & DB_PORTABILITY_LOWERCASE) {
|
||||
$case_func = 'strtolower';
|
||||
} else {
|
||||
$case_func = 'strval';
|
||||
}
|
||||
|
||||
$count = count($id);
|
||||
$res = array();
|
||||
|
||||
if ($mode) {
|
||||
$res['num_fields'] = $count;
|
||||
}
|
||||
|
||||
for ($i = 0; $i < $count; $i++) {
|
||||
if (strpos($id[$i]['type'], '(') !== false) {
|
||||
$bits = explode('(', $id[$i]['type']);
|
||||
$type = $bits[0];
|
||||
$len = rtrim($bits[1],')');
|
||||
} else {
|
||||
$type = $id[$i]['type'];
|
||||
$len = 0;
|
||||
}
|
||||
|
||||
$flags = '';
|
||||
if ($id[$i]['pk']) {
|
||||
$flags .= 'primary_key ';
|
||||
}
|
||||
if ($id[$i]['notnull']) {
|
||||
$flags .= 'not_null ';
|
||||
}
|
||||
if ($id[$i]['dflt_value'] !== null) {
|
||||
$flags .= 'default_' . rawurlencode($id[$i]['dflt_value']);
|
||||
}
|
||||
$flags = trim($flags);
|
||||
|
||||
$res[$i] = array(
|
||||
'table' => $case_func($result),
|
||||
'name' => $case_func($id[$i]['name']),
|
||||
'type' => $type,
|
||||
'len' => $len,
|
||||
'flags' => $flags,
|
||||
);
|
||||
|
||||
if ($mode & DB_TABLEINFO_ORDER) {
|
||||
$res['order'][$res[$i]['name']] = $i;
|
||||
}
|
||||
if ($mode & DB_TABLEINFO_ORDERTABLE) {
|
||||
$res['ordertable'][$res[$i]['table']][$res[$i]['name']] = $i;
|
||||
}
|
||||
}
|
||||
|
||||
return $res;
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ getSpecialQuery()
|
||||
|
||||
/**
|
||||
* Obtains the query string needed for listing a given type of objects
|
||||
*
|
||||
* @param string $type the kind of objects you want to retrieve
|
||||
* @param array $args SQLITE DRIVER ONLY: a private array of arguments
|
||||
* used by the getSpecialQuery(). Do not use
|
||||
* this directly.
|
||||
*
|
||||
* @return string the SQL query string or null if the driver doesn't
|
||||
* support the object type requested
|
||||
*
|
||||
* @access protected
|
||||
* @see DB_common::getListOf()
|
||||
*/
|
||||
function getSpecialQuery($type, $args = array())
|
||||
{
|
||||
if (!is_array($args)) {
|
||||
return $this->raiseError('no key specified', null, null, null,
|
||||
'Argument has to be an array.');
|
||||
}
|
||||
|
||||
switch ($type) {
|
||||
case 'master':
|
||||
return 'SELECT * FROM sqlite_master;';
|
||||
case 'tables':
|
||||
return "SELECT name FROM sqlite_master WHERE type='table' "
|
||||
. 'UNION ALL SELECT name FROM sqlite_temp_master '
|
||||
. "WHERE type='table' ORDER BY name;";
|
||||
case 'schema':
|
||||
return 'SELECT sql FROM (SELECT * FROM sqlite_master '
|
||||
. 'UNION ALL SELECT * FROM sqlite_temp_master) '
|
||||
. "WHERE type!='meta' "
|
||||
. 'ORDER BY tbl_name, type DESC, name;';
|
||||
case 'schemax':
|
||||
case 'schema_x':
|
||||
/*
|
||||
* Use like:
|
||||
* $res = $db->query($db->getSpecialQuery('schema_x',
|
||||
* array('table' => 'table3')));
|
||||
*/
|
||||
return 'SELECT sql FROM (SELECT * FROM sqlite_master '
|
||||
. 'UNION ALL SELECT * FROM sqlite_temp_master) '
|
||||
. "WHERE tbl_name LIKE '{$args['table']}' "
|
||||
. "AND type!='meta' "
|
||||
. 'ORDER BY type DESC, name;';
|
||||
case 'alter':
|
||||
/*
|
||||
* SQLite does not support ALTER TABLE; this is a helper query
|
||||
* to handle this. 'table' represents the table name, 'rows'
|
||||
* the news rows to create, 'save' the row(s) to keep _with_
|
||||
* the data.
|
||||
*
|
||||
* Use like:
|
||||
* $args = array(
|
||||
* 'table' => $table,
|
||||
* 'rows' => "id INTEGER PRIMARY KEY, firstname TEXT, surname TEXT, datetime TEXT",
|
||||
* 'save' => "NULL, titel, content, datetime"
|
||||
* );
|
||||
* $res = $db->query( $db->getSpecialQuery('alter', $args));
|
||||
*/
|
||||
$rows = strtr($args['rows'], $this->keywords);
|
||||
|
||||
$q = array(
|
||||
'BEGIN TRANSACTION',
|
||||
"CREATE TEMPORARY TABLE {$args['table']}_backup ({$args['rows']})",
|
||||
"INSERT INTO {$args['table']}_backup SELECT {$args['save']} FROM {$args['table']}",
|
||||
"DROP TABLE {$args['table']}",
|
||||
"CREATE TABLE {$args['table']} ({$args['rows']})",
|
||||
"INSERT INTO {$args['table']} SELECT {$rows} FROM {$args['table']}_backup",
|
||||
"DROP TABLE {$args['table']}_backup",
|
||||
'COMMIT',
|
||||
);
|
||||
|
||||
/*
|
||||
* This is a dirty hack, since the above query will not get
|
||||
* executed with a single query call so here the query method
|
||||
* will be called directly and return a select instead.
|
||||
*/
|
||||
foreach ($q as $query) {
|
||||
$this->query($query);
|
||||
}
|
||||
return "SELECT * FROM {$args['table']};";
|
||||
default:
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
// }}}
|
||||
}
|
||||
|
||||
/*
|
||||
* Local variables:
|
||||
* tab-width: 4
|
||||
* c-basic-offset: 4
|
||||
* End:
|
||||
*/
|
||||
|
||||
?>
|
||||
504
include/pear/DB/storage.php
Normal file
504
include/pear/DB/storage.php
Normal file
@@ -0,0 +1,504 @@
|
||||
<?php
|
||||
|
||||
/* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4: */
|
||||
|
||||
/**
|
||||
* Provides an object interface to a table row
|
||||
*
|
||||
* 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 Database
|
||||
* @package DB
|
||||
* @author Stig Bakken <stig@php.net>
|
||||
* @copyright 1997-2005 The PHP Group
|
||||
* @license http://www.php.net/license/3_0.txt PHP License 3.0
|
||||
* @version CVS: $Id: storage.php,v 1.21 2005/02/02 02:54:51 danielc Exp $
|
||||
* @link http://pear.php.net/package/DB
|
||||
*/
|
||||
|
||||
/**
|
||||
* Obtain the DB class so it can be extended from
|
||||
*/
|
||||
require_once 'DB.php';
|
||||
|
||||
/**
|
||||
* Provides an object interface to a table row
|
||||
*
|
||||
* It lets you add, delete and change rows using objects rather than SQL
|
||||
* statements.
|
||||
*
|
||||
* @category Database
|
||||
* @package DB
|
||||
* @author Stig Bakken <stig@php.net>
|
||||
* @copyright 1997-2005 The PHP Group
|
||||
* @license http://www.php.net/license/3_0.txt PHP License 3.0
|
||||
* @version Release: @package_version@
|
||||
* @link http://pear.php.net/package/DB
|
||||
*/
|
||||
class DB_storage extends PEAR
|
||||
{
|
||||
// {{{ properties
|
||||
|
||||
/** the name of the table (or view, if the backend database supports
|
||||
updates in views) we hold data from */
|
||||
var $_table = null;
|
||||
|
||||
/** which column(s) in the table contains primary keys, can be a
|
||||
string for single-column primary keys, or an array of strings
|
||||
for multiple-column primary keys */
|
||||
var $_keycolumn = null;
|
||||
|
||||
/** DB connection handle used for all transactions */
|
||||
var $_dbh = null;
|
||||
|
||||
/** an assoc with the names of database fields stored as properties
|
||||
in this object */
|
||||
var $_properties = array();
|
||||
|
||||
/** an assoc with the names of the properties in this object that
|
||||
have been changed since they were fetched from the database */
|
||||
var $_changes = array();
|
||||
|
||||
/** flag that decides if data in this object can be changed.
|
||||
objects that don't have their table's key column in their
|
||||
property lists will be flagged as read-only. */
|
||||
var $_readonly = false;
|
||||
|
||||
/** function or method that implements a validator for fields that
|
||||
are set, this validator function returns true if the field is
|
||||
valid, false if not */
|
||||
var $_validator = null;
|
||||
|
||||
// }}}
|
||||
// {{{ constructor
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* @param $table string the name of the database table
|
||||
*
|
||||
* @param $keycolumn mixed string with name of key column, or array of
|
||||
* strings if the table has a primary key of more than one column
|
||||
*
|
||||
* @param $dbh object database connection object
|
||||
*
|
||||
* @param $validator mixed function or method used to validate
|
||||
* each new value, called with three parameters: the name of the
|
||||
* field/column that is changing, a reference to the new value and
|
||||
* a reference to this object
|
||||
*
|
||||
*/
|
||||
function DB_storage($table, $keycolumn, &$dbh, $validator = null)
|
||||
{
|
||||
$this->PEAR('DB_Error');
|
||||
$this->_table = $table;
|
||||
$this->_keycolumn = $keycolumn;
|
||||
$this->_dbh = $dbh;
|
||||
$this->_readonly = false;
|
||||
$this->_validator = $validator;
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ _makeWhere()
|
||||
|
||||
/**
|
||||
* Utility method to build a "WHERE" clause to locate ourselves in
|
||||
* the table.
|
||||
*
|
||||
* XXX future improvement: use rowids?
|
||||
*
|
||||
* @access private
|
||||
*/
|
||||
function _makeWhere($keyval = null)
|
||||
{
|
||||
if (is_array($this->_keycolumn)) {
|
||||
if ($keyval === null) {
|
||||
for ($i = 0; $i < sizeof($this->_keycolumn); $i++) {
|
||||
$keyval[] = $this->{$this->_keycolumn[$i]};
|
||||
}
|
||||
}
|
||||
$whereclause = '';
|
||||
for ($i = 0; $i < sizeof($this->_keycolumn); $i++) {
|
||||
if ($i > 0) {
|
||||
$whereclause .= ' AND ';
|
||||
}
|
||||
$whereclause .= $this->_keycolumn[$i];
|
||||
if (is_null($keyval[$i])) {
|
||||
// there's not much point in having a NULL key,
|
||||
// but we support it anyway
|
||||
$whereclause .= ' IS NULL';
|
||||
} else {
|
||||
$whereclause .= ' = ' . $this->_dbh->quote($keyval[$i]);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if ($keyval === null) {
|
||||
$keyval = @$this->{$this->_keycolumn};
|
||||
}
|
||||
$whereclause = $this->_keycolumn;
|
||||
if (is_null($keyval)) {
|
||||
// there's not much point in having a NULL key,
|
||||
// but we support it anyway
|
||||
$whereclause .= ' IS NULL';
|
||||
} else {
|
||||
$whereclause .= ' = ' . $this->_dbh->quote($keyval);
|
||||
}
|
||||
}
|
||||
return $whereclause;
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ setup()
|
||||
|
||||
/**
|
||||
* Method used to initialize a DB_storage object from the
|
||||
* configured table.
|
||||
*
|
||||
* @param $keyval mixed the key[s] of the row to fetch (string or array)
|
||||
*
|
||||
* @return int DB_OK on success, a DB error if not
|
||||
*/
|
||||
function setup($keyval)
|
||||
{
|
||||
$whereclause = $this->_makeWhere($keyval);
|
||||
$query = 'SELECT * FROM ' . $this->_table . ' WHERE ' . $whereclause;
|
||||
$sth = $this->_dbh->query($query);
|
||||
if (DB::isError($sth)) {
|
||||
return $sth;
|
||||
}
|
||||
$row = $sth->fetchRow(DB_FETCHMODE_ASSOC);
|
||||
if (DB::isError($row)) {
|
||||
return $row;
|
||||
}
|
||||
if (!$row) {
|
||||
return $this->raiseError(null, DB_ERROR_NOT_FOUND, null, null,
|
||||
$query, null, true);
|
||||
}
|
||||
foreach ($row as $key => $value) {
|
||||
$this->_properties[$key] = true;
|
||||
$this->$key = $value;
|
||||
}
|
||||
return DB_OK;
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ insert()
|
||||
|
||||
/**
|
||||
* Create a new (empty) row in the configured table for this
|
||||
* object.
|
||||
*/
|
||||
function insert($newpk)
|
||||
{
|
||||
if (is_array($this->_keycolumn)) {
|
||||
$primarykey = $this->_keycolumn;
|
||||
} else {
|
||||
$primarykey = array($this->_keycolumn);
|
||||
}
|
||||
settype($newpk, "array");
|
||||
for ($i = 0; $i < sizeof($primarykey); $i++) {
|
||||
$pkvals[] = $this->_dbh->quote($newpk[$i]);
|
||||
}
|
||||
|
||||
$sth = $this->_dbh->query("INSERT INTO $this->_table (" .
|
||||
implode(",", $primarykey) . ") VALUES(" .
|
||||
implode(",", $pkvals) . ")");
|
||||
if (DB::isError($sth)) {
|
||||
return $sth;
|
||||
}
|
||||
if (sizeof($newpk) == 1) {
|
||||
$newpk = $newpk[0];
|
||||
}
|
||||
$this->setup($newpk);
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ toString()
|
||||
|
||||
/**
|
||||
* Output a simple description of this DB_storage object.
|
||||
* @return string object description
|
||||
*/
|
||||
function toString()
|
||||
{
|
||||
$info = strtolower(get_class($this));
|
||||
$info .= " (table=";
|
||||
$info .= $this->_table;
|
||||
$info .= ", keycolumn=";
|
||||
if (is_array($this->_keycolumn)) {
|
||||
$info .= "(" . implode(",", $this->_keycolumn) . ")";
|
||||
} else {
|
||||
$info .= $this->_keycolumn;
|
||||
}
|
||||
$info .= ", dbh=";
|
||||
if (is_object($this->_dbh)) {
|
||||
$info .= $this->_dbh->toString();
|
||||
} else {
|
||||
$info .= "null";
|
||||
}
|
||||
$info .= ")";
|
||||
if (sizeof($this->_properties)) {
|
||||
$info .= " [loaded, key=";
|
||||
$keyname = $this->_keycolumn;
|
||||
if (is_array($keyname)) {
|
||||
$info .= "(";
|
||||
for ($i = 0; $i < sizeof($keyname); $i++) {
|
||||
if ($i > 0) {
|
||||
$info .= ",";
|
||||
}
|
||||
$info .= $this->$keyname[$i];
|
||||
}
|
||||
$info .= ")";
|
||||
} else {
|
||||
$info .= $this->$keyname;
|
||||
}
|
||||
$info .= "]";
|
||||
}
|
||||
if (sizeof($this->_changes)) {
|
||||
$info .= " [modified]";
|
||||
}
|
||||
return $info;
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ dump()
|
||||
|
||||
/**
|
||||
* Dump the contents of this object to "standard output".
|
||||
*/
|
||||
function dump()
|
||||
{
|
||||
foreach ($this->_properties as $prop => $foo) {
|
||||
print "$prop = ";
|
||||
print htmlentities($this->$prop);
|
||||
print "<br />\n";
|
||||
}
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ &create()
|
||||
|
||||
/**
|
||||
* Static method used to create new DB storage objects.
|
||||
* @param $data assoc. array where the keys are the names
|
||||
* of properties/columns
|
||||
* @return object a new instance of DB_storage or a subclass of it
|
||||
*/
|
||||
function &create($table, &$data)
|
||||
{
|
||||
$classname = strtolower(get_class($this));
|
||||
$obj =& new $classname($table);
|
||||
foreach ($data as $name => $value) {
|
||||
$obj->_properties[$name] = true;
|
||||
$obj->$name = &$value;
|
||||
}
|
||||
return $obj;
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ loadFromQuery()
|
||||
|
||||
/**
|
||||
* Loads data into this object from the given query. If this
|
||||
* object already contains table data, changes will be saved and
|
||||
* the object re-initialized first.
|
||||
*
|
||||
* @param $query SQL query
|
||||
*
|
||||
* @param $params parameter list in case you want to use
|
||||
* prepare/execute mode
|
||||
*
|
||||
* @return int DB_OK on success, DB_WARNING_READ_ONLY if the
|
||||
* returned object is read-only (because the object's specified
|
||||
* key column was not found among the columns returned by $query),
|
||||
* or another DB error code in case of errors.
|
||||
*/
|
||||
// XXX commented out for now
|
||||
/*
|
||||
function loadFromQuery($query, $params = null)
|
||||
{
|
||||
if (sizeof($this->_properties)) {
|
||||
if (sizeof($this->_changes)) {
|
||||
$this->store();
|
||||
$this->_changes = array();
|
||||
}
|
||||
$this->_properties = array();
|
||||
}
|
||||
$rowdata = $this->_dbh->getRow($query, DB_FETCHMODE_ASSOC, $params);
|
||||
if (DB::isError($rowdata)) {
|
||||
return $rowdata;
|
||||
}
|
||||
reset($rowdata);
|
||||
$found_keycolumn = false;
|
||||
while (list($key, $value) = each($rowdata)) {
|
||||
if ($key == $this->_keycolumn) {
|
||||
$found_keycolumn = true;
|
||||
}
|
||||
$this->_properties[$key] = true;
|
||||
$this->$key = &$value;
|
||||
unset($value); // have to unset, or all properties will
|
||||
// refer to the same value
|
||||
}
|
||||
if (!$found_keycolumn) {
|
||||
$this->_readonly = true;
|
||||
return DB_WARNING_READ_ONLY;
|
||||
}
|
||||
return DB_OK;
|
||||
}
|
||||
*/
|
||||
|
||||
// }}}
|
||||
// {{{ set()
|
||||
|
||||
/**
|
||||
* Modify an attriute value.
|
||||
*/
|
||||
function set($property, $newvalue)
|
||||
{
|
||||
// only change if $property is known and object is not
|
||||
// read-only
|
||||
if ($this->_readonly) {
|
||||
return $this->raiseError(null, DB_WARNING_READ_ONLY, null,
|
||||
null, null, null, true);
|
||||
}
|
||||
if (@isset($this->_properties[$property])) {
|
||||
if (empty($this->_validator)) {
|
||||
$valid = true;
|
||||
} else {
|
||||
$valid = @call_user_func($this->_validator,
|
||||
$this->_table,
|
||||
$property,
|
||||
$newvalue,
|
||||
$this->$property,
|
||||
$this);
|
||||
}
|
||||
if ($valid) {
|
||||
$this->$property = $newvalue;
|
||||
if (empty($this->_changes[$property])) {
|
||||
$this->_changes[$property] = 0;
|
||||
} else {
|
||||
$this->_changes[$property]++;
|
||||
}
|
||||
} else {
|
||||
return $this->raiseError(null, DB_ERROR_INVALID, null,
|
||||
null, "invalid field: $property",
|
||||
null, true);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
return $this->raiseError(null, DB_ERROR_NOSUCHFIELD, null,
|
||||
null, "unknown field: $property",
|
||||
null, true);
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ &get()
|
||||
|
||||
/**
|
||||
* Fetch an attribute value.
|
||||
*
|
||||
* @param string attribute name
|
||||
*
|
||||
* @return attribute contents, or null if the attribute name is
|
||||
* unknown
|
||||
*/
|
||||
function &get($property)
|
||||
{
|
||||
// only return if $property is known
|
||||
if (isset($this->_properties[$property])) {
|
||||
return $this->$property;
|
||||
}
|
||||
$tmp = null;
|
||||
return $tmp;
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ _DB_storage()
|
||||
|
||||
/**
|
||||
* Destructor, calls DB_storage::store() if there are changes
|
||||
* that are to be kept.
|
||||
*/
|
||||
function _DB_storage()
|
||||
{
|
||||
if (sizeof($this->_changes)) {
|
||||
$this->store();
|
||||
}
|
||||
$this->_properties = array();
|
||||
$this->_changes = array();
|
||||
$this->_table = null;
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ store()
|
||||
|
||||
/**
|
||||
* Stores changes to this object in the database.
|
||||
*
|
||||
* @return DB_OK or a DB error
|
||||
*/
|
||||
function store()
|
||||
{
|
||||
foreach ($this->_changes as $name => $foo) {
|
||||
$params[] = &$this->$name;
|
||||
$vars[] = $name . ' = ?';
|
||||
}
|
||||
if ($vars) {
|
||||
$query = 'UPDATE ' . $this->_table . ' SET ' .
|
||||
implode(', ', $vars) . ' WHERE ' .
|
||||
$this->_makeWhere();
|
||||
$stmt = $this->_dbh->prepare($query);
|
||||
$res = $this->_dbh->execute($stmt, $params);
|
||||
if (DB::isError($res)) {
|
||||
return $res;
|
||||
}
|
||||
$this->_changes = array();
|
||||
}
|
||||
return DB_OK;
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ remove()
|
||||
|
||||
/**
|
||||
* Remove the row represented by this object from the database.
|
||||
*
|
||||
* @return mixed DB_OK or a DB error
|
||||
*/
|
||||
function remove()
|
||||
{
|
||||
if ($this->_readonly) {
|
||||
return $this->raiseError(null, DB_WARNING_READ_ONLY, null,
|
||||
null, null, null, true);
|
||||
}
|
||||
$query = 'DELETE FROM ' . $this->_table .' WHERE '.
|
||||
$this->_makeWhere();
|
||||
$res = $this->_dbh->query($query);
|
||||
if (DB::isError($res)) {
|
||||
return $res;
|
||||
}
|
||||
foreach ($this->_properties as $prop => $foo) {
|
||||
unset($this->$prop);
|
||||
}
|
||||
$this->_properties = array();
|
||||
$this->_changes = array();
|
||||
return DB_OK;
|
||||
}
|
||||
|
||||
// }}}
|
||||
}
|
||||
|
||||
/*
|
||||
* Local variables:
|
||||
* tab-width: 4
|
||||
* c-basic-offset: 4
|
||||
* End:
|
||||
*/
|
||||
|
||||
?>
|
||||
907
include/pear/DB/sybase.php
Normal file
907
include/pear/DB/sybase.php
Normal file
@@ -0,0 +1,907 @@
|
||||
<?php
|
||||
|
||||
/* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4: */
|
||||
|
||||
/**
|
||||
* The PEAR DB driver for PHP's sybase extension
|
||||
* for interacting with Sybase databases
|
||||
*
|
||||
* 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 Database
|
||||
* @package DB
|
||||
* @author Sterling Hughes <sterling@php.net>
|
||||
* @author Antônio Carlos Venâncio Júnior <floripa@php.net>
|
||||
* @author Daniel Convissor <danielc@php.net>
|
||||
* @copyright 1997-2005 The PHP Group
|
||||
* @license http://www.php.net/license/3_0.txt PHP License 3.0
|
||||
* @version CVS: $Id: sybase.php,v 1.78 2005/02/20 00:44:48 danielc Exp $
|
||||
* @link http://pear.php.net/package/DB
|
||||
*/
|
||||
|
||||
/**
|
||||
* Obtain the DB_common class so it can be extended from
|
||||
*/
|
||||
require_once 'DB/common.php';
|
||||
|
||||
/**
|
||||
* The methods PEAR DB uses to interact with PHP's sybase extension
|
||||
* for interacting with Sybase databases
|
||||
*
|
||||
* These methods overload the ones declared in DB_common.
|
||||
*
|
||||
* WARNING: This driver may fail with multiple connections under the
|
||||
* same user/pass/host and different databases.
|
||||
*
|
||||
* @category Database
|
||||
* @package DB
|
||||
* @author Sterling Hughes <sterling@php.net>
|
||||
* @author Antônio Carlos Venâncio Júnior <floripa@php.net>
|
||||
* @author Daniel Convissor <danielc@php.net>
|
||||
* @copyright 1997-2005 The PHP Group
|
||||
* @license http://www.php.net/license/3_0.txt PHP License 3.0
|
||||
* @version Release: @package_version@
|
||||
* @link http://pear.php.net/package/DB
|
||||
*/
|
||||
class DB_sybase extends DB_common
|
||||
{
|
||||
// {{{ properties
|
||||
|
||||
/**
|
||||
* The DB driver type (mysql, oci8, odbc, etc.)
|
||||
* @var string
|
||||
*/
|
||||
var $phptype = 'sybase';
|
||||
|
||||
/**
|
||||
* The database syntax variant to be used (db2, access, etc.), if any
|
||||
* @var string
|
||||
*/
|
||||
var $dbsyntax = 'sybase';
|
||||
|
||||
/**
|
||||
* The capabilities of this DB implementation
|
||||
*
|
||||
* The 'new_link' element contains the PHP version that first provided
|
||||
* new_link support for this DBMS. Contains false if it's unsupported.
|
||||
*
|
||||
* Meaning of the 'limit' element:
|
||||
* + 'emulate' = emulate with fetch row by number
|
||||
* + 'alter' = alter the query
|
||||
* + false = skip rows
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
var $features = array(
|
||||
'limit' => 'emulate',
|
||||
'new_link' => false,
|
||||
'numrows' => true,
|
||||
'pconnect' => true,
|
||||
'prepare' => false,
|
||||
'ssl' => false,
|
||||
'transactions' => true,
|
||||
);
|
||||
|
||||
/**
|
||||
* A mapping of native error codes to DB error codes
|
||||
* @var array
|
||||
*/
|
||||
var $errorcode_map = array(
|
||||
);
|
||||
|
||||
/**
|
||||
* The raw database connection created by PHP
|
||||
* @var resource
|
||||
*/
|
||||
var $connection;
|
||||
|
||||
/**
|
||||
* The DSN information for connecting to a database
|
||||
* @var array
|
||||
*/
|
||||
var $dsn = array();
|
||||
|
||||
|
||||
/**
|
||||
* Should data manipulation queries be committed automatically?
|
||||
* @var bool
|
||||
* @access private
|
||||
*/
|
||||
var $autocommit = true;
|
||||
|
||||
/**
|
||||
* The quantity of transactions begun
|
||||
*
|
||||
* {@internal While this is private, it can't actually be designated
|
||||
* private in PHP 5 because it is directly accessed in the test suite.}}
|
||||
*
|
||||
* @var integer
|
||||
* @access private
|
||||
*/
|
||||
var $transaction_opcount = 0;
|
||||
|
||||
/**
|
||||
* The database specified in the DSN
|
||||
*
|
||||
* It's a fix to allow calls to different databases in the same script.
|
||||
*
|
||||
* @var string
|
||||
* @access private
|
||||
*/
|
||||
var $_db = '';
|
||||
|
||||
|
||||
// }}}
|
||||
// {{{ constructor
|
||||
|
||||
/**
|
||||
* This constructor calls <kbd>$this->DB_common()</kbd>
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
function DB_sybase()
|
||||
{
|
||||
$this->DB_common();
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ connect()
|
||||
|
||||
/**
|
||||
* Connect to the database server, log in and open the database
|
||||
*
|
||||
* Don't call this method directly. Use DB::connect() instead.
|
||||
*
|
||||
* PEAR DB's sybase driver supports the following extra DSN options:
|
||||
* + appname The application name to use on this connection.
|
||||
* Available since PEAR DB 1.7.0.
|
||||
* + charset The character set to use on this connection.
|
||||
* Available since PEAR DB 1.7.0.
|
||||
*
|
||||
* @param array $dsn the data source name
|
||||
* @param bool $persistent should the connection be persistent?
|
||||
*
|
||||
* @return int DB_OK on success. A DB_Error object on failure.
|
||||
*/
|
||||
function connect($dsn, $persistent = false)
|
||||
{
|
||||
if (!PEAR::loadExtension('sybase') &&
|
||||
!PEAR::loadExtension('sybase_ct'))
|
||||
{
|
||||
return $this->raiseError(DB_ERROR_EXTENSION_NOT_FOUND);
|
||||
}
|
||||
|
||||
$this->dsn = $dsn;
|
||||
if ($dsn['dbsyntax']) {
|
||||
$this->dbsyntax = $dsn['dbsyntax'];
|
||||
}
|
||||
|
||||
$dsn['hostspec'] = $dsn['hostspec'] ? $dsn['hostspec'] : 'localhost';
|
||||
$dsn['password'] = !empty($dsn['password']) ? $dsn['password'] : false;
|
||||
$dsn['charset'] = isset($dsn['charset']) ? $dsn['charset'] : false;
|
||||
$dsn['appname'] = isset($dsn['appname']) ? $dsn['appname'] : false;
|
||||
|
||||
$connect_function = $persistent ? 'sybase_pconnect' : 'sybase_connect';
|
||||
|
||||
if ($dsn['username']) {
|
||||
$this->connection = @$connect_function($dsn['hostspec'],
|
||||
$dsn['username'],
|
||||
$dsn['password'],
|
||||
$dsn['charset'],
|
||||
$dsn['appname']);
|
||||
} else {
|
||||
return $this->raiseError(DB_ERROR_CONNECT_FAILED,
|
||||
null, null, null,
|
||||
'The DSN did not contain a username.');
|
||||
}
|
||||
|
||||
if (!$this->connection) {
|
||||
return $this->raiseError(DB_ERROR_CONNECT_FAILED,
|
||||
null, null, null,
|
||||
@sybase_get_last_message());
|
||||
}
|
||||
|
||||
if ($dsn['database']) {
|
||||
if (!@sybase_select_db($dsn['database'], $this->connection)) {
|
||||
return $this->raiseError(DB_ERROR_NODBSELECTED,
|
||||
null, null, null,
|
||||
@sybase_get_last_message());
|
||||
}
|
||||
$this->_db = $dsn['database'];
|
||||
}
|
||||
|
||||
return DB_OK;
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ disconnect()
|
||||
|
||||
/**
|
||||
* Disconnects from the database server
|
||||
*
|
||||
* @return bool TRUE on success, FALSE on failure
|
||||
*/
|
||||
function disconnect()
|
||||
{
|
||||
$ret = @sybase_close($this->connection);
|
||||
$this->connection = null;
|
||||
return $ret;
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ simpleQuery()
|
||||
|
||||
/**
|
||||
* Sends a query to the database server
|
||||
*
|
||||
* @param string the SQL query string
|
||||
*
|
||||
* @return mixed + a PHP result resrouce for successful SELECT queries
|
||||
* + the DB_OK constant for other successful queries
|
||||
* + a DB_Error object on failure
|
||||
*/
|
||||
function simpleQuery($query)
|
||||
{
|
||||
$ismanip = DB::isManip($query);
|
||||
$this->last_query = $query;
|
||||
if (!@sybase_select_db($this->_db, $this->connection)) {
|
||||
return $this->sybaseRaiseError(DB_ERROR_NODBSELECTED);
|
||||
}
|
||||
$query = $this->modifyQuery($query);
|
||||
if (!$this->autocommit && $ismanip) {
|
||||
if ($this->transaction_opcount == 0) {
|
||||
$result = @sybase_query('BEGIN TRANSACTION', $this->connection);
|
||||
if (!$result) {
|
||||
return $this->sybaseRaiseError();
|
||||
}
|
||||
}
|
||||
$this->transaction_opcount++;
|
||||
}
|
||||
$result = @sybase_query($query, $this->connection);
|
||||
if (!$result) {
|
||||
return $this->sybaseRaiseError();
|
||||
}
|
||||
if (is_resource($result)) {
|
||||
return $result;
|
||||
}
|
||||
// Determine which queries that should return data, and which
|
||||
// should return an error code only.
|
||||
return $ismanip ? DB_OK : $result;
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ nextResult()
|
||||
|
||||
/**
|
||||
* Move the internal sybase result pointer to the next available result
|
||||
*
|
||||
* @param a valid sybase result resource
|
||||
*
|
||||
* @access public
|
||||
*
|
||||
* @return true if a result is available otherwise return false
|
||||
*/
|
||||
function nextResult($result)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ fetchInto()
|
||||
|
||||
/**
|
||||
* Places a row from the result set into the given array
|
||||
*
|
||||
* Formating of the array and the data therein are configurable.
|
||||
* See DB_result::fetchInto() for more information.
|
||||
*
|
||||
* This method is not meant to be called directly. Use
|
||||
* DB_result::fetchInto() instead. It can't be declared "protected"
|
||||
* because DB_result is a separate object.
|
||||
*
|
||||
* @param resource $result the query result resource
|
||||
* @param array $arr the referenced array to put the data in
|
||||
* @param int $fetchmode how the resulting array should be indexed
|
||||
* @param int $rownum the row number to fetch (0 = first row)
|
||||
*
|
||||
* @return mixed DB_OK on success, NULL when the end of a result set is
|
||||
* reached or on failure
|
||||
*
|
||||
* @see DB_result::fetchInto()
|
||||
*/
|
||||
function fetchInto($result, &$arr, $fetchmode, $rownum = null)
|
||||
{
|
||||
if ($rownum !== null) {
|
||||
if (!@sybase_data_seek($result, $rownum)) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
if ($fetchmode & DB_FETCHMODE_ASSOC) {
|
||||
if (function_exists('sybase_fetch_assoc')) {
|
||||
$arr = @sybase_fetch_assoc($result);
|
||||
} else {
|
||||
if ($arr = @sybase_fetch_array($result)) {
|
||||
foreach ($arr as $key => $value) {
|
||||
if (is_int($key)) {
|
||||
unset($arr[$key]);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if ($this->options['portability'] & DB_PORTABILITY_LOWERCASE && $arr) {
|
||||
$arr = array_change_key_case($arr, CASE_LOWER);
|
||||
}
|
||||
} else {
|
||||
$arr = @sybase_fetch_row($result);
|
||||
}
|
||||
if (!$arr) {
|
||||
return null;
|
||||
}
|
||||
if ($this->options['portability'] & DB_PORTABILITY_RTRIM) {
|
||||
$this->_rtrimArrayValues($arr);
|
||||
}
|
||||
if ($this->options['portability'] & DB_PORTABILITY_NULL_TO_EMPTY) {
|
||||
$this->_convertNullArrayValuesToEmpty($arr);
|
||||
}
|
||||
return DB_OK;
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ freeResult()
|
||||
|
||||
/**
|
||||
* Deletes the result set and frees the memory occupied by the result set
|
||||
*
|
||||
* This method is not meant to be called directly. Use
|
||||
* DB_result::free() instead. It can't be declared "protected"
|
||||
* because DB_result is a separate object.
|
||||
*
|
||||
* @param resource $result PHP's query result resource
|
||||
*
|
||||
* @return bool TRUE on success, FALSE if $result is invalid
|
||||
*
|
||||
* @see DB_result::free()
|
||||
*/
|
||||
function freeResult($result)
|
||||
{
|
||||
return @sybase_free_result($result);
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ numCols()
|
||||
|
||||
/**
|
||||
* Gets the number of columns in a result set
|
||||
*
|
||||
* This method is not meant to be called directly. Use
|
||||
* DB_result::numCols() instead. It can't be declared "protected"
|
||||
* because DB_result is a separate object.
|
||||
*
|
||||
* @param resource $result PHP's query result resource
|
||||
*
|
||||
* @return int the number of columns. A DB_Error object on failure.
|
||||
*
|
||||
* @see DB_result::numCols()
|
||||
*/
|
||||
function numCols($result)
|
||||
{
|
||||
$cols = @sybase_num_fields($result);
|
||||
if (!$cols) {
|
||||
return $this->sybaseRaiseError();
|
||||
}
|
||||
return $cols;
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ numRows()
|
||||
|
||||
/**
|
||||
* Gets the number of rows in a result set
|
||||
*
|
||||
* This method is not meant to be called directly. Use
|
||||
* DB_result::numRows() instead. It can't be declared "protected"
|
||||
* because DB_result is a separate object.
|
||||
*
|
||||
* @param resource $result PHP's query result resource
|
||||
*
|
||||
* @return int the number of rows. A DB_Error object on failure.
|
||||
*
|
||||
* @see DB_result::numRows()
|
||||
*/
|
||||
function numRows($result)
|
||||
{
|
||||
$rows = @sybase_num_rows($result);
|
||||
if ($rows === false) {
|
||||
return $this->sybaseRaiseError();
|
||||
}
|
||||
return $rows;
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ affectedRows()
|
||||
|
||||
/**
|
||||
* Determines the number of rows affected by a data maniuplation query
|
||||
*
|
||||
* 0 is returned for queries that don't manipulate data.
|
||||
*
|
||||
* @return int the number of rows. A DB_Error object on failure.
|
||||
*/
|
||||
function affectedRows()
|
||||
{
|
||||
if (DB::isManip($this->last_query)) {
|
||||
$result = @sybase_affected_rows($this->connection);
|
||||
} else {
|
||||
$result = 0;
|
||||
}
|
||||
return $result;
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ nextId()
|
||||
|
||||
/**
|
||||
* Returns the next free id in a sequence
|
||||
*
|
||||
* @param string $seq_name name of the sequence
|
||||
* @param boolean $ondemand when true, the seqence is automatically
|
||||
* created if it does not exist
|
||||
*
|
||||
* @return int the next id number in the sequence.
|
||||
* A DB_Error object on failure.
|
||||
*
|
||||
* @see DB_common::nextID(), DB_common::getSequenceName(),
|
||||
* DB_sybase::createSequence(), DB_sybase::dropSequence()
|
||||
*/
|
||||
function nextId($seq_name, $ondemand = true)
|
||||
{
|
||||
$seqname = $this->getSequenceName($seq_name);
|
||||
if (!@sybase_select_db($this->_db, $this->connection)) {
|
||||
return $this->sybaseRaiseError(DB_ERROR_NODBSELECTED);
|
||||
}
|
||||
$repeat = 0;
|
||||
do {
|
||||
$this->pushErrorHandling(PEAR_ERROR_RETURN);
|
||||
$result = $this->query("INSERT INTO $seqname (vapor) VALUES (0)");
|
||||
$this->popErrorHandling();
|
||||
if ($ondemand && DB::isError($result) &&
|
||||
($result->getCode() == DB_ERROR || $result->getCode() == DB_ERROR_NOSUCHTABLE))
|
||||
{
|
||||
$repeat = 1;
|
||||
$result = $this->createSequence($seq_name);
|
||||
if (DB::isError($result)) {
|
||||
return $this->raiseError($result);
|
||||
}
|
||||
} elseif (!DB::isError($result)) {
|
||||
$result =& $this->query("SELECT @@IDENTITY FROM $seqname");
|
||||
$repeat = 0;
|
||||
} else {
|
||||
$repeat = false;
|
||||
}
|
||||
} while ($repeat);
|
||||
if (DB::isError($result)) {
|
||||
return $this->raiseError($result);
|
||||
}
|
||||
$result = $result->fetchRow(DB_FETCHMODE_ORDERED);
|
||||
return $result[0];
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new sequence
|
||||
*
|
||||
* @param string $seq_name name of the new sequence
|
||||
*
|
||||
* @return int DB_OK on success. A DB_Error object on failure.
|
||||
*
|
||||
* @see DB_common::createSequence(), DB_common::getSequenceName(),
|
||||
* DB_sybase::nextID(), DB_sybase::dropSequence()
|
||||
*/
|
||||
function createSequence($seq_name)
|
||||
{
|
||||
return $this->query('CREATE TABLE '
|
||||
. $this->getSequenceName($seq_name)
|
||||
. ' (id numeric(10, 0) IDENTITY NOT NULL,'
|
||||
. ' vapor int NULL)');
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ dropSequence()
|
||||
|
||||
/**
|
||||
* Deletes a sequence
|
||||
*
|
||||
* @param string $seq_name name of the sequence to be deleted
|
||||
*
|
||||
* @return int DB_OK on success. A DB_Error object on failure.
|
||||
*
|
||||
* @see DB_common::dropSequence(), DB_common::getSequenceName(),
|
||||
* DB_sybase::nextID(), DB_sybase::createSequence()
|
||||
*/
|
||||
function dropSequence($seq_name)
|
||||
{
|
||||
return $this->query('DROP TABLE ' . $this->getSequenceName($seq_name));
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ autoCommit()
|
||||
|
||||
/**
|
||||
* Enables or disables automatic commits
|
||||
*
|
||||
* @param bool $onoff true turns it on, false turns it off
|
||||
*
|
||||
* @return int DB_OK on success. A DB_Error object if the driver
|
||||
* doesn't support auto-committing transactions.
|
||||
*/
|
||||
function autoCommit($onoff = false)
|
||||
{
|
||||
// XXX if $this->transaction_opcount > 0, we should probably
|
||||
// issue a warning here.
|
||||
$this->autocommit = $onoff ? true : false;
|
||||
return DB_OK;
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ commit()
|
||||
|
||||
/**
|
||||
* Commits the current transaction
|
||||
*
|
||||
* @return int DB_OK on success. A DB_Error object on failure.
|
||||
*/
|
||||
function commit()
|
||||
{
|
||||
if ($this->transaction_opcount > 0) {
|
||||
if (!@sybase_select_db($this->_db, $this->connection)) {
|
||||
return $this->sybaseRaiseError(DB_ERROR_NODBSELECTED);
|
||||
}
|
||||
$result = @sybase_query('COMMIT', $this->connection);
|
||||
$this->transaction_opcount = 0;
|
||||
if (!$result) {
|
||||
return $this->sybaseRaiseError();
|
||||
}
|
||||
}
|
||||
return DB_OK;
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ rollback()
|
||||
|
||||
/**
|
||||
* Reverts the current transaction
|
||||
*
|
||||
* @return int DB_OK on success. A DB_Error object on failure.
|
||||
*/
|
||||
function rollback()
|
||||
{
|
||||
if ($this->transaction_opcount > 0) {
|
||||
if (!@sybase_select_db($this->_db, $this->connection)) {
|
||||
return $this->sybaseRaiseError(DB_ERROR_NODBSELECTED);
|
||||
}
|
||||
$result = @sybase_query('ROLLBACK', $this->connection);
|
||||
$this->transaction_opcount = 0;
|
||||
if (!$result) {
|
||||
return $this->sybaseRaiseError();
|
||||
}
|
||||
}
|
||||
return DB_OK;
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ sybaseRaiseError()
|
||||
|
||||
/**
|
||||
* Produces a DB_Error object regarding the current problem
|
||||
*
|
||||
* @param int $errno if the error is being manually raised pass a
|
||||
* DB_ERROR* constant here. If this isn't passed
|
||||
* the error information gathered from the DBMS.
|
||||
*
|
||||
* @return object the DB_Error object
|
||||
*
|
||||
* @see DB_common::raiseError(),
|
||||
* DB_sybase::errorNative(), DB_sybase::errorCode()
|
||||
*/
|
||||
function sybaseRaiseError($errno = null)
|
||||
{
|
||||
$native = $this->errorNative();
|
||||
if ($errno === null) {
|
||||
$errno = $this->errorCode($native);
|
||||
}
|
||||
return $this->raiseError($errno, null, null, null, $native);
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ errorNative()
|
||||
|
||||
/**
|
||||
* Gets the DBMS' native error message produced by the last query
|
||||
*
|
||||
* @return string the DBMS' error message
|
||||
*/
|
||||
function errorNative()
|
||||
{
|
||||
return @sybase_get_last_message();
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ errorCode()
|
||||
|
||||
/**
|
||||
* Determines PEAR::DB error code from the database's text error message.
|
||||
*
|
||||
* @param string $errormsg error message returned from the database
|
||||
* @return integer an error number from a DB error constant
|
||||
*/
|
||||
function errorCode($errormsg)
|
||||
{
|
||||
static $error_regexps;
|
||||
if (!isset($error_regexps)) {
|
||||
$error_regexps = array(
|
||||
'/Incorrect syntax near/'
|
||||
=> DB_ERROR_SYNTAX,
|
||||
'/^Unclosed quote before the character string [\"\'].*[\"\']\./'
|
||||
=> DB_ERROR_SYNTAX,
|
||||
'/Implicit conversion (from datatype|of NUMERIC value)/i'
|
||||
=> DB_ERROR_INVALID_NUMBER,
|
||||
'/Cannot drop the table [\"\'].+[\"\'], because it doesn\'t exist in the system catalogs\./'
|
||||
=> DB_ERROR_NOSUCHTABLE,
|
||||
'/Only the owner of object [\"\'].+[\"\'] or a user with System Administrator \(SA\) role can run this command\./'
|
||||
=> DB_ERROR_ACCESS_VIOLATION,
|
||||
'/^.+ permission denied on object .+, database .+, owner .+/'
|
||||
=> DB_ERROR_ACCESS_VIOLATION,
|
||||
'/^.* permission denied, database .+, owner .+/'
|
||||
=> DB_ERROR_ACCESS_VIOLATION,
|
||||
'/[^.*] not found\./'
|
||||
=> DB_ERROR_NOSUCHTABLE,
|
||||
'/There is already an object named/'
|
||||
=> DB_ERROR_ALREADY_EXISTS,
|
||||
'/Invalid column name/'
|
||||
=> DB_ERROR_NOSUCHFIELD,
|
||||
'/does not allow null values/'
|
||||
=> DB_ERROR_CONSTRAINT_NOT_NULL,
|
||||
'/Command has been aborted/'
|
||||
=> DB_ERROR_CONSTRAINT,
|
||||
'/^Cannot drop the index .* because it doesn\'t exist/i'
|
||||
=> DB_ERROR_NOT_FOUND,
|
||||
'/^There is already an index/i'
|
||||
=> DB_ERROR_ALREADY_EXISTS,
|
||||
'/^There are fewer columns in the INSERT statement than values specified/i'
|
||||
=> DB_ERROR_VALUE_COUNT_ON_ROW,
|
||||
);
|
||||
}
|
||||
|
||||
foreach ($error_regexps as $regexp => $code) {
|
||||
if (preg_match($regexp, $errormsg)) {
|
||||
return $code;
|
||||
}
|
||||
}
|
||||
return DB_ERROR;
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ tableInfo()
|
||||
|
||||
/**
|
||||
* Returns information about a table or a result set
|
||||
*
|
||||
* NOTE: only supports 'table' and 'flags' if <var>$result</var>
|
||||
* is a table name.
|
||||
*
|
||||
* @param object|string $result DB_result object from a query or a
|
||||
* string containing the name of a table.
|
||||
* While this also accepts a query result
|
||||
* resource identifier, this behavior is
|
||||
* deprecated.
|
||||
* @param int $mode a valid tableInfo mode
|
||||
*
|
||||
* @return array an associative array with the information requested.
|
||||
* A DB_Error object on failure.
|
||||
*
|
||||
* @see DB_common::tableInfo()
|
||||
* @since Method available since Release 1.6.0
|
||||
*/
|
||||
function tableInfo($result, $mode = null)
|
||||
{
|
||||
if (is_string($result)) {
|
||||
/*
|
||||
* Probably received a table name.
|
||||
* Create a result resource identifier.
|
||||
*/
|
||||
if (!@sybase_select_db($this->_db, $this->connection)) {
|
||||
return $this->sybaseRaiseError(DB_ERROR_NODBSELECTED);
|
||||
}
|
||||
$id = @sybase_query("SELECT * FROM $result WHERE 1=0",
|
||||
$this->connection);
|
||||
$got_string = true;
|
||||
} elseif (isset($result->result)) {
|
||||
/*
|
||||
* Probably received a result object.
|
||||
* Extract the result resource identifier.
|
||||
*/
|
||||
$id = $result->result;
|
||||
$got_string = false;
|
||||
} else {
|
||||
/*
|
||||
* Probably received a result resource identifier.
|
||||
* Copy it.
|
||||
* Deprecated. Here for compatibility only.
|
||||
*/
|
||||
$id = $result;
|
||||
$got_string = false;
|
||||
}
|
||||
|
||||
if (!is_resource($id)) {
|
||||
return $this->sybaseRaiseError(DB_ERROR_NEED_MORE_DATA);
|
||||
}
|
||||
|
||||
if ($this->options['portability'] & DB_PORTABILITY_LOWERCASE) {
|
||||
$case_func = 'strtolower';
|
||||
} else {
|
||||
$case_func = 'strval';
|
||||
}
|
||||
|
||||
$count = @sybase_num_fields($id);
|
||||
$res = array();
|
||||
|
||||
if ($mode) {
|
||||
$res['num_fields'] = $count;
|
||||
}
|
||||
|
||||
for ($i = 0; $i < $count; $i++) {
|
||||
$f = @sybase_fetch_field($id, $i);
|
||||
// column_source is often blank
|
||||
$res[$i] = array(
|
||||
'table' => $got_string
|
||||
? $case_func($result)
|
||||
: $case_func($f->column_source),
|
||||
'name' => $case_func($f->name),
|
||||
'type' => $f->type,
|
||||
'len' => $f->max_length,
|
||||
'flags' => '',
|
||||
);
|
||||
if ($res[$i]['table']) {
|
||||
$res[$i]['flags'] = $this->_sybase_field_flags(
|
||||
$res[$i]['table'], $res[$i]['name']);
|
||||
}
|
||||
if ($mode & DB_TABLEINFO_ORDER) {
|
||||
$res['order'][$res[$i]['name']] = $i;
|
||||
}
|
||||
if ($mode & DB_TABLEINFO_ORDERTABLE) {
|
||||
$res['ordertable'][$res[$i]['table']][$res[$i]['name']] = $i;
|
||||
}
|
||||
}
|
||||
|
||||
// free the result only if we were called on a table
|
||||
if ($got_string) {
|
||||
@sybase_free_result($id);
|
||||
}
|
||||
return $res;
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ _sybase_field_flags()
|
||||
|
||||
/**
|
||||
* Get the flags for a field
|
||||
*
|
||||
* Currently supports:
|
||||
* + <samp>unique_key</samp> (unique index, unique check or primary_key)
|
||||
* + <samp>multiple_key</samp> (multi-key index)
|
||||
*
|
||||
* @param string $table the table name
|
||||
* @param string $column the field name
|
||||
*
|
||||
* @return string space delimited string of flags. Empty string if none.
|
||||
*
|
||||
* @access private
|
||||
*/
|
||||
function _sybase_field_flags($table, $column)
|
||||
{
|
||||
static $tableName = null;
|
||||
static $flags = array();
|
||||
|
||||
if ($table != $tableName) {
|
||||
$flags = array();
|
||||
$tableName = $table;
|
||||
|
||||
// get unique/primary keys
|
||||
$res = $this->getAll("sp_helpindex $table", DB_FETCHMODE_ASSOC);
|
||||
|
||||
if (!isset($res[0]['index_description'])) {
|
||||
return '';
|
||||
}
|
||||
|
||||
foreach ($res as $val) {
|
||||
$keys = explode(', ', trim($val['index_keys']));
|
||||
|
||||
if (sizeof($keys) > 1) {
|
||||
foreach ($keys as $key) {
|
||||
$this->_add_flag($flags[$key], 'multiple_key');
|
||||
}
|
||||
}
|
||||
|
||||
if (strpos($val['index_description'], 'unique')) {
|
||||
foreach ($keys as $key) {
|
||||
$this->_add_flag($flags[$key], 'unique_key');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if (array_key_exists($column, $flags)) {
|
||||
return(implode(' ', $flags[$column]));
|
||||
}
|
||||
|
||||
return '';
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ _add_flag()
|
||||
|
||||
/**
|
||||
* Adds a string to the flags array if the flag is not yet in there
|
||||
* - if there is no flag present the array is created
|
||||
*
|
||||
* @param array $array reference of flags array to add a value to
|
||||
* @param mixed $value value to add to the flag array
|
||||
*
|
||||
* @return void
|
||||
*
|
||||
* @access private
|
||||
*/
|
||||
function _add_flag(&$array, $value)
|
||||
{
|
||||
if (!is_array($array)) {
|
||||
$array = array($value);
|
||||
} elseif (!in_array($value, $array)) {
|
||||
array_push($array, $value);
|
||||
}
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ getSpecialQuery()
|
||||
|
||||
/**
|
||||
* Obtains the query string needed for listing a given type of objects
|
||||
*
|
||||
* @param string $type the kind of objects you want to retrieve
|
||||
*
|
||||
* @return string the SQL query string or null if the driver doesn't
|
||||
* support the object type requested
|
||||
*
|
||||
* @access protected
|
||||
* @see DB_common::getListOf()
|
||||
*/
|
||||
function getSpecialQuery($type)
|
||||
{
|
||||
switch ($type) {
|
||||
case 'tables':
|
||||
return "SELECT name FROM sysobjects WHERE type = 'U'"
|
||||
. ' ORDER BY name';
|
||||
case 'views':
|
||||
return "SELECT name FROM sysobjects WHERE type = 'V'";
|
||||
default:
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
// }}}
|
||||
|
||||
}
|
||||
|
||||
/*
|
||||
* Local variables:
|
||||
* tab-width: 4
|
||||
* c-basic-offset: 4
|
||||
* End:
|
||||
*/
|
||||
|
||||
?>
|
||||
1465
include/pear/Date.php
Normal file
1465
include/pear/Date.php
Normal file
File diff suppressed because it is too large
Load Diff
2117
include/pear/Date/Calc.php
Normal file
2117
include/pear/Date/Calc.php
Normal file
File diff suppressed because it is too large
Load Diff
242
include/pear/Date/Human.php
Normal file
242
include/pear/Date/Human.php
Normal file
@@ -0,0 +1,242 @@
|
||||
<?php
|
||||
/* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4 foldmethod=marker: */
|
||||
|
||||
// {{{ Header
|
||||
|
||||
/**
|
||||
* Class to convert date strings between Gregorian and Human calendar formats
|
||||
*
|
||||
* The Human Calendar format has been proposed by Scott Flansburg and can be
|
||||
* explained as follows:
|
||||
* The year is made up of 13 months
|
||||
* Each month has 28 days
|
||||
* Counting of months starts from 0 (zero) so the months will run from 0 to 12
|
||||
* New Years day (00) is a monthless day
|
||||
* Note: Leap Years are not yet accounted for in the Human Calendar system
|
||||
*
|
||||
* PHP versions 4 and 5
|
||||
*
|
||||
* LICENSE:
|
||||
*
|
||||
* Copyright (c) 1997-2006 Allan Kent
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted under the terms of the BSD License.
|
||||
*
|
||||
* 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 Date and Time
|
||||
* @package Date
|
||||
* @author Allan Kent <allan@lodestone.co.za>
|
||||
* @copyright 1997-2006 Allan Kent
|
||||
* @license http://www.opensource.org/licenses/bsd-license.php
|
||||
* BSD License
|
||||
* @version CVS: $Id: Human.php,v 1.6 2006/11/21 17:38:15 firman Exp $
|
||||
* @link http://pear.php.net/package/Date
|
||||
* @since File available since Release 1.3
|
||||
*/
|
||||
|
||||
// }}}
|
||||
// {{{ Class: Date_Human
|
||||
|
||||
/**
|
||||
* Class to convert date strings between Gregorian and Human calendar formats
|
||||
*
|
||||
* The Human Calendar format has been proposed by Scott Flansburg and can be
|
||||
* explained as follows:
|
||||
* The year is made up of 13 months
|
||||
* Each month has 28 days
|
||||
* Counting of months starts from 0 (zero) so the months will run from 0 to 12
|
||||
* New Years day (00) is a monthless day
|
||||
* Note: Leap Years are not yet accounted for in the Human Calendar system
|
||||
*
|
||||
* @author Allan Kent <allan@lodestone.co.za>
|
||||
* @copyright 1997-2005 Allan Kent
|
||||
* @license http://www.opensource.org/licenses/bsd-license.php
|
||||
* BSD License
|
||||
* @version Release: 1.4.7
|
||||
* @link http://pear.php.net/package/Date
|
||||
* @since Class available since Release 1.3
|
||||
*/
|
||||
class Date_Human
|
||||
{
|
||||
// {{{ gregorianToHuman()
|
||||
|
||||
/**
|
||||
* Returns an associative array containing the converted date information
|
||||
* in 'Human Calendar' format.
|
||||
*
|
||||
* @param int day in DD format, default current local day
|
||||
* @param int month in MM format, default current local month
|
||||
* @param int year in CCYY format, default to current local year
|
||||
*
|
||||
* @access public
|
||||
*
|
||||
* @return associative array(
|
||||
* hdom, // Human Day Of Month, starting at 1
|
||||
* hdow, // Human Day Of Week, starting at 1
|
||||
* hwom, // Human Week of Month, starting at 1
|
||||
* hwoy, // Human Week of Year, starting at 1
|
||||
* hmoy, // Human Month of Year, starting at 0
|
||||
* )
|
||||
*
|
||||
* If the day is New Years Day, the function will return
|
||||
* "hdom" => 0
|
||||
* "hdow" => 0
|
||||
* "hwom" => 0
|
||||
* "hwoy" => 0
|
||||
* "hmoy" => -1
|
||||
* Since 0 is a valid month number under the Human Calendar, I have left
|
||||
* the month as -1 for New Years Day.
|
||||
*/
|
||||
function gregorianToHuman($day=0, $month=0, $year=0)
|
||||
{
|
||||
/*
|
||||
* Check to see if any of the arguments are empty
|
||||
* If they are then populate the $dateinfo array
|
||||
* Then check to see which arguments are empty and fill
|
||||
* those with the current date info
|
||||
*/
|
||||
if ((empty($day) || (empty($month)) || empty($year))) {
|
||||
$dateinfo = getdate(time());
|
||||
}
|
||||
if (empty($day)) {
|
||||
$day = $dateinfo["mday"];
|
||||
}
|
||||
if (empty($month)) {
|
||||
$month = $dateinfo["mon"];
|
||||
}
|
||||
if (empty($year)) {
|
||||
$year = $dateinfo["year"];
|
||||
}
|
||||
/*
|
||||
* We need to know how many days into the year we are
|
||||
*/
|
||||
$dateinfo = getdate(mktime(0, 0, 0, $month, $day, $year));
|
||||
$dayofyear = $dateinfo["yday"];
|
||||
/*
|
||||
* Human Calendar starts at 0 for months and the first day of the year
|
||||
* is designated 00, so we need to start our day of the year at 0 for
|
||||
* these calculations.
|
||||
* Also, the day of the month is calculated with a modulus of 28.
|
||||
* Because a day is 28 days, the last day of the month would have a
|
||||
* remainder of 0 and not 28 as it should be. Decrementing $dayofyear
|
||||
* gets around this.
|
||||
*/
|
||||
$dayofyear--;
|
||||
/*
|
||||
* 28 days in a month...
|
||||
*/
|
||||
$humanMonthOfYear = floor($dayofyear / 28);
|
||||
/*
|
||||
* If we are in the first month then the day of the month is $dayofyear
|
||||
* else we need to find the modulus of 28.
|
||||
*/
|
||||
if ($humanMonthOfYear == 0) {
|
||||
$humanDayOfMonth = $dayofyear;
|
||||
} else {
|
||||
$humanDayOfMonth = ($dayofyear) % 28;
|
||||
}
|
||||
/*
|
||||
* Day of the week is modulus 7
|
||||
*/
|
||||
$humanDayOfWeek = $dayofyear % 7;
|
||||
/*
|
||||
* We can now increment $dayofyear back to it's correct value for
|
||||
* the remainder of the calculations
|
||||
*/
|
||||
$dayofyear++;
|
||||
/*
|
||||
* $humanDayOfMonth needs to be incremented now - recall that we fudged
|
||||
* it a bit by decrementing $dayofyear earlier
|
||||
* Same goes for $humanDayOfWeek
|
||||
*/
|
||||
$humanDayOfMonth++;
|
||||
$humanDayOfWeek++;
|
||||
/*
|
||||
* Week of the month is day of the month divided by 7, rounded up
|
||||
* Same for week of the year, but use $dayofyear instead $humanDayOfMonth
|
||||
*/
|
||||
$humanWeekOfMonth = ceil($humanDayOfMonth / 7);
|
||||
$humanWeekOfYear = ceil($dayofyear / 7);
|
||||
/*
|
||||
* Return an associative array of the values
|
||||
*/
|
||||
return array(
|
||||
"hdom" => $humanDayOfMonth,
|
||||
"hdow" => $humanDayOfWeek,
|
||||
"hwom" => $humanWeekOfMonth,
|
||||
"hwoy" => $humanWeekOfYear,
|
||||
"hmoy" => $humanMonthOfYear );
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ humanToGregorian()
|
||||
|
||||
/**
|
||||
* Returns unix timestamp for a given Human Calendar date
|
||||
*
|
||||
* @param int day in DD format
|
||||
* @param int month in MM format
|
||||
* @param int year in CCYY format, default to current local year
|
||||
*
|
||||
* @access public
|
||||
*
|
||||
* @return int unix timestamp of date
|
||||
*/
|
||||
function humanToGregorian($day, $month, $year=0)
|
||||
{
|
||||
/*
|
||||
* Check to see if the year has been passed through.
|
||||
* If not get current year
|
||||
*/
|
||||
if (empty($year)) {
|
||||
$dateinfo = getdate(time());
|
||||
$year = $dateinfo["year"];
|
||||
}
|
||||
/*
|
||||
* We need to get the day of the year that we are currently at so that
|
||||
* we can work out the Gregorian Month and day
|
||||
*/
|
||||
$DayOfYear = $month * 28;
|
||||
$DayOfYear += $day;
|
||||
/*
|
||||
* Human Calendar starts at 0, so we need to increment $DayOfYear
|
||||
* to take into account the day 00
|
||||
*/
|
||||
$DayOfYear++;
|
||||
/*
|
||||
* the mktime() function will correctly calculate the date for out of
|
||||
* range values, so putting $DayOfYear instead of the day of the month
|
||||
* will work fine.
|
||||
*/
|
||||
$GregorianTimeStamp = mktime(0, 0, 0, 1, $DayOfYear, $year);
|
||||
return $GregorianTimeStamp;
|
||||
}
|
||||
|
||||
// }}}
|
||||
}
|
||||
|
||||
// }}}
|
||||
|
||||
/*
|
||||
* Local variables:
|
||||
* mode: php
|
||||
* tab-width: 4
|
||||
* c-basic-offset: 4
|
||||
* c-hanging-comment-ender-p: nil
|
||||
* End:
|
||||
*/
|
||||
?>
|
||||
1083
include/pear/Date/Span.php
Normal file
1083
include/pear/Date/Span.php
Normal file
File diff suppressed because it is too large
Load Diff
4731
include/pear/Date/TimeZone.php
Normal file
4731
include/pear/Date/TimeZone.php
Normal file
File diff suppressed because it is too large
Load Diff
957
include/pear/HTML/AJAX.php
Normal file
957
include/pear/HTML/AJAX.php
Normal file
@@ -0,0 +1,957 @@
|
||||
<?php
|
||||
// $Id$
|
||||
|
||||
/**
|
||||
* This is a quick hack, loading serializers as needed doesn't work in php5
|
||||
*/
|
||||
require_once "HTML/AJAX/Serializer/JSON.php";
|
||||
require_once "HTML/AJAX/Serializer/Null.php";
|
||||
require_once "HTML/AJAX/Serializer/Error.php";
|
||||
require_once "HTML/AJAX/Serializer/XML.php";
|
||||
require_once "HTML/AJAX/Serializer/PHP.php";
|
||||
require_once 'HTML/AJAX/Debug.php';
|
||||
|
||||
/**
|
||||
* OO AJAX Implementation for PHP
|
||||
*
|
||||
* @category HTML
|
||||
* @package AJAX
|
||||
* @author Joshua Eichorn <josh@bluga.net>
|
||||
* @author Arpad Ray <arpad@php.net>
|
||||
* @author David Coallier <davidc@php.net>
|
||||
* @author Elizabeth Smith <auroraeosrose@gmail.com>
|
||||
* @copyright 2005 Joshua Eichorn, Arpad Ray, David Coallier, Elizabeth Smith
|
||||
* @license http://www.opensource.org/licenses/lgpl-license.php LGPL
|
||||
* @version Release: 0.5.2
|
||||
* @link http://pear.php.net/package/HTML_AJAX
|
||||
*/
|
||||
class HTML_AJAX {
|
||||
/**
|
||||
* An array holding the instances were exporting
|
||||
*
|
||||
* key is the exported name
|
||||
*
|
||||
* row format is array('className'=>'','exportedName'=>'','instance'=>'','exportedMethods=>'')
|
||||
*
|
||||
* @var object
|
||||
* @access private
|
||||
*/
|
||||
var $_exportedInstances = array();
|
||||
|
||||
/**
|
||||
* Set the server url in the generated stubs to this value
|
||||
* If set to false, serverUrl will not be set
|
||||
* @var false|string
|
||||
*/
|
||||
var $serverUrl = false;
|
||||
|
||||
/**
|
||||
* What encoding your going to use for serializing data from php being sent to javascript
|
||||
* @var string JSON|PHP|Null
|
||||
*/
|
||||
var $serializer = 'JSON';
|
||||
|
||||
/**
|
||||
* What encoding your going to use for unserializing data sent from javascript
|
||||
* @var string JSON|PHP|Null
|
||||
*/
|
||||
var $unserializer = 'JSON';
|
||||
|
||||
/**
|
||||
* Option to use loose typing for JSON encoding
|
||||
* @var bool
|
||||
* @access public
|
||||
*/
|
||||
var $jsonLooseType = true;
|
||||
|
||||
/**
|
||||
* Content-type map
|
||||
*
|
||||
* Used in to automatically choose serializers as needed
|
||||
*/
|
||||
var $contentTypeMap = array(
|
||||
'JSON' => 'application/json',
|
||||
'XML' => 'application/xml',
|
||||
'Null' => 'text/plain',
|
||||
'Error' => 'application/error',
|
||||
'PHP' => 'application/php-serialized',
|
||||
'Urlencoded' => 'application/x-www-form-urlencoded'
|
||||
);
|
||||
|
||||
/**
|
||||
* This is the debug variable that we will be passing the
|
||||
* HTML_AJAX_Debug instance to.
|
||||
*
|
||||
* @param object HTML_AJAX_Debug
|
||||
*/
|
||||
var $debug;
|
||||
|
||||
/**
|
||||
* This is to tell if debug is enabled or not. If so, then
|
||||
* debug is called, instantiated then saves the file and such.
|
||||
*/
|
||||
var $debugEnabled = false;
|
||||
|
||||
/**
|
||||
* This puts the error into a session variable is set to true.
|
||||
* set to false by default.
|
||||
*
|
||||
* @access public
|
||||
*/
|
||||
var $debugSession = false;
|
||||
|
||||
/**
|
||||
* If the Content-Length header should be sent, if your using a gzip handler on an output buffer, or run into any compatability problems, try disabling this.
|
||||
*
|
||||
* @access public
|
||||
* @var boolean
|
||||
*/
|
||||
var $sendContentLength = true;
|
||||
|
||||
/**
|
||||
* Make Generated code compatible with php4 by lowercasing all class/method names before exporting to JavaScript
|
||||
* If you have code that works on php4 but not on php5 then setting this flag can fix the problem.
|
||||
* The recommended solution is too specify the class and method names when registering the class letting you have function case in php4 as well
|
||||
*
|
||||
* @access public
|
||||
* @var boolean
|
||||
*/
|
||||
var $php4CompatCase = false;
|
||||
|
||||
/**
|
||||
* Automatically pack all generated JavaScript making it smaller
|
||||
*
|
||||
* If your using output compression this might not make sense
|
||||
*/
|
||||
var $packJavaScript = false;
|
||||
|
||||
/**
|
||||
* Holds current payload info
|
||||
*
|
||||
* @access private
|
||||
* @var string
|
||||
*/
|
||||
var $_payload;
|
||||
|
||||
/**
|
||||
* Holds iframe id IF this is an iframe xmlhttprequest
|
||||
*
|
||||
* @access private
|
||||
* @var string
|
||||
*/
|
||||
var $_iframe;
|
||||
|
||||
/**
|
||||
* Holds the list of classes permitted to be unserialized
|
||||
*
|
||||
* @access private
|
||||
* @var array
|
||||
*/
|
||||
var $_allowedClasses = array();
|
||||
|
||||
/**
|
||||
* Holds serializer instances
|
||||
*/
|
||||
var $_serializers = array();
|
||||
|
||||
/**
|
||||
* PHP callbacks we're exporting
|
||||
*/
|
||||
var $_validCallbacks = array();
|
||||
|
||||
/**
|
||||
* Interceptor instance
|
||||
*/
|
||||
var $_interceptor = false;
|
||||
|
||||
/**
|
||||
* Set a class to handle requests
|
||||
*
|
||||
* @param object $instance
|
||||
* @param mixed $exportedName Name used for the javascript class, if false the name of the php class is used
|
||||
* @param mixed $exportedMethods If false all functions without a _ prefix are exported, if an array only the methods listed in the array are exported
|
||||
* @return void
|
||||
*/
|
||||
function registerClass(&$instance, $exportedName = false, $exportedMethods = false)
|
||||
{
|
||||
$className = strtolower(get_class($instance));
|
||||
|
||||
if ($exportedName === false) {
|
||||
$exportedName = get_class($instance);
|
||||
if ($this->php4CompatCase) {
|
||||
$exportedName = strtolower($exportedName);
|
||||
}
|
||||
}
|
||||
|
||||
if ($exportedMethods === false) {
|
||||
$exportedMethods = $this->_getMethodsToExport($className);
|
||||
}
|
||||
|
||||
|
||||
$index = strtolower($exportedName);
|
||||
$this->_exportedInstances[$index] = array();
|
||||
$this->_exportedInstances[$index]['className'] = $className;
|
||||
$this->_exportedInstances[$index]['exportedName'] = $exportedName;
|
||||
$this->_exportedInstances[$index]['instance'] =& $instance;
|
||||
$this->_exportedInstances[$index]['exportedMethods'] = $exportedMethods;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a list of methods in a class to export
|
||||
*
|
||||
* This function uses get_class_methods to get a list of callable methods, so if you're on PHP5 extending this class with a class you want to export should export its
|
||||
* protected methods, while normally only its public methods would be exported. All methods starting with _ are removed from the export list.
|
||||
* This covers PHP4 style private by naming as well as magic methods in either PHP4 or PHP5
|
||||
*
|
||||
* @param string $className
|
||||
* @return array all methods of the class that are public
|
||||
* @access private
|
||||
*/
|
||||
function _getMethodsToExport($className)
|
||||
{
|
||||
$funcs = get_class_methods($className);
|
||||
|
||||
foreach ($funcs as $key => $func) {
|
||||
if (strtolower($func) === $className || substr($func,0,1) === '_') {
|
||||
unset($funcs[$key]);
|
||||
}
|
||||
else if ($this->php4CompatCase) {
|
||||
$funcs[$key] = strtolower($func);
|
||||
}
|
||||
}
|
||||
return $funcs;
|
||||
}
|
||||
|
||||
/**
|
||||
* Generate the client Javascript code
|
||||
*
|
||||
* @return string generated javascript client code
|
||||
*/
|
||||
function generateJavaScriptClient()
|
||||
{
|
||||
$client = '';
|
||||
|
||||
$names = array_keys($this->_exportedInstances);
|
||||
foreach ($names as $name) {
|
||||
$client .= $this->generateClassStub($name);
|
||||
}
|
||||
return $client;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the stub for a class
|
||||
*
|
||||
* @param string $name name of the class to generated the stub for, note that this is the exported name not the php class name
|
||||
* @return string javascript proxy stub code for a single class
|
||||
*/
|
||||
function generateClassStub($name)
|
||||
{
|
||||
if (!isset($this->_exportedInstances[$name])) {
|
||||
return '';
|
||||
}
|
||||
|
||||
$client = "// Client stub for the {$this->_exportedInstances[$name]['exportedName']} PHP Class\n";
|
||||
$client .= "function {$this->_exportedInstances[$name]['exportedName']}(callback) {\n";
|
||||
$client .= "\tmode = 'sync';\n";
|
||||
$client .= "\tif (callback) { mode = 'async'; }\n";
|
||||
$client .= "\tthis.className = '{$this->_exportedInstances[$name]['exportedName']}';\n";
|
||||
if ($this->serverUrl) {
|
||||
$client .= "\tthis.dispatcher = new HTML_AJAX_Dispatcher(this.className,mode,callback,'{$this->serverUrl}','{$this->unserializer}');\n}\n";
|
||||
} else {
|
||||
$client .= "\tthis.dispatcher = new HTML_AJAX_Dispatcher(this.className,mode,callback,false,'{$this->unserializer}');\n}\n";
|
||||
}
|
||||
$client .= "{$this->_exportedInstances[$name]['exportedName']}.prototype = {\n";
|
||||
$client .= "\tSync: function() { this.dispatcher.Sync(); }, \n";
|
||||
$client .= "\tAsync: function(callback) { this.dispatcher.Async(callback); },\n";
|
||||
foreach($this->_exportedInstances[$name]['exportedMethods'] as $method) {
|
||||
$client .= $this->_generateMethodStub($method);
|
||||
}
|
||||
$client = substr($client,0,(strlen($client)-2))."\n";
|
||||
$client .= "}\n\n";
|
||||
|
||||
if ($this->packJavaScript) {
|
||||
$client = $this->packJavaScript($client);
|
||||
}
|
||||
return $client;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a methods stub
|
||||
*
|
||||
*
|
||||
* @param string the method name
|
||||
* @return string the js code
|
||||
* @access private
|
||||
*/
|
||||
function _generateMethodStub($method)
|
||||
{
|
||||
$stub = "\t{$method}: function() { return this.dispatcher.doCall('{$method}',arguments); },\n";
|
||||
return $stub;
|
||||
}
|
||||
|
||||
/**
|
||||
* Populates the current payload
|
||||
*
|
||||
*
|
||||
* @param string the method name
|
||||
* @return string the js code
|
||||
* @access private
|
||||
*/
|
||||
function populatePayload()
|
||||
{
|
||||
if(isset($_REQUEST['Iframe_XHR'])) {
|
||||
$this->_iframe = $_REQUEST['Iframe_XHR_id'];
|
||||
if (isset($_REQUEST['Iframe_XHR_headers']) && is_array($_REQUEST['Iframe_XHR_headers'])) {
|
||||
foreach ($_REQUEST['Iframe_XHR_headers'] as $header) {
|
||||
$array = explode(':', $header);
|
||||
$array[0] = strip_tags(strtoupper(str_replace('-', '_', $array[0])));
|
||||
//only content-length and content-type can go in without an http_ prefix - security
|
||||
if(strpos($array[0], 'HTTP_') !== 0
|
||||
&& strcmp('CONTENT_TYPE', $array[0])
|
||||
&& strcmp('CONTENT_LENGTH', $array[0])) {
|
||||
$array[0] = 'HTTP_' . $array[0];
|
||||
}
|
||||
$_SERVER[$array[0]] = strip_tags($array[1]);
|
||||
}
|
||||
}
|
||||
$this->_payload = (isset($_REQUEST['Iframe_XHR_data']) ? $_REQUEST['Iframe_XHR_data'] : '');
|
||||
if (isset($_REQUEST['Iframe_XHR_method'])) {
|
||||
$_GET['m'] = $_REQUEST['Iframe_XHR_method'];
|
||||
}
|
||||
if (isset($_REQUEST['Iframe_XHR_class'])) {
|
||||
$_GET['c'] = $_REQUEST['Iframe_XHR_class'];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Handle a ajax request if needed
|
||||
*
|
||||
* The current check is if GET variables c (class) and m (method) are set, more options may be available in the future
|
||||
*
|
||||
* @todo is it worth it to figure out howto use just 1 instance if the type is the same for serialize and unserialize
|
||||
*
|
||||
* @return boolean true if an ajax call was handled, false otherwise
|
||||
*/
|
||||
function handleRequest()
|
||||
{
|
||||
set_error_handler(array(&$this,'_errorHandler'));
|
||||
if (function_exists('set_exception_handler')) {
|
||||
set_exception_handler(array(&$this,'_exceptionHandler'));
|
||||
}
|
||||
if (isset($_GET['px'])) {
|
||||
if ($this->_iframeGrabProxy()) {
|
||||
restore_error_handler();
|
||||
if (function_exists('restore_exception_handler')) {
|
||||
restore_exception_handler();
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
$class = strtolower($this->_getVar('c'));
|
||||
$method = $this->_getVar('m');
|
||||
$phpCallback = $this->_getVar('cb');
|
||||
|
||||
|
||||
if (!empty($class) && !empty($method)) {
|
||||
if (!isset($this->_exportedInstances[$class])) {
|
||||
// handle error
|
||||
trigger_error('Unknown class: '. $class);
|
||||
}
|
||||
if (!in_array(($this->php4CompatCase ? strtolower($method) : $method),$this->_exportedInstances[$class]['exportedMethods'])) {
|
||||
// handle error
|
||||
trigger_error('Unknown method: ' . $method);
|
||||
}
|
||||
} else if (!empty($phpCallback)) {
|
||||
if (strpos($phpCallback, '.') !== false) {
|
||||
$phpCallback = explode('.', $phpCallback);
|
||||
}
|
||||
if (!$this->_validatePhpCallback($phpCallback)) {
|
||||
restore_error_handler();
|
||||
if (function_exists('restore_exception_handler')) {
|
||||
restore_exception_handler();
|
||||
}
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
restore_error_handler();
|
||||
if (function_exists('restore_exception_handler')) {
|
||||
restore_exception_handler();
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
// auto-detect serializer to use from content-type
|
||||
$type = $this->unserializer;
|
||||
$key = array_search($this->_getClientPayloadContentType(),$this->contentTypeMap);
|
||||
if ($key) {
|
||||
$type = $key;
|
||||
}
|
||||
$unserializer = $this->_getSerializer($type);
|
||||
|
||||
$args = $unserializer->unserialize($this->_getClientPayload(), $this->_allowedClasses);
|
||||
if (!is_array($args)) {
|
||||
$args = array($args);
|
||||
}
|
||||
|
||||
if ($this->_interceptor !== false) {
|
||||
$args = $this->_processInterceptor($class,$method,$phpCallback,$args);
|
||||
}
|
||||
|
||||
if (empty($phpCallback)) {
|
||||
$ret = call_user_func_array(array(&$this->_exportedInstances[$class]['instance'], $method), $args);
|
||||
} else {
|
||||
$ret = call_user_func_array($phpCallback, $args);
|
||||
}
|
||||
|
||||
restore_error_handler();
|
||||
$this->_sendResponse($ret);
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Determines the content type of the client payload
|
||||
*
|
||||
* @return string
|
||||
* a MIME content type
|
||||
*/
|
||||
function _getClientPayloadContentType()
|
||||
{
|
||||
//OPERA IS STUPID FIX
|
||||
if (isset($_SERVER['HTTP_X_CONTENT_TYPE'])) {
|
||||
$type = $this->_getServer('HTTP_X_CONTENT_TYPE');
|
||||
$pos = strpos($type, ';');
|
||||
return strtolower($pos ? substr($type, 0, $pos) : $type);
|
||||
} else if (isset($_SERVER['CONTENT_TYPE'])) {
|
||||
$type = $this->_getServer('CONTENT_TYPE');
|
||||
$pos = strpos($type, ';');
|
||||
return strtolower($pos ? substr($type, 0, $pos) : $type);
|
||||
}
|
||||
return 'text/plain';
|
||||
}
|
||||
|
||||
/**
|
||||
* Send a reponse adding needed headers and serializing content
|
||||
*
|
||||
* Note: this method echo's output as well as setting headers to prevent caching
|
||||
* Iframe Detection: if this has been detected as an iframe response, it has to
|
||||
* be wrapped in different code and headers changed (quite a mess)
|
||||
*
|
||||
* @param mixed content to serialize and send
|
||||
* @access private
|
||||
*/
|
||||
function _sendResponse($response)
|
||||
{
|
||||
if(is_object($response) && is_a($response, 'HTML_AJAX_Response')) {
|
||||
$output = $response->getPayload();
|
||||
$content = $response->getContentType();
|
||||
} else if(is_a($response, 'PEAR_Error')) {
|
||||
$serializer = $this->_getSerializer('Error');
|
||||
$output = $serializer->serialize(array(
|
||||
'message' => $response->getMessage(),
|
||||
'userinfo' => $response->getUserInfo(),
|
||||
'code' => $response->getCode(),
|
||||
'mode' => $response->getMode()
|
||||
)
|
||||
);
|
||||
$content = $this->contentTypeMap['Error'];
|
||||
} else {
|
||||
$serializer = $this->_getSerializer($this->serializer);
|
||||
$output = $serializer->serialize($response);
|
||||
|
||||
$serializerType = $this->serializer;
|
||||
// let a serializer change its output type
|
||||
if (isset($serializer->serializerNewType)) {
|
||||
$serializerType = $serializer->serializerNewType;
|
||||
}
|
||||
|
||||
if (isset($this->contentTypeMap[$serializerType])) {
|
||||
$content = $this->contentTypeMap[$serializerType];
|
||||
}
|
||||
}
|
||||
// headers to force things not to be cached:
|
||||
$headers = array();
|
||||
//OPERA IS STUPID FIX
|
||||
if(isset($_SERVER['HTTP_X_CONTENT_TYPE']))
|
||||
{
|
||||
$headers['X-Content-Type'] = $content;
|
||||
$content = 'text/plain';
|
||||
}
|
||||
if ($this->_sendContentLength()) {
|
||||
$headers['Content-Length'] = strlen($output);
|
||||
}
|
||||
$headers['Expires'] = 'Mon, 26 Jul 1997 05:00:00 GMT';
|
||||
$headers['Last-Modified'] = gmdate( "D, d M Y H:i:s" ) . 'GMT';
|
||||
$headers['Cache-Control'] = 'no-cache, must-revalidate';
|
||||
$headers['Pragma'] = 'no-cache';
|
||||
$headers['Content-Type'] = $content.'; charset=utf-8';
|
||||
|
||||
//intercept to wrap iframe return data
|
||||
if($this->_iframe)
|
||||
{
|
||||
$output = $this->_iframeWrapper($this->_iframe, $output, $headers);
|
||||
$headers['Content-Type'] = 'text/html; charset=utf-8';
|
||||
}
|
||||
$this->_sendHeaders($headers);
|
||||
echo $output;
|
||||
}
|
||||
|
||||
/**
|
||||
* Decide if we should send a Content-length header
|
||||
* @return bool true if it's ok to send the header, false otherwise
|
||||
* @access private
|
||||
*/
|
||||
function _sendContentLength() {
|
||||
if (!$this->sendContentLength) {
|
||||
return false;
|
||||
}
|
||||
$ini_tests = array( "output_handler",
|
||||
"zlib.output_compression",
|
||||
"zlib.output_handler");
|
||||
foreach($ini_tests as $test) {
|
||||
if (ini_get($test)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return (ob_get_level() <= 0);
|
||||
}
|
||||
|
||||
/**
|
||||
* Actually send a list of headers
|
||||
*
|
||||
* @param array list of headers to send, default callback for headers
|
||||
* @access private
|
||||
*/
|
||||
function _sendHeaders($array)
|
||||
{
|
||||
foreach($array as $header => $value) {
|
||||
header($header . ': ' . $value);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get an instance of a serializer class
|
||||
*
|
||||
* @access private
|
||||
*/
|
||||
function _getSerializer($type)
|
||||
{
|
||||
if (isset($this->_serializers[$type])) {
|
||||
return $this->_serializers[$type];
|
||||
}
|
||||
|
||||
$class = 'HTML_AJAX_Serializer_'.$type;
|
||||
|
||||
if ( (version_compare(phpversion(),5,'>') && !class_exists($class,false)) || (version_compare(phpversion(),5,'<') && !class_exists($class)) ) {
|
||||
// include the class only if it isn't defined
|
||||
require_once "HTML/AJAX/Serializer/{$type}.php";
|
||||
}
|
||||
|
||||
//handle JSON loose typing option for associative arrays
|
||||
if ($type == 'JSON') {
|
||||
$this->_serializers[$type] = new $class($this->jsonLooseType);
|
||||
} else {
|
||||
$this->_serializers[$type] = new $class();
|
||||
}
|
||||
return $this->_serializers[$type];
|
||||
}
|
||||
|
||||
/**
|
||||
* Get payload in its submitted form, currently only supports raw post
|
||||
*
|
||||
* @access private
|
||||
* @return string raw post data
|
||||
*/
|
||||
function _getClientPayload()
|
||||
{
|
||||
if (empty($this->_payload)) {
|
||||
if (isset($GLOBALS['HTTP_RAW_POST_DATA'])) {
|
||||
$this->_payload = $GLOBALS['HTTP_RAW_POST_DATA'];
|
||||
} else if (function_exists('file_get_contents')) {
|
||||
// both file_get_contents() and php://input require PHP >= 4.3.0
|
||||
$this->_payload = file_get_contents('php://input');
|
||||
} else {
|
||||
$this->_payload = '';
|
||||
}
|
||||
}
|
||||
return $this->_payload;
|
||||
}
|
||||
|
||||
/**
|
||||
* stub for getting get vars - applies strip_tags
|
||||
*
|
||||
* @access private
|
||||
* @return string filtered _GET value
|
||||
*/
|
||||
function _getVar($var)
|
||||
{
|
||||
if (!isset($_GET[$var])) {
|
||||
return NULL;
|
||||
} else {
|
||||
return strip_tags($_GET[$var]);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* stub for getting server vars - applies strip_tags
|
||||
*
|
||||
* @access private
|
||||
* @return string filtered _GET value
|
||||
*/
|
||||
function _getServer($var)
|
||||
{
|
||||
if (!isset($_SERVER[$var])) {
|
||||
return NULL;
|
||||
} else {
|
||||
return strip_tags($_SERVER[$var]);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Exception handler, passes them to _errorHandler to do the actual work
|
||||
*
|
||||
* @access private
|
||||
*/
|
||||
function _exceptionHandler($ex)
|
||||
{
|
||||
$this->_errorHandler($ex->getCode(),$ex->getMessage(),$ex->getFile(),$ex->getLine());
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Error handler that sends it errors to the client side
|
||||
*
|
||||
* @access private
|
||||
*/
|
||||
function _errorHandler($errno, $errstr, $errfile, $errline)
|
||||
{
|
||||
if ($errno & error_reporting()) {
|
||||
$e = new stdClass();
|
||||
$e->errNo = $errno;
|
||||
$e->errStr = $errstr;
|
||||
$e->errFile = $errfile;
|
||||
$e->errLine = $errline;
|
||||
$this->serializer = 'Error';
|
||||
$this->_sendResponse($e);
|
||||
if ($this->debugEnabled) {
|
||||
$this->debug = new HTML_AJAX_Debug($errstr, $errline, $errno, $errfile);
|
||||
if ($this->debugSession) {
|
||||
$this->debug->sessionError();
|
||||
}
|
||||
$this->debug->_saveError();
|
||||
}
|
||||
die();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates html to wrap serialized info for iframe xmlhttprequest fakeout
|
||||
*
|
||||
* @access private
|
||||
*/
|
||||
function _iframeWrapper($id, $data, $headers = array())
|
||||
{
|
||||
$string = '<html><script type="text/javascript">'."\n".'var Iframe_XHR_headers = new Object();';
|
||||
foreach($headers as $label => $value) {
|
||||
$string .= 'Iframe_XHR_headers["'.preg_replace("/\r?\n/", "\\n", addslashes($label)).'"] = "'.preg_replace("/\r?\n/", "\\n", addslashes($value))."\";\n";
|
||||
}
|
||||
$string .= 'var Iframe_XHR_data = "' . preg_replace("/\r?\n/", "\\n", addslashes($data)) . '";</script>'
|
||||
. '<body onload="parent.HTML_AJAX_IframeXHR_instances[\''.$id.'\']'
|
||||
. '.isLoaded(Iframe_XHR_headers, Iframe_XHR_data);"></body></html>';
|
||||
return $string;
|
||||
}
|
||||
|
||||
/**
|
||||
* Handles a proxied grab request
|
||||
*
|
||||
* @return bool true to end the response, false to continue trying to handle it
|
||||
* @access private
|
||||
*/
|
||||
function _iframeGrabProxy()
|
||||
{
|
||||
if (!isset($_REQUEST['Iframe_XHR_id'])) {
|
||||
trigger_error('Invalid iframe ID');
|
||||
return false;
|
||||
}
|
||||
$this->_iframe = $_REQUEST['Iframe_XHR_id'];
|
||||
$this->_payload = (isset($_REQUEST['Iframe_XHR_data']) ? $_REQUEST['Iframe_XHR_data'] : '');
|
||||
$url = urldecode($_GET['px']);
|
||||
$url_parts = parse_url($url);
|
||||
$urlregex = '#^https?://#i';
|
||||
if (!preg_match($urlregex, $url) || $url_parts['host'] != $_SERVER['HTTP_HOST']) {
|
||||
trigger_error('Invalid URL for grab proxy');
|
||||
return true;
|
||||
}
|
||||
$method = (isset($_REQUEST['Iframe_XHR_HTTP_method'])
|
||||
? strtoupper($_REQUEST['Iframe_XHR_HTTP_method'])
|
||||
: 'GET');
|
||||
// validate method
|
||||
if ($method != 'GET' && $method != 'POST') {
|
||||
trigger_error('Invalid grab URL');
|
||||
return true;
|
||||
}
|
||||
// validate headers
|
||||
$headers = '';
|
||||
if (isset($_REQUEST['Iframe_XHR_headers'])) {
|
||||
foreach ($_REQUEST['Iframe_XHR_headers'] as $header) {
|
||||
if (strpos($header, "\r") !== false
|
||||
|| strpos($header, "\n") !== false) {
|
||||
trigger_error('Invalid grab header');
|
||||
return true;
|
||||
}
|
||||
$headers .= $header . "\r\n";
|
||||
}
|
||||
}
|
||||
// tries to make request with file_get_contents()
|
||||
if (ini_get('allow_url_fopen') && version_compare(phpversion(), '5.0.0'. '>=')) {
|
||||
$opts = array(
|
||||
$url_parts['scheme'] => array(
|
||||
'method' => $method,
|
||||
'headers' => $headers,
|
||||
'content' => $this->_payload
|
||||
)
|
||||
);
|
||||
$ret = @file_get_contents($url, false, stream_context_create($opts));
|
||||
if (!empty($ret)) {
|
||||
$this->_sendResponse($ret);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
// tries to make request using the curl extension
|
||||
if (function_exists('curl_setopt')) {
|
||||
$ch = curl_init();
|
||||
curl_setopt($ch, CURLOPT_URL, $url);
|
||||
curl_setopt($ch, CURLOPT_HEADER, $headers);
|
||||
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
|
||||
$ret = curl_exec($ch);
|
||||
if ($ret !== false) {
|
||||
curl_close($ch);
|
||||
$this->_sendResponse($ret);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
if (isset($url_parts['port'])) {
|
||||
$port = $url_parts['port'];
|
||||
} else {
|
||||
$port = getservbyname(strtolower($url_parts['scheme']), 'tcp');
|
||||
if ($port === false) {
|
||||
trigger_error('Grab proxy: Unknown port or service, defaulting to 80', E_USER_WARNING);
|
||||
$port = 80;
|
||||
}
|
||||
}
|
||||
if (!isset($url_parts['path'])) {
|
||||
$url_parts['path'] = '/';
|
||||
}
|
||||
if (!empty($url_parts['query'])) {
|
||||
$url_parts['path'] .= '?' . $url_parts['query'];
|
||||
}
|
||||
$request = "$method {$url_parts['path']} HTTP/1.0\r\n"
|
||||
. "Host: {$url['host']}\r\n"
|
||||
. "Connection: close\r\n"
|
||||
. "$headers\r\n";
|
||||
// tries to make request using the socket functions
|
||||
$fp = fsockopen($_SERVER['HTTP_HOST'], $port, $errno, $errstr, 4);
|
||||
if ($fp) {
|
||||
fputs($fp, $request);
|
||||
$ret = '';
|
||||
$done_headers = false;
|
||||
while (!feof($fp)) {
|
||||
$ret .= fgets($fp, 2048);
|
||||
if ($done_headers || ($contentpos = strpos($ret, "\r\n\r\n")) === false) {
|
||||
continue;
|
||||
}
|
||||
$done_headers = true;
|
||||
$ret = substr($ret, $contentpos + 4);
|
||||
}
|
||||
fclose($fp);
|
||||
$this->_sendResponse($ret);
|
||||
return true;
|
||||
}
|
||||
// tries to make the request using the socket extension
|
||||
$host = gethostbyname($url['host']);
|
||||
if (($socket = socket_create(AF_INET, SOCK_STREAM, SOL_TCP)) < 0
|
||||
|| ($connected = socket_connect($socket, $host, $port)) < 0
|
||||
|| ($written = socket_write($socket, $request)) < strlen($request)) {
|
||||
trigger_error('Grab proxy failed: ' . socket_strerror($socket));
|
||||
return true;
|
||||
}
|
||||
$ret = '';
|
||||
$done_headers = false;
|
||||
while ($out = socket_read($socket, 2048)) {
|
||||
$ret .= $out;
|
||||
if ($done_headers || ($contentpos = strpos($ret, "\r\n\r\n")) === false) {
|
||||
continue;
|
||||
}
|
||||
$done_headers = true;
|
||||
$ret = substr($ret, $contentpos + 4);
|
||||
}
|
||||
socket_close($socket);
|
||||
$this->_sendResponse($ret);
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a class or classes to those allowed to be unserialized
|
||||
*
|
||||
* @param mixed $classes
|
||||
* the class or array of classes to add
|
||||
* @access public
|
||||
*/
|
||||
function addAllowedClasses($classes)
|
||||
{
|
||||
if (!is_array($classes)) {
|
||||
$this->_allowedClasses[] = $classes;
|
||||
} else {
|
||||
$this->_allowedClasses = array_merge($this->_allowedClasses, $classes);
|
||||
}
|
||||
$this->_allowedClasses = array_unique($this->_allowedClasses);
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks that the given callback is callable and allowed to be called
|
||||
*
|
||||
* @param callback $callback
|
||||
* the callback to check
|
||||
* @return bool
|
||||
* true if the callback is valid, false otherwise
|
||||
* @access private
|
||||
*/
|
||||
function _validatePhpCallback($callback)
|
||||
{
|
||||
if (!is_callable($callback)) {
|
||||
return false;
|
||||
}
|
||||
$sig = md5(serialize($callback));
|
||||
return isset($this->_validCallbacks[$sig]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Register a callback so it may be called from JS
|
||||
*
|
||||
* @param callback $callback
|
||||
* the callback to register
|
||||
* @access public
|
||||
*/
|
||||
function registerPhpCallback($callback)
|
||||
{
|
||||
$this->_validCallbacks[md5(serialize($callback))] = 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* Make JavaScript code smaller
|
||||
*
|
||||
* Currently just strips whitespace and comments, needs to remain fast
|
||||
* Strips comments only if they are not preceeded by code
|
||||
* Strips /*-style comments only if they span over more than one line
|
||||
* Since strings cannot span over multiple lines, it cannot be defeated by a string
|
||||
* containing /*
|
||||
*/
|
||||
function packJavaScript($input) {
|
||||
$stripPregs = array(
|
||||
'/^\s*$/',
|
||||
'/^\s*\/\/.*$/'
|
||||
);
|
||||
$blockStart = '/^\s*\/\/\*/';
|
||||
$blockEnd = '/\*\/\s*(.*)$/';
|
||||
$inlineComment = '/\/\*.*\*\//';
|
||||
$out = '';
|
||||
|
||||
$lines = explode("\n",$input);
|
||||
$inblock = false;
|
||||
foreach($lines as $line) {
|
||||
$keep = true;
|
||||
if ($inblock) {
|
||||
if (preg_match($blockEnd,$line)) {
|
||||
$inblock = false;
|
||||
$line = preg_match($blockEnd,'$1',$line);
|
||||
$keep = strlen($line) > 0;
|
||||
}
|
||||
}
|
||||
else if (preg_match($inlineComment,$line)) {
|
||||
$keep = true;
|
||||
}
|
||||
else if (preg_match($blockStart,$line)) {
|
||||
$inblock = true;
|
||||
$keep = false;
|
||||
}
|
||||
|
||||
if (!$inblock) {
|
||||
foreach($stripPregs as $preg) {
|
||||
if (preg_match($preg,$line)) {
|
||||
$keep = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ($keep && !$inblock) {
|
||||
$out .= trim($line)."\n";
|
||||
}
|
||||
/* Enable to see what your striping out
|
||||
else {
|
||||
echo $line."<br>";
|
||||
}//*/
|
||||
}
|
||||
return $out;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set an intercptor class
|
||||
*
|
||||
* An interceptor class runs during the process of handling a request, it allows you to run security checks globally
|
||||
* It also allows you to rewrite parameters
|
||||
*
|
||||
* You can throw errors and exceptions in your intercptor methods and they will be passed to javascript
|
||||
*
|
||||
* You can add interceptors are 3 levels
|
||||
* For a particular class/method, this is done by add a method to you class named ClassName_MethodName($params)
|
||||
* For a particular class, method ClassName($methodName,$params)
|
||||
* Globally, method intercept($className,$methodName,$params)
|
||||
*
|
||||
* Only one match is done, using the most specific interceptor
|
||||
*
|
||||
* All methods have to return $params, if you want to empty all of the parameters return an empty array
|
||||
*
|
||||
* @todo handle php callbacks
|
||||
*/
|
||||
function setInterceptor($instance) {
|
||||
$this->_interceptor = $instance;
|
||||
}
|
||||
|
||||
/**
|
||||
* Attempt to intercept a call
|
||||
*
|
||||
* @todo handle php callbacks
|
||||
*/
|
||||
function _processInterceptor($className,$methodName,$callback,$params) {
|
||||
|
||||
$m = $className.'_'.$methodName;
|
||||
if (method_exists($this->_interceptor,$m)) {
|
||||
return $this->_interceptor->$m($params);
|
||||
}
|
||||
|
||||
$m = $className;
|
||||
if (method_exists($this->_interceptor,$m)) {
|
||||
return $this->_interceptor->$m($methodName,$params);
|
||||
}
|
||||
|
||||
$m = 'intercept';
|
||||
if (method_exists($this->_interceptor,$m)) {
|
||||
return $this->_interceptor->$m($className,$methodName,$params);
|
||||
}
|
||||
|
||||
return $params;
|
||||
}
|
||||
}
|
||||
|
||||
function HTML_AJAX_class_exists($class,$autoload) {
|
||||
if (function_exists('interface_exists')) {
|
||||
return class_exists($class,$autoload);
|
||||
}
|
||||
else {
|
||||
return class_exists($class);
|
||||
}
|
||||
}
|
||||
/* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4: */
|
||||
?>
|
||||
340
include/pear/HTML/AJAX/Action.php
Normal file
340
include/pear/HTML/AJAX/Action.php
Normal file
@@ -0,0 +1,340 @@
|
||||
<?php
|
||||
/**
|
||||
* OO AJAX Implementation for PHP, contains HTML_AJAX_Action
|
||||
*
|
||||
* @category HTML
|
||||
* @package AJAX
|
||||
* @author Elizabeth Smith <auroraeosrose@gmail.com>
|
||||
* @copyright 2005-2006 Elizabeth Smith
|
||||
* @license http://www.opensource.org/licenses/lgpl-license.php LGPL
|
||||
* @version Release: 0.5.2
|
||||
*/
|
||||
|
||||
/**
|
||||
* Require the response class and json serializer
|
||||
*/
|
||||
require_once 'HTML/AJAX/Response.php';
|
||||
require_once 'HTML/AJAX/Serializer/JSON.php';
|
||||
|
||||
/**
|
||||
* Helper class to eliminate the need to write javascript functions to deal with data
|
||||
*
|
||||
* This class creates information that can be properly serialized and used by
|
||||
* the haaction serializer which eliminates the need for php users to write javascript
|
||||
* for dealing with the information returned by an ajax method - instead the javascript
|
||||
* is basically created for them
|
||||
*
|
||||
* @version $Id: Action.php 537 2006-08-12 01:48:12Z emsmith $
|
||||
*/
|
||||
class HTML_AJAX_Action extends HTML_AJAX_Response
|
||||
{
|
||||
|
||||
/**
|
||||
* Content type for the HAA response
|
||||
*
|
||||
* goofy but unique content type to tell the javascript which deserializer to use
|
||||
* overrides HTML_AJAX_Response
|
||||
*
|
||||
* @var string
|
||||
* @access public
|
||||
*/
|
||||
var $contentType = 'application/html_ajax_action';
|
||||
|
||||
/**
|
||||
* An array holding all the actions for the class
|
||||
*
|
||||
* these have numeric keys and each new action is added on the end, remember
|
||||
* these are executed in the order added
|
||||
*
|
||||
* @var array
|
||||
* @access private
|
||||
*/
|
||||
var $_actions;
|
||||
|
||||
/**
|
||||
* Prepends data to the attribute identified by id
|
||||
*
|
||||
* The data will be added to the beginning of the attribute identified by the id
|
||||
* sent, id must be unique
|
||||
*
|
||||
* $response->prependAttr('myid', 'class', 'red');
|
||||
* $response->prependAttr('myid', array('class' => 'red', 'innerHTML' => 'this is an error'));
|
||||
*
|
||||
* @param string $id id for a specific item on the page <div id="myid"></div>
|
||||
* @param string|array $attribute either an array of attribute/data pairs or a string attribute name
|
||||
* @param mixed $data should be NULL if attribute is an array, otherwise data you wish to set the attribute to
|
||||
* @return void
|
||||
* @access public
|
||||
*/
|
||||
function prependAttr($id, $attribute, $data = NULL)
|
||||
{
|
||||
if(!is_null($data))
|
||||
{
|
||||
$attribute = array($attribute => $data);
|
||||
}
|
||||
$this->_actions[] = array(
|
||||
'action' => 'prepend',
|
||||
'id' => $id,
|
||||
'attributes' => $attribute,
|
||||
'data' => $data,
|
||||
);
|
||||
return;
|
||||
}
|
||||
|
||||
/**
|
||||
* Appends data to the attribute identified by id
|
||||
*
|
||||
* The data will be added to the end of the attribute identified by the id
|
||||
* sent, id must be unique
|
||||
*
|
||||
* $response->appendAttr('myid', 'class', 'red');
|
||||
* $response->appendAttr('myid', array('class' => 'red', 'innerHTML' => 'this is an error'));
|
||||
*
|
||||
* @param string $id id for a specific item on the page <div id="myid"></div>
|
||||
* @param string|array $attribute either an array of attribute/data pairs or a string attribute name
|
||||
* @param mixed $data should be NULL if attribute is an array, otherwise data you wish to set the attribute to
|
||||
* @return void
|
||||
* @access public
|
||||
*/
|
||||
function appendAttr($id, $attribute, $data = NULL)
|
||||
{
|
||||
if(!is_null($data))
|
||||
{
|
||||
$attribute = array($attribute => $data);
|
||||
}
|
||||
$this->_actions[] = array(
|
||||
'action' => 'append',
|
||||
'id' => $id,
|
||||
'attributes' => $attribute,
|
||||
);
|
||||
return;
|
||||
}
|
||||
|
||||
/**
|
||||
* Assigns data to the attribute identified by id overwriting any previous values
|
||||
*
|
||||
* The data will be assigned to the attribute identified by the id
|
||||
* sent, id must be unique
|
||||
*
|
||||
* $response->assignAttr('myid', 'class', 'red');
|
||||
* $response->assignAttr('myid', array('class' => 'red', 'innerHTML' => 'this is an error'));
|
||||
*
|
||||
* @param string $id id for a specific item on the page <div id="myid"></div>
|
||||
* @param string|array $attribute either an array of attribute/data pairs or a string attribute name
|
||||
* @param mixed $data should be NULL if attribute is an array, otherwise data you wish to set the attribute to
|
||||
* @return void
|
||||
* @access public
|
||||
*/
|
||||
function assignAttr($id, $attribute, $data = NULL)
|
||||
{
|
||||
if(!is_null($data))
|
||||
{
|
||||
$attribute = array($attribute => $data);
|
||||
}
|
||||
$this->_actions[] = array(
|
||||
'action' => 'assign',
|
||||
'id' => $id,
|
||||
'attributes' => $attribute,
|
||||
);
|
||||
return;
|
||||
}
|
||||
|
||||
/**
|
||||
* Deletes or assigns a value of an empty string to an attribute
|
||||
*
|
||||
* You may send either a single attribute or an array of attributes to clear
|
||||
*
|
||||
* $response->clearAttr('myid', 'class');
|
||||
* $response->clearAttr('myid', array('class', 'innerHTML'));
|
||||
*
|
||||
* @param string $id id for a specific item on the page <div id="myid"></div>
|
||||
* @param string|array $attribute either an array of attribute/data pairs or a string attribute name
|
||||
* @return void
|
||||
* @access public
|
||||
*/
|
||||
function clearAttr($id, $attribute)
|
||||
{
|
||||
if(!is_array($attribute))
|
||||
{
|
||||
$attribute = array($attribute);
|
||||
}
|
||||
$this->_actions[] = array(
|
||||
'action' => 'clear',
|
||||
'id' => $id,
|
||||
'attributes' => $attribute,
|
||||
);
|
||||
return;
|
||||
}
|
||||
|
||||
/**
|
||||
* create a dom node via javascript
|
||||
*
|
||||
* higher level dom manipulation - creates a new node to insert into the dom
|
||||
* You can control where the new node is inserted with two things, the insertion
|
||||
* type and the id/ The type should be append, prepend, insertBefore, or insertAfter
|
||||
*
|
||||
* The id is a sibling node - like a div in the same div you want to add more to
|
||||
* If you choose to append or prepend a node it will be placed at the beginning
|
||||
* or end of the node with the id you send. If you choose insertBefore or
|
||||
* InsertAfter it will be put right before or right after the node you specified.
|
||||
* You can send an array of attributes to apply to the new node as well,
|
||||
* so you don't have to create it and then assign Attributes.
|
||||
*
|
||||
* $response->createNode('myid', 'div');
|
||||
* $response->createNode('submit', 'input',
|
||||
* array('id' => 'key',
|
||||
* 'name' => 'key',
|
||||
* 'type' => 'hidden',
|
||||
* 'value' => $id),
|
||||
* 'insertBefore');
|
||||
*
|
||||
* @param string $id id for a specific item on the page <div id="myid"></div>
|
||||
* @param string $tag html node to create
|
||||
* @param array $attributes array of attribute -> data to fill the node with
|
||||
* @return void
|
||||
* @access public
|
||||
*/
|
||||
function createNode($id, $tag, $attributes, $type = 'append')
|
||||
{
|
||||
$types = array('append', 'prepend', 'insertBefore', 'insertAfter');
|
||||
if(!in_array($type, $types))
|
||||
{
|
||||
$type = 'append';
|
||||
}
|
||||
settype($attributes, 'array');
|
||||
$this->_actions[] = array(
|
||||
'action' => 'create',
|
||||
'id' => $id,
|
||||
'tag' => $tag,
|
||||
'attributes' => $attributes,
|
||||
'type' => $type,
|
||||
);
|
||||
return;
|
||||
}
|
||||
|
||||
/**
|
||||
* Replace a dom node via javascript
|
||||
*
|
||||
* higher level dom manipulation - replaces one node with another
|
||||
* This can be used to replace a div with a form for inline editing
|
||||
* use innerHtml attribute to change inside text
|
||||
*
|
||||
* $response->replaceNode('myid', 'div', array('innerHTML' => 'loading complete'));
|
||||
* $response->replaceNode('mydiv', 'form', array('innerHTML' => $form));
|
||||
*
|
||||
* @param string $id id for a specific item on the page <div id="myid"></div>
|
||||
* @param string $tag html node to create
|
||||
* @param array $attributes array of attribute -> data to fill the node with
|
||||
* @return void
|
||||
* @access public
|
||||
*/
|
||||
function replaceNode($id, $tag, $attributes)
|
||||
{
|
||||
settype($attributes, 'array');
|
||||
$this->_actions[] = array(
|
||||
'action' => 'replace',
|
||||
'id' => $id,
|
||||
'tag' => $tag,
|
||||
'attributes' => $attributes,
|
||||
);
|
||||
return;
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete a dom node via javascript
|
||||
*
|
||||
* $response->removeNode('myid');
|
||||
* $response->removeNode(array('mydiv', 'myform'));
|
||||
*
|
||||
* @param string $id id for a specific item on the page <div id="myid"></div>
|
||||
* @return void
|
||||
* @access public
|
||||
*/
|
||||
function removeNode($id)
|
||||
{
|
||||
$this->_actions[] = array(
|
||||
'action' => 'remove',
|
||||
'id' => $id,
|
||||
);
|
||||
return;
|
||||
}
|
||||
|
||||
/**
|
||||
* Send a string to a javascript eval
|
||||
*
|
||||
* This will send the data right to the eval javascript function, it will NOT
|
||||
* allow you to dynamically add a javascript function for use later on because
|
||||
* it is constrined by the eval function
|
||||
*
|
||||
* @param string $data string to pass to the alert javascript function
|
||||
* @return void
|
||||
* @access public
|
||||
*/
|
||||
function insertScript($data)
|
||||
{
|
||||
$this->_actions[] = array(
|
||||
'action' => 'script',
|
||||
'data' => $data,
|
||||
);
|
||||
return;
|
||||
}
|
||||
|
||||
/**
|
||||
* Send a string to a javascript alert
|
||||
*
|
||||
* This will send the data right to the alert javascript function
|
||||
*
|
||||
* @param string $data string to pass to the alert javascript function
|
||||
* @return void
|
||||
* @access public
|
||||
*/
|
||||
function insertAlert($data)
|
||||
{
|
||||
$this->_actions[] = array(
|
||||
'action' => 'alert',
|
||||
'data' => $data,
|
||||
);
|
||||
return;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the serialized content of the response class
|
||||
*
|
||||
* we actually use the json serializer underneath, so we send the actions array
|
||||
* to the json serializer and return the data
|
||||
*
|
||||
* @return string serialized response content
|
||||
* @access public
|
||||
*/
|
||||
function getPayload()
|
||||
{
|
||||
$serializer = new HTML_AJAX_Serializer_JSON();
|
||||
return $serializer->serialize($this->_actions);
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds all the actions from one response object to another, feature request
|
||||
* #6635 at pear.php.net
|
||||
*
|
||||
* @param object $instance referenced HTML_AJAX_Action object
|
||||
* @return array
|
||||
* @access public
|
||||
*/
|
||||
function combineActions(&$instance)
|
||||
{
|
||||
$this->_actions = array_merge($this->_actions, $instance->retrieveActions());
|
||||
}
|
||||
|
||||
/**
|
||||
* to follow proper property access we need a way to retrieve the private
|
||||
* actions array
|
||||
*
|
||||
* @return array
|
||||
* @access public
|
||||
*/
|
||||
function retrieveActions()
|
||||
{
|
||||
return $this->_actions;
|
||||
}
|
||||
}
|
||||
?>
|
||||
140
include/pear/HTML/AJAX/Debug.php
Normal file
140
include/pear/HTML/AJAX/Debug.php
Normal file
@@ -0,0 +1,140 @@
|
||||
<?php
|
||||
define ("HTML_AJAX_NEWLINE", "\n");
|
||||
// {{{ class HTML_AJAX_Debug
|
||||
/**
|
||||
* AJAX Debugging implementation
|
||||
*
|
||||
* 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 HTML
|
||||
* @package AJAX
|
||||
* @author David Coallier <davidc@php.net>
|
||||
* @copyright 2005 David Coallier
|
||||
* @license http://www.opensource.org/licenses/lgpl-license.php LGPL
|
||||
* @version Release: 0.5.2
|
||||
*/
|
||||
class HTML_AJAX_Debug {
|
||||
// {{{ properties
|
||||
/**
|
||||
* This is the error message.
|
||||
*
|
||||
* @access private
|
||||
*/
|
||||
var $errorMsg;
|
||||
|
||||
/**
|
||||
* The line where the error occured.
|
||||
*
|
||||
* @access private
|
||||
*/
|
||||
var $errorLine;
|
||||
|
||||
/**
|
||||
* The error code.
|
||||
*
|
||||
* @access private
|
||||
*/
|
||||
var $errorCode;
|
||||
|
||||
/**
|
||||
* The file where the error occured.
|
||||
*
|
||||
* @access private
|
||||
*/
|
||||
var $errorFile;
|
||||
|
||||
/**
|
||||
* Time the error occured
|
||||
*
|
||||
* @access private
|
||||
*/
|
||||
var $_timeOccured;
|
||||
|
||||
/**
|
||||
* The whole error itself
|
||||
*
|
||||
* @access private
|
||||
* @see errorMsg
|
||||
* @see errorLine
|
||||
* @see errorFile
|
||||
* @see errorCode
|
||||
*/
|
||||
var $error;
|
||||
|
||||
/**
|
||||
* The file to save the error to.
|
||||
*
|
||||
* @access private
|
||||
* @default ajaxErrLog.xml
|
||||
*/
|
||||
var $file = 'ajaxErrLog.xml';
|
||||
// }}}
|
||||
// {{{ constructor
|
||||
/**
|
||||
* The constructor.
|
||||
*
|
||||
* @param string $errorMsg The error message.
|
||||
* @param string $errLine The line where error occured.
|
||||
* @param string $errCode The error Code.
|
||||
* @param string $errFile The file where error occured.
|
||||
*/
|
||||
function HTML_AJAX_Debug($errMsg, $errLine, $errCode, $errFile)
|
||||
{
|
||||
$this->errorMsg = $errMsg;
|
||||
$this->errorLine = $errLine;
|
||||
$this->errorCode = $errCode;
|
||||
$this->errorFile = $errFile;
|
||||
$this->_timeOccured = date("Y-m-d H:i:s", time());
|
||||
$this->xmlError();
|
||||
}
|
||||
// }}}
|
||||
// {{{ xmlError
|
||||
/**
|
||||
* This functions formats the error to xml format then we can save it.
|
||||
*
|
||||
* @access protected
|
||||
* @return $this->error the main error.
|
||||
*/
|
||||
function xmlError()
|
||||
{
|
||||
$error = " <when>{$this->_timeOccured}</when>" . HTML_AJAX_NEWLINE;
|
||||
$error .= " <msg>{$this->errorMsg}</msg>" . HTML_AJAX_NEWLINE;
|
||||
$error .= " <code>{$this->errorCode}</code>" . HTML_AJAX_NEWLINE;
|
||||
$error .= " <line>{$this->errorLine}</line>" . HTML_AJAX_NEWLINE;
|
||||
$error .= " <file>{$this->errorFile}</file>" . HTML_AJAX_NEWLINE . HTML_AJAX_NEWLINE;
|
||||
return $this->error = $error;
|
||||
}
|
||||
// }}}
|
||||
// {{{ sessionError
|
||||
/**
|
||||
* This function pushes the array $_SESSION['html_ajax_debug']['time'][]
|
||||
* with the values inside of $this->error
|
||||
*
|
||||
* @access public
|
||||
*/
|
||||
function sessionError()
|
||||
{
|
||||
$_SESSION['html_ajax_debug']['time'][] = $this->error;
|
||||
}
|
||||
// }}}
|
||||
// {{{ _saveError
|
||||
/**
|
||||
* This function saves the error to a file
|
||||
* appending to this file.
|
||||
*
|
||||
* @access private.
|
||||
*/
|
||||
function _saveError()
|
||||
{
|
||||
if ($handle = fopen($this->file, 'a')) {
|
||||
fwrite($handle, $this->error);
|
||||
}
|
||||
}
|
||||
// }}}
|
||||
}
|
||||
// }}}
|
||||
?>
|
||||
162
include/pear/HTML/AJAX/Helper.php
Normal file
162
include/pear/HTML/AJAX/Helper.php
Normal file
@@ -0,0 +1,162 @@
|
||||
<?php
|
||||
/**
|
||||
* HTML/JavaScript Generation Helper
|
||||
*
|
||||
* @category HTML
|
||||
* @package AJAX
|
||||
* @author Joshua Eichorn <josh@bluga.net>
|
||||
* @copyright 2005 Joshua Eichorn
|
||||
* @license http://www.opensource.org/licenses/lgpl-license.php LGPL
|
||||
* @version Release: 0.5.2
|
||||
*/
|
||||
|
||||
/**
|
||||
* HTML/JavaScript Generation Helper
|
||||
*
|
||||
* @category HTML
|
||||
* @package AJAX
|
||||
* @author Joshua Eichorn <josh@bluga.net>
|
||||
* @copyright 2005 Joshua Eichorn
|
||||
* @license http://www.opensource.org/licenses/lgpl-license.php LGPL
|
||||
* @version Release: 0.5.2
|
||||
* @link http://pear.php.net/package/HTML_AJAX
|
||||
*/
|
||||
class HTML_AJAX_Helper
|
||||
{
|
||||
/**
|
||||
* URL where an HTML_AJAX_Server instance is serving up clients and taking ajax requests
|
||||
*/
|
||||
var $serverUrl = 'server.php';
|
||||
|
||||
/**
|
||||
* JS libraries to include
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
var $jsLibraries = array('Util','Main','Request','HttpClient','Dispatcher','Behavior','Loading','JSON','iframe');
|
||||
|
||||
/**
|
||||
* Remote class stubs to include
|
||||
*/
|
||||
var $stubs = array();
|
||||
|
||||
/**
|
||||
* Include all needed libraries, stubs, and set defaultServer
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
function setupAJAX()
|
||||
{
|
||||
$libs = array(0=>array());
|
||||
foreach($this->jsLibraries as $library) {
|
||||
if (is_array($library)) {
|
||||
$libs[] = implode(',',$library);
|
||||
}
|
||||
else {
|
||||
$libs[0][] = $library;
|
||||
}
|
||||
}
|
||||
$libs[0] = implode(',',$libs[0]);
|
||||
|
||||
$ret = '';
|
||||
foreach($libs as $list) {
|
||||
$ret .= "<script type='text/javascript' src='{$this->serverUrl}?client={$list}'></script>\n";
|
||||
}
|
||||
|
||||
if (count($this->stubs) > 0) {
|
||||
$stubs = implode(',',$this->stubs);
|
||||
$ret .= "<script type='text/javascript' src='{$this->serverUrl}?stub={$stubs}'></script>\n";
|
||||
}
|
||||
$ret .= $this->encloseInScript('HTML_AJAX.defaultServerUrl = '.$this->escape($this->serverUrl));
|
||||
return $ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a custom Loading message
|
||||
*
|
||||
* @param string $body HTML body of the loading div
|
||||
* @param string $class CSS class of the div
|
||||
* @param string $style style tag of the loading div
|
||||
*/
|
||||
function loadingMessage($body, $class = 'HTML_AJAX_Loading',
|
||||
$style = 'position: absolute; top: 0; right: 0; background-color: red; width: 80px; padding: 4px; display: none')
|
||||
{
|
||||
return "<div id='HTML_AJAX_LOADING' class='{$class}' style=\"{$style}\">{$body}</div>\n";
|
||||
}
|
||||
|
||||
/**
|
||||
* Update the contents of an element using ajax
|
||||
*
|
||||
* @param string $id id of the element to update
|
||||
* @param string|array $update Either a url to update with or a array like array('class','method')
|
||||
* @param string $type replace or append
|
||||
* @param boolean $enclose
|
||||
*/
|
||||
function updateElement($id, $update, $type, $enclose = false) {
|
||||
if (is_array($update)) {
|
||||
$updateStr = "";
|
||||
$comma = '';
|
||||
foreach($update as $item) {
|
||||
$updateStr .= $comma.$this->escape($item);
|
||||
$comma = ',';
|
||||
}
|
||||
}
|
||||
else {
|
||||
$updateStr = $this->escape($update);
|
||||
}
|
||||
|
||||
$ret = "HTML_AJAX.{$type}(".$this->escape($id).",{$updateStr});\n";
|
||||
if ($enclose) {
|
||||
$ret = $this->encloseInScript($ret);
|
||||
}
|
||||
return $ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* Escape a string and add quotes allowing it to be a javascript paramater
|
||||
*
|
||||
* @param string $input
|
||||
* @return string
|
||||
* @todo do something here besides a quick hack
|
||||
*/
|
||||
function escape($input) {
|
||||
return "'".addslashes($input)."'";
|
||||
}
|
||||
|
||||
/**
|
||||
* Enclose a string in a script block
|
||||
*
|
||||
* @param string $input
|
||||
* @return string
|
||||
*/
|
||||
function encloseInScript($input) {
|
||||
return '<script type="text/javascript">'.$input."</script>\n";
|
||||
}
|
||||
|
||||
/**
|
||||
* Generate a JSON String
|
||||
*
|
||||
* @param string $input
|
||||
* @return string
|
||||
*/
|
||||
function jsonEncode($input) {
|
||||
require_once 'HTML/AJAX/Serializer/JSON.php';
|
||||
|
||||
$s = new HTML_AJAX_Serializer_JSON();
|
||||
return $s->serialize($input);
|
||||
}
|
||||
|
||||
/**
|
||||
* Check the request headers to see if this is an AJAX request
|
||||
*
|
||||
* @return boolean
|
||||
*/
|
||||
function isAJAX() {
|
||||
if (isset($_SERVER['HTTP_X_REQUESTED_WITH']) && $_SERVER['HTTP_X_REQUESTED_WITH'] == 'XMLHttpRequest') {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
/* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4: */
|
||||
?>
|
||||
801
include/pear/HTML/AJAX/JSON.php
Normal file
801
include/pear/HTML/AJAX/JSON.php
Normal file
@@ -0,0 +1,801 @@
|
||||
<?php
|
||||
/* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4: */
|
||||
/**
|
||||
* This is an embedded version of HTML_AJAX_JSON since it has yet to have a PEAR release
|
||||
* it has been renamed to HTML_AJAX_JSON so no problems will be caused by an eventual release
|
||||
* Feel free to report bugs against it to HTML_AJAX
|
||||
*/
|
||||
|
||||
/**
|
||||
* Needed for compat functions
|
||||
*/
|
||||
require_once 'HTML/AJAX.php';
|
||||
|
||||
/**
|
||||
* Converts to and from JSON format.
|
||||
*
|
||||
* JSON (JavaScript Object Notation) is a lightweight data-interchange
|
||||
* format. It is easy for humans to read and write. It is easy for machines
|
||||
* to parse and generate. It is based on a subset of the JavaScript
|
||||
* Programming Language, Standard ECMA-262 3rd Edition - December 1999.
|
||||
* This feature can also be found in Python. JSON is a text format that is
|
||||
* completely language independent but uses conventions that are familiar
|
||||
* to programmers of the C-family of languages, including C, C++, C#, Java,
|
||||
* JavaScript, Perl, TCL, and many others. These properties make JSON an
|
||||
* ideal data-interchange language.
|
||||
*
|
||||
* This package provides a simple encoder and decoder for JSON notation. It
|
||||
* is intended for use with client-side Javascript applications that make
|
||||
* use of HTTPRequest to perform server communication functions - data can
|
||||
* be encoded into JSON notation for use in a client-side javascript, or
|
||||
* decoded from incoming Javascript requests. JSON format is native to
|
||||
* Javascript, and can be directly eval()'ed with no further parsing
|
||||
* overhead
|
||||
*
|
||||
* All strings should be in ASCII or UTF-8 format!
|
||||
*
|
||||
* LICENSE: 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.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED ``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 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
|
||||
* @package HTML_AJAX_JSON
|
||||
* @author Michal Migurski <mike-json@teczno.com>
|
||||
* @author Matt Knapp <mdknapp[at]gmail[dot]com>
|
||||
* @author Brett Stimmerman <brettstimmerman[at]gmail[dot]com>
|
||||
* @copyright 2005 Michal Migurski
|
||||
* @license http://www.opensource.org/licenses/bsd-license.php
|
||||
* @link http://pear.php.net/pepr/pepr-proposal-show.php?id=198
|
||||
*/
|
||||
|
||||
/**
|
||||
* Marker constant for HTML_AJAX_JSON::decode(), used to flag stack state
|
||||
*/
|
||||
define('SERVICES_JSON_SLICE', 1);
|
||||
|
||||
/**
|
||||
* Marker constant for HTML_AJAX_JSON::decode(), used to flag stack state
|
||||
*/
|
||||
define('SERVICES_JSON_IN_STR', 2);
|
||||
|
||||
/**
|
||||
* Marker constant for HTML_AJAX_JSON::decode(), used to flag stack state
|
||||
*/
|
||||
define('SERVICES_JSON_IN_ARR', 3);
|
||||
|
||||
/**
|
||||
* Marker constant for HTML_AJAX_JSON::decode(), used to flag stack state
|
||||
*/
|
||||
define('SERVICES_JSON_IN_OBJ', 4);
|
||||
|
||||
/**
|
||||
* Marker constant for HTML_AJAX_JSON::decode(), used to flag stack state
|
||||
*/
|
||||
define('SERVICES_JSON_IN_CMT', 5);
|
||||
|
||||
/**
|
||||
* Behavior switch for HTML_AJAX_JSON::decode()
|
||||
*/
|
||||
define('SERVICES_JSON_LOOSE_TYPE', 16);
|
||||
|
||||
/**
|
||||
* Behavior switch for HTML_AJAX_JSON::decode()
|
||||
*/
|
||||
define('SERVICES_JSON_SUPPRESS_ERRORS', 32);
|
||||
|
||||
/**
|
||||
* Converts to and from JSON format.
|
||||
*
|
||||
* Brief example of use:
|
||||
*
|
||||
* <code>
|
||||
* // create a new instance of HTML_AJAX_JSON
|
||||
* $json = new HTML_AJAX_JSON();
|
||||
*
|
||||
* // convert a complexe value to JSON notation, and send it to the browser
|
||||
* $value = array('foo', 'bar', array(1, 2, 'baz'), array(3, array(4)));
|
||||
* $output = $json->encode($value);
|
||||
*
|
||||
* print($output);
|
||||
* // prints: ["foo","bar",[1,2,"baz"],[3,[4]]]
|
||||
*
|
||||
* // accept incoming POST data, assumed to be in JSON notation
|
||||
* $input = file_get_contents('php://input', 1000000);
|
||||
* $value = $json->decode($input);
|
||||
* </code>
|
||||
*/
|
||||
class HTML_AJAX_JSON
|
||||
{
|
||||
/**
|
||||
* constructs a new JSON instance
|
||||
*
|
||||
* @param int $use object behavior flags; combine with boolean-OR
|
||||
*
|
||||
* possible values:
|
||||
* - SERVICES_JSON_LOOSE_TYPE: loose typing.
|
||||
* "{...}" syntax creates associative arrays
|
||||
* instead of objects in decode().
|
||||
* - SERVICES_JSON_SUPPRESS_ERRORS: error suppression.
|
||||
* Values which can't be encoded (e.g. resources)
|
||||
* appear as NULL instead of throwing errors.
|
||||
* By default, a deeply-nested resource will
|
||||
* bubble up with an error, so all return values
|
||||
* from encode() should be checked with isError()
|
||||
*/
|
||||
function HTML_AJAX_JSON($use = 0)
|
||||
{
|
||||
$this->use = $use;
|
||||
}
|
||||
|
||||
/**
|
||||
* convert a string from one UTF-16 char to one UTF-8 char
|
||||
*
|
||||
* Normally should be handled by mb_convert_encoding, but
|
||||
* provides a slower PHP-only method for installations
|
||||
* that lack the multibye string extension.
|
||||
*
|
||||
* @param string $utf16 UTF-16 character
|
||||
* @return string UTF-8 character
|
||||
* @access private
|
||||
*/
|
||||
function utf162utf8($utf16)
|
||||
{
|
||||
// oh please oh please oh please oh please oh please
|
||||
if(function_exists('mb_convert_encoding'))
|
||||
return mb_convert_encoding($utf16, 'UTF-8', 'UTF-16');
|
||||
|
||||
$bytes = (ord($utf16{0}) << 8) | ord($utf16{1});
|
||||
|
||||
switch(true) {
|
||||
case ((0x7F & $bytes) == $bytes):
|
||||
// this case should never be reached, because we are in ASCII range
|
||||
// see: http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8
|
||||
return chr(0x7F & $bytes);
|
||||
|
||||
case (0x07FF & $bytes) == $bytes:
|
||||
// return a 2-byte UTF-8 character
|
||||
// see: http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8
|
||||
return chr(0xC0 | (($bytes >> 6) & 0x1F))
|
||||
. chr(0x80 | ($bytes & 0x3F));
|
||||
|
||||
case (0xFFFF & $bytes) == $bytes:
|
||||
// return a 3-byte UTF-8 character
|
||||
// see: http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8
|
||||
return chr(0xE0 | (($bytes >> 12) & 0x0F))
|
||||
. chr(0x80 | (($bytes >> 6) & 0x3F))
|
||||
. chr(0x80 | ($bytes & 0x3F));
|
||||
}
|
||||
|
||||
// ignoring UTF-32 for now, sorry
|
||||
return '';
|
||||
}
|
||||
|
||||
/**
|
||||
* convert a string from one UTF-8 char to one UTF-16 char
|
||||
*
|
||||
* Normally should be handled by mb_convert_encoding, but
|
||||
* provides a slower PHP-only method for installations
|
||||
* that lack the multibye string extension.
|
||||
*
|
||||
* @param string $utf8 UTF-8 character
|
||||
* @return string UTF-16 character
|
||||
* @access private
|
||||
*/
|
||||
function utf82utf16($utf8)
|
||||
{
|
||||
// oh please oh please oh please oh please oh please
|
||||
if(function_exists('mb_convert_encoding'))
|
||||
return mb_convert_encoding($utf8, 'UTF-16', 'UTF-8');
|
||||
|
||||
switch(strlen($utf8)) {
|
||||
case 1:
|
||||
// this case should never be reached, because we are in ASCII range
|
||||
// see: http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8
|
||||
return $ut8;
|
||||
|
||||
case 2:
|
||||
// return a UTF-16 character from a 2-byte UTF-8 char
|
||||
// see: http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8
|
||||
return chr(0x07 & (ord($utf8{0}) >> 2))
|
||||
. chr((0xC0 & (ord($utf8{0}) << 6))
|
||||
| (0x3F & ord($utf8{1})));
|
||||
|
||||
case 3:
|
||||
// return a UTF-16 character from a 3-byte UTF-8 char
|
||||
// see: http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8
|
||||
return chr((0xF0 & (ord($utf8{0}) << 4))
|
||||
| (0x0F & (ord($utf8{1}) >> 2)))
|
||||
. chr((0xC0 & (ord($utf8{1}) << 6))
|
||||
| (0x7F & ord($utf8{2})));
|
||||
}
|
||||
|
||||
// ignoring UTF-32 for now, sorry
|
||||
return '';
|
||||
}
|
||||
|
||||
/**
|
||||
* encodes an arbitrary variable into JSON format
|
||||
*
|
||||
* @param mixed $var any number, boolean, string, array, or object to be encoded.
|
||||
* see argument 1 to HTML_AJAX_JSON() above for array-parsing behavior.
|
||||
* if var is a strng, note that encode() always expects it
|
||||
* to be in ASCII or UTF-8 format!
|
||||
*
|
||||
* @return mixed JSON string representation of input var or an error if a problem occurs
|
||||
* @access public
|
||||
*/
|
||||
function encode($var)
|
||||
{
|
||||
switch (gettype($var)) {
|
||||
case 'boolean':
|
||||
return $var ? 'true' : 'false';
|
||||
|
||||
case 'NULL':
|
||||
return 'null';
|
||||
|
||||
case 'integer':
|
||||
return (int) $var;
|
||||
|
||||
case 'double':
|
||||
case 'float':
|
||||
return (float) $var;
|
||||
|
||||
case 'string':
|
||||
// STRINGS ARE EXPECTED TO BE IN ASCII OR UTF-8 FORMAT
|
||||
$ascii = '';
|
||||
$strlen_var = strlen($var);
|
||||
|
||||
/*
|
||||
* Iterate over every character in the string,
|
||||
* escaping with a slash or encoding to UTF-8 where necessary
|
||||
*/
|
||||
for ($c = 0; $c < $strlen_var; ++$c) {
|
||||
|
||||
$ord_var_c = ord($var{$c});
|
||||
|
||||
switch (true) {
|
||||
case $ord_var_c == 0x08:
|
||||
$ascii .= '\b';
|
||||
break;
|
||||
case $ord_var_c == 0x09:
|
||||
$ascii .= '\t';
|
||||
break;
|
||||
case $ord_var_c == 0x0A:
|
||||
$ascii .= '\n';
|
||||
break;
|
||||
case $ord_var_c == 0x0C:
|
||||
$ascii .= '\f';
|
||||
break;
|
||||
case $ord_var_c == 0x0D:
|
||||
$ascii .= '\r';
|
||||
break;
|
||||
|
||||
case $ord_var_c == 0x22:
|
||||
case $ord_var_c == 0x2F:
|
||||
case $ord_var_c == 0x5C:
|
||||
// double quote, slash, slosh
|
||||
$ascii .= '\\'.$var{$c};
|
||||
break;
|
||||
|
||||
case (($ord_var_c >= 0x20) && ($ord_var_c <= 0x7F)):
|
||||
// characters U-00000000 - U-0000007F (same as ASCII)
|
||||
$ascii .= $var{$c};
|
||||
break;
|
||||
|
||||
case (($ord_var_c & 0xE0) == 0xC0):
|
||||
// characters U-00000080 - U-000007FF, mask 110XXXXX
|
||||
// see http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8
|
||||
$char = pack('C*', $ord_var_c, ord($var{$c + 1}));
|
||||
$c += 1;
|
||||
$utf16 = $this->utf82utf16($char);
|
||||
$ascii .= sprintf('\u%04s', bin2hex($utf16));
|
||||
break;
|
||||
|
||||
case (($ord_var_c & 0xF0) == 0xE0):
|
||||
// characters U-00000800 - U-0000FFFF, mask 1110XXXX
|
||||
// see http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8
|
||||
$char = pack('C*', $ord_var_c,
|
||||
ord($var{$c + 1}),
|
||||
ord($var{$c + 2}));
|
||||
$c += 2;
|
||||
$utf16 = $this->utf82utf16($char);
|
||||
$ascii .= sprintf('\u%04s', bin2hex($utf16));
|
||||
break;
|
||||
|
||||
case (($ord_var_c & 0xF8) == 0xF0):
|
||||
// characters U-00010000 - U-001FFFFF, mask 11110XXX
|
||||
// see http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8
|
||||
$char = pack('C*', $ord_var_c,
|
||||
ord($var{$c + 1}),
|
||||
ord($var{$c + 2}),
|
||||
ord($var{$c + 3}));
|
||||
$c += 3;
|
||||
$utf16 = $this->utf82utf16($char);
|
||||
$ascii .= sprintf('\u%04s', bin2hex($utf16));
|
||||
break;
|
||||
|
||||
case (($ord_var_c & 0xFC) == 0xF8):
|
||||
// characters U-00200000 - U-03FFFFFF, mask 111110XX
|
||||
// see http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8
|
||||
$char = pack('C*', $ord_var_c,
|
||||
ord($var{$c + 1}),
|
||||
ord($var{$c + 2}),
|
||||
ord($var{$c + 3}),
|
||||
ord($var{$c + 4}));
|
||||
$c += 4;
|
||||
$utf16 = $this->utf82utf16($char);
|
||||
$ascii .= sprintf('\u%04s', bin2hex($utf16));
|
||||
break;
|
||||
|
||||
case (($ord_var_c & 0xFE) == 0xFC):
|
||||
// characters U-04000000 - U-7FFFFFFF, mask 1111110X
|
||||
// see http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8
|
||||
$char = pack('C*', $ord_var_c,
|
||||
ord($var{$c + 1}),
|
||||
ord($var{$c + 2}),
|
||||
ord($var{$c + 3}),
|
||||
ord($var{$c + 4}),
|
||||
ord($var{$c + 5}));
|
||||
$c += 5;
|
||||
$utf16 = $this->utf82utf16($char);
|
||||
$ascii .= sprintf('\u%04s', bin2hex($utf16));
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return '"'.$ascii.'"';
|
||||
|
||||
case 'array':
|
||||
/*
|
||||
* As per JSON spec if any array key is not an integer
|
||||
* we must treat the the whole array as an object. We
|
||||
* also try to catch a sparsely populated associative
|
||||
* array with numeric keys here because some JS engines
|
||||
* will create an array with empty indexes up to
|
||||
* max_index which can cause memory issues and because
|
||||
* the keys, which may be relevant, will be remapped
|
||||
* otherwise.
|
||||
*
|
||||
* As per the ECMA and JSON specification an object may
|
||||
* have any string as a property. Unfortunately due to
|
||||
* a hole in the ECMA specification if the key is a
|
||||
* ECMA reserved word or starts with a digit the
|
||||
* parameter is only accessible using ECMAScript's
|
||||
* bracket notation.
|
||||
*/
|
||||
|
||||
// treat as a JSON object
|
||||
if (is_array($var) && count($var) && (array_keys($var) !== range(0, sizeof($var) - 1))) {
|
||||
$properties = array_map(array($this, 'name_value'),
|
||||
array_keys($var),
|
||||
array_values($var));
|
||||
|
||||
foreach($properties as $property)
|
||||
if(HTML_AJAX_JSON::isError($property))
|
||||
return $property;
|
||||
|
||||
return '{' . join(',', $properties) . '}';
|
||||
}
|
||||
|
||||
// treat it like a regular array
|
||||
$elements = array_map(array($this, 'encode'), $var);
|
||||
|
||||
foreach($elements as $element)
|
||||
if(HTML_AJAX_JSON::isError($element))
|
||||
return $element;
|
||||
|
||||
return '[' . join(',', $elements) . ']';
|
||||
|
||||
case 'object':
|
||||
$vars = get_object_vars($var);
|
||||
|
||||
$properties = array_map(array($this, 'name_value'),
|
||||
array_keys($vars),
|
||||
array_values($vars));
|
||||
|
||||
foreach($properties as $property)
|
||||
if(HTML_AJAX_JSON::isError($property))
|
||||
return $property;
|
||||
|
||||
return '{' . join(',', $properties) . '}';
|
||||
|
||||
default:
|
||||
return ($this->use & SERVICES_JSON_SUPPRESS_ERRORS)
|
||||
? 'null'
|
||||
: new HTML_AJAX_JSON_Error(gettype($var)." can not be encoded as JSON string");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* array-walking function for use in generating JSON-formatted name-value pairs
|
||||
*
|
||||
* @param string $name name of key to use
|
||||
* @param mixed $value reference to an array element to be encoded
|
||||
*
|
||||
* @return string JSON-formatted name-value pair, like '"name":value'
|
||||
* @access private
|
||||
*/
|
||||
function name_value($name, $value)
|
||||
{
|
||||
$encoded_value = $this->encode($value);
|
||||
|
||||
if(HTML_AJAX_JSON::isError($encoded_value))
|
||||
return $encoded_value;
|
||||
|
||||
return $this->encode(strval($name)) . ':' . $encoded_value;
|
||||
}
|
||||
|
||||
/**
|
||||
* reduce a string by removing leading and trailing comments and whitespace
|
||||
*
|
||||
* @param $str string string value to strip of comments and whitespace
|
||||
*
|
||||
* @return string string value stripped of comments and whitespace
|
||||
* @access private
|
||||
*/
|
||||
function reduce_string($str)
|
||||
{
|
||||
$str = preg_replace(array(
|
||||
|
||||
// eliminate single line comments in '// ...' form
|
||||
'#^\s*//(.+)$#m',
|
||||
|
||||
// eliminate multi-line comments in '/* ... */' form, at start of string
|
||||
'#^\s*/\*(.+)\*/#Us',
|
||||
|
||||
// eliminate multi-line comments in '/* ... */' form, at end of string
|
||||
'#/\*(.+)\*/\s*$#Us'
|
||||
|
||||
), '', $str);
|
||||
|
||||
// eliminate extraneous space
|
||||
return trim($str);
|
||||
}
|
||||
|
||||
/**
|
||||
* decodes a JSON string into appropriate variable
|
||||
*
|
||||
* @param string $str JSON-formatted string
|
||||
*
|
||||
* @return mixed number, boolean, string, array, or object
|
||||
* corresponding to given JSON input string.
|
||||
* See argument 1 to HTML_AJAX_JSON() above for object-output behavior.
|
||||
* Note that decode() always returns strings
|
||||
* in ASCII or UTF-8 format!
|
||||
* @access public
|
||||
*/
|
||||
function decode($str)
|
||||
{
|
||||
$str = $this->reduce_string($str);
|
||||
|
||||
switch (strtolower($str)) {
|
||||
case 'true':
|
||||
return true;
|
||||
|
||||
case 'false':
|
||||
return false;
|
||||
|
||||
case 'null':
|
||||
return null;
|
||||
|
||||
default:
|
||||
if (is_numeric($str)) {
|
||||
// Lookie-loo, it's a number
|
||||
|
||||
// This would work on its own, but I'm trying to be
|
||||
// good about returning integers where appropriate:
|
||||
// return (float)$str;
|
||||
|
||||
// Return float or int, as appropriate
|
||||
return ((float)$str == (integer)$str)
|
||||
? (integer)$str
|
||||
: (float)$str;
|
||||
|
||||
} elseif (preg_match('/^("|\').*(\1)$/s', $str, $m) && $m[1] == $m[2]) {
|
||||
// STRINGS RETURNED IN UTF-8 FORMAT
|
||||
$delim = substr($str, 0, 1);
|
||||
$chrs = substr($str, 1, -1);
|
||||
$utf8 = '';
|
||||
$strlen_chrs = strlen($chrs);
|
||||
|
||||
for ($c = 0; $c < $strlen_chrs; ++$c) {
|
||||
|
||||
$substr_chrs_c_2 = substr($chrs, $c, 2);
|
||||
$ord_chrs_c = ord($chrs{$c});
|
||||
|
||||
switch (true) {
|
||||
case $substr_chrs_c_2 == '\b':
|
||||
$utf8 .= chr(0x08);
|
||||
++$c;
|
||||
break;
|
||||
case $substr_chrs_c_2 == '\t':
|
||||
$utf8 .= chr(0x09);
|
||||
++$c;
|
||||
break;
|
||||
case $substr_chrs_c_2 == '\n':
|
||||
$utf8 .= chr(0x0A);
|
||||
++$c;
|
||||
break;
|
||||
case $substr_chrs_c_2 == '\f':
|
||||
$utf8 .= chr(0x0C);
|
||||
++$c;
|
||||
break;
|
||||
case $substr_chrs_c_2 == '\r':
|
||||
$utf8 .= chr(0x0D);
|
||||
++$c;
|
||||
break;
|
||||
|
||||
case $substr_chrs_c_2 == '\\"':
|
||||
case $substr_chrs_c_2 == '\\\'':
|
||||
case $substr_chrs_c_2 == '\\\\':
|
||||
case $substr_chrs_c_2 == '\\/':
|
||||
if (($delim == '"' && $substr_chrs_c_2 != '\\\'') ||
|
||||
($delim == "'" && $substr_chrs_c_2 != '\\"')) {
|
||||
$utf8 .= $chrs{++$c};
|
||||
}
|
||||
break;
|
||||
|
||||
case preg_match('/\\\u[0-9A-F]{4}/i', substr($chrs, $c, 6)):
|
||||
// single, escaped unicode character
|
||||
$utf16 = chr(hexdec(substr($chrs, ($c + 2), 2)))
|
||||
. chr(hexdec(substr($chrs, ($c + 4), 2)));
|
||||
$utf8 .= $this->utf162utf8($utf16);
|
||||
$c += 5;
|
||||
break;
|
||||
|
||||
case ($ord_chrs_c >= 0x20) && ($ord_chrs_c <= 0x7F):
|
||||
$utf8 .= $chrs{$c};
|
||||
break;
|
||||
|
||||
case ($ord_chrs_c & 0xE0) == 0xC0:
|
||||
// characters U-00000080 - U-000007FF, mask 110XXXXX
|
||||
//see http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8
|
||||
$utf8 .= substr($chrs, $c, 2);
|
||||
++$c;
|
||||
break;
|
||||
|
||||
case ($ord_chrs_c & 0xF0) == 0xE0:
|
||||
// characters U-00000800 - U-0000FFFF, mask 1110XXXX
|
||||
// see http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8
|
||||
$utf8 .= substr($chrs, $c, 3);
|
||||
$c += 2;
|
||||
break;
|
||||
|
||||
case ($ord_chrs_c & 0xF8) == 0xF0:
|
||||
// characters U-00010000 - U-001FFFFF, mask 11110XXX
|
||||
// see http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8
|
||||
$utf8 .= substr($chrs, $c, 4);
|
||||
$c += 3;
|
||||
break;
|
||||
|
||||
case ($ord_chrs_c & 0xFC) == 0xF8:
|
||||
// characters U-00200000 - U-03FFFFFF, mask 111110XX
|
||||
// see http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8
|
||||
$utf8 .= substr($chrs, $c, 5);
|
||||
$c += 4;
|
||||
break;
|
||||
|
||||
case ($ord_chrs_c & 0xFE) == 0xFC:
|
||||
// characters U-04000000 - U-7FFFFFFF, mask 1111110X
|
||||
// see http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8
|
||||
$utf8 .= substr($chrs, $c, 6);
|
||||
$c += 5;
|
||||
break;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return $utf8;
|
||||
|
||||
} elseif (preg_match('/^\[.*\]$/s', $str) || preg_match('/^\{.*\}$/s', $str)) {
|
||||
// array, or object notation
|
||||
|
||||
if ($str{0} == '[') {
|
||||
$stk = array(SERVICES_JSON_IN_ARR);
|
||||
$arr = array();
|
||||
} else {
|
||||
if ($this->use & SERVICES_JSON_LOOSE_TYPE) {
|
||||
$stk = array(SERVICES_JSON_IN_OBJ);
|
||||
$obj = array();
|
||||
} else {
|
||||
$stk = array(SERVICES_JSON_IN_OBJ);
|
||||
$obj = new stdClass();
|
||||
}
|
||||
}
|
||||
|
||||
array_push($stk, array('what' => SERVICES_JSON_SLICE,
|
||||
'where' => 0,
|
||||
'delim' => false));
|
||||
|
||||
$chrs = substr($str, 1, -1);
|
||||
$chrs = $this->reduce_string($chrs);
|
||||
|
||||
if ($chrs == '') {
|
||||
if (reset($stk) == SERVICES_JSON_IN_ARR) {
|
||||
return $arr;
|
||||
|
||||
} else {
|
||||
return $obj;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
//print("\nparsing {$chrs}\n");
|
||||
|
||||
$strlen_chrs = strlen($chrs);
|
||||
|
||||
for ($c = 0; $c <= $strlen_chrs; ++$c) {
|
||||
|
||||
$top = end($stk);
|
||||
$substr_chrs_c_2 = substr($chrs, $c, 2);
|
||||
|
||||
if (($c == $strlen_chrs) || (($chrs{$c} == ',') && ($top['what'] == SERVICES_JSON_SLICE))) {
|
||||
// found a comma that is not inside a string, array, etc.,
|
||||
// OR we've reached the end of the character list
|
||||
$slice = substr($chrs, $top['where'], ($c - $top['where']));
|
||||
array_push($stk, array('what' => SERVICES_JSON_SLICE, 'where' => ($c + 1), 'delim' => false));
|
||||
//print("Found split at {$c}: ".substr($chrs, $top['where'], (1 + $c - $top['where']))."\n");
|
||||
|
||||
if (reset($stk) == SERVICES_JSON_IN_ARR) {
|
||||
// we are in an array, so just push an element onto the stack
|
||||
array_push($arr, $this->decode($slice));
|
||||
|
||||
} elseif (reset($stk) == SERVICES_JSON_IN_OBJ) {
|
||||
// we are in an object, so figure
|
||||
// out the property name and set an
|
||||
// element in an associative array,
|
||||
// for now
|
||||
if (preg_match('/^\s*(["\'].*[^\\\]["\'])\s*:\s*(\S.*),?$/Uis', $slice, $parts)) {
|
||||
// "name":value pair
|
||||
$key = $this->decode($parts[1]);
|
||||
$val = $this->decode($parts[2]);
|
||||
|
||||
if ($this->use & SERVICES_JSON_LOOSE_TYPE) {
|
||||
$obj[$key] = $val;
|
||||
} else {
|
||||
$obj->$key = $val;
|
||||
}
|
||||
} elseif (preg_match('/^\s*(\w+)\s*:\s*(\S.*),?$/Uis', $slice, $parts)) {
|
||||
// name:value pair, where name is unquoted
|
||||
$key = $parts[1];
|
||||
$val = $this->decode($parts[2]);
|
||||
|
||||
if ($this->use & SERVICES_JSON_LOOSE_TYPE) {
|
||||
$obj[$key] = $val;
|
||||
} else {
|
||||
$obj->$key = $val;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
} elseif ((($chrs{$c} == '"') || ($chrs{$c} == "'")) && ($top['what'] != SERVICES_JSON_IN_STR)) {
|
||||
// found a quote, and we are not inside a string
|
||||
array_push($stk, array('what' => SERVICES_JSON_IN_STR, 'where' => $c, 'delim' => $chrs{$c}));
|
||||
//print("Found start of string at {$c}\n");
|
||||
|
||||
} elseif (($chrs{$c} == $top['delim']) &&
|
||||
($top['what'] == SERVICES_JSON_IN_STR) &&
|
||||
(($chrs{$c - 1} != '\\') ||
|
||||
($chrs{$c - 1} == '\\' && $chrs{$c - 2} == '\\'))) {
|
||||
// found a quote, we're in a string, and it's not escaped
|
||||
array_pop($stk);
|
||||
//print("Found end of string at {$c}: ".substr($chrs, $top['where'], (1 + 1 + $c - $top['where']))."\n");
|
||||
|
||||
} elseif (($chrs{$c} == '[') &&
|
||||
in_array($top['what'], array(SERVICES_JSON_SLICE, SERVICES_JSON_IN_ARR, SERVICES_JSON_IN_OBJ))) {
|
||||
// found a left-bracket, and we are in an array, object, or slice
|
||||
array_push($stk, array('what' => SERVICES_JSON_IN_ARR, 'where' => $c, 'delim' => false));
|
||||
//print("Found start of array at {$c}\n");
|
||||
|
||||
} elseif (($chrs{$c} == ']') && ($top['what'] == SERVICES_JSON_IN_ARR)) {
|
||||
// found a right-bracket, and we're in an array
|
||||
array_pop($stk);
|
||||
//print("Found end of array at {$c}: ".substr($chrs, $top['where'], (1 + $c - $top['where']))."\n");
|
||||
|
||||
} elseif (($chrs{$c} == '{') &&
|
||||
in_array($top['what'], array(SERVICES_JSON_SLICE, SERVICES_JSON_IN_ARR, SERVICES_JSON_IN_OBJ))) {
|
||||
// found a left-brace, and we are in an array, object, or slice
|
||||
array_push($stk, array('what' => SERVICES_JSON_IN_OBJ, 'where' => $c, 'delim' => false));
|
||||
//print("Found start of object at {$c}\n");
|
||||
|
||||
} elseif (($chrs{$c} == '}') && ($top['what'] == SERVICES_JSON_IN_OBJ)) {
|
||||
// found a right-brace, and we're in an object
|
||||
array_pop($stk);
|
||||
//print("Found end of object at {$c}: ".substr($chrs, $top['where'], (1 + $c - $top['where']))."\n");
|
||||
|
||||
} elseif (($substr_chrs_c_2 == '/*') &&
|
||||
in_array($top['what'], array(SERVICES_JSON_SLICE, SERVICES_JSON_IN_ARR, SERVICES_JSON_IN_OBJ))) {
|
||||
// found a comment start, and we are in an array, object, or slice
|
||||
array_push($stk, array('what' => SERVICES_JSON_IN_CMT, 'where' => $c, 'delim' => false));
|
||||
$c++;
|
||||
//print("Found start of comment at {$c}\n");
|
||||
|
||||
} elseif (($substr_chrs_c_2 == '*/') && ($top['what'] == SERVICES_JSON_IN_CMT)) {
|
||||
// found a comment end, and we're in one now
|
||||
array_pop($stk);
|
||||
$c++;
|
||||
|
||||
for ($i = $top['where']; $i <= $c; ++$i)
|
||||
$chrs = substr_replace($chrs, ' ', $i, 1);
|
||||
|
||||
//print("Found end of comment at {$c}: ".substr($chrs, $top['where'], (1 + $c - $top['where']))."\n");
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if (reset($stk) == SERVICES_JSON_IN_ARR) {
|
||||
return $arr;
|
||||
|
||||
} elseif (reset($stk) == SERVICES_JSON_IN_OBJ) {
|
||||
return $obj;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @todo Ultimately, this should just call PEAR::isError()
|
||||
*/
|
||||
function isError($data, $code = null)
|
||||
{
|
||||
if (HTML_AJAX_class_exists('pear', false)) {
|
||||
return PEAR::isError($data, $code);
|
||||
} elseif (is_object($data) && (get_class($data) == 'services_json_error' ||
|
||||
is_subclass_of($data, 'services_json_error'))) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
if (HTML_AJAX_class_exists('pear_error', false)) {
|
||||
|
||||
class HTML_AJAX_JSON_Error extends PEAR_Error
|
||||
{
|
||||
function HTML_AJAX_JSON_Error($message = 'unknown error', $code = null,
|
||||
$mode = null, $options = null, $userinfo = null)
|
||||
{
|
||||
parent::PEAR_Error($message, $code, $mode, $options, $userinfo);
|
||||
}
|
||||
}
|
||||
|
||||
} else {
|
||||
|
||||
/**
|
||||
* @todo Ultimately, this class shall be descended from PEAR_Error
|
||||
*/
|
||||
class HTML_AJAX_JSON_Error
|
||||
{
|
||||
function HTML_AJAX_JSON_Error($message = 'unknown error', $code = null,
|
||||
$mode = null, $options = null, $userinfo = null)
|
||||
{
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
?>
|
||||
76
include/pear/HTML/AJAX/Response.php
Normal file
76
include/pear/HTML/AJAX/Response.php
Normal file
@@ -0,0 +1,76 @@
|
||||
<?php
|
||||
/**
|
||||
* OO AJAX Implementation for PHP, contains HTML_AJAX_Response
|
||||
*
|
||||
* @category HTML
|
||||
* @package AJAX
|
||||
* @author Elizabeth Smith <auroraeosrose@gmail.com>
|
||||
* @copyright 2005-2006 Elizabeth Smith
|
||||
* @license http://www.opensource.org/licenses/lgpl-license.php LGPL
|
||||
* @version Release: 0.5.2
|
||||
*/
|
||||
|
||||
/**
|
||||
* Require the main AJAX library
|
||||
*/
|
||||
require_once 'HTML/AJAX.php';
|
||||
|
||||
/**
|
||||
* Simple base class for a response object to use as an ajax callback
|
||||
*
|
||||
* This is the base response class, more interesting response classes can be
|
||||
* built off of this, simply give it a unique content type and override the
|
||||
* getPayload method or fill the payload property with your extended classes's
|
||||
* serialized content
|
||||
*
|
||||
* @version $Id: Response.php 536 2006-08-12 01:05:54Z emsmith $
|
||||
*/
|
||||
class HTML_AJAX_Response
|
||||
{
|
||||
|
||||
/**
|
||||
* The base response class uses plain text so use that content type
|
||||
*
|
||||
* @var string
|
||||
* @access public
|
||||
*/
|
||||
var $contentType = 'text/plain';
|
||||
|
||||
/**
|
||||
* Assign a string to this variable to use the bare response class
|
||||
*
|
||||
* @var string
|
||||
* @access public
|
||||
*/
|
||||
var $payload = '';
|
||||
|
||||
/**
|
||||
* Returns the appropriate content type
|
||||
*
|
||||
* This normally simply returns the contentType property but can be overridden
|
||||
* by an extending class if the content-type is variable
|
||||
*
|
||||
* @return string appropriate content type
|
||||
* @access public
|
||||
*/
|
||||
function getContentType()
|
||||
{
|
||||
return $this->contentType;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the serialized content of the response class
|
||||
*
|
||||
* You can either fill the payload elsewhere in an extending class and leave
|
||||
* this method alone, or you can override it if you have a different type
|
||||
* of payload that needs special treatment
|
||||
*
|
||||
* @return string serialized response content
|
||||
* @access public
|
||||
*/
|
||||
function getPayload()
|
||||
{
|
||||
return $this->payload;
|
||||
}
|
||||
}
|
||||
?>
|
||||
20
include/pear/HTML/AJAX/Serializer/Error.php
Normal file
20
include/pear/HTML/AJAX/Serializer/Error.php
Normal file
@@ -0,0 +1,20 @@
|
||||
<?php
|
||||
require_once 'HTML/AJAX/Serializer/JSON.php';
|
||||
// $Id
|
||||
/**
|
||||
* Error Serializer, for now just uses JSON
|
||||
*
|
||||
* @category HTML
|
||||
* @package AJAX
|
||||
* @author Joshua Eichorn <josh@bluga.net>
|
||||
* @copyright 2005 Joshua Eichorn
|
||||
* @license http://www.php.net/license/3_0.txt PHP License 3.0
|
||||
* @version Release: 0.5.2
|
||||
* @link http://pear.php.net/package/HTML_AJAX
|
||||
*/
|
||||
class HTML_AJAX_Serializer_Error extends HTML_AJAX_Serializer_JSON
|
||||
{
|
||||
|
||||
}
|
||||
/* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4: */
|
||||
?>
|
||||
96
include/pear/HTML/AJAX/Serializer/JSON.php
Normal file
96
include/pear/HTML/AJAX/Serializer/JSON.php
Normal file
@@ -0,0 +1,96 @@
|
||||
<?php
|
||||
require_once 'HTML/AJAX/JSON.php';
|
||||
// $Id$
|
||||
/**
|
||||
* JSON Serializer
|
||||
*
|
||||
* @category HTML
|
||||
* @package AJAX
|
||||
* @author Joshua Eichorn <josh@bluga.net>
|
||||
* @copyright 2005 Joshua Eichorn
|
||||
* @license http://www.opensource.org/licenses/lgpl-license.php LGPL
|
||||
* @version Release: 0.5.2
|
||||
* @link http://pear.php.net/package/PackageName
|
||||
*/
|
||||
// {{{ class HTMLA_AJAX_Serialize_JSON
|
||||
class HTML_AJAX_Serializer_JSON
|
||||
{
|
||||
// {{{ variables-properties
|
||||
/**
|
||||
* JSON instance
|
||||
* @var HTML_AJAX_JSON
|
||||
* @access private
|
||||
*/
|
||||
var $_json;
|
||||
|
||||
/**
|
||||
* use json php extension http://www.aurore.net/projects/php-json/
|
||||
* @access private
|
||||
*/
|
||||
var $_jsonext;
|
||||
|
||||
/**
|
||||
* use loose typing to decode js objects into php associative arrays
|
||||
* @access public
|
||||
*/
|
||||
var $loose_type;
|
||||
|
||||
// }}}
|
||||
// {{{ constructor
|
||||
function HTML_AJAX_Serializer_JSON($use_loose_type = true)
|
||||
{
|
||||
$this->loose_type = (bool) $use_loose_type;
|
||||
$this->_jsonext = $this->_detect();
|
||||
if(!$this->_jsonext) {
|
||||
$use_loose_type = ($this->loose_type) ? SERVICES_JSON_LOOSE_TYPE : 0;
|
||||
$this->_json = new HTML_AJAX_JSON($use_loose_type);
|
||||
}
|
||||
}
|
||||
// }}}
|
||||
// {{{ serialize
|
||||
/**
|
||||
* This function serializes and input passed to it.
|
||||
*
|
||||
* @access public
|
||||
* @param string $input The input to serialize.
|
||||
* @return string $input The serialized input.
|
||||
*/
|
||||
function serialize($input)
|
||||
{
|
||||
if($this->_jsonext) {
|
||||
return json_encode($input);
|
||||
} else {
|
||||
return $this->_json->encode($input);
|
||||
}
|
||||
}
|
||||
// }}}
|
||||
// {{{ unserialize
|
||||
/**
|
||||
* this function unserializes the input passed to it.
|
||||
*
|
||||
* @access public
|
||||
* @param string $input The input to unserialize
|
||||
* @return string $input The unserialized input.
|
||||
*/
|
||||
function unserialize($input)
|
||||
{
|
||||
if($this->_jsonext) {
|
||||
return json_decode($input, $this->loose_type);
|
||||
} else {
|
||||
return $this->_json->decode($input);
|
||||
}
|
||||
}
|
||||
// }}}
|
||||
// {{{ _detect
|
||||
/**
|
||||
* detects the loaded extension
|
||||
*/
|
||||
function _detect()
|
||||
{
|
||||
return extension_loaded('json');
|
||||
}
|
||||
// }}}
|
||||
}
|
||||
// }}}
|
||||
/* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4: */
|
||||
?>
|
||||
28
include/pear/HTML/AJAX/Serializer/Null.php
Normal file
28
include/pear/HTML/AJAX/Serializer/Null.php
Normal file
@@ -0,0 +1,28 @@
|
||||
<?php
|
||||
// $Id$
|
||||
/**
|
||||
* Null Serializer
|
||||
*
|
||||
* @category HTML
|
||||
* @package AJAX
|
||||
* @author Joshua Eichorn <josh@bluga.net>
|
||||
* @copyright 2005 Joshua Eichorn
|
||||
* @license http://www.opensource.org/licenses/lgpl-license.php LGPL
|
||||
* @version Release: 0.5.2
|
||||
* @link http://pear.php.net/package/PackageName
|
||||
*/
|
||||
class HTML_AJAX_Serializer_Null
|
||||
{
|
||||
|
||||
function serialize($input)
|
||||
{
|
||||
return $input;
|
||||
}
|
||||
|
||||
function unserialize($input)
|
||||
{
|
||||
return $input;
|
||||
}
|
||||
}
|
||||
/* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4: */
|
||||
?>
|
||||
88
include/pear/HTML/AJAX/Serializer/PHP.php
Normal file
88
include/pear/HTML/AJAX/Serializer/PHP.php
Normal file
@@ -0,0 +1,88 @@
|
||||
<?php
|
||||
// $Id$
|
||||
/**
|
||||
* PHP Serializer
|
||||
*
|
||||
* @category HTML
|
||||
* @package AJAX
|
||||
* @author Arpad Ray <arpad@php.net>
|
||||
* @copyright 2005 Arpad Ray
|
||||
* @license http://www.opensource.org/licenses/lgpl-license.php LGPL
|
||||
* @version Release: 0.5.2
|
||||
* @link http://pear.php.net/package/HTML_AJAX
|
||||
*/
|
||||
class HTML_AJAX_Serializer_PHP
|
||||
{
|
||||
function serialize($input)
|
||||
{
|
||||
return serialize($input);
|
||||
}
|
||||
|
||||
/**
|
||||
* Unserializes the given string
|
||||
*
|
||||
* Triggers an error if a class is found which is not
|
||||
* in the provided array of allowed class names.
|
||||
*
|
||||
* @param string $input
|
||||
* the serialized string to process
|
||||
* @param array $allowedClasses
|
||||
* an array of class names to check objects against
|
||||
* before instantion
|
||||
* @return mixed
|
||||
* the unserialized variable on success, or false on
|
||||
* failure. If this method fails it will also trigger
|
||||
* a warning.
|
||||
*/
|
||||
function unserialize($input, $allowedClasses)
|
||||
{
|
||||
if (version_compare(PHP_VERSION, '4.3.10', '<')
|
||||
|| (substr(PHP_VERSION, 0, 1) == '5' && version_compare(PHP_VERSION, '5.0.3', '<'))) {
|
||||
trigger_error('Unsafe version of PHP for native unserialization');
|
||||
return false;
|
||||
}
|
||||
$classes = $this->_getSerializedClassNames($input);
|
||||
if ($classes === false) {
|
||||
trigger_error('Invalidly serialized string');
|
||||
return false;
|
||||
}
|
||||
$diff = array_diff($classes, $allowedClasses);
|
||||
if (!empty($diff)) {
|
||||
trigger_error('Class(es) not allowed to be serialized');
|
||||
return false;
|
||||
}
|
||||
return unserialize($input);
|
||||
}
|
||||
|
||||
/**
|
||||
* Extract class names from serialized string
|
||||
*
|
||||
* Adapted from code by Harry Fuecks
|
||||
*
|
||||
* @param string $string
|
||||
* the serialized string to process
|
||||
* @return mixed
|
||||
* an array of class names found, or false if the input
|
||||
* is invalidly formed
|
||||
*/
|
||||
function _getSerializedClassNames($string) {
|
||||
// Strip any string representations (which might contain object syntax)
|
||||
while (($pos = strpos($string, 's:')) !== false) {
|
||||
$pos2 = strpos($string, ':', $pos + 2);
|
||||
if ($pos2 === false) {
|
||||
// invalidly serialized string
|
||||
return false;
|
||||
}
|
||||
$end = $pos + 2 + substr($string, $pos + 2, $pos2) + 1;
|
||||
$string = substr($string, 0, $pos) . substr($string, $end);
|
||||
}
|
||||
|
||||
// Pull out the class names
|
||||
preg_match_all('/O:[0-9]+:"(.*)"/U', $string, $matches);
|
||||
|
||||
// Make sure names are unique (same object serialized twice)
|
||||
return array_unique($matches[1]);
|
||||
}
|
||||
}
|
||||
/* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4: */
|
||||
?>
|
||||
67
include/pear/HTML/AJAX/Serializer/Urlencoded.php
Normal file
67
include/pear/HTML/AJAX/Serializer/Urlencoded.php
Normal file
@@ -0,0 +1,67 @@
|
||||
<?php
|
||||
// $Id$
|
||||
|
||||
// {{{ http_build_query
|
||||
/**
|
||||
* Replacement for http_build_query()
|
||||
*
|
||||
* @link http://php.net/function.http-build-query
|
||||
* @author vlad_mustafin@ukr.net
|
||||
* @author Arpad Ray <arpad@php.net>
|
||||
*/
|
||||
if (!function_exists('http_build_query')) {
|
||||
function http_build_query($formdata, $numeric_prefix = null, $key = null)
|
||||
{
|
||||
$res = array();
|
||||
foreach ((array)$formdata as $k => $v) {
|
||||
if (is_resource($v)) {
|
||||
return null;
|
||||
}
|
||||
$tmp_key = urlencode(is_int($k) ? $numeric_prefix . $k : $k);
|
||||
if (!is_null($key)) {
|
||||
$tmp_key = $key . '[' . $tmp_key . ']';
|
||||
}
|
||||
$res[] = (is_scalar($v))
|
||||
? $tmp_key . '=' . urlencode($v)
|
||||
: http_build_query($v, null , $tmp_key);
|
||||
}
|
||||
$separator = ini_get('arg_separator.output');
|
||||
if (strlen($separator) == 0) {
|
||||
$separator = '&';
|
||||
}
|
||||
return implode($separator, $res);
|
||||
}
|
||||
}
|
||||
// }}}
|
||||
// {{{ class HTML_AJAX_Serialize_Urlencoded
|
||||
/**
|
||||
* URL Encoding Serializer
|
||||
*
|
||||
* @category HTML
|
||||
* @package AJAX
|
||||
* @author Arpad Ray <arpad@php.net>
|
||||
* @author David Coallier <davidc@php.net>
|
||||
* @copyright 2005 Arpad Ray
|
||||
* @license http://www.opensource.org/licenses/lgpl-license.php LGPL
|
||||
* @version Release: 0.5.2
|
||||
* @link http://pear.php.net/package/HTML_AJAX
|
||||
*/
|
||||
class HTML_AJAX_Serializer_Urlencoded
|
||||
{
|
||||
// {{{ serialize
|
||||
function serialize($input)
|
||||
{
|
||||
return http_build_query(array('_HTML_AJAX' => $input));
|
||||
}
|
||||
// }}}
|
||||
// {{{ unserialize
|
||||
function unserialize($input)
|
||||
{
|
||||
parse_str($input, $ret);
|
||||
return (isset($ret['_HTML_AJAX']) ? $ret['_HTML_AJAX'] : $ret);
|
||||
}
|
||||
// }}}
|
||||
}
|
||||
// }}}
|
||||
/* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4: */
|
||||
?>
|
||||
88
include/pear/HTML/AJAX/Serializer/XML.php
Normal file
88
include/pear/HTML/AJAX/Serializer/XML.php
Normal file
@@ -0,0 +1,88 @@
|
||||
<?php
|
||||
// $Id: XML.php 583 2007-03-05 22:13:30Z jeichorn $
|
||||
/**
|
||||
* XML Serializer - does NOT need a js serializer, use responseXML property in XmlHttpRequest
|
||||
*
|
||||
* @category HTML
|
||||
* @package AJAX
|
||||
* @author Elizabeth Smith <auroraeosrose@gmail.com>
|
||||
* @copyright 2005-2006 Elizabeth Smith
|
||||
* @license http://www.opensource.org/licenses/lgpl-license.php LGPL
|
||||
* @version Release: 0.5.2
|
||||
* @link http://pear.php.net/package/PackageName
|
||||
*/
|
||||
class HTML_AJAX_Serializer_XML
|
||||
{
|
||||
|
||||
/**
|
||||
* Serializes a domdocument into an xml string
|
||||
*
|
||||
* Uses dom or domxml to dump a string from a DomDocument instance
|
||||
* remember dom is always the default and this will die horribly without
|
||||
* a domdocument instance
|
||||
*
|
||||
* @access public
|
||||
* @param object $input instanceof DomDocument
|
||||
* @return string xml string of DomDocument
|
||||
*/
|
||||
function serialize($input)
|
||||
{
|
||||
if(empty($input))
|
||||
{
|
||||
return $input;
|
||||
}
|
||||
// we check for the dom extension
|
||||
elseif (extension_loaded('Dom'))
|
||||
{
|
||||
return $input->saveXml();
|
||||
}
|
||||
// then will check for domxml
|
||||
elseif (extension_loaded('Domxml'))
|
||||
{
|
||||
return $input->dump_mem();
|
||||
}
|
||||
// will throw an error
|
||||
else {
|
||||
$error = new HTML_AJAX_Serializer_Error();
|
||||
$this->serializerNewType = 'Error';
|
||||
return $error->serialize(array('errStr'=>"Missing PHP Dom extension direct XML won't work"));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Unserializes the xml string sent from the document
|
||||
*
|
||||
* Uses dom or domxml to pump a string into a DomDocument instance
|
||||
* remember dom is always the default and this will die horribly without
|
||||
* one or the other, and will throw warnings if you have bad xml
|
||||
*
|
||||
* @access public
|
||||
* @param string $input The input to serialize.
|
||||
* @return object instanceofDomDocument
|
||||
*/
|
||||
function unserialize($input)
|
||||
{
|
||||
if(empty($input))
|
||||
{
|
||||
return $input;
|
||||
}
|
||||
// we check for the dom extension
|
||||
elseif (extension_loaded('Dom'))
|
||||
{
|
||||
$doc = new DOMDocument();
|
||||
$doc->loadXML($input);
|
||||
return $doc;
|
||||
}
|
||||
// then we check for the domxml extensions
|
||||
elseif (extension_loaded('Domxml'))
|
||||
{
|
||||
return domxml_open_mem($input);
|
||||
}
|
||||
// we give up and just return the xml directly
|
||||
else
|
||||
{
|
||||
return $input;
|
||||
}
|
||||
}
|
||||
}
|
||||
?>
|
||||
698
include/pear/HTML/AJAX/Server.php
Normal file
698
include/pear/HTML/AJAX/Server.php
Normal file
@@ -0,0 +1,698 @@
|
||||
<?php
|
||||
/**
|
||||
* OO AJAX Implementation for PHP
|
||||
*
|
||||
* @category HTML
|
||||
* @package AJAX
|
||||
* @author Joshua Eichorn <josh@bluga.net>
|
||||
* @copyright 2005 Joshua Eichorn
|
||||
* @license http://www.opensource.org/licenses/lgpl-license.php LGPL
|
||||
* @version Release: 0.5.2
|
||||
*/
|
||||
|
||||
/**
|
||||
* Require the main AJAX library
|
||||
*/
|
||||
require_once 'HTML/AJAX.php';
|
||||
|
||||
/**
|
||||
* Class for creating an external AJAX server
|
||||
*
|
||||
* Can be used in 2 different modes, registerClass mode where you create an instance of the server and add the classes that will be registered
|
||||
* and then run handle request
|
||||
*
|
||||
* Or you can extend it and add init{className} methods for each class you want to export
|
||||
*
|
||||
* Client js generation is exposed through 2 _GET params client and stub
|
||||
* Setting the _GET param client to `all` will give you all the js classes needed
|
||||
* Setting the _GET param stub to `all` will give you stubs of all registered classes, you can also set it too just 1 class
|
||||
*
|
||||
* @category HTML
|
||||
* @package AJAX
|
||||
* @author Joshua Eichorn <josh@bluga.net>
|
||||
* @copyright 2005 Joshua Eichorn
|
||||
* @license http://www.opensource.org/licenses/lgpl-license.php LGPL
|
||||
* @version Release: 0.5.2
|
||||
* @link http://pear.php.net/package/PackageName
|
||||
*/
|
||||
class HTML_AJAX_Server
|
||||
{
|
||||
|
||||
/**
|
||||
* Client options array if set to true the code looks at _GET
|
||||
* @var bool|array
|
||||
*/
|
||||
var $options = true;
|
||||
|
||||
/**
|
||||
* HTML_AJAX instance
|
||||
* @var HTML_AJAX
|
||||
*/
|
||||
var $ajax;
|
||||
|
||||
/**
|
||||
* Set to true if your extending the server to add init{className methods}
|
||||
* @var boolean
|
||||
* @access public
|
||||
*/
|
||||
var $initMethods = false;
|
||||
|
||||
/**
|
||||
* Location on filesystem of client javascript library
|
||||
* @var false|string if false the default pear data dir location is used
|
||||
*/
|
||||
var $clientJsLocation = false;
|
||||
|
||||
/**
|
||||
* An array of options that tell the server howto Cache output
|
||||
*
|
||||
* The rules are functions that make etag hash used to see if the client needs to download updated content
|
||||
* If you extend this class you can make your own rule function the naming convention is _cacheRule{RuleName}
|
||||
*
|
||||
* <code>
|
||||
* array(
|
||||
* 'httpCacheClient' => true, // send 304 headers for responses to ?client=* requests
|
||||
* 'ClientCacheRule' => 'File', // create a hash from file names and modified times, options: file|content
|
||||
* 'ClientCacheExpects'=> 'files', // what type of content to send to the hash function, options: files|classes|content
|
||||
* 'httpCacheStub' => true, // send 304 headers for responses to ?stub=* requests
|
||||
* 'StubCacheRule' => 'Api', // create a hash from the exposed api, options: api|content
|
||||
* 'StubCacheExpects'=> 'classes', // what type of content to send to the hash function, options: files|classes|content
|
||||
* )
|
||||
* </code>
|
||||
*
|
||||
* @var array
|
||||
* @access public
|
||||
*/
|
||||
var $cacheOptions = array(
|
||||
'httpCacheClient' => true,
|
||||
'ClientCacheRule' => 'file',
|
||||
'ClientCacheExpects' => 'files',
|
||||
'httpCacheStub' => true,
|
||||
'StubCacheRule' => 'api',
|
||||
'StubCacheExpects' => 'classes',
|
||||
);
|
||||
|
||||
/**
|
||||
* Javascript library names and there path
|
||||
*
|
||||
* the return of $this->clientJsLocation(), is prepended before running readfile on them
|
||||
*
|
||||
* @access public
|
||||
* @var array
|
||||
*/
|
||||
var $javascriptLibraries = array(
|
||||
'all' => 'HTML_AJAX.js',
|
||||
'html_ajax' => 'HTML_AJAX.js',
|
||||
'html_ajax_lite'=> 'HTML_AJAX_lite.js',
|
||||
'json' => 'serializer/JSON.js',
|
||||
'request' => 'Request.js',
|
||||
'main' => array('Compat.js','Main.js','clientPool.js'),
|
||||
'httpclient' => 'HttpClient.js',
|
||||
'dispatcher' => 'Dispatcher.js',
|
||||
'util' => 'util.js',
|
||||
'loading' => 'Loading.js',
|
||||
'phpserializer' => 'serializer/phpSerializer.js',
|
||||
'urlserializer' => 'serializer/UrlSerializer.js',
|
||||
'haserializer' => 'serializer/haSerializer.js',
|
||||
'clientpool' => 'clientPool.js',
|
||||
'iframe' => 'IframeXHR.js',
|
||||
'alias' => 'Alias.js',
|
||||
'queues' => 'Queue.js',
|
||||
'behavior' => array('behavior/behavior.js','behavior/cssQuery-p.js'),
|
||||
|
||||
// rules to help you use a minimal library set
|
||||
'standard' => array('Compat.js','clientPool.js','util.js','Main.js','HttpClient.js','Request.js','serializer/JSON.js',
|
||||
'Loading.js','serializer/UrlSerializer.js','Alias.js','behavior/behavior.js','behavior/cssQuery-p.js'),
|
||||
'jsonrpc' => array('Compat.js','util.js','Main.js','clientPool.js','HttpClient.js','Request.js','serializer/JSON.js'),
|
||||
'proxyobjects' => array('Compat.js','util.js','Main.js','clientPool.js','Request.js','serializer/JSON.js','Dispatcher.js'),
|
||||
|
||||
// BC rules
|
||||
'priorityqueue' => 'Queue.js',
|
||||
'orderedqueue' => 'Queue.js',
|
||||
);
|
||||
|
||||
/**
|
||||
* Custom paths to use for javascript libraries, if not set {@link clientJsLocation} is used to find the system path
|
||||
*
|
||||
* @access public
|
||||
* @var array
|
||||
* @see registerJsLibrary
|
||||
*/
|
||||
var $javascriptLibraryPaths = array();
|
||||
|
||||
/**
|
||||
* Array of className => init methods to call, generated from constructor from initClassName methods
|
||||
*
|
||||
* @access protected
|
||||
*/
|
||||
var $_initLookup = array();
|
||||
|
||||
|
||||
/**
|
||||
* Constructor creates the HTML_AJAX instance
|
||||
*
|
||||
* @param string $serverUrl (Optional) the url the client should be making a request too
|
||||
*/
|
||||
function HTML_AJAX_Server($serverUrl = false)
|
||||
{
|
||||
$this->ajax = new HTML_AJAX();
|
||||
|
||||
// parameters for HTML::AJAX
|
||||
$parameters = array('stub', 'client');
|
||||
|
||||
// keep in the query string all the parameters that don't belong to AJAX
|
||||
// we remove all string like "parameter=something&". Final '&' can also
|
||||
// be '&' (to be sure) and is optional. '=something' is optional too.
|
||||
$querystring = '';
|
||||
if (isset($_SERVER['QUERY_STRING'])) {
|
||||
$querystring = preg_replace('/(' . join('|', $parameters) . ')(?:=[^&]*(?:&(?:amp;)?|$))?/', '', $this->ajax->_getServer('QUERY_STRING'));
|
||||
}
|
||||
|
||||
// call the server with this query string
|
||||
if ($serverUrl === false) {
|
||||
$serverUrl = htmlentities($this->ajax->_getServer('PHP_SELF'));
|
||||
}
|
||||
|
||||
if (substr($serverUrl,-1) != '?') {
|
||||
$serverUrl .= '?';
|
||||
}
|
||||
$this->ajax->serverUrl = $serverUrl . htmlentities($querystring);
|
||||
|
||||
$methods = get_class_methods($this);
|
||||
foreach($methods as $method) {
|
||||
if (preg_match('/^init([a-zA-Z0-9_]+)$/',$method,$match)) {
|
||||
$this->_initLookup[strtolower($match[1])] = $method;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Handle a client request, either generating a client or having HTML_AJAX handle the request
|
||||
*
|
||||
* @return boolean true if request was handled, false otherwise
|
||||
*/
|
||||
function handleRequest()
|
||||
{
|
||||
if ($this->options == true) {
|
||||
$this->_loadOptions();
|
||||
}
|
||||
//basically a hook for iframe but allows processing of data earlier
|
||||
$this->ajax->populatePayload();
|
||||
if (!isset($_GET['c']) && (count($this->options['client']) > 0 || count($this->options['stub']) > 0) ) {
|
||||
$this->generateClient();
|
||||
return true;
|
||||
} else {
|
||||
if (!empty($_GET['c'])) {
|
||||
$this->_init($this->_cleanIdentifier($this->ajax->_getVar('c')));
|
||||
}
|
||||
return $this->ajax->handleRequest();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Register method passthrough to HTML_AJAX
|
||||
*
|
||||
* @see HTML_AJAX::registerClass for docs
|
||||
*/
|
||||
function registerClass(&$instance, $exportedName = false, $exportedMethods = false)
|
||||
{
|
||||
$this->ajax->registerClass($instance,$exportedName,$exportedMethods);
|
||||
}
|
||||
|
||||
/**
|
||||
* Change default serialization - important for exporting classes
|
||||
*
|
||||
* I wanted this for the xml serializer :)
|
||||
*/
|
||||
function setSerializer($type)
|
||||
{
|
||||
$this->ajax->serializer = $type;
|
||||
$this->ajax->unserializer = $type;
|
||||
}
|
||||
|
||||
/**
|
||||
* Register a new js client library
|
||||
*
|
||||
* @param string $libraryName name you'll reference the library as
|
||||
* @param string|array $fileName actual filename with no path, for example customLib.js
|
||||
* @param string|false $path Optional, if not set the result from jsClientLocation is used
|
||||
*/
|
||||
function registerJSLibrary($libraryName,$fileName,$path = false) {
|
||||
$libraryName = strtolower($libraryName);
|
||||
$this->javascriptLibraries[$libraryName] = $fileName;
|
||||
|
||||
if ($path !== false) {
|
||||
$this->javascriptLibraryPaths[$libraryName] = $path;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Register init methods from an external class
|
||||
*
|
||||
* @param object $instance an external class with initClassName methods
|
||||
*/
|
||||
function registerInitObject(&$instance) {
|
||||
$instance->server =& $this;
|
||||
$methods = get_class_methods($instance);
|
||||
foreach($methods as $method) {
|
||||
if (preg_match('/^init([a-zA-Z0-9_]+)$/',$method,$match)) {
|
||||
$this->_initLookup[strtolower($match[1])] = array(&$instance,$method);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Register a callback to be exported to the client
|
||||
*
|
||||
* This function uses the PHP callback pseudo-type
|
||||
*
|
||||
*/
|
||||
function registerPhpCallback($callback)
|
||||
{
|
||||
if (!is_callable($callback)) {
|
||||
// invalid callback
|
||||
return false;
|
||||
}
|
||||
|
||||
if (is_array($callback) && is_object($callback[0])) {
|
||||
// object method
|
||||
$this->registerClass($callback[0], strtolower(get_class($callback[0])), array($callback[1]));
|
||||
return true;
|
||||
}
|
||||
|
||||
// static callback
|
||||
$this->ajax->registerPhpCallback($callback);
|
||||
}
|
||||
|
||||
/**
|
||||
* Generate client js
|
||||
*
|
||||
* @todo this is going to need tests to cover all the options
|
||||
*/
|
||||
function generateClient()
|
||||
{
|
||||
$headers = array();
|
||||
|
||||
ob_start();
|
||||
|
||||
// create a list list of js files were going to need to output
|
||||
// index is the full file and so is the value, this keeps duplicates out of $fileList
|
||||
$fileList = array();
|
||||
|
||||
if(!is_array($this->options['client'])) {
|
||||
$this->options['client'] = array();
|
||||
}
|
||||
foreach($this->options['client'] as $library) {
|
||||
if (isset($this->javascriptLibraries[$library])) {
|
||||
$lib = (array)$this->javascriptLibraries[$library];
|
||||
foreach($lib as $file) {
|
||||
if (isset($this->javascriptLibraryPaths[$library])) {
|
||||
$fileList[$this->javascriptLibraryPaths[$library].$file] = $this->javascriptLibraryPaths[$library].$file;
|
||||
}
|
||||
else {
|
||||
$fileList[$this->clientJsLocation().$file] = $this->clientJsLocation().$file;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// do needed class init if were running an init server
|
||||
if(!is_array($this->options['stub'])) {
|
||||
$this->options['stub'] = array();
|
||||
}
|
||||
$classList = $this->options['stub'];
|
||||
if ($this->initMethods) {
|
||||
if (isset($this->options['stub'][0]) && $this->options['stub'][0] === 'all') {
|
||||
$this->_initAll();
|
||||
} else {
|
||||
foreach($this->options['stub'] as $stub) {
|
||||
$this->_init($stub);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (isset($this->options['stub'][0]) && $this->options['stub'][0] === 'all') {
|
||||
$classList = array_keys($this->ajax->_exportedInstances);
|
||||
}
|
||||
|
||||
// if were doing stub and client we have to wait for both ETags before we can compare with the client
|
||||
$combinedOutput = false;
|
||||
if ($classList != false && count($classList) > 0 && count($fileList) > 0) {
|
||||
$combinedOutput = true;
|
||||
}
|
||||
|
||||
|
||||
if ($classList != false && count($classList) > 0) {
|
||||
|
||||
// were setup enough to make a stubETag if the input it wants is a class list
|
||||
if ($this->cacheOptions['httpCacheStub'] &&
|
||||
$this->cacheOptions['StubCacheExpects'] == 'classes')
|
||||
{
|
||||
$stubETag = $this->_callCacheRule('Stub',$classList);
|
||||
}
|
||||
|
||||
// if were not in combined output compare etags, if method returns true were done
|
||||
if (!$combinedOutput && isset($stubETag)) {
|
||||
if ($this->_compareEtags($stubETag)) {
|
||||
ob_end_clean();
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// output the stubs for all the classes in our list
|
||||
foreach($classList as $class) {
|
||||
echo $this->ajax->generateClassStub($class);
|
||||
}
|
||||
|
||||
// if were cacheing and the rule expects content make a tag and check it, if the check is true were done
|
||||
if ($this->cacheOptions['httpCacheStub'] &&
|
||||
$this->cacheOptions['StubCacheExpects'] == 'content')
|
||||
{
|
||||
$stubETag = $this->_callCacheRule('Stub',ob_get_contents());
|
||||
}
|
||||
|
||||
// if were not in combined output compare etags, if method returns true were done
|
||||
if (!$combinedOutput && isset($stubETag)) {
|
||||
if ($this->_compareEtags($stubETag)) {
|
||||
ob_end_clean();
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (count($fileList) > 0) {
|
||||
// if were caching and need a file list build our jsETag
|
||||
if ($this->cacheOptions['httpCacheClient'] &&
|
||||
$this->cacheOptions['ClientCacheExpects'] === 'files')
|
||||
{
|
||||
$jsETag = $this->_callCacheRule('Client',$fileList);
|
||||
|
||||
}
|
||||
|
||||
// if were not in combined output compare etags, if method returns true were done
|
||||
if (!$combinedOutput && isset($jsETag)) {
|
||||
if ($this->_compareEtags($jsETag)) {
|
||||
ob_end_clean();
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// output the needed client js files
|
||||
foreach($fileList as $file) {
|
||||
$this->_readFile($file);
|
||||
}
|
||||
|
||||
// if were caching and need content build the etag
|
||||
if ($this->cacheOptions['httpCacheClient'] &&
|
||||
$this->cacheOptions['ClientCacheExpects'] === 'content')
|
||||
{
|
||||
$jsETag = $this->_callCacheRule('Client',ob_get_contents());
|
||||
}
|
||||
|
||||
// if were not in combined output compare etags, if method returns true were done
|
||||
if (!$combinedOutput && isset($jsETag)) {
|
||||
if ($this->_compareEtags($jsETag)) {
|
||||
ob_end_clean();
|
||||
return;
|
||||
}
|
||||
}
|
||||
// were in combined output, merge the 2 ETags and compare
|
||||
else if (isset($jsETag) && isset($stubETag)) {
|
||||
if ($this->_compareEtags(md5($stubETag.$jsETag))) {
|
||||
ob_end_clean();
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// were outputting content, add our length header and send the output
|
||||
$length = ob_get_length();
|
||||
$output = ob_get_contents();
|
||||
ob_end_clean();
|
||||
|
||||
if ($this->ajax->packJavaScript) {
|
||||
$output = $this->ajax->packJavaScript($output);
|
||||
$length = strlen($output);
|
||||
}
|
||||
if ($length > 0 && $this->ajax->_sendContentLength()) {
|
||||
//$headers['Content-Length'] = $length;
|
||||
}
|
||||
$headers['Content-Type'] = 'text/javascript; charset=utf-8';
|
||||
$this->ajax->_sendHeaders($headers);
|
||||
echo($output);
|
||||
}
|
||||
|
||||
/**
|
||||
* Run readfile on input with basic error checking
|
||||
*
|
||||
* @param string $file file to read
|
||||
* @access private
|
||||
* @todo is addslashes enough encoding for js?
|
||||
*/
|
||||
function _readFile($file)
|
||||
{
|
||||
if (file_exists($file)) {
|
||||
readfile($file);
|
||||
} else {
|
||||
$file = addslashes($file);
|
||||
echo "alert('Unable to find javascript file: $file');";
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the location of the client js
|
||||
* To override the default pear datadir location set $this->clientJsLocation
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
function clientJsLocation()
|
||||
{
|
||||
if (!$this->clientJsLocation) {
|
||||
$path = '/usr/share/php/data'.DIRECTORY_SEPARATOR.'HTML_AJAX'.DIRECTORY_SEPARATOR.'js'.DIRECTORY_SEPARATOR;
|
||||
if(strpos($path, '@'.'data-dir@') === 0)
|
||||
{
|
||||
$path = realpath(dirname(__FILE__).DIRECTORY_SEPARATOR.'..'.DIRECTORY_SEPARATOR.'js').DIRECTORY_SEPARATOR;
|
||||
}
|
||||
return $path;
|
||||
} else {
|
||||
return $this->clientJsLocation;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the location of the client js
|
||||
*
|
||||
* @access public
|
||||
* @param string $location Location
|
||||
* @return void
|
||||
*/
|
||||
function setClientJsLocation($location)
|
||||
{
|
||||
$this->clientJsLocation = $location;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the path to a Javascript libraries
|
||||
*
|
||||
* @access public
|
||||
* @param string $library Library name
|
||||
* @param string $path Path
|
||||
* @return void
|
||||
*/
|
||||
function setJavascriptLibraryPath($library, $path)
|
||||
{
|
||||
$this->javascriptLibraryPaths[$library] = $path;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the path to more than one Javascript libraries at once
|
||||
*
|
||||
* @access public
|
||||
* @param array $paths Paths
|
||||
* @return void
|
||||
*/
|
||||
function setJavascriptLibraryPaths($paths)
|
||||
{
|
||||
if (is_array($paths)) {
|
||||
$this->javascriptLibraryPaths = array_merge($this->javascriptLibraryPaths, $paths);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Load options from _GET
|
||||
*
|
||||
* @access private
|
||||
*/
|
||||
function _loadOptions()
|
||||
{
|
||||
$this->options = array('client'=>array(),'stub'=>array());
|
||||
if (isset($_GET['client'])) {
|
||||
$clients = explode(',',$this->ajax->_getVar('client'));
|
||||
$client = array();
|
||||
foreach($clients as $val) {
|
||||
$cleanVal = $this->_cleanIdentifier($val);
|
||||
if (!empty($cleanVal)) {
|
||||
$client[] = strtolower($cleanVal);
|
||||
}
|
||||
}
|
||||
|
||||
if (count($client) > 0) {
|
||||
$this->options['client'] = $client;
|
||||
}
|
||||
}
|
||||
if (isset($_GET['stub'])) {
|
||||
$stubs = explode(',',$this->ajax->_getVar('stub'));
|
||||
$stub = array();
|
||||
foreach($stubs as $val) {
|
||||
$cleanVal = $this->_cleanIdentifier($val);
|
||||
if (!empty($cleanVal)) {
|
||||
$stub[] = strtolower($cleanVal);
|
||||
}
|
||||
}
|
||||
|
||||
if (count($stub) > 0) {
|
||||
$this->options['stub'] = $stub;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Clean an identifier like a class name making it safe to use
|
||||
*
|
||||
* @param string $input
|
||||
* @return string
|
||||
* @access private
|
||||
*/
|
||||
function _cleanIdentifier($input) {
|
||||
return trim(preg_replace('/[^A-Za-z_0-9]/','',$input));
|
||||
}
|
||||
|
||||
/**
|
||||
* Run every init method on the class
|
||||
*
|
||||
* @access private
|
||||
*/
|
||||
function _initAll()
|
||||
{
|
||||
if ($this->initMethods) {
|
||||
foreach($this->_initLookup as $class => $method) {
|
||||
$this->_init($class);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Init one class
|
||||
*
|
||||
* @param string $className
|
||||
* @access private
|
||||
*/
|
||||
function _init($className)
|
||||
{
|
||||
$className = strtolower($className);
|
||||
if ($this->initMethods) {
|
||||
if (isset($this->_initLookup[$className])) {
|
||||
$method =& $this->_initLookup[$className];
|
||||
if (is_array($method)) {
|
||||
call_user_func($method);
|
||||
}
|
||||
else {
|
||||
$this->$method();
|
||||
}
|
||||
} else {
|
||||
trigger_error("Could find an init method for class: " . $className);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Generate a hash from a list of files
|
||||
*
|
||||
* @param array $files file list
|
||||
* @return string a hash that can be used as an etag
|
||||
* @access private
|
||||
*/
|
||||
function _cacheRuleFile($files) {
|
||||
$signature = "";
|
||||
foreach($files as $file) {
|
||||
if (file_exists($file)) {
|
||||
$signature .= $file.filemtime($file);
|
||||
}
|
||||
}
|
||||
return md5($signature);
|
||||
}
|
||||
|
||||
/**
|
||||
* Generate a hash from the api of registered classes
|
||||
*
|
||||
* @param array $classes class list
|
||||
* @return string a hash that can be used as an etag
|
||||
* @access private
|
||||
*/
|
||||
function _cacheRuleApi($classes) {
|
||||
$signature = "";
|
||||
foreach($classes as $class) {
|
||||
if (isset($this->ajax->_exportedInstances[$class])) {
|
||||
$signature .= $class.implode(',',$this->ajax->_exportedInstances[$class]['exportedMethods']);
|
||||
}
|
||||
}
|
||||
return md5($signature);
|
||||
}
|
||||
|
||||
/**
|
||||
* Generate a hash from the raw content
|
||||
*
|
||||
* @param array $content
|
||||
* @return string a hash that can be used as an etag
|
||||
* @access private
|
||||
*/
|
||||
function _cacheRuleContent($content) {
|
||||
return md5($content);
|
||||
}
|
||||
|
||||
/**
|
||||
* Send cache control headers
|
||||
* @access private
|
||||
*/
|
||||
function _sendCacheHeaders($etag,$notModified) {
|
||||
header('Cache-Control: must-revalidate');
|
||||
header('ETag: '.$etag);
|
||||
if ($notModified) {
|
||||
header('HTTP/1.0 304 Not Modified',false,304);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Compare eTags
|
||||
*
|
||||
* @param string $serverETag server eTag
|
||||
* @return boolean
|
||||
* @access private
|
||||
*/
|
||||
function _compareEtags($serverETag) {
|
||||
if (isset($_SERVER['HTTP_IF_NONE_MATCH'])) {
|
||||
if (strcmp($this->ajax->_getServer('HTTP_IF_NONE_MATCH'),$serverETag) == 0) {
|
||||
$this->_sendCacheHeaders($serverETag,true);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
$this->_sendCacheHeaders($serverETag,false);
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Call a cache rule and return its retusn
|
||||
*
|
||||
* @param string $rule Stub|Client
|
||||
* @param mixed $payload
|
||||
* @return boolean
|
||||
* @access private
|
||||
* @todo decide if error checking is needed
|
||||
*/
|
||||
function _callCacheRule($rule,$payload) {
|
||||
$method = '_cacheRule'.$this->cacheOptions[$rule.'CacheRule'];
|
||||
return call_user_func(array(&$this,$method),$payload);
|
||||
}
|
||||
}
|
||||
/* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4: */
|
||||
?>
|
||||
464
include/pear/HTML/Common.php
Normal file
464
include/pear/HTML/Common.php
Normal file
@@ -0,0 +1,464 @@
|
||||
<?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-2007 The PHP Group
|
||||
* @license http://www.php.net/license/3_01.txt PHP License 3.01
|
||||
* @version CVS: $Id: Common.php,v 1.14 2007/05/16 20:06:44 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.4
|
||||
* @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 = '';
|
||||
|
||||
/**
|
||||
* 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
|
||||
*/
|
||||
function HTML_Common($attributes = null, $tabOffset = 0)
|
||||
{
|
||||
$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);
|
||||
} // end func _getTabs
|
||||
|
||||
/**
|
||||
* Returns an HTML formatted attribute string
|
||||
* @param array $attributes
|
||||
* @return string
|
||||
* @access private
|
||||
*/
|
||||
function _getAttrString($attributes)
|
||||
{
|
||||
$strAttr = '';
|
||||
|
||||
if (is_array($attributes)) {
|
||||
$charset = HTML_Common::charset();
|
||||
foreach ($attributes as $key => $value) {
|
||||
$strAttr .= ' ' . $key . '="' . htmlspecialchars($value, ENT_COMPAT, $charset) . '"';
|
||||
}
|
||||
}
|
||||
return $strAttr;
|
||||
} // end func _getAttrString
|
||||
|
||||
/**
|
||||
* Returns a valid atrributes array from either a string or array
|
||||
* @param mixed $attributes Either a typical HTML attribute string or an associative array
|
||||
* @access private
|
||||
* @return array
|
||||
*/
|
||||
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) == "'") {
|
||||
$value = substr($value, 1, -1);
|
||||
}
|
||||
$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]);
|
||||
}
|
||||
} //end func _removeAttr
|
||||
|
||||
/**
|
||||
* 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
|
||||
*/
|
||||
function getAttribute($attr)
|
||||
{
|
||||
$attr = strtolower($attr);
|
||||
if (isset($this->_attributes[$attr])) {
|
||||
return $this->_attributes[$attr];
|
||||
}
|
||||
return null;
|
||||
} //end func getAttribute
|
||||
|
||||
/**
|
||||
* 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)
|
||||
{
|
||||
static $charset = 'ISO-8859-1';
|
||||
|
||||
if (!is_null($newCharset)) {
|
||||
$charset = $newCharset;
|
||||
}
|
||||
return $charset;
|
||||
} // end func charset
|
||||
} // end class HTML_Common
|
||||
?>
|
||||
2059
include/pear/HTML/QuickForm.php
Normal file
2059
include/pear/HTML/QuickForm.php
Normal file
File diff suppressed because it is too large
Load Diff
158
include/pear/HTML/QuickForm/Renderer.php
Normal file
158
include/pear/HTML/QuickForm/Renderer.php
Normal file
@@ -0,0 +1,158 @@
|
||||
<?php
|
||||
/* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4: */
|
||||
|
||||
/**
|
||||
* 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-2007 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.10
|
||||
* @since 3.0
|
||||
* @abstract
|
||||
*/
|
||||
class HTML_QuickForm_Renderer
|
||||
{
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* @access public
|
||||
*/
|
||||
function HTML_QuickForm_Renderer()
|
||||
{
|
||||
} // end constructor
|
||||
|
||||
/**
|
||||
* 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;
|
||||
} // end func startForm
|
||||
|
||||
/**
|
||||
* 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;
|
||||
} // end func renderElement
|
||||
|
||||
/**
|
||||
* Called when visiting a hidden element
|
||||
*
|
||||
* @param HTML_QuickForm_element a hidden element being visited
|
||||
* @access public
|
||||
* @return void
|
||||
* @abstract
|
||||
*/
|
||||
function renderHidden(&$element)
|
||||
{
|
||||
return;
|
||||
} // end func renderHidden
|
||||
|
||||
/**
|
||||
* 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;
|
||||
} // end func finishGroup
|
||||
} // end class HTML_QuickForm_Renderer
|
||||
?>
|
||||
340
include/pear/HTML/QuickForm/Renderer/Array.php
Normal file
340
include/pear/HTML/QuickForm/Renderer/Array.php
Normal file
@@ -0,0 +1,340 @@
|
||||
<?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-2007 The PHP Group
|
||||
* @license http://www.php.net/license/3_01.txt PHP License 3.01
|
||||
* @version CVS: $Id: Array.php,v 1.10 2007/05/29 18:34:36 avb Exp $
|
||||
* @link http://pear.php.net/package/HTML_QuickForm
|
||||
*/
|
||||
|
||||
/**
|
||||
* An abstract base class for QuickForm renderers
|
||||
*/
|
||||
require_once 'HTML/QuickForm/Renderer.php';
|
||||
|
||||
/**
|
||||
* 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.10
|
||||
* @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;
|
||||
}
|
||||
}
|
||||
}
|
||||
?>
|
||||
402
include/pear/HTML/QuickForm/Renderer/ArraySmarty.php
Normal file
402
include/pear/HTML/QuickForm/Renderer/ArraySmarty.php
Normal file
@@ -0,0 +1,402 @@
|
||||
<?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-2007 The PHP Group
|
||||
* @license http://www.php.net/license/3_01.txt PHP License 3.01
|
||||
* @version CVS: $Id: ArraySmarty.php,v 1.12 2007/05/29 18:34:36 avb Exp $
|
||||
* @link http://pear.php.net/package/HTML_QuickForm
|
||||
*/
|
||||
|
||||
/**
|
||||
* A concrete renderer for HTML_QuickForm, makes an array of form contents
|
||||
*/
|
||||
require_once 'HTML/QuickForm/Renderer/Array.php';
|
||||
|
||||
/**
|
||||
* 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.10
|
||||
* @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"
|
||||
* @access public
|
||||
*/
|
||||
function HTML_QuickForm_Renderer_ArraySmarty(&$tpl, $staticLabels = false)
|
||||
{
|
||||
$this->HTML_QuickForm_Renderer_Array(true, $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
|
||||
}
|
||||
?>
|
||||
485
include/pear/HTML/QuickForm/Renderer/Default.php
Normal file
485
include/pear/HTML/QuickForm/Renderer/Default.php
Normal file
@@ -0,0 +1,485 @@
|
||||
<?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-2007 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
|
||||
*/
|
||||
require_once 'HTML/QuickForm/Renderer.php';
|
||||
|
||||
/**
|
||||
* 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.10
|
||||
* @since 3.0
|
||||
*/
|
||||
class HTML_QuickForm_Renderer_Default extends HTML_QuickForm_Renderer
|
||||
{
|
||||
/**
|
||||
* 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
|
||||
*/
|
||||
function HTML_QuickForm_Renderer_Default()
|
||||
{
|
||||
$this->HTML_QuickForm_Renderer();
|
||||
} // end constructor
|
||||
|
||||
/**
|
||||
* returns the HTML generated for the form
|
||||
*
|
||||
* @access public
|
||||
* @return string
|
||||
*/
|
||||
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->_html = '';
|
||||
$this->_hiddenHtml = '';
|
||||
} // 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
|
||||
*/
|
||||
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 string Element name
|
||||
* @param mixed Element label (if using an array of labels, you should set the appropriate template)
|
||||
* @param bool Whether an element is required
|
||||
* @param string Error message associated with the element
|
||||
* @access private
|
||||
* @see renderElement()
|
||||
* @return string Html for element
|
||||
*/
|
||||
function _prepareTemplate($name, $label, $required, $error)
|
||||
{
|
||||
if (is_array($label)) {
|
||||
$nameLabel = array_shift($label);
|
||||
} else {
|
||||
$nameLabel = $label;
|
||||
}
|
||||
if (isset($this->_templates[$name])) {
|
||||
$html = str_replace('{label}', $nameLabel, $this->_templates[$name]);
|
||||
} else {
|
||||
$html = str_replace('{label}', $nameLabel, $this->_elementTemplate);
|
||||
}
|
||||
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('<!-- BEGIN error -->', '', $html);
|
||||
$html = str_replace('<!-- END error -->', '', $html);
|
||||
} else {
|
||||
$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;
|
||||
} // end func _prepareTemplate
|
||||
|
||||
/**
|
||||
* 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
|
||||
*/
|
||||
function renderElement(&$element, $required, $error)
|
||||
{
|
||||
if (!$this->_inGroup) {
|
||||
$html = $this->_prepareTemplate($element->getName(), $element->getLabel(), $required, $error);
|
||||
$this->_html .= str_replace('{element}', $element->toHtml(), $html);
|
||||
|
||||
} elseif (!empty($this->_groupElementTemplate)) {
|
||||
$html = str_replace('{label}', $element->getLabel(), $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($name, $group->getLabel(), $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 = ' ';
|
||||
}
|
||||
$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
|
||||
?>
|
||||
300
include/pear/HTML/QuickForm/Renderer/ITDynamic.php
Normal file
300
include/pear/HTML/QuickForm/Renderer/ITDynamic.php
Normal file
@@ -0,0 +1,300 @@
|
||||
<?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-2007 The PHP Group
|
||||
* @license http://www.php.net/license/3_01.txt PHP License 3.01
|
||||
* @version CVS: $Id: ITDynamic.php,v 1.6 2007/05/29 18:34:36 avb Exp $
|
||||
* @link http://pear.php.net/package/HTML_QuickForm
|
||||
*/
|
||||
|
||||
/**
|
||||
* An abstract base class for QuickForm renderers
|
||||
*/
|
||||
require_once 'HTML/QuickForm/Renderer.php';
|
||||
|
||||
/**
|
||||
* 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.10
|
||||
* @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)? ' ': $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;
|
||||
}
|
||||
}
|
||||
?>
|
||||
504
include/pear/HTML/QuickForm/Renderer/ITStatic.php
Normal file
504
include/pear/HTML/QuickForm/Renderer/ITStatic.php
Normal file
@@ -0,0 +1,504 @@
|
||||
<?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-2007 The PHP Group
|
||||
* @license http://www.php.net/license/3_01.txt PHP License 3.01
|
||||
* @version CVS: $Id: ITStatic.php,v 1.8 2007/05/29 18:34:36 avb Exp $
|
||||
* @link http://pear.php.net/package/HTML_QuickForm
|
||||
*/
|
||||
|
||||
/**
|
||||
* An abstract base class for QuickForm renderers
|
||||
*/
|
||||
require_once 'HTML/QuickForm/Renderer.php';
|
||||
|
||||
/**
|
||||
* 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.10
|
||||
* @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
|
||||
?>
|
||||
461
include/pear/HTML/QuickForm/Renderer/Object.php
Normal file
461
include/pear/HTML/QuickForm/Renderer/Object.php
Normal file
@@ -0,0 +1,461 @@
|
||||
<?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-2007 The PHP Group
|
||||
* @license http://www.php.net/license/3_01.txt PHP License 3.01
|
||||
* @version CVS: $Id: Object.php,v 1.5 2007/05/29 18:34:36 avb Exp $
|
||||
* @link http://pear.php.net/package/HTML_QuickForm
|
||||
*/
|
||||
|
||||
/**
|
||||
* An abstract base class for QuickForm renderers
|
||||
*/
|
||||
require_once 'HTML/QuickForm/Renderer.php';
|
||||
|
||||
/**
|
||||
* 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.10
|
||||
* @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.10
|
||||
* @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 <form> header
|
||||
* {form.outputHeader():h}
|
||||
* @return string <form attributes>
|
||||
*/
|
||||
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.10
|
||||
* @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
|
||||
?>
|
||||
291
include/pear/HTML/QuickForm/Renderer/ObjectFlexy.php
Normal file
291
include/pear/HTML/QuickForm/Renderer/ObjectFlexy.php
Normal file
@@ -0,0 +1,291 @@
|
||||
<?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-2007 The PHP Group
|
||||
* @license http://www.php.net/license/3_01.txt PHP License 3.01
|
||||
* @version CVS: $Id: ObjectFlexy.php,v 1.9 2007/05/29 18:34:36 avb Exp $
|
||||
* @link http://pear.php.net/package/HTML_QuickForm
|
||||
*/
|
||||
|
||||
/**
|
||||
* A concrete renderer for HTML_QuickForm, makes an object from form contents
|
||||
*/
|
||||
require_once 'HTML/QuickForm/Renderer/Object.php';
|
||||
|
||||
/**
|
||||
* 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.10
|
||||
* @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
|
||||
{
|
||||
}
|
||||
?>
|
||||
213
include/pear/HTML/QuickForm/Renderer/QuickHtml.php
Normal file
213
include/pear/HTML/QuickForm/Renderer/QuickHtml.php
Normal file
@@ -0,0 +1,213 @@
|
||||
<?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-2007 The PHP Group
|
||||
* @license http://www.php.net/license/3_01.txt PHP License 3.01
|
||||
* @version CVS: $Id: QuickHtml.php,v 1.2 2007/05/29 18:34:36 avb Exp $
|
||||
* @link http://pear.php.net/package/HTML_QuickForm
|
||||
*/
|
||||
|
||||
/**
|
||||
* A concrete renderer for HTML_QuickForm, based on QuickForm 2.x built-in one
|
||||
*/
|
||||
require_once 'HTML/QuickForm/Renderer/Default.php';
|
||||
|
||||
/**
|
||||
* 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.10
|
||||
* @since 3.1.1
|
||||
*/
|
||||
class HTML_QuickForm_Renderer_QuickHtml extends HTML_QuickForm_Renderer_Default {
|
||||
// {{{ properties
|
||||
|
||||
/**
|
||||
* The array of rendered elements
|
||||
* @var array
|
||||
*/
|
||||
var $renderedElements = array();
|
||||
|
||||
// }}}
|
||||
// {{{ constructor
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* @access public
|
||||
* @return void
|
||||
*/
|
||||
function HTML_QuickForm_Renderer_QuickHtml()
|
||||
{
|
||||
$this->HTML_QuickForm_Renderer_Default();
|
||||
// The default templates aren't used for this renderer
|
||||
$this->clearAllTemplates();
|
||||
} // end constructor
|
||||
|
||||
// }}}
|
||||
// {{{ toHtml()
|
||||
|
||||
/**
|
||||
* 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;
|
||||
} // end func toHtml
|
||||
|
||||
// }}}
|
||||
// {{{ elementToHtml()
|
||||
|
||||
/**
|
||||
* 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
|
||||
* @throws HTML_QuickForm_Error
|
||||
*/
|
||||
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.";
|
||||
return PEAR::raiseError(null, QUICKFORM_UNREGISTERED_ELEMENT, null, E_USER_WARNING, $msg, 'HTML_QuickForm_Error', true);
|
||||
} 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.";
|
||||
return PEAR::raiseError(null, QUICKFORM_ERROR, null, E_USER_WARNING, $msg, 'HTML_QuickForm_Error', true);
|
||||
} else {
|
||||
$this->renderedElements[$elementKey]['rendered'] = true;
|
||||
return $this->renderedElements[$elementKey]['html'];
|
||||
}
|
||||
}
|
||||
} // end func elementToHtml
|
||||
|
||||
// }}}
|
||||
// {{{ renderElement()
|
||||
|
||||
/**
|
||||
* 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
|
||||
*/
|
||||
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 = '';
|
||||
} // end func renderElement
|
||||
|
||||
// }}}
|
||||
// {{{ renderHidden()
|
||||
|
||||
/**
|
||||
* 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
|
||||
*/
|
||||
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
|
||||
*/
|
||||
function finishGroup(&$group)
|
||||
{
|
||||
$this->_html = '';
|
||||
parent::finishGroup($group);
|
||||
$this->renderedElements[] = array(
|
||||
'name' => $group->getName(),
|
||||
'value' => $group->getValue(),
|
||||
'html' => $this->_html,
|
||||
'rendered' => false);
|
||||
$this->_html = '';
|
||||
} // end func finishGroup
|
||||
|
||||
// }}}
|
||||
} // end class HTML_QuickForm_Renderer_QuickHtml
|
||||
?>
|
||||
82
include/pear/HTML/QuickForm/Rule.php
Normal file
82
include/pear/HTML/QuickForm/Rule.php
Normal file
@@ -0,0 +1,82 @@
|
||||
<?php
|
||||
/* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4: */
|
||||
|
||||
/**
|
||||
* 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-2007 The PHP Group
|
||||
* @license http://www.php.net/license/3_01.txt PHP License 3.01
|
||||
* @version CVS: $Id: Rule.php,v 1.3 2007/05/29 18:34:36 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.10
|
||||
* @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
|
||||
*/
|
||||
var $name;
|
||||
|
||||
/**
|
||||
* Validates a value
|
||||
*
|
||||
* @access public
|
||||
* @abstract
|
||||
*/
|
||||
function validate($value)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the rule name
|
||||
*
|
||||
* @param string rule name
|
||||
* @access 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('', '');
|
||||
}
|
||||
}
|
||||
?>
|
||||
124
include/pear/HTML/QuickForm/Rule/Callback.php
Normal file
124
include/pear/HTML/QuickForm/Rule/Callback.php
Normal file
@@ -0,0 +1,124 @@
|
||||
<?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-2007 The PHP Group
|
||||
* @license http://www.php.net/license/3_01.txt PHP License 3.01
|
||||
* @version CVS: $Id: Callback.php,v 1.8 2007/05/29 18:34:36 avb Exp $
|
||||
* @link http://pear.php.net/package/HTML_QuickForm
|
||||
*/
|
||||
|
||||
/**
|
||||
* Abstract base class for QuickForm validation rules
|
||||
*/
|
||||
require_once 'HTML/QuickForm/Rule.php';
|
||||
|
||||
/**
|
||||
* Validates values using callback functions or methods
|
||||
*
|
||||
* @category HTML
|
||||
* @package HTML_QuickForm
|
||||
* @author Bertrand Mansion <bmansion@mamasam.com>
|
||||
* @version Release: 3.2.10
|
||||
* @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
|
||||
?>
|
||||
105
include/pear/HTML/QuickForm/Rule/Compare.php
Normal file
105
include/pear/HTML/QuickForm/Rule/Compare.php
Normal file
@@ -0,0 +1,105 @@
|
||||
<?php
|
||||
/* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4: */
|
||||
|
||||
/**
|
||||
* 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-2007 The PHP Group
|
||||
* @license http://www.php.net/license/3_01.txt PHP License 3.01
|
||||
* @version CVS: $Id: Compare.php,v 1.6 2007/06/05 18:35:49 avb Exp $
|
||||
* @link http://pear.php.net/package/HTML_QuickForm
|
||||
*/
|
||||
|
||||
/**
|
||||
* Abstract base class for QuickForm validation rules
|
||||
*/
|
||||
require_once 'HTML/QuickForm/Rule.php';
|
||||
|
||||
/**
|
||||
* 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.10
|
||||
* @since 3.2
|
||||
*/
|
||||
class HTML_QuickForm_Rule_Compare extends HTML_QuickForm_Rule
|
||||
{
|
||||
/**
|
||||
* Possible operators to use
|
||||
* @var array
|
||||
* @access private
|
||||
*/
|
||||
var $_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
|
||||
*/
|
||||
function _findOperator($name)
|
||||
{
|
||||
if (empty($name)) {
|
||||
return '===';
|
||||
} elseif (isset($this->_operators[$name])) {
|
||||
return $this->_operators[$name];
|
||||
} elseif (in_array($name, $this->_operators)) {
|
||||
return $name;
|
||||
} else {
|
||||
return '===';
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
function validate($values, $operator = null)
|
||||
{
|
||||
$operator = $this->_findOperator($operator);
|
||||
if ('===' != $operator && '!==' != $operator) {
|
||||
$compareFn = create_function('$a, $b', 'return floatval($a) ' . $operator . ' floatval($b);');
|
||||
} else {
|
||||
$compareFn = create_function('$a, $b', 'return strval($a) ' . $operator . ' strval($b);');
|
||||
}
|
||||
|
||||
return $compareFn($values[0], $values[1]);
|
||||
}
|
||||
|
||||
|
||||
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}");
|
||||
}
|
||||
}
|
||||
?>
|
||||
73
include/pear/HTML/QuickForm/Rule/Email.php
Normal file
73
include/pear/HTML/QuickForm/Rule/Email.php
Normal file
@@ -0,0 +1,73 @@
|
||||
<?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-2007 The PHP Group
|
||||
* @license http://www.php.net/license/3_01.txt PHP License 3.01
|
||||
* @version CVS: $Id: Email.php,v 1.6 2007/06/03 13:47:06 avb Exp $
|
||||
* @link http://pear.php.net/package/HTML_QuickForm
|
||||
*/
|
||||
|
||||
/**
|
||||
* Abstract base class for QuickForm validation rules
|
||||
*/
|
||||
require_once 'HTML/QuickForm/Rule.php';
|
||||
|
||||
/**
|
||||
* Email validation rule
|
||||
*
|
||||
* @category HTML
|
||||
* @package HTML_QuickForm
|
||||
* @author Bertrand Mansion <bmansion@mamasam.com>
|
||||
* @version Release: 3.2.10
|
||||
* @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
|
||||
?>
|
||||
75
include/pear/HTML/QuickForm/Rule/Range.php
Normal file
75
include/pear/HTML/QuickForm/Rule/Range.php
Normal 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-2007 The PHP Group
|
||||
* @license http://www.php.net/license/3_01.txt PHP License 3.01
|
||||
* @version CVS: $Id: Range.php,v 1.7 2007/05/29 18:34:36 avb Exp $
|
||||
* @link http://pear.php.net/package/HTML_QuickForm
|
||||
*/
|
||||
|
||||
/**
|
||||
* Abstract base class for QuickForm validation rules
|
||||
*/
|
||||
require_once 'HTML/QuickForm/Rule.php';
|
||||
|
||||
/**
|
||||
* Checks that the length of value is within range
|
||||
*
|
||||
* @category HTML
|
||||
* @package HTML_QuickForm
|
||||
* @author Bertrand Mansion <bmansion@mamasam.com>
|
||||
* @version Release: 3.2.10
|
||||
* @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
|
||||
*/
|
||||
function validate($value, $options)
|
||||
{
|
||||
$length = strlen($value);
|
||||
switch ($this->name) {
|
||||
case 'minlength': return ($length >= $options);
|
||||
case 'maxlength': return ($length <= $options);
|
||||
default: return ($length >= $options[0] && $length <= $options[1]);
|
||||
}
|
||||
} // end func validate
|
||||
|
||||
|
||||
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}");
|
||||
} // end func getValidationScript
|
||||
|
||||
} // end class HTML_QuickForm_Rule_Range
|
||||
?>
|
||||
101
include/pear/HTML/QuickForm/Rule/Regex.php
Normal file
101
include/pear/HTML/QuickForm/Rule/Regex.php
Normal file
@@ -0,0 +1,101 @@
|
||||
<?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-2007 The PHP Group
|
||||
* @license http://www.php.net/license/3_01.txt PHP License 3.01
|
||||
* @version CVS: $Id: Regex.php,v 1.5 2007/06/03 13:47:06 avb Exp $
|
||||
* @link http://pear.php.net/package/HTML_QuickForm
|
||||
*/
|
||||
|
||||
/**
|
||||
* Abstract base class for QuickForm validation rules
|
||||
*/
|
||||
require_once 'HTML/QuickForm/Rule.php';
|
||||
|
||||
/**
|
||||
* Validates values using regular expressions
|
||||
*
|
||||
* @category HTML
|
||||
* @package HTML_QuickForm
|
||||
* @author Bertrand Mansion <bmansion@mamasam.com>
|
||||
* @version Release: 3.2.10
|
||||
* @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
|
||||
*/
|
||||
var $_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
|
||||
*/
|
||||
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;
|
||||
|
||||
return array(" var regex = " . $regex . ";\n", "{jsVar} != '' && !regex.test({jsVar})");
|
||||
} // end func getValidationScript
|
||||
|
||||
} // end class HTML_QuickForm_Rule_Regex
|
||||
?>
|
||||
63
include/pear/HTML/QuickForm/Rule/Required.php
Normal file
63
include/pear/HTML/QuickForm/Rule/Required.php
Normal file
@@ -0,0 +1,63 @@
|
||||
<?php
|
||||
/* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4: */
|
||||
|
||||
/**
|
||||
* 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-2007 The PHP Group
|
||||
* @license http://www.php.net/license/3_01.txt PHP License 3.01
|
||||
* @version CVS: $Id: Required.php,v 1.5 2007/05/29 18:34:36 avb Exp $
|
||||
* @link http://pear.php.net/package/HTML_QuickForm
|
||||
*/
|
||||
|
||||
/**
|
||||
* Abstract base class for QuickForm validation rules
|
||||
*/
|
||||
require_once 'HTML/QuickForm/Rule.php';
|
||||
|
||||
/**
|
||||
* Required elements validation
|
||||
*
|
||||
* @category HTML
|
||||
* @package HTML_QuickForm
|
||||
* @author Bertrand Mansion <bmansion@mamasam.com>
|
||||
* @version Release: 3.2.10
|
||||
* @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
|
||||
*/
|
||||
function validate($value, $options = null)
|
||||
{
|
||||
if ((string)$value == '') {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
} // end func validate
|
||||
|
||||
|
||||
function getValidationScript($options = null)
|
||||
{
|
||||
return array('', "{jsVar} == ''");
|
||||
} // end func getValidationScript
|
||||
|
||||
} // end class HTML_QuickForm_Rule_Required
|
||||
?>
|
||||
349
include/pear/HTML/QuickForm/RuleRegistry.php
Normal file
349
include/pear/HTML/QuickForm/RuleRegistry.php
Normal file
@@ -0,0 +1,349 @@
|
||||
<?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-2007 The PHP Group
|
||||
* @license http://www.php.net/license/3_01.txt PHP License 3.01
|
||||
* @version CVS: $Id: RuleRegistry.php,v 1.18 2007/05/29 18:34:36 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.10
|
||||
* @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
|
||||
*/
|
||||
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
|
||||
*/
|
||||
function registerRule($ruleName, $type, $data1, $data2 = null)
|
||||
{
|
||||
$type = strtolower($type);
|
||||
if ($type == 'regex') {
|
||||
// Regular expression
|
||||
$rule =& $this->getRule('regex');
|
||||
$rule->addData($ruleName, $data1);
|
||||
$GLOBALS['_HTML_QuickForm_registered_rules'][$ruleName] = $GLOBALS['_HTML_QuickForm_registered_rules']['regex'];
|
||||
|
||||
} elseif ($type == 'function' || $type == 'callback') {
|
||||
// Callback function
|
||||
$rule =& $this->getRule('callback');
|
||||
$rule->addData($ruleName, $data1, $data2, 'function' == $type);
|
||||
$GLOBALS['_HTML_QuickForm_registered_rules'][$ruleName] = $GLOBALS['_HTML_QuickForm_registered_rules']['callback'];
|
||||
|
||||
} elseif (is_object($data1)) {
|
||||
// An instance of HTML_QuickForm_Rule
|
||||
$this->_rules[strtolower(get_class($data1))] = $data1;
|
||||
$GLOBALS['_HTML_QuickForm_registered_rules'][$ruleName] = array(strtolower(get_class($data1)), null);
|
||||
|
||||
} else {
|
||||
// Rule class name
|
||||
$GLOBALS['_HTML_QuickForm_registered_rules'][$ruleName] = array(strtolower($data1), $data2);
|
||||
}
|
||||
} // end func registerRule
|
||||
|
||||
/**
|
||||
* Returns a reference to the requested rule object
|
||||
*
|
||||
* @param string $ruleName Name of the requested rule
|
||||
* @access public
|
||||
* @return HTML_QuickForm_Rule
|
||||
*/
|
||||
function &getRule($ruleName)
|
||||
{
|
||||
list($class, $path) = $GLOBALS['_HTML_QuickForm_registered_rules'][$ruleName];
|
||||
|
||||
if (!isset($this->_rules[$class])) {
|
||||
if (!empty($path)) {
|
||||
include_once($path);
|
||||
}
|
||||
$this->_rules[$class] =& new $class();
|
||||
}
|
||||
$this->_rules[$class]->setName($ruleName);
|
||||
return $this->_rules[$class];
|
||||
} // end func getRule
|
||||
|
||||
/**
|
||||
* 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);
|
||||
}
|
||||
} // end class HTML_QuickForm_RuleRegistry
|
||||
?>
|
||||
286
include/pear/HTML/QuickForm/advcheckbox.php
Normal file
286
include/pear/HTML/QuickForm/advcheckbox.php
Normal file
@@ -0,0 +1,286 @@
|
||||
<?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-2007 The PHP Group
|
||||
* @license http://www.php.net/license/3_01.txt PHP License 3.01
|
||||
* @version CVS: $Id: advcheckbox.php,v 1.17 2007/05/29 18:34:36 avb Exp $
|
||||
* @link http://pear.php.net/package/HTML_QuickForm
|
||||
*/
|
||||
|
||||
/**
|
||||
* HTML class for a checkbox type field
|
||||
*/
|
||||
require_once 'HTML/QuickForm/checkbox.php';
|
||||
|
||||
/**
|
||||
* 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.10
|
||||
* @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
|
||||
*/
|
||||
function HTML_QuickForm_advcheckbox($elementName=null, $elementLabel=null, $text=null, $attributes=null, $values=null)
|
||||
{
|
||||
$this->HTML_QuickForm_checkbox($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
|
||||
?>
|
||||
258
include/pear/HTML/QuickForm/autocomplete.php
Normal file
258
include/pear/HTML/QuickForm/autocomplete.php
Normal file
@@ -0,0 +1,258 @@
|
||||
<?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-2007 The PHP Group
|
||||
* @license http://www.php.net/license/3_01.txt PHP License 3.01
|
||||
* @version CVS: $Id: autocomplete.php,v 1.7 2007/05/29 18:34:36 avb Exp $
|
||||
* @link http://pear.php.net/package/HTML_QuickForm
|
||||
*/
|
||||
|
||||
/**
|
||||
* HTML class for a text field
|
||||
*/
|
||||
require_once 'HTML/QuickForm/text.php';
|
||||
|
||||
/**
|
||||
* 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.10
|
||||
* @since 3.2
|
||||
*/
|
||||
class HTML_QuickForm_autocomplete extends HTML_QuickForm_text
|
||||
{
|
||||
// {{{ properties
|
||||
|
||||
/**
|
||||
* Options for the autocomplete input text element
|
||||
*
|
||||
* @var array
|
||||
* @access private
|
||||
*/
|
||||
var $_options = array();
|
||||
|
||||
/**
|
||||
* "One-time" javascript (containing functions), see bug #4611
|
||||
*
|
||||
* @var string
|
||||
* @access private
|
||||
*/
|
||||
var $_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
|
||||
*/
|
||||
function HTML_QuickForm_autocomplete($elementName = null, $elementLabel = null, $options = null, $attributes = null)
|
||||
{
|
||||
$this->HTML_QuickForm_text($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
|
||||
?>
|
||||
80
include/pear/HTML/QuickForm/button.php
Normal file
80
include/pear/HTML/QuickForm/button.php
Normal file
@@ -0,0 +1,80 @@
|
||||
<?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-2007 The PHP Group
|
||||
* @license http://www.php.net/license/3_01.txt PHP License 3.01
|
||||
* @version CVS: $Id: button.php,v 1.5 2007/05/29 18:34:36 avb Exp $
|
||||
* @link http://pear.php.net/package/HTML_QuickForm
|
||||
*/
|
||||
|
||||
/**
|
||||
* Base class for <input /> form elements
|
||||
*/
|
||||
require_once 'HTML/QuickForm/input.php';
|
||||
|
||||
/**
|
||||
* 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.10
|
||||
* @since 1.0
|
||||
*/
|
||||
class HTML_QuickForm_button extends HTML_QuickForm_input
|
||||
{
|
||||
// {{{ constructor
|
||||
|
||||
/**
|
||||
* 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
|
||||
*/
|
||||
function HTML_QuickForm_button($elementName=null, $value=null, $attributes=null)
|
||||
{
|
||||
HTML_QuickForm_input::HTML_QuickForm_input($elementName, null, $attributes);
|
||||
$this->_persistantFreeze = false;
|
||||
$this->setValue($value);
|
||||
$this->setType('button');
|
||||
} //end constructor
|
||||
|
||||
// }}}
|
||||
// {{{ freeze()
|
||||
|
||||
/**
|
||||
* Freeze the element so that only its value is returned
|
||||
*
|
||||
* @access public
|
||||
* @return void
|
||||
*/
|
||||
function freeze()
|
||||
{
|
||||
return false;
|
||||
} //end func freeze
|
||||
|
||||
// }}}
|
||||
|
||||
} //end class HTML_QuickForm_button
|
||||
?>
|
||||
277
include/pear/HTML/QuickForm/checkbox.php
Normal file
277
include/pear/HTML/QuickForm/checkbox.php
Normal file
@@ -0,0 +1,277 @@
|
||||
<?php
|
||||
/* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4: */
|
||||
|
||||
/**
|
||||
* 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
|
||||
* @package HTML_QuickForm
|
||||
* @author Adam Daniel <adaniel1@eesus.jnj.com>
|
||||
* @author Bertrand Mansion <bmansion@mamasam.com>
|
||||
* @author Alexey Borzov <avb@php.net>
|
||||
* @copyright 2001-2007 The PHP Group
|
||||
* @license http://www.php.net/license/3_01.txt PHP License 3.01
|
||||
* @version CVS: $Id: checkbox.php,v 1.22 2007/06/03 15:25:28 avb Exp $
|
||||
* @link http://pear.php.net/package/HTML_QuickForm
|
||||
*/
|
||||
|
||||
/**
|
||||
* Base class for <input /> form elements
|
||||
*/
|
||||
require_once 'HTML/QuickForm/input.php';
|
||||
|
||||
/**
|
||||
* HTML class for a checkbox type 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.10
|
||||
* @since 1.0
|
||||
*/
|
||||
class HTML_QuickForm_checkbox extends HTML_QuickForm_input
|
||||
{
|
||||
// {{{ properties
|
||||
|
||||
/**
|
||||
* Checkbox display text
|
||||
* @var string
|
||||
* @since 1.1
|
||||
* @access private
|
||||
*/
|
||||
var $_text = '';
|
||||
|
||||
// }}}
|
||||
// {{{ constructor
|
||||
|
||||
/**
|
||||
* 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
|
||||
* @access public
|
||||
* @return void
|
||||
*/
|
||||
function HTML_QuickForm_checkbox($elementName=null, $elementLabel=null, $text='', $attributes=null)
|
||||
{
|
||||
HTML_QuickForm_input::HTML_QuickForm_input($elementName, $elementLabel, $attributes);
|
||||
$this->_persistantFreeze = true;
|
||||
$this->_text = $text;
|
||||
$this->setType('checkbox');
|
||||
$this->updateAttributes(array('value'=>1));
|
||||
$this->_generateId();
|
||||
} //end constructor
|
||||
|
||||
// }}}
|
||||
// {{{ setChecked()
|
||||
|
||||
/**
|
||||
* Sets whether a checkbox is checked
|
||||
*
|
||||
* @param bool $checked Whether the field is checked or not
|
||||
* @since 1.0
|
||||
* @access public
|
||||
* @return void
|
||||
*/
|
||||
function setChecked($checked)
|
||||
{
|
||||
if (!$checked) {
|
||||
$this->removeAttribute('checked');
|
||||
} else {
|
||||
$this->updateAttributes(array('checked'=>'checked'));
|
||||
}
|
||||
} //end func setChecked
|
||||
|
||||
// }}}
|
||||
// {{{ getChecked()
|
||||
|
||||
/**
|
||||
* Returns whether a checkbox is checked
|
||||
*
|
||||
* @since 1.0
|
||||
* @access public
|
||||
* @return bool
|
||||
*/
|
||||
function getChecked()
|
||||
{
|
||||
return (bool)$this->getAttribute('checked');
|
||||
} //end func getChecked
|
||||
|
||||
// }}}
|
||||
// {{{ toHtml()
|
||||
|
||||
/**
|
||||
* Returns the checkbox element in HTML
|
||||
*
|
||||
* @since 1.0
|
||||
* @access public
|
||||
* @return string
|
||||
*/
|
||||
function toHtml()
|
||||
{
|
||||
if (0 == strlen($this->_text)) {
|
||||
$label = '';
|
||||
} elseif ($this->_flagFrozen) {
|
||||
$label = $this->_text;
|
||||
} else {
|
||||
$label = '<label for="' . $this->getAttribute('id') . '">' . $this->_text . '</label>';
|
||||
}
|
||||
return HTML_QuickForm_input::toHtml() . $label;
|
||||
} //end func toHtml
|
||||
|
||||
// }}}
|
||||
// {{{ getFrozenHtml()
|
||||
|
||||
/**
|
||||
* Returns the value of field without HTML tags
|
||||
*
|
||||
* @since 1.0
|
||||
* @access public
|
||||
* @return string
|
||||
*/
|
||||
function getFrozenHtml()
|
||||
{
|
||||
if ($this->getChecked()) {
|
||||
return '<tt>[x]</tt>' .
|
||||
$this->_getPersistantData();
|
||||
} else {
|
||||
return '<tt>[ ]</tt>';
|
||||
}
|
||||
} //end func getFrozenHtml
|
||||
|
||||
// }}}
|
||||
// {{{ setText()
|
||||
|
||||
/**
|
||||
* Sets the checkbox text
|
||||
*
|
||||
* @param string $text
|
||||
* @since 1.1
|
||||
* @access public
|
||||
* @return void
|
||||
*/
|
||||
function setText($text)
|
||||
{
|
||||
$this->_text = $text;
|
||||
} //end func setText
|
||||
|
||||
// }}}
|
||||
// {{{ getText()
|
||||
|
||||
/**
|
||||
* Returns the checkbox text
|
||||
*
|
||||
* @since 1.1
|
||||
* @access public
|
||||
* @return string
|
||||
*/
|
||||
function getText()
|
||||
{
|
||||
return $this->_text;
|
||||
} //end func getText
|
||||
|
||||
// }}}
|
||||
// {{{ setValue()
|
||||
|
||||
/**
|
||||
* Sets the value of the form element
|
||||
*
|
||||
* @param string $value Default value of the form element
|
||||
* @since 1.0
|
||||
* @access public
|
||||
* @return void
|
||||
*/
|
||||
function setValue($value)
|
||||
{
|
||||
return $this->setChecked($value);
|
||||
} // end func setValue
|
||||
|
||||
// }}}
|
||||
// {{{ getValue()
|
||||
|
||||
/**
|
||||
* Returns the value of the form element
|
||||
*
|
||||
* @since 1.0
|
||||
* @access public
|
||||
* @return bool
|
||||
*/
|
||||
function getValue()
|
||||
{
|
||||
return $this->getChecked();
|
||||
} // end func getValue
|
||||
|
||||
// }}}
|
||||
// {{{ 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) {
|
||||
// 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;
|
||||
} // end func onQuickFormEvent
|
||||
|
||||
// }}}
|
||||
// {{{ exportValue()
|
||||
|
||||
/**
|
||||
* Return true if the checkbox is checked, null if it is not checked (getValue() returns false)
|
||||
*/
|
||||
function exportValue(&$submitValues, $assoc = false)
|
||||
{
|
||||
$value = $this->_findValue($submitValues);
|
||||
if (null === $value) {
|
||||
$value = $this->getChecked()? true: null;
|
||||
}
|
||||
return $this->_prepareValue($value, $assoc);
|
||||
}
|
||||
|
||||
// }}}
|
||||
} //end class HTML_QuickForm_checkbox
|
||||
?>
|
||||
528
include/pear/HTML/QuickForm/date.php
Normal file
528
include/pear/HTML/QuickForm/date.php
Normal file
@@ -0,0 +1,528 @@
|
||||
<?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-2007 The PHP Group
|
||||
* @license http://www.php.net/license/3_01.txt PHP License 3.01
|
||||
* @version CVS: $Id: date.php,v 1.61 2007/10/05 10:58:54 avb Exp $
|
||||
* @link http://pear.php.net/package/HTML_QuickForm
|
||||
*/
|
||||
|
||||
/**
|
||||
* Class for a group of form elements
|
||||
*/
|
||||
require_once 'HTML/QuickForm/group.php';
|
||||
/**
|
||||
* Class for <select></select> elements
|
||||
*/
|
||||
require_once 'HTML/QuickForm/select.php';
|
||||
|
||||
/**
|
||||
* 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.10
|
||||
* @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' => 2010,
|
||||
'addEmptyOption' => false,
|
||||
'emptyOptionValue' => '',
|
||||
'emptyOptionText' => ' ',
|
||||
'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ärz', 'April', 'Mai', 'Juni', 'Juli', 'Aug', 'Sept', 'Okt', 'Nov', 'Dez'),
|
||||
'months_long' => array ('Januar', 'Februar', 'Mä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év', 'Mar', 'Avr', 'Mai', 'Juin', 'Juil', 'Août', 'Sep', 'Oct', 'Nov', 'Déc'),
|
||||
'months_long' => array ('Janvier', 'Février', 'Mars', 'Avril', 'Mai', 'Juin', 'Juillet', 'Août', 'Septembre', 'Octobre', 'Novembre', 'Décembre')
|
||||
),
|
||||
'hu' => array (
|
||||
'weekdays_short'=> array ('V', 'H', 'K', 'Sze', 'Cs', 'P', 'Szo'),
|
||||
'weekdays_long' => array ('vasárnap', 'hétfő', 'kedd', 'szerda', 'csütörtök', 'péntek', 'szombat'),
|
||||
'months_short' => array ('jan', 'feb', 'márc', 'ápr', 'máj', 'jún', 'júl', 'aug', 'szept', 'okt', 'nov', 'dec'),
|
||||
'months_long' => array ('január', 'február', 'március', 'április', 'május', 'június', 'július', 'augusztus', 'szeptember', 'október', 'november', 'december')
|
||||
),
|
||||
'pl' => array (
|
||||
'weekdays_short'=> array ('Nie', 'Pn', 'Wt', 'Śr', 'Czw', 'Pt', 'Sob'),
|
||||
'weekdays_long' => array ('Niedziela', 'Poniedziałek', 'Wtorek', 'Środa', 'Czwartek', 'Piątek', 'Sobota'),
|
||||
'months_short' => array ('Sty', 'Lut', 'Mar', 'Kwi', 'Maj', 'Cze', 'Lip', 'Sie', 'Wrz', 'Paź', 'Lis', 'Gru'),
|
||||
'months_long' => array ('Styczeń', 'Luty', 'Marzec', 'Kwiecień', 'Maj', 'Czerwiec', 'Lipiec', 'Sierpień', 'Wrzesień', 'Październik', 'Listopad', 'Grudzień')
|
||||
),
|
||||
'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 ('Вс', 'Пн', 'Вт', 'Ср', 'Чт', 'Пт', 'Сб'),
|
||||
'weekdays_long' => array ('Воскресенье', 'Понедельник', 'Вторник', 'Среда', 'Четверг', 'Пятница', 'Суббота'),
|
||||
'months_short' => array ('Янв', 'Фев', 'Мар', 'Апр', 'Май', 'Июн', 'Июл', 'Авг', 'Сен', 'Окт', 'Ноя', 'Дек'),
|
||||
'months_long' => array ('Январь', 'Февраль', 'Март', 'Апрель', 'Май', 'Июнь', 'Июль', 'Август', 'Сентябрь', 'Октябрь', 'Ноябрь', 'Декабрь')
|
||||
),
|
||||
'es' => array (
|
||||
'weekdays_short'=> array ('Dom', 'Lun', 'Mar', 'Mié', 'Jue', 'Vie', 'Sáb'),
|
||||
'weekdays_long' => array ('Domingo', 'Lunes', 'Martes', 'Miércoles', 'Jueves', 'Viernes', 'Sá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øn', 'Man', 'Tir', 'Ons', 'Tor', 'Fre', 'Lør'),
|
||||
'weekdays_long' => array ('Søndag', 'Mandag', 'Tirsdag', 'Onsdag', 'Torsdag', 'Fredag', 'Lø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án', 'Þri', 'Mið', 'Fim', 'Fös', 'Lau'),
|
||||
'weekdays_long' => array ('Sunnudagur', 'Mánudagur', 'Þriðjudagur', 'Miðvikudagur', 'Fimmtudagur', 'Föstudagur', 'Laugardagur'),
|
||||
'months_short' => array ('Jan', 'Feb', 'Mar', 'Apr', 'Maí', 'Jún', 'Júl', 'Ágú', 'Sep', 'Okt', 'Nóv', 'Des'),
|
||||
'months_long' => array ('Janúar', 'Febrúar', 'Mars', 'Apríl', 'Maí', 'Júní', 'Júlí', 'Ágúst', 'September', 'Október', 'Nóvember', 'Desember')
|
||||
),
|
||||
'it' => array (
|
||||
'weekdays_short'=> array ('Dom', 'Lun', 'Mar', 'Mer', 'Gio', 'Ven', 'Sab'),
|
||||
'weekdays_long' => array ('Domenica', 'Lunedì', 'Martedì', 'Mercoledì', 'Giovedì', 'Venerdì', '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', 'Štv', 'Pia', 'Sob'),
|
||||
'weekdays_long' => array ('Nedeža', 'Pondelok', 'Utorok', 'Streda', 'Štvrtok', 'Piatok', 'Sobota'),
|
||||
'months_short' => array ('Jan', 'Feb', 'Mar', 'Apr', 'Máj', 'Jún', 'Júl', 'Aug', 'Sep', 'Okt', 'Nov', 'Dec'),
|
||||
'months_long' => array ('Január', 'Február', 'Marec', 'Apríl', 'Máj', 'Jún', 'Júl', 'August', 'September', 'Október', 'November', 'December')
|
||||
),
|
||||
'cs' => array (
|
||||
'weekdays_short'=> array ('Ne', 'Po', 'Út', 'St', 'Čt', 'Pá', 'So'),
|
||||
'weekdays_long' => array ('Neděle', 'Pondělí', 'Úterý', 'Středa', 'Čtvrtek', 'Pátek', 'Sobota'),
|
||||
'months_short' => array ('Led', 'Úno', 'Bře', 'Dub', 'Kvě', 'Čen', 'Čec', 'Srp', 'Zář', 'Říj', 'Lis', 'Pro'),
|
||||
'months_long' => array ('Leden', 'Únor', 'Březen', 'Duben', 'Květen', 'Červen', 'Červenec', 'Srpen', 'Září', 'Říjen', 'Listopad', 'Prosinec')
|
||||
),
|
||||
'hy' => array (
|
||||
'weekdays_short'=> array ('Կրկ', 'Երկ', 'Երք', 'Չրք', 'Հնգ', 'Ուր', 'Շբթ'),
|
||||
'weekdays_long' => array ('Կիրակի', 'Երկուշաբթի', 'Երեքշաբթի', 'Չորեքշաբթի', 'Հինգշաբթի', 'Ուրբաթ', 'Շաբաթ'),
|
||||
'months_short' => array ('Հնվ', 'Փտր', 'Մրտ', 'Ապր', 'Մյս', 'Հնս', 'Հլս', 'Օգս', 'Սպտ', 'Հկտ', 'Նյմ', 'Դկտ'),
|
||||
'months_long' => array ('Հունվար', 'Փետրվար', 'Մարտ', 'Ապրիլ', 'Մայիս', 'Հունիս', 'Հուլիս', 'Օգոստոս', 'Սեպտեմբեր', 'Հոկտեմբեր', 'Նոյեմբեր', 'Դեկտեմբեր')
|
||||
),
|
||||
'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ühapäev', 'Esmaspäev', 'Teisipäev', 'Kolmapäev', 'Neljapäev', 'Reede', 'Laupäev'),
|
||||
'months_short' => array ('Jaan', 'Veebr', 'Märts', 'Aprill', 'Mai', 'Juuni', 'Juuli', 'Aug', 'Sept', 'Okt', 'Nov', 'Dets'),
|
||||
'months_long' => array ('Jaanuar', 'Veebruar', 'Märts', 'Aprill', 'Mai', 'Juuni', 'Juuli', 'August', 'September', 'Oktoober', 'November', 'Detsember')
|
||||
),
|
||||
'tr' => array (
|
||||
'weekdays_short'=> array ('Paz', 'Pzt', 'Sal', 'Çar', 'Per', 'Cum', 'Cts'),
|
||||
'weekdays_long' => array ('Pazar', 'Pazartesi', 'Salı', 'Çarşamba', 'Perşembe', 'Cuma', 'Cumartesi'),
|
||||
'months_short' => array ('Ock', 'Şbt', 'Mrt', 'Nsn', 'Mys', 'Hzrn', 'Tmmz', 'Ağst', 'Eyl', 'Ekm', 'Ksm', 'Arlk'),
|
||||
'months_long' => array ('Ocak', 'Şubat', 'Mart', 'Nisan', 'Mayıs', 'Haziran', 'Temmuz', 'Ağustos', 'Eylül', 'Ekim', 'Kasım', 'Aralık')
|
||||
),
|
||||
'no' => array (
|
||||
'weekdays_short'=> array ('Søn', 'Man', 'Tir', 'Ons', 'Tor', 'Fre', 'Lør'),
|
||||
'weekdays_long' => array ('Søndag', 'Mandag', 'Tirsdag', 'Onsdag', 'Torsdag', 'Fredag', 'Lø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', 'Ĵaŭ', 'Ven', 'Sab'),
|
||||
'weekdays_long' => array ('Dimanĉo', 'Lundo', 'Mardo', 'Merkredo', 'Ĵaŭdo', 'Vendredo', 'Sabato'),
|
||||
'months_short' => array ('Jan', 'Feb', 'Mar', 'Apr', 'Maj', 'Jun', 'Jul', 'Aŭg', 'Sep', 'Okt', 'Nov', 'Dec'),
|
||||
'months_long' => array ('Januaro', 'Februaro', 'Marto', 'Aprilo', 'Majo', 'Junio', 'Julio', 'Aŭgusto', 'Septembro', 'Oktobro', 'Novembro', 'Decembro')
|
||||
),
|
||||
'ua' => array (
|
||||
'weekdays_short'=> array('Ндл', 'Пнд', 'Втр', 'Срд', 'Чтв', 'Птн', 'Сбт'),
|
||||
'weekdays_long' => array('Неділя', 'Понеділок', 'Вівторок', 'Середа', 'Четвер', 'П\'ятниця', 'Субота'),
|
||||
'months_short' => array('Січ', 'Лют', 'Бер', 'Кві', 'Тра', 'Чер', 'Лип', 'Сер', 'Вер', 'Жов', 'Лис', 'Гру'),
|
||||
'months_long' => array('Січень', 'Лютий', 'Березень', 'Квітень', 'Травень', 'Червень', 'Липень', 'Серпень', 'Вересень', 'Жовтень', 'Листопад', 'Грудень')
|
||||
),
|
||||
'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 ('ראשון', 'שני', 'שלישי', 'רביעי', 'חמישי', 'שישי', 'שבת'),
|
||||
'weekdays_long' => array ('יום ראשון', 'יום שני', 'יום שלישי', 'יום רביעי', 'יום חמישי', 'יום שישי', 'שבת'),
|
||||
'months_short' => array ('ינואר', 'פברואר', 'מרץ', 'אפריל', 'מאי', 'יוני', 'יולי', 'אוגוסט', 'ספטמבר', 'אוקטובר', 'נובמבר', 'דצמבר'),
|
||||
'months_long' => array ('ינואר', 'פברואר', 'מרץ', 'אפריל', 'מאי', 'יוני', 'יולי', 'אוגוסט', 'ספטמבר', 'אוקטובר', 'נובמבר', 'דצמבר')
|
||||
),
|
||||
'sv' => array (
|
||||
'weekdays_short'=> array ('Sön', 'Mån', 'Tis', 'Ons', 'Tor', 'Fre', 'Lör'),
|
||||
'weekdays_long' => array ('Söndag', 'Måndag', 'Tisdag', 'Onsdag', 'Torsdag', 'Fredag', 'Lö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áb'),
|
||||
'weekdays_long' => array ('Domingo', 'Segunda-feira', 'Terça-feira', 'Quarta-feira', 'Quinta-feira', 'Sexta-feira', 'Sábado'),
|
||||
'months_short' => array ('Jan', 'Fev', 'Mar', 'Abr', 'Mai', 'Jun', 'Jul', 'Ago', 'Set', 'Out', 'Nov', 'Dez'),
|
||||
'months_long' => array ('Janeiro', 'Fevereiro', 'Março', 'Abril', 'Maio', 'Junho', 'Julho', 'Agosto', 'Setembro', 'Outubro', 'Novembro', 'Dezembro')
|
||||
),
|
||||
'tw' => array (
|
||||
'weekdays_short'=> array ('週日','週一', '週二','週三', '週四','週五', '週六'),
|
||||
'weekdays_long' => array ('星期日', '星期一', '星期二', '星期三', '星期四', '星期五', '星期六'),
|
||||
'months_short' => array ('一月', '二月', '三月', '四月', '五月', '六月', '七月', '八月', '九月', '十月', '十一月', '十二月'),
|
||||
'months_long' => array ('一月', '二月', '三月', '四月', '五月', '六月', '七月', '八月', '九月', '十月', '十一月', '十二月')
|
||||
),
|
||||
'pt-br' => array (
|
||||
'weekdays_short'=> array ('Dom', 'Seg', 'Ter', 'Qua', 'Qui', 'Sex', 'Sáb'),
|
||||
'weekdays_long' => array ('Domingo', 'Segunda', 'Terça', 'Quarta', 'Quinta', 'Sexta', 'Sábado'),
|
||||
'months_short' => array ('Jan', 'Fev', 'Mar', 'Abr', 'Mai', 'Jun', 'Jul', 'Ago', 'Set', 'Out', 'Nov', 'Dez'),
|
||||
'months_long' => array ('Janeiro', 'Fevereiro', 'Març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
|
||||
*/
|
||||
function HTML_QuickForm_date($elementName = null, $elementLabel = null, $options = array(), $attributes = null)
|
||||
{
|
||||
$this->HTML_QuickForm_element($elementName, $elementLabel, $attributes);
|
||||
$this->_persistantFreeze = true;
|
||||
$this->_appendName = true;
|
||||
$this->_type = 'date';
|
||||
// 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;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ _createElements()
|
||||
|
||||
function _createElements()
|
||||
{
|
||||
$this->_separator = $this->_elements = array();
|
||||
$separator = '';
|
||||
$locale =& $this->_locale[$this->_options['language']];
|
||||
$backslash = false;
|
||||
for ($i = 0, $length = strlen($this->_options['format']); $i < $length; $i++) {
|
||||
$sign = $this->_options['format']{$i};
|
||||
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? ' ': $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);
|
||||
}
|
||||
}
|
||||
|
||||
// }}}
|
||||
}
|
||||
?>
|
||||
494
include/pear/HTML/QuickForm/element.php
Normal file
494
include/pear/HTML/QuickForm/element.php
Normal file
@@ -0,0 +1,494 @@
|
||||
<?php
|
||||
/* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4: */
|
||||
|
||||
/**
|
||||
* 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-2007 The PHP Group
|
||||
* @license http://www.php.net/license/3_01.txt PHP License 3.01
|
||||
* @version CVS: $Id: element.php,v 1.36 2007/10/05 10:22:57 avb Exp $
|
||||
* @link http://pear.php.net/package/HTML_QuickForm
|
||||
*/
|
||||
|
||||
/**
|
||||
* Base class for all HTML classes
|
||||
*/
|
||||
require_once 'HTML/Common.php';
|
||||
|
||||
/**
|
||||
* 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.10
|
||||
* @since 1.0
|
||||
* @abstract
|
||||
*/
|
||||
class HTML_QuickForm_element extends HTML_Common
|
||||
{
|
||||
// {{{ properties
|
||||
|
||||
/**
|
||||
* Label of the field
|
||||
* @var string
|
||||
* @since 1.3
|
||||
* @access private
|
||||
*/
|
||||
var $_label = '';
|
||||
|
||||
/**
|
||||
* Form element type
|
||||
* @var string
|
||||
* @since 1.0
|
||||
* @access private
|
||||
*/
|
||||
var $_type = '';
|
||||
|
||||
/**
|
||||
* Flag to tell if element is frozen
|
||||
* @var boolean
|
||||
* @since 1.0
|
||||
* @access private
|
||||
*/
|
||||
var $_flagFrozen = false;
|
||||
|
||||
/**
|
||||
* Does the element support persistant data when frozen
|
||||
* @var boolean
|
||||
* @since 1.3
|
||||
* @access private
|
||||
*/
|
||||
var $_persistantFreeze = false;
|
||||
|
||||
// }}}
|
||||
// {{{ constructor
|
||||
|
||||
/**
|
||||
* Class constructor
|
||||
*
|
||||
* @param string Name of the element
|
||||
* @param mixed Label(s) for the element
|
||||
* @param mixed Associative array of tag attributes or HTML attributes name="value" pairs
|
||||
* @since 1.0
|
||||
* @access public
|
||||
* @return void
|
||||
*/
|
||||
function HTML_QuickForm_element($elementName=null, $elementLabel=null, $attributes=null)
|
||||
{
|
||||
HTML_Common::HTML_Common($attributes);
|
||||
if (isset($elementName)) {
|
||||
$this->setName($elementName);
|
||||
}
|
||||
if (isset($elementLabel)) {
|
||||
$this->setLabel($elementLabel);
|
||||
}
|
||||
} //end constructor
|
||||
|
||||
// }}}
|
||||
// {{{ apiVersion()
|
||||
|
||||
/**
|
||||
* Returns the current API version
|
||||
*
|
||||
* @since 1.0
|
||||
* @access public
|
||||
* @return float
|
||||
*/
|
||||
function apiVersion()
|
||||
{
|
||||
return 3.2;
|
||||
} // end func apiVersion
|
||||
|
||||
// }}}
|
||||
// {{{ getType()
|
||||
|
||||
/**
|
||||
* Returns element type
|
||||
*
|
||||
* @since 1.0
|
||||
* @access public
|
||||
* @return string
|
||||
*/
|
||||
function getType()
|
||||
{
|
||||
return $this->_type;
|
||||
} // end func getType
|
||||
|
||||
// }}}
|
||||
// {{{ setName()
|
||||
|
||||
/**
|
||||
* Sets the input field name
|
||||
*
|
||||
* @param string $name Input field name attribute
|
||||
* @since 1.0
|
||||
* @access public
|
||||
* @return void
|
||||
*/
|
||||
function setName($name)
|
||||
{
|
||||
// interface method
|
||||
} //end func setName
|
||||
|
||||
// }}}
|
||||
// {{{ getName()
|
||||
|
||||
/**
|
||||
* Returns the element name
|
||||
*
|
||||
* @since 1.0
|
||||
* @access public
|
||||
* @return string
|
||||
*/
|
||||
function getName()
|
||||
{
|
||||
// interface method
|
||||
} //end func getName
|
||||
|
||||
// }}}
|
||||
// {{{ setValue()
|
||||
|
||||
/**
|
||||
* Sets the value of the form element
|
||||
*
|
||||
* @param string $value Default value of the form element
|
||||
* @since 1.0
|
||||
* @access public
|
||||
* @return void
|
||||
*/
|
||||
function setValue($value)
|
||||
{
|
||||
// interface
|
||||
} // end func setValue
|
||||
|
||||
// }}}
|
||||
// {{{ getValue()
|
||||
|
||||
/**
|
||||
* Returns the value of the form element
|
||||
*
|
||||
* @since 1.0
|
||||
* @access public
|
||||
* @return mixed
|
||||
*/
|
||||
function getValue()
|
||||
{
|
||||
// interface
|
||||
return null;
|
||||
} // end func getValue
|
||||
|
||||
// }}}
|
||||
// {{{ freeze()
|
||||
|
||||
/**
|
||||
* Freeze the element so that only its value is returned
|
||||
*
|
||||
* @access public
|
||||
* @return void
|
||||
*/
|
||||
function freeze()
|
||||
{
|
||||
$this->_flagFrozen = true;
|
||||
} //end func freeze
|
||||
|
||||
// }}}
|
||||
// {{{ unfreeze()
|
||||
|
||||
/**
|
||||
* Unfreezes the element so that it becomes editable
|
||||
*
|
||||
* @access public
|
||||
* @return void
|
||||
* @since 3.2.4
|
||||
*/
|
||||
function unfreeze()
|
||||
{
|
||||
$this->_flagFrozen = false;
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ getFrozenHtml()
|
||||
|
||||
/**
|
||||
* Returns the value of field without HTML tags
|
||||
*
|
||||
* @since 1.0
|
||||
* @access public
|
||||
* @return string
|
||||
*/
|
||||
function getFrozenHtml()
|
||||
{
|
||||
$value = $this->getValue();
|
||||
return (strlen($value)? htmlspecialchars($value): ' ') .
|
||||
$this->_getPersistantData();
|
||||
} //end func getFrozenHtml
|
||||
|
||||
// }}}
|
||||
// {{{ _getPersistantData()
|
||||
|
||||
/**
|
||||
* Used by getFrozenHtml() to pass the element's value if _persistantFreeze is on
|
||||
*
|
||||
* @access private
|
||||
* @return string
|
||||
*/
|
||||
function _getPersistantData()
|
||||
{
|
||||
if (!$this->_persistantFreeze) {
|
||||
return '';
|
||||
} else {
|
||||
$id = $this->getAttribute('id');
|
||||
return '<input' . $this->_getAttrString(array(
|
||||
'type' => 'hidden',
|
||||
'name' => $this->getName(),
|
||||
'value' => $this->getValue()
|
||||
) + (isset($id)? array('id' => $id): array())) . ' />';
|
||||
}
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ isFrozen()
|
||||
|
||||
/**
|
||||
* Returns whether or not the element is frozen
|
||||
*
|
||||
* @since 1.3
|
||||
* @access public
|
||||
* @return bool
|
||||
*/
|
||||
function isFrozen()
|
||||
{
|
||||
return $this->_flagFrozen;
|
||||
} // end func isFrozen
|
||||
|
||||
// }}}
|
||||
// {{{ setPersistantFreeze()
|
||||
|
||||
/**
|
||||
* 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
|
||||
* @access public
|
||||
* @return void
|
||||
*/
|
||||
function setPersistantFreeze($persistant=false)
|
||||
{
|
||||
$this->_persistantFreeze = $persistant;
|
||||
} //end func setPersistantFreeze
|
||||
|
||||
// }}}
|
||||
// {{{ setLabel()
|
||||
|
||||
/**
|
||||
* Sets display text for the element
|
||||
*
|
||||
* @param string $label Display text for the element
|
||||
* @since 1.3
|
||||
* @access public
|
||||
* @return void
|
||||
*/
|
||||
function setLabel($label)
|
||||
{
|
||||
$this->_label = $label;
|
||||
} //end func setLabel
|
||||
|
||||
// }}}
|
||||
// {{{ getLabel()
|
||||
|
||||
/**
|
||||
* Returns display text for the element
|
||||
*
|
||||
* @since 1.3
|
||||
* @access public
|
||||
* @return string
|
||||
*/
|
||||
function getLabel()
|
||||
{
|
||||
return $this->_label;
|
||||
} //end func getLabel
|
||||
|
||||
// }}}
|
||||
// {{{ _findValue()
|
||||
|
||||
/**
|
||||
* 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, '[')) {
|
||||
$myVar = "['" . str_replace(
|
||||
array('\\', '\'', ']', '['), array('\\\\', '\\\'', '', "']['"),
|
||||
$elementName
|
||||
) . "']";
|
||||
return eval("return (isset(\$values$myVar)) ? \$values$myVar : null;");
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
} //end func _findValue
|
||||
|
||||
// }}}
|
||||
// {{{ 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 'createElement':
|
||||
$className = get_class($this);
|
||||
$this->$className($arg[0], $arg[1], $arg[2], $arg[3], $arg[4]);
|
||||
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;
|
||||
} // end func onQuickFormEvent
|
||||
|
||||
// }}}
|
||||
// {{{ accept()
|
||||
|
||||
/**
|
||||
* 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
|
||||
*/
|
||||
function accept(&$renderer, $required=false, $error=null)
|
||||
{
|
||||
$renderer->renderElement($this, $required, $error);
|
||||
} // end func accept
|
||||
|
||||
// }}}
|
||||
// {{{ _generateId()
|
||||
|
||||
/**
|
||||
* 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
|
||||
*/
|
||||
function _generateId()
|
||||
{
|
||||
static $idx = 1;
|
||||
|
||||
if (!$this->getAttribute('id')) {
|
||||
$this->updateAttributes(array('id' => 'qf_' . substr(md5(microtime() . $idx++), 0, 6)));
|
||||
}
|
||||
} // end func _generateId
|
||||
|
||||
// }}}
|
||||
// {{{ exportValue()
|
||||
|
||||
/**
|
||||
* 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
|
||||
*/
|
||||
function exportValue(&$submitValues, $assoc = false)
|
||||
{
|
||||
$value = $this->_findValue($submitValues);
|
||||
if (null === $value) {
|
||||
$value = $this->getValue();
|
||||
}
|
||||
return $this->_prepareValue($value, $assoc);
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ _prepareValue()
|
||||
|
||||
/**
|
||||
* 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
|
||||
*/
|
||||
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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// }}}
|
||||
} // end class HTML_QuickForm_element
|
||||
?>
|
||||
358
include/pear/HTML/QuickForm/file.php
Normal file
358
include/pear/HTML/QuickForm/file.php
Normal file
@@ -0,0 +1,358 @@
|
||||
<?php
|
||||
/* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4: */
|
||||
|
||||
/**
|
||||
* 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-2007 The PHP Group
|
||||
* @license http://www.php.net/license/3_01.txt PHP License 3.01
|
||||
* @version CVS: $Id: file.php,v 1.24 2007/10/05 10:17:55 avb Exp $
|
||||
* @link http://pear.php.net/package/HTML_QuickForm
|
||||
*/
|
||||
|
||||
/**
|
||||
* Base class for <input /> form elements
|
||||
*/
|
||||
require_once 'HTML/QuickForm/input.php';
|
||||
|
||||
// register file-related rules
|
||||
if (class_exists('HTML_QuickForm')) {
|
||||
HTML_QuickForm::registerRule('uploadedfile', 'callback', '_ruleIsUploadedFile', 'HTML_QuickForm_file');
|
||||
HTML_QuickForm::registerRule('maxfilesize', 'callback', '_ruleCheckMaxFileSize', 'HTML_QuickForm_file');
|
||||
HTML_QuickForm::registerRule('mimetype', 'callback', '_ruleCheckMimeType', 'HTML_QuickForm_file');
|
||||
HTML_QuickForm::registerRule('filename', 'callback', '_ruleCheckFileName', 'HTML_QuickForm_file');
|
||||
}
|
||||
|
||||
/**
|
||||
* 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.10
|
||||
* @since 1.0
|
||||
*/
|
||||
class HTML_QuickForm_file extends HTML_QuickForm_input
|
||||
{
|
||||
// {{{ properties
|
||||
|
||||
/**
|
||||
* Uploaded file data, from $_FILES
|
||||
* @var array
|
||||
*/
|
||||
var $_value = null;
|
||||
|
||||
// }}}
|
||||
// {{{ constructor
|
||||
|
||||
/**
|
||||
* 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
|
||||
*/
|
||||
function HTML_QuickForm_file($elementName=null, $elementLabel=null, $attributes=null)
|
||||
{
|
||||
HTML_QuickForm_input::HTML_QuickForm_input($elementName, $elementLabel, $attributes);
|
||||
$this->setType('file');
|
||||
} //end constructor
|
||||
|
||||
// }}}
|
||||
// {{{ setSize()
|
||||
|
||||
/**
|
||||
* Sets size of file element
|
||||
*
|
||||
* @param int Size of file element
|
||||
* @since 1.0
|
||||
* @access public
|
||||
*/
|
||||
function setSize($size)
|
||||
{
|
||||
$this->updateAttributes(array('size' => $size));
|
||||
} //end func setSize
|
||||
|
||||
// }}}
|
||||
// {{{ getSize()
|
||||
|
||||
/**
|
||||
* Returns size of file element
|
||||
*
|
||||
* @since 1.0
|
||||
* @access public
|
||||
* @return int
|
||||
*/
|
||||
function getSize()
|
||||
{
|
||||
return $this->getAttribute('size');
|
||||
} //end func getSize
|
||||
|
||||
// }}}
|
||||
// {{{ freeze()
|
||||
|
||||
/**
|
||||
* Freeze the element so that only its value is returned
|
||||
*
|
||||
* @access public
|
||||
* @return bool
|
||||
*/
|
||||
function freeze()
|
||||
{
|
||||
return false;
|
||||
} //end func freeze
|
||||
|
||||
// }}}
|
||||
// {{{ setValue()
|
||||
|
||||
/**
|
||||
* 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;
|
||||
} //end func setValue
|
||||
|
||||
// }}}
|
||||
// {{{ getValue()
|
||||
|
||||
/**
|
||||
* Returns information about the uploaded file
|
||||
*
|
||||
* @since 3.0
|
||||
* @access public
|
||||
* @return array
|
||||
*/
|
||||
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
|
||||
*/
|
||||
function onQuickFormEvent($event, $arg, &$caller)
|
||||
{
|
||||
switch ($event) {
|
||||
case 'updateValue':
|
||||
if ($caller->getAttribute('method') == 'get') {
|
||||
return PEAR::raiseError('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->$className($arg[0], $arg[1], $arg[2]);
|
||||
break;
|
||||
}
|
||||
return true;
|
||||
} // end func onQuickFormEvent
|
||||
|
||||
// }}}
|
||||
// {{{ moveUploadedFile()
|
||||
|
||||
/**
|
||||
* 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
|
||||
*/
|
||||
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);
|
||||
} // end func moveUploadedFile
|
||||
|
||||
// }}}
|
||||
// {{{ isUploadedFile()
|
||||
|
||||
/**
|
||||
* Checks if the element contains an uploaded file
|
||||
*
|
||||
* @access public
|
||||
* @return bool true if file has been uploaded, false otherwise
|
||||
*/
|
||||
function isUploadedFile()
|
||||
{
|
||||
return $this->_ruleIsUploadedFile($this->_value);
|
||||
} // end func isUploadedFile
|
||||
|
||||
// }}}
|
||||
// {{{ _ruleIsUploadedFile()
|
||||
|
||||
/**
|
||||
* 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
|
||||
*/
|
||||
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;
|
||||
}
|
||||
} // end func _ruleIsUploadedFile
|
||||
|
||||
// }}}
|
||||
// {{{ _ruleCheckMaxFileSize()
|
||||
|
||||
/**
|
||||
* Checks that the file does not exceed the max file size
|
||||
*
|
||||
* @param array Uploaded file info (from $_FILES)
|
||||
* @param int Max file size
|
||||
* @access private
|
||||
* @return bool true if filesize is lower than maxsize, false otherwise
|
||||
*/
|
||||
function _ruleCheckMaxFileSize($elementValue, $maxSize)
|
||||
{
|
||||
if (!empty($elementValue['error']) &&
|
||||
(UPLOAD_ERR_FORM_SIZE == $elementValue['error'] || UPLOAD_ERR_INI_SIZE == $elementValue['error'])) {
|
||||
return false;
|
||||
}
|
||||
if (!HTML_QuickForm_file::_ruleIsUploadedFile($elementValue)) {
|
||||
return true;
|
||||
}
|
||||
return ($maxSize >= @filesize($elementValue['tmp_name']));
|
||||
} // end func _ruleCheckMaxFileSize
|
||||
|
||||
// }}}
|
||||
// {{{ _ruleCheckMimeType()
|
||||
|
||||
/**
|
||||
* Checks if the given element contains an uploaded file of the right mime type
|
||||
*
|
||||
* @param array Uploaded file info (from $_FILES)
|
||||
* @param mixed Mime Type (can be an array of allowed types)
|
||||
* @access private
|
||||
* @return bool true if mimetype is correct, false otherwise
|
||||
*/
|
||||
function _ruleCheckMimeType($elementValue, $mimeType)
|
||||
{
|
||||
if (!HTML_QuickForm_file::_ruleIsUploadedFile($elementValue)) {
|
||||
return true;
|
||||
}
|
||||
if (is_array($mimeType)) {
|
||||
return in_array($elementValue['type'], $mimeType);
|
||||
}
|
||||
return $elementValue['type'] == $mimeType;
|
||||
} // end func _ruleCheckMimeType
|
||||
|
||||
// }}}
|
||||
// {{{ _ruleCheckFileName()
|
||||
|
||||
/**
|
||||
* Checks if the given element contains an uploaded file of the filename regex
|
||||
*
|
||||
* @param array Uploaded file info (from $_FILES)
|
||||
* @param string Regular expression
|
||||
* @access private
|
||||
* @return bool true if name matches regex, false otherwise
|
||||
*/
|
||||
function _ruleCheckFileName($elementValue, $regex)
|
||||
{
|
||||
if (!HTML_QuickForm_file::_ruleIsUploadedFile($elementValue)) {
|
||||
return true;
|
||||
}
|
||||
return (bool)preg_match($regex, $elementValue['name']);
|
||||
} // end func _ruleCheckFileName
|
||||
|
||||
// }}}
|
||||
// {{{ _findValue()
|
||||
|
||||
/**
|
||||
* 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 private
|
||||
* @return mixed
|
||||
*/
|
||||
function _findValue()
|
||||
{
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
// }}}
|
||||
} // end class HTML_QuickForm_file
|
||||
?>
|
||||
588
include/pear/HTML/QuickForm/group.php
Normal file
588
include/pear/HTML/QuickForm/group.php
Normal file
@@ -0,0 +1,588 @@
|
||||
<?php
|
||||
/* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4: */
|
||||
|
||||
/**
|
||||
* 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
|
||||
* @package HTML_QuickForm
|
||||
* @author Adam Daniel <adaniel1@eesus.jnj.com>
|
||||
* @author Bertrand Mansion <bmansion@mamasam.com>
|
||||
* @author Alexey Borzov <avb@php.net>
|
||||
* @copyright 2001-2007 The PHP Group
|
||||
* @license http://www.php.net/license/3_01.txt PHP License 3.01
|
||||
* @version CVS: $Id: group.php,v 1.39 2007/05/29 18:34:36 avb Exp $
|
||||
* @link http://pear.php.net/package/HTML_QuickForm
|
||||
*/
|
||||
|
||||
/**
|
||||
* Base class for form elements
|
||||
*/
|
||||
require_once 'HTML/QuickForm/element.php';
|
||||
|
||||
/**
|
||||
* HTML class for a form element group
|
||||
*
|
||||
* @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.10
|
||||
* @since 1.0
|
||||
*/
|
||||
class HTML_QuickForm_group extends HTML_QuickForm_element
|
||||
{
|
||||
// {{{ properties
|
||||
|
||||
/**
|
||||
* Name of the element
|
||||
* @var string
|
||||
* @since 1.0
|
||||
* @access private
|
||||
*/
|
||||
var $_name = '';
|
||||
|
||||
/**
|
||||
* Array of grouped elements
|
||||
* @var array
|
||||
* @since 1.0
|
||||
* @access private
|
||||
*/
|
||||
var $_elements = array();
|
||||
|
||||
/**
|
||||
* String to separate elements
|
||||
* @var mixed
|
||||
* @since 2.5
|
||||
* @access private
|
||||
*/
|
||||
var $_separator = null;
|
||||
|
||||
/**
|
||||
* Required elements in this group
|
||||
* @var array
|
||||
* @since 2.5
|
||||
* @access private
|
||||
*/
|
||||
var $_required = array();
|
||||
|
||||
/**
|
||||
* Whether to change elements' names to $groupName[$elementName] or leave them as is
|
||||
* @var bool
|
||||
* @since 3.0
|
||||
* @access private
|
||||
*/
|
||||
var $_appendName = true;
|
||||
|
||||
// }}}
|
||||
// {{{ constructor
|
||||
|
||||
/**
|
||||
* 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
|
||||
* @access public
|
||||
* @return void
|
||||
*/
|
||||
function HTML_QuickForm_group($elementName=null, $elementLabel=null, $elements=null, $separator=null, $appendName = true)
|
||||
{
|
||||
$this->HTML_QuickForm_element($elementName, $elementLabel);
|
||||
$this->_type = 'group';
|
||||
if (isset($elements) && is_array($elements)) {
|
||||
$this->setElements($elements);
|
||||
}
|
||||
if (isset($separator)) {
|
||||
$this->_separator = $separator;
|
||||
}
|
||||
if (isset($appendName)) {
|
||||
$this->_appendName = $appendName;
|
||||
}
|
||||
} //end constructor
|
||||
|
||||
// }}}
|
||||
// {{{ setName()
|
||||
|
||||
/**
|
||||
* Sets the group name
|
||||
*
|
||||
* @param string $name Group name
|
||||
* @since 1.0
|
||||
* @access public
|
||||
* @return void
|
||||
*/
|
||||
function setName($name)
|
||||
{
|
||||
$this->_name = $name;
|
||||
} //end func setName
|
||||
|
||||
// }}}
|
||||
// {{{ getName()
|
||||
|
||||
/**
|
||||
* Returns the group name
|
||||
*
|
||||
* @since 1.0
|
||||
* @access public
|
||||
* @return string
|
||||
*/
|
||||
function getName()
|
||||
{
|
||||
return $this->_name;
|
||||
} //end func getName
|
||||
|
||||
// }}}
|
||||
// {{{ setValue()
|
||||
|
||||
/**
|
||||
* Sets values for group's elements
|
||||
*
|
||||
* @param mixed Values for group's elements
|
||||
* @since 1.0
|
||||
* @access public
|
||||
* @return void
|
||||
*/
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
} //end func setValue
|
||||
|
||||
// }}}
|
||||
// {{{ getValue()
|
||||
|
||||
/**
|
||||
* Returns the value of the group
|
||||
*
|
||||
* @since 1.0
|
||||
* @access public
|
||||
* @return mixed
|
||||
*/
|
||||
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)? array(): array($value);
|
||||
}
|
||||
if ('' === $elementName) {
|
||||
$value[] = $v;
|
||||
} else {
|
||||
$value[$elementName] = $v;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return $value;
|
||||
} // end func getValue
|
||||
|
||||
// }}}
|
||||
// {{{ setElements()
|
||||
|
||||
/**
|
||||
* Sets the grouped elements
|
||||
*
|
||||
* @param array $elements Array of elements
|
||||
* @since 1.1
|
||||
* @access public
|
||||
* @return void
|
||||
*/
|
||||
function setElements($elements)
|
||||
{
|
||||
$this->_elements = array_values($elements);
|
||||
if ($this->_flagFrozen) {
|
||||
$this->freeze();
|
||||
}
|
||||
} // end func setElements
|
||||
|
||||
// }}}
|
||||
// {{{ getElements()
|
||||
|
||||
/**
|
||||
* Gets the grouped elements
|
||||
*
|
||||
* @since 2.4
|
||||
* @access public
|
||||
* @return array
|
||||
*/
|
||||
function &getElements()
|
||||
{
|
||||
$this->_createElementsIfNotExist();
|
||||
return $this->_elements;
|
||||
} // end func getElements
|
||||
|
||||
// }}}
|
||||
// {{{ getGroupType()
|
||||
|
||||
/**
|
||||
* Gets the group type based on its elements
|
||||
* Will return 'mixed' if elements contained in the group
|
||||
* are of different types.
|
||||
*
|
||||
* @access public
|
||||
* @return string group elements type
|
||||
*/
|
||||
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;
|
||||
} // end func getGroupType
|
||||
|
||||
// }}}
|
||||
// {{{ toHtml()
|
||||
|
||||
/**
|
||||
* Returns Html for the group
|
||||
*
|
||||
* @since 1.0
|
||||
* @access public
|
||||
* @return string
|
||||
*/
|
||||
function toHtml()
|
||||
{
|
||||
include_once('HTML/QuickForm/Renderer/Default.php');
|
||||
$renderer =& new HTML_QuickForm_Renderer_Default();
|
||||
$renderer->setElementTemplate('{element}');
|
||||
$this->accept($renderer);
|
||||
return $renderer->toHtml();
|
||||
} //end func toHtml
|
||||
|
||||
// }}}
|
||||
// {{{ getElementName()
|
||||
|
||||
/**
|
||||
* 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
|
||||
* @access public
|
||||
* @return mixed string with element name, false if not found
|
||||
*/
|
||||
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;
|
||||
} //end func getElementName
|
||||
|
||||
// }}}
|
||||
// {{{ getFrozenHtml()
|
||||
|
||||
/**
|
||||
* Returns the value of field without HTML tags
|
||||
*
|
||||
* @since 1.3
|
||||
* @access public
|
||||
* @return string
|
||||
*/
|
||||
function getFrozenHtml()
|
||||
{
|
||||
$flags = array();
|
||||
$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;
|
||||
} //end func getFrozenHtml
|
||||
|
||||
// }}}
|
||||
// {{{ 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':
|
||||
$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;
|
||||
} // end func onQuickFormEvent
|
||||
|
||||
// }}}
|
||||
// {{{ accept()
|
||||
|
||||
/**
|
||||
* 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
|
||||
* @access public
|
||||
* @return void
|
||||
*/
|
||||
function accept(&$renderer, $required = false, $error = null)
|
||||
{
|
||||
$this->_createElementsIfNotExist();
|
||||
$renderer->startGroup($this, $required, $error);
|
||||
$name = $this->getName();
|
||||
foreach (array_keys($this->_elements) as $key) {
|
||||
$element =& $this->_elements[$key];
|
||||
|
||||
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);
|
||||
} // end func accept
|
||||
|
||||
// }}}
|
||||
// {{{ exportValue()
|
||||
|
||||
/**
|
||||
* As usual, to get the group's value we access its elements and call
|
||||
* their exportValue() methods
|
||||
*/
|
||||
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 = array();
|
||||
}
|
||||
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;
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ _createElements()
|
||||
|
||||
/**
|
||||
* 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.
|
||||
*
|
||||
* @access private
|
||||
* @abstract
|
||||
*/
|
||||
function _createElements()
|
||||
{
|
||||
// abstract
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ _createElementsIfNotExist()
|
||||
|
||||
/**
|
||||
* 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.
|
||||
*
|
||||
* @access private
|
||||
*/
|
||||
function _createElementsIfNotExist()
|
||||
{
|
||||
if (empty($this->_elements)) {
|
||||
$this->_createElements();
|
||||
if ($this->_flagFrozen) {
|
||||
$this->freeze();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ freeze()
|
||||
|
||||
function freeze()
|
||||
{
|
||||
parent::freeze();
|
||||
foreach (array_keys($this->_elements) as $key) {
|
||||
$this->_elements[$key]->freeze();
|
||||
}
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ unfreeze()
|
||||
|
||||
function unfreeze()
|
||||
{
|
||||
parent::unfreeze();
|
||||
foreach (array_keys($this->_elements) as $key) {
|
||||
$this->_elements[$key]->unfreeze();
|
||||
}
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ setPersistantFreeze()
|
||||
|
||||
function setPersistantFreeze($persistant = false)
|
||||
{
|
||||
parent::setPersistantFreeze($persistant);
|
||||
foreach (array_keys($this->_elements) as $key) {
|
||||
$this->_elements[$key]->setPersistantFreeze($persistant);
|
||||
}
|
||||
}
|
||||
|
||||
// }}}
|
||||
} //end class HTML_QuickForm_group
|
||||
?>
|
||||
74
include/pear/HTML/QuickForm/header.php
Normal file
74
include/pear/HTML/QuickForm/header.php
Normal file
@@ -0,0 +1,74 @@
|
||||
<?php
|
||||
/* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4: */
|
||||
|
||||
/**
|
||||
* 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-2007 The PHP Group
|
||||
* @license http://www.php.net/license/3_01.txt PHP License 3.01
|
||||
* @version CVS: $Id: header.php,v 1.2 2007/05/29 18:34:36 avb Exp $
|
||||
* @link http://pear.php.net/package/HTML_QuickForm
|
||||
*/
|
||||
|
||||
/**
|
||||
* HTML class for static data
|
||||
*/
|
||||
require_once 'HTML/QuickForm/static.php';
|
||||
|
||||
/**
|
||||
* A pseudo-element used for adding headers to form
|
||||
*
|
||||
* @category HTML
|
||||
* @package HTML_QuickForm
|
||||
* @author Alexey Borzov <avb@php.net>
|
||||
* @version Release: 3.2.10
|
||||
* @since 3.0
|
||||
*/
|
||||
class HTML_QuickForm_header extends HTML_QuickForm_static
|
||||
{
|
||||
// {{{ constructor
|
||||
|
||||
/**
|
||||
* Class constructor
|
||||
*
|
||||
* @param string $elementName Header name
|
||||
* @param string $text Header text
|
||||
* @access public
|
||||
* @return void
|
||||
*/
|
||||
function HTML_QuickForm_header($elementName = null, $text = null)
|
||||
{
|
||||
$this->HTML_QuickForm_static($elementName, null, $text);
|
||||
$this->_type = 'header';
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ accept()
|
||||
|
||||
/**
|
||||
* Accepts a renderer
|
||||
*
|
||||
* @param HTML_QuickForm_Renderer renderer object
|
||||
* @access public
|
||||
* @return void
|
||||
*/
|
||||
function accept(&$renderer)
|
||||
{
|
||||
$renderer->renderHeader($this);
|
||||
} // end func accept
|
||||
|
||||
// }}}
|
||||
|
||||
} //end class HTML_QuickForm_header
|
||||
?>
|
||||
94
include/pear/HTML/QuickForm/hidden.php
Normal file
94
include/pear/HTML/QuickForm/hidden.php
Normal file
@@ -0,0 +1,94 @@
|
||||
<?php
|
||||
/* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4: */
|
||||
|
||||
/**
|
||||
* 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-2007 The PHP Group
|
||||
* @license http://www.php.net/license/3_01.txt PHP License 3.01
|
||||
* @version CVS: $Id: hidden.php,v 1.11 2007/05/29 18:34:36 avb Exp $
|
||||
* @link http://pear.php.net/package/HTML_QuickForm
|
||||
*/
|
||||
|
||||
/**
|
||||
* Base class for <input /> form elements
|
||||
*/
|
||||
require_once 'HTML/QuickForm/input.php';
|
||||
|
||||
/**
|
||||
* 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.10
|
||||
* @since 1.0
|
||||
*/
|
||||
class HTML_QuickForm_hidden extends HTML_QuickForm_input
|
||||
{
|
||||
// {{{ constructor
|
||||
|
||||
/**
|
||||
* 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
|
||||
*/
|
||||
function HTML_QuickForm_hidden($elementName=null, $value='', $attributes=null)
|
||||
{
|
||||
HTML_QuickForm_input::HTML_QuickForm_input($elementName, null, $attributes);
|
||||
$this->setType('hidden');
|
||||
$this->setValue($value);
|
||||
} //end constructor
|
||||
|
||||
// }}}
|
||||
// {{{ freeze()
|
||||
|
||||
/**
|
||||
* Freeze the element so that only its value is returned
|
||||
*
|
||||
* @access public
|
||||
* @return void
|
||||
*/
|
||||
function freeze()
|
||||
{
|
||||
return false;
|
||||
} //end func freeze
|
||||
|
||||
// }}}
|
||||
// {{{ accept()
|
||||
|
||||
/**
|
||||
* Accepts a renderer
|
||||
*
|
||||
* @param HTML_QuickForm_Renderer renderer object
|
||||
* @access public
|
||||
* @return void
|
||||
*/
|
||||
function accept(&$renderer)
|
||||
{
|
||||
$renderer->renderHidden($this);
|
||||
} // end func accept
|
||||
|
||||
// }}}
|
||||
|
||||
} //end class HTML_QuickForm_hidden
|
||||
?>
|
||||
118
include/pear/HTML/QuickForm/hiddenselect.php
Normal file
118
include/pear/HTML/QuickForm/hiddenselect.php
Normal file
@@ -0,0 +1,118 @@
|
||||
<?php
|
||||
/* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4: */
|
||||
|
||||
/**
|
||||
* 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-2007 The PHP Group
|
||||
* @license http://www.php.net/license/3_01.txt PHP License 3.01
|
||||
* @version CVS: $Id: hiddenselect.php,v 1.6 2007/05/29 18:34:36 avb Exp $
|
||||
* @link http://pear.php.net/package/HTML_QuickForm
|
||||
*/
|
||||
|
||||
/**
|
||||
* Class for <select></select> elements
|
||||
*/
|
||||
require_once 'HTML/QuickForm/select.php';
|
||||
|
||||
/**
|
||||
* 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.10
|
||||
* @since 2.1
|
||||
*/
|
||||
class HTML_QuickForm_hiddenselect extends HTML_QuickForm_select
|
||||
{
|
||||
// {{{ constructor
|
||||
|
||||
/**
|
||||
* 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
|
||||
*/
|
||||
function HTML_QuickForm_hiddenselect($elementName=null, $elementLabel=null, $options=null, $attributes=null)
|
||||
{
|
||||
HTML_QuickForm_element::HTML_QuickForm_element($elementName, $elementLabel, $attributes);
|
||||
$this->_persistantFreeze = true;
|
||||
$this->_type = 'hiddenselect';
|
||||
if (isset($options)) {
|
||||
$this->load($options);
|
||||
}
|
||||
} //end constructor
|
||||
|
||||
// }}}
|
||||
// {{{ toHtml()
|
||||
|
||||
/**
|
||||
* 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;
|
||||
} //end func toHtml
|
||||
|
||||
// }}}
|
||||
// {{{ accept()
|
||||
|
||||
/**
|
||||
* This is essentially a hidden element and should be rendered as one
|
||||
*/
|
||||
function accept(&$renderer)
|
||||
{
|
||||
$renderer->renderHidden($this);
|
||||
}
|
||||
|
||||
// }}}
|
||||
} //end class HTML_QuickForm_hiddenselect
|
||||
?>
|
||||
593
include/pear/HTML/QuickForm/hierselect.php
Normal file
593
include/pear/HTML/QuickForm/hierselect.php
Normal file
@@ -0,0 +1,593 @@
|
||||
<?php
|
||||
/* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4: */
|
||||
|
||||
/**
|
||||
* Hierarchical select 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 Herim Vasquez <vasquezh@iro.umontreal.ca>
|
||||
* @author Bertrand Mansion <bmansion@mamasam.com>
|
||||
* @author Alexey Borzov <avb@php.net>
|
||||
* @copyright 2001-2007 The PHP Group
|
||||
* @license http://www.php.net/license/3_01.txt PHP License 3.01
|
||||
* @version CVS: $Id: hierselect.php,v 1.19 2007/05/29 18:34:36 avb Exp $
|
||||
* @link http://pear.php.net/package/HTML_QuickForm
|
||||
*/
|
||||
|
||||
/**
|
||||
* Class for a group of form elements
|
||||
*/
|
||||
require_once 'HTML/QuickForm/group.php';
|
||||
/**
|
||||
* Class for <select></select> elements
|
||||
*/
|
||||
require_once 'HTML/QuickForm/select.php';
|
||||
|
||||
/**
|
||||
* Hierarchical select element
|
||||
*
|
||||
* Class to dynamically create two or more HTML Select elements
|
||||
* The first select changes the content of the second select and so on.
|
||||
* This element is considered as a group. Selects will be named
|
||||
* groupName[0], groupName[1], groupName[2]...
|
||||
*
|
||||
* @category HTML
|
||||
* @package HTML_QuickForm
|
||||
* @author Herim Vasquez <vasquezh@iro.umontreal.ca>
|
||||
* @author Bertrand Mansion <bmansion@mamasam.com>
|
||||
* @author Alexey Borzov <avb@php.net>
|
||||
* @version Release: 3.2.10
|
||||
* @since 3.1
|
||||
*/
|
||||
class HTML_QuickForm_hierselect extends HTML_QuickForm_group
|
||||
{
|
||||
// {{{ properties
|
||||
|
||||
/**
|
||||
* Options for all the select elements
|
||||
*
|
||||
* @see setOptions()
|
||||
* @var array
|
||||
* @access private
|
||||
*/
|
||||
var $_options = array();
|
||||
|
||||
/**
|
||||
* Number of select elements on this group
|
||||
*
|
||||
* @var int
|
||||
* @access private
|
||||
*/
|
||||
var $_nbElements = 0;
|
||||
|
||||
/**
|
||||
* The javascript used to set and change the options
|
||||
*
|
||||
* @var string
|
||||
* @access private
|
||||
*/
|
||||
var $_js = '';
|
||||
|
||||
// }}}
|
||||
// {{{ constructor
|
||||
|
||||
/**
|
||||
* Class constructor
|
||||
*
|
||||
* @param string $elementName (optional)Input field name attribute
|
||||
* @param string $elementLabel (optional)Input field label in form
|
||||
* @param mixed $attributes (optional)Either a typical HTML attribute string
|
||||
* or an associative array. Date format is passed along the attributes.
|
||||
* @param mixed $separator (optional)Use a string for one separator,
|
||||
* use an array to alternate the separators.
|
||||
* @access public
|
||||
* @return void
|
||||
*/
|
||||
function HTML_QuickForm_hierselect($elementName=null, $elementLabel=null, $attributes=null, $separator=null)
|
||||
{
|
||||
$this->HTML_QuickForm_element($elementName, $elementLabel, $attributes);
|
||||
$this->_persistantFreeze = true;
|
||||
if (isset($separator)) {
|
||||
$this->_separator = $separator;
|
||||
}
|
||||
$this->_type = 'hierselect';
|
||||
$this->_appendName = true;
|
||||
} //end constructor
|
||||
|
||||
// }}}
|
||||
// {{{ setOptions()
|
||||
|
||||
/**
|
||||
* Initialize the array structure containing the options for each select element.
|
||||
* Call the functions that actually do the magic.
|
||||
*
|
||||
* Format is a bit more complex than for a simple select as we need to know
|
||||
* which options are related to the ones in the previous select:
|
||||
*
|
||||
* Ex:
|
||||
* <code>
|
||||
* // first select
|
||||
* $select1[0] = 'Pop';
|
||||
* $select1[1] = 'Classical';
|
||||
* $select1[2] = 'Funeral doom';
|
||||
*
|
||||
* // second select
|
||||
* $select2[0][0] = 'Red Hot Chil Peppers';
|
||||
* $select2[0][1] = 'The Pixies';
|
||||
* $select2[1][0] = 'Wagner';
|
||||
* $select2[1][1] = 'Strauss';
|
||||
* $select2[2][0] = 'Pantheist';
|
||||
* $select2[2][1] = 'Skepticism';
|
||||
*
|
||||
* // If only need two selects
|
||||
* // - and using the deprecated functions
|
||||
* $sel =& $form->addElement('hierselect', 'cds', 'Choose CD:');
|
||||
* $sel->setMainOptions($select1);
|
||||
* $sel->setSecOptions($select2);
|
||||
*
|
||||
* // - and using the new setOptions function
|
||||
* $sel =& $form->addElement('hierselect', 'cds', 'Choose CD:');
|
||||
* $sel->setOptions(array($select1, $select2));
|
||||
*
|
||||
* // If you have a third select with prices for the cds
|
||||
* $select3[0][0][0] = '15.00$';
|
||||
* $select3[0][0][1] = '17.00$';
|
||||
* // etc
|
||||
*
|
||||
* // You can now use
|
||||
* $sel =& $form->addElement('hierselect', 'cds', 'Choose CD:');
|
||||
* $sel->setOptions(array($select1, $select2, $select3));
|
||||
* </code>
|
||||
*
|
||||
* @param array $options Array of options defining each element
|
||||
* @access public
|
||||
* @return void
|
||||
*/
|
||||
function setOptions($options)
|
||||
{
|
||||
$this->_options = $options;
|
||||
|
||||
if (empty($this->_elements)) {
|
||||
$this->_nbElements = count($this->_options);
|
||||
$this->_createElements();
|
||||
} else {
|
||||
// setDefaults has probably been called before this function
|
||||
// check if all elements have been created
|
||||
$totalNbElements = count($this->_options);
|
||||
for ($i = $this->_nbElements; $i < $totalNbElements; $i ++) {
|
||||
$this->_elements[] =& new HTML_QuickForm_select($i, null, array(), $this->getAttributes());
|
||||
$this->_nbElements++;
|
||||
}
|
||||
}
|
||||
|
||||
$this->_setOptions();
|
||||
} // end func setMainOptions
|
||||
|
||||
// }}}
|
||||
// {{{ setMainOptions()
|
||||
|
||||
/**
|
||||
* Sets the options for the first select element. Deprecated. setOptions() should be used.
|
||||
*
|
||||
* @param array $array Options for the first select element
|
||||
*
|
||||
* @access public
|
||||
* @deprecated Deprecated since release 3.2.2
|
||||
* @return void
|
||||
*/
|
||||
function setMainOptions($array)
|
||||
{
|
||||
$this->_options[0] = $array;
|
||||
|
||||
if (empty($this->_elements)) {
|
||||
$this->_nbElements = 2;
|
||||
$this->_createElements();
|
||||
}
|
||||
} // end func setMainOptions
|
||||
|
||||
// }}}
|
||||
// {{{ setSecOptions()
|
||||
|
||||
/**
|
||||
* Sets the options for the second select element. Deprecated. setOptions() should be used.
|
||||
* The main _options array is initialized and the _setOptions function is called.
|
||||
*
|
||||
* @param array $array Options for the second select element
|
||||
*
|
||||
* @access public
|
||||
* @deprecated Deprecated since release 3.2.2
|
||||
* @return void
|
||||
*/
|
||||
function setSecOptions($array)
|
||||
{
|
||||
$this->_options[1] = $array;
|
||||
|
||||
if (empty($this->_elements)) {
|
||||
$this->_nbElements = 2;
|
||||
$this->_createElements();
|
||||
} else {
|
||||
// setDefaults has probably been called before this function
|
||||
// check if all elements have been created
|
||||
$totalNbElements = 2;
|
||||
for ($i = $this->_nbElements; $i < $totalNbElements; $i ++) {
|
||||
$this->_elements[] =& new HTML_QuickForm_select($i, null, array(), $this->getAttributes());
|
||||
$this->_nbElements++;
|
||||
}
|
||||
}
|
||||
|
||||
$this->_setOptions();
|
||||
} // end func setSecOptions
|
||||
|
||||
// }}}
|
||||
// {{{ _setOptions()
|
||||
|
||||
/**
|
||||
* Sets the options for each select element
|
||||
*
|
||||
* @access private
|
||||
* @return void
|
||||
*/
|
||||
function _setOptions()
|
||||
{
|
||||
$toLoad = '';
|
||||
foreach (array_keys($this->_elements) AS $key) {
|
||||
$array = eval("return isset(\$this->_options[{$key}]{$toLoad})? \$this->_options[{$key}]{$toLoad}: null;");
|
||||
if (is_array($array)) {
|
||||
$select =& $this->_elements[$key];
|
||||
$select->_options = array();
|
||||
$select->loadArray($array);
|
||||
|
||||
$value = is_array($v = $select->getValue()) ? $v[0] : key($array);
|
||||
$toLoad .= '[\'' . str_replace(array('\\', '\''), array('\\\\', '\\\''), $value) . '\']';
|
||||
}
|
||||
}
|
||||
} // end func _setOptions
|
||||
|
||||
// }}}
|
||||
// {{{ setValue()
|
||||
|
||||
/**
|
||||
* Sets values for group's elements
|
||||
*
|
||||
* @param array $value An array of 2 or more values, for the first,
|
||||
* the second, the third etc. select
|
||||
*
|
||||
* @access public
|
||||
* @return void
|
||||
*/
|
||||
function setValue($value)
|
||||
{
|
||||
// fix for bug #6766. Hope this doesn't break anything more
|
||||
// after bug #7961. Forgot that _nbElements was used in
|
||||
// _createElements() called in several places...
|
||||
$this->_nbElements = max($this->_nbElements, count($value));
|
||||
parent::setValue($value);
|
||||
$this->_setOptions();
|
||||
} // end func setValue
|
||||
|
||||
// }}}
|
||||
// {{{ _createElements()
|
||||
|
||||
/**
|
||||
* Creates all the elements for the group
|
||||
*
|
||||
* @access private
|
||||
* @return void
|
||||
*/
|
||||
function _createElements()
|
||||
{
|
||||
for ($i = 0; $i < $this->_nbElements; $i++) {
|
||||
$this->_elements[] =& new HTML_QuickForm_select($i, null, array(), $this->getAttributes());
|
||||
}
|
||||
} // end func _createElements
|
||||
|
||||
// }}}
|
||||
// {{{ toHtml()
|
||||
|
||||
function toHtml()
|
||||
{
|
||||
$this->_js = '';
|
||||
if (!$this->_flagFrozen) {
|
||||
// set the onchange attribute for each element except last
|
||||
$keys = array_keys($this->_elements);
|
||||
$onChange = array();
|
||||
for ($i = 0; $i < count($keys) - 1; $i++) {
|
||||
$select =& $this->_elements[$keys[$i]];
|
||||
$onChange[$i] = $select->getAttribute('onchange');
|
||||
$select->updateAttributes(
|
||||
array('onchange' => '_hs_swapOptions(this.form, \'' . $this->_escapeString($this->getName()) . '\', ' . $keys[$i] . ');' . $onChange[$i])
|
||||
);
|
||||
}
|
||||
|
||||
// create the js function to call
|
||||
if (!defined('HTML_QUICKFORM_HIERSELECT_EXISTS')) {
|
||||
$this->_js .= <<<JAVASCRIPT
|
||||
function _hs_findOptions(ary, keys)
|
||||
{
|
||||
var key = keys.shift();
|
||||
if (!key in ary) {
|
||||
return {};
|
||||
} else if (0 == keys.length) {
|
||||
return ary[key];
|
||||
} else {
|
||||
return _hs_findOptions(ary[key], keys);
|
||||
}
|
||||
}
|
||||
|
||||
function _hs_findSelect(form, groupName, selectIndex)
|
||||
{
|
||||
if (groupName+'['+ selectIndex +']' in form) {
|
||||
return form[groupName+'['+ selectIndex +']'];
|
||||
} else {
|
||||
return form[groupName+'['+ selectIndex +'][]'];
|
||||
}
|
||||
}
|
||||
|
||||
function _hs_unescapeEntities(str)
|
||||
{
|
||||
var div = document.createElement('div');
|
||||
div.innerHTML = str;
|
||||
return div.childNodes[0] ? div.childNodes[0].nodeValue : '';
|
||||
}
|
||||
|
||||
function _hs_replaceOptions(ctl, optionList)
|
||||
{
|
||||
var j = 0;
|
||||
ctl.options.length = 0;
|
||||
for (i in optionList) {
|
||||
var optionText = (-1 == String(optionList[i]).indexOf('&'))? optionList[i]: _hs_unescapeEntities(optionList[i]);
|
||||
ctl.options[j++] = new Option(optionText, i, false, false);
|
||||
}
|
||||
}
|
||||
|
||||
function _hs_setValue(ctl, value)
|
||||
{
|
||||
var testValue = {};
|
||||
if (value instanceof Array) {
|
||||
for (var i = 0; i < value.length; i++) {
|
||||
testValue[value[i]] = true;
|
||||
}
|
||||
} else {
|
||||
testValue[value] = true;
|
||||
}
|
||||
for (var i = 0; i < ctl.options.length; i++) {
|
||||
if (ctl.options[i].value in testValue) {
|
||||
ctl.options[i].selected = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function _hs_swapOptions(form, groupName, selectIndex)
|
||||
{
|
||||
var hsValue = [];
|
||||
for (var i = 0; i <= selectIndex; i++) {
|
||||
hsValue[i] = _hs_findSelect(form, groupName, i).value;
|
||||
}
|
||||
|
||||
_hs_replaceOptions(_hs_findSelect(form, groupName, selectIndex + 1),
|
||||
_hs_findOptions(_hs_options[groupName][selectIndex], hsValue));
|
||||
if (selectIndex + 1 < _hs_options[groupName].length) {
|
||||
_hs_swapOptions(form, groupName, selectIndex + 1);
|
||||
}
|
||||
}
|
||||
|
||||
function _hs_onReset(form, groupNames)
|
||||
{
|
||||
for (var i = 0; i < groupNames.length; i++) {
|
||||
try {
|
||||
for (var j = 0; j <= _hs_options[groupNames[i]].length; j++) {
|
||||
_hs_setValue(_hs_findSelect(form, groupNames[i], j), _hs_defaults[groupNames[i]][j]);
|
||||
if (j < _hs_options[groupNames[i]].length) {
|
||||
_hs_replaceOptions(_hs_findSelect(form, groupNames[i], j + 1),
|
||||
_hs_findOptions(_hs_options[groupNames[i]][j], _hs_defaults[groupNames[i]].slice(0, j + 1)));
|
||||
}
|
||||
}
|
||||
} catch (e) {
|
||||
if (!(e instanceof TypeError)) {
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function _hs_setupOnReset(form, groupNames)
|
||||
{
|
||||
setTimeout(function() { _hs_onReset(form, groupNames); }, 25);
|
||||
}
|
||||
|
||||
function _hs_onReload()
|
||||
{
|
||||
var ctl;
|
||||
for (var i = 0; i < document.forms.length; i++) {
|
||||
for (var j in _hs_defaults) {
|
||||
if (ctl = _hs_findSelect(document.forms[i], j, 0)) {
|
||||
for (var k = 0; k < _hs_defaults[j].length; k++) {
|
||||
_hs_setValue(_hs_findSelect(document.forms[i], j, k), _hs_defaults[j][k]);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (_hs_prevOnload) {
|
||||
_hs_prevOnload();
|
||||
}
|
||||
}
|
||||
|
||||
var _hs_prevOnload = null;
|
||||
if (window.onload) {
|
||||
_hs_prevOnload = window.onload;
|
||||
}
|
||||
window.onload = _hs_onReload;
|
||||
|
||||
var _hs_options = {};
|
||||
var _hs_defaults = {};
|
||||
|
||||
JAVASCRIPT;
|
||||
define('HTML_QUICKFORM_HIERSELECT_EXISTS', true);
|
||||
}
|
||||
// option lists
|
||||
$jsParts = array();
|
||||
for ($i = 1; $i < $this->_nbElements; $i++) {
|
||||
$jsParts[] = $this->_convertArrayToJavascript($this->_options[$i]);
|
||||
}
|
||||
$this->_js .= "\n_hs_options['" . $this->_escapeString($this->getName()) . "'] = [\n" .
|
||||
implode(",\n", $jsParts) .
|
||||
"\n];\n";
|
||||
// default value; if we don't actually have any values yet just use
|
||||
// the first option (for single selects) or empty array (for multiple)
|
||||
$values = array();
|
||||
foreach (array_keys($this->_elements) as $key) {
|
||||
if (is_array($v = $this->_elements[$key]->getValue())) {
|
||||
$values[] = count($v) > 1? $v: $v[0];
|
||||
} else {
|
||||
// XXX: accessing the supposedly private _options array
|
||||
$values[] = $this->_elements[$key]->getMultiple() || empty($this->_elements[$key]->_options[0])?
|
||||
array():
|
||||
$this->_elements[$key]->_options[0]['attr']['value'];
|
||||
}
|
||||
}
|
||||
$this->_js .= "_hs_defaults['" . $this->_escapeString($this->getName()) . "'] = " .
|
||||
$this->_convertArrayToJavascript($values, false) . ";\n";
|
||||
}
|
||||
include_once('HTML/QuickForm/Renderer/Default.php');
|
||||
$renderer =& new HTML_QuickForm_Renderer_Default();
|
||||
$renderer->setElementTemplate('{element}');
|
||||
parent::accept($renderer);
|
||||
|
||||
if (!empty($onChange)) {
|
||||
$keys = array_keys($this->_elements);
|
||||
for ($i = 0; $i < count($keys) - 1; $i++) {
|
||||
$this->_elements[$keys[$i]]->updateAttributes(array('onchange' => $onChange[$i]));
|
||||
}
|
||||
}
|
||||
return (empty($this->_js)? '': "<script type=\"text/javascript\">\n//<![CDATA[\n" . $this->_js . "//]]>\n</script>") .
|
||||
$renderer->toHtml();
|
||||
} // end func toHtml
|
||||
|
||||
// }}}
|
||||
// {{{ accept()
|
||||
|
||||
function accept(&$renderer, $required = false, $error = null)
|
||||
{
|
||||
$renderer->renderElement($this, $required, $error);
|
||||
} // end func accept
|
||||
|
||||
// }}}
|
||||
// {{{ onQuickFormEvent()
|
||||
|
||||
function onQuickFormEvent($event, $arg, &$caller)
|
||||
{
|
||||
if ('updateValue' == $event) {
|
||||
// we need to call setValue() so that the secondary option
|
||||
// matches the main option
|
||||
return HTML_QuickForm_element::onQuickFormEvent($event, $arg, $caller);
|
||||
} else {
|
||||
$ret = parent::onQuickFormEvent($event, $arg, $caller);
|
||||
// add onreset handler to form to properly reset hierselect (see bug #2970)
|
||||
if ('addElement' == $event) {
|
||||
$onReset = $caller->getAttribute('onreset');
|
||||
if (strlen($onReset)) {
|
||||
if (strpos($onReset, '_hs_setupOnReset')) {
|
||||
$caller->updateAttributes(array('onreset' => str_replace('_hs_setupOnReset(this, [', "_hs_setupOnReset(this, ['" . $this->_escapeString($this->getName()) . "', ", $onReset)));
|
||||
} else {
|
||||
$caller->updateAttributes(array('onreset' => "var temp = function() { {$onReset} } ; if (!temp()) { return false; } ; if (typeof _hs_setupOnReset != 'undefined') { return _hs_setupOnReset(this, ['" . $this->_escapeString($this->getName()) . "']); } "));
|
||||
}
|
||||
} else {
|
||||
$caller->updateAttributes(array('onreset' => "if (typeof _hs_setupOnReset != 'undefined') { return _hs_setupOnReset(this, ['" . $this->_escapeString($this->getName()) . "']); } "));
|
||||
}
|
||||
}
|
||||
return $ret;
|
||||
}
|
||||
} // end func onQuickFormEvent
|
||||
|
||||
// }}}
|
||||
// {{{ _convertArrayToJavascript()
|
||||
|
||||
/**
|
||||
* Converts PHP array to its Javascript analog
|
||||
*
|
||||
* @access private
|
||||
* @param array PHP array to convert
|
||||
* @param bool Generate Javascript object literal (default, works like PHP's associative array) or array literal
|
||||
* @return string Javascript representation of the value
|
||||
*/
|
||||
function _convertArrayToJavascript($array, $assoc = true)
|
||||
{
|
||||
if (!is_array($array)) {
|
||||
return $this->_convertScalarToJavascript($array);
|
||||
} else {
|
||||
$items = array();
|
||||
foreach ($array as $key => $val) {
|
||||
$item = $assoc? "'" . $this->_escapeString($key) . "': ": '';
|
||||
if (is_array($val)) {
|
||||
$item .= $this->_convertArrayToJavascript($val, $assoc);
|
||||
} else {
|
||||
$item .= $this->_convertScalarToJavascript($val);
|
||||
}
|
||||
$items[] = $item;
|
||||
}
|
||||
}
|
||||
$js = implode(', ', $items);
|
||||
return $assoc? '{ ' . $js . ' }': '[' . $js . ']';
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ _convertScalarToJavascript()
|
||||
|
||||
/**
|
||||
* Converts PHP's scalar value to its Javascript analog
|
||||
*
|
||||
* @access private
|
||||
* @param mixed PHP value to convert
|
||||
* @return string Javascript representation of the value
|
||||
*/
|
||||
function _convertScalarToJavascript($val)
|
||||
{
|
||||
if (is_bool($val)) {
|
||||
return $val ? 'true' : 'false';
|
||||
} elseif (is_int($val) || is_double($val)) {
|
||||
return $val;
|
||||
} elseif (is_string($val)) {
|
||||
return "'" . $this->_escapeString($val) . "'";
|
||||
} elseif (is_null($val)) {
|
||||
return 'null';
|
||||
} else {
|
||||
// don't bother
|
||||
return '{}';
|
||||
}
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ _escapeString()
|
||||
|
||||
/**
|
||||
* Quotes the string so that it can be used in Javascript string constants
|
||||
*
|
||||
* @access private
|
||||
* @param string
|
||||
* @return string
|
||||
*/
|
||||
function _escapeString($str)
|
||||
{
|
||||
return strtr($str,array(
|
||||
"\r" => '\r',
|
||||
"\n" => '\n',
|
||||
"\t" => '\t',
|
||||
"'" => "\\'",
|
||||
'"' => '\"',
|
||||
'\\' => '\\\\'
|
||||
));
|
||||
}
|
||||
|
||||
// }}}
|
||||
} // end class HTML_QuickForm_hierselect
|
||||
?>
|
||||
77
include/pear/HTML/QuickForm/html.php
Normal file
77
include/pear/HTML/QuickForm/html.php
Normal file
@@ -0,0 +1,77 @@
|
||||
<?php
|
||||
/* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4: */
|
||||
|
||||
/**
|
||||
* 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-2007 The PHP Group
|
||||
* @license http://www.php.net/license/3_01.txt PHP License 3.01
|
||||
* @version CVS: $Id: html.php,v 1.2 2007/05/29 18:34:36 avb Exp $
|
||||
* @link http://pear.php.net/package/HTML_QuickForm
|
||||
*/
|
||||
|
||||
/**
|
||||
* HTML class for static data
|
||||
*/
|
||||
require_once 'HTML/QuickForm/static.php';
|
||||
|
||||
/**
|
||||
* 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.10
|
||||
* @since 3.0
|
||||
* @deprecated Please use the templates rather than add raw HTML via this element
|
||||
*/
|
||||
class HTML_QuickForm_html extends HTML_QuickForm_static
|
||||
{
|
||||
// {{{ constructor
|
||||
|
||||
/**
|
||||
* Class constructor
|
||||
*
|
||||
* @param string $text raw HTML to add
|
||||
* @access public
|
||||
* @return void
|
||||
*/
|
||||
function HTML_QuickForm_html($text = null)
|
||||
{
|
||||
$this->HTML_QuickForm_static(null, null, $text);
|
||||
$this->_type = 'html';
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ accept()
|
||||
|
||||
/**
|
||||
* Accepts a renderer
|
||||
*
|
||||
* @param HTML_QuickForm_Renderer renderer object (only works with Default renderer!)
|
||||
* @access public
|
||||
* @return void
|
||||
*/
|
||||
function accept(&$renderer)
|
||||
{
|
||||
$renderer->renderHtml($this);
|
||||
} // end func accept
|
||||
|
||||
// }}}
|
||||
|
||||
} //end class HTML_QuickForm_html
|
||||
?>
|
||||
127
include/pear/HTML/QuickForm/image.php
Normal file
127
include/pear/HTML/QuickForm/image.php
Normal file
@@ -0,0 +1,127 @@
|
||||
<?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-2007 The PHP Group
|
||||
* @license http://www.php.net/license/3_01.txt PHP License 3.01
|
||||
* @version CVS: $Id: image.php,v 1.5 2007/05/29 18:34:36 avb Exp $
|
||||
* @link http://pear.php.net/package/HTML_QuickForm
|
||||
*/
|
||||
|
||||
/**
|
||||
* Base class for <input /> form elements
|
||||
*/
|
||||
require_once 'HTML/QuickForm/input.php';
|
||||
|
||||
/**
|
||||
* 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.10
|
||||
* @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
|
||||
*/
|
||||
function HTML_QuickForm_image($elementName=null, $src='', $attributes=null)
|
||||
{
|
||||
HTML_QuickForm_input::HTML_QuickForm_input($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));
|
||||
} // end func setBorder
|
||||
|
||||
// }}}
|
||||
// {{{ setAlign()
|
||||
|
||||
/**
|
||||
* 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));
|
||||
} // end func setAlign
|
||||
|
||||
// }}}
|
||||
// {{{ freeze()
|
||||
|
||||
/**
|
||||
* Freeze the element so that only its value is returned
|
||||
*
|
||||
* @access public
|
||||
* @return void
|
||||
*/
|
||||
function freeze()
|
||||
{
|
||||
return false;
|
||||
} //end func freeze
|
||||
|
||||
// }}}
|
||||
|
||||
} // end class HTML_QuickForm_image
|
||||
?>
|
||||
209
include/pear/HTML/QuickForm/input.php
Normal file
209
include/pear/HTML/QuickForm/input.php
Normal file
@@ -0,0 +1,209 @@
|
||||
<?php
|
||||
/* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4: */
|
||||
|
||||
/**
|
||||
* 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-2007 The PHP Group
|
||||
* @license http://www.php.net/license/3_01.txt PHP License 3.01
|
||||
* @version CVS: $Id: input.php,v 1.9 2007/05/29 18:34:36 avb Exp $
|
||||
* @link http://pear.php.net/package/HTML_QuickForm
|
||||
*/
|
||||
|
||||
/**
|
||||
* Base class for form elements
|
||||
*/
|
||||
require_once 'HTML/QuickForm/element.php';
|
||||
|
||||
/**
|
||||
* 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.10
|
||||
* @since 1.0
|
||||
* @abstract
|
||||
*/
|
||||
class HTML_QuickForm_input extends HTML_QuickForm_element
|
||||
{
|
||||
// {{{ constructor
|
||||
|
||||
/**
|
||||
* Class constructor
|
||||
*
|
||||
* @param string Input field name attribute
|
||||
* @param mixed Label(s) for the input field
|
||||
* @param mixed Either a typical HTML attribute string or an associative array
|
||||
* @since 1.0
|
||||
* @access public
|
||||
* @return void
|
||||
*/
|
||||
function HTML_QuickForm_input($elementName=null, $elementLabel=null, $attributes=null)
|
||||
{
|
||||
$this->HTML_QuickForm_element($elementName, $elementLabel, $attributes);
|
||||
} //end constructor
|
||||
|
||||
// }}}
|
||||
// {{{ setType()
|
||||
|
||||
/**
|
||||
* Sets the element type
|
||||
*
|
||||
* @param string $type Element type
|
||||
* @since 1.0
|
||||
* @access public
|
||||
* @return void
|
||||
*/
|
||||
function setType($type)
|
||||
{
|
||||
$this->_type = $type;
|
||||
$this->updateAttributes(array('type'=>$type));
|
||||
} // end func setType
|
||||
|
||||
// }}}
|
||||
// {{{ setName()
|
||||
|
||||
/**
|
||||
* Sets the input field name
|
||||
*
|
||||
* @param string $name Input field name attribute
|
||||
* @since 1.0
|
||||
* @access public
|
||||
* @return void
|
||||
*/
|
||||
function setName($name)
|
||||
{
|
||||
$this->updateAttributes(array('name'=>$name));
|
||||
} //end func setName
|
||||
|
||||
// }}}
|
||||
// {{{ getName()
|
||||
|
||||
/**
|
||||
* Returns the element name
|
||||
*
|
||||
* @since 1.0
|
||||
* @access public
|
||||
* @return string
|
||||
*/
|
||||
function getName()
|
||||
{
|
||||
return $this->getAttribute('name');
|
||||
} //end func getName
|
||||
|
||||
// }}}
|
||||
// {{{ setValue()
|
||||
|
||||
/**
|
||||
* Sets the value of the form element
|
||||
*
|
||||
* @param string $value Default value of the form element
|
||||
* @since 1.0
|
||||
* @access public
|
||||
* @return void
|
||||
*/
|
||||
function setValue($value)
|
||||
{
|
||||
$this->updateAttributes(array('value'=>$value));
|
||||
} // end func setValue
|
||||
|
||||
// }}}
|
||||
// {{{ getValue()
|
||||
|
||||
/**
|
||||
* Returns the value of the form element
|
||||
*
|
||||
* @since 1.0
|
||||
* @access public
|
||||
* @return string
|
||||
*/
|
||||
function getValue()
|
||||
{
|
||||
return $this->getAttribute('value');
|
||||
} // end func getValue
|
||||
|
||||
// }}}
|
||||
// {{{ toHtml()
|
||||
|
||||
/**
|
||||
* Returns the input field in HTML
|
||||
*
|
||||
* @since 1.0
|
||||
* @access public
|
||||
* @return string
|
||||
*/
|
||||
function toHtml()
|
||||
{
|
||||
if ($this->_flagFrozen) {
|
||||
return $this->getFrozenHtml();
|
||||
} else {
|
||||
return $this->_getTabs() . '<input' . $this->_getAttrString($this->_attributes) . ' />';
|
||||
}
|
||||
} //end func toHtml
|
||||
|
||||
// }}}
|
||||
// {{{ 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
|
||||
* @throws
|
||||
*/
|
||||
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;
|
||||
} // end func onQuickFormEvent
|
||||
|
||||
// }}}
|
||||
// {{{ exportValue()
|
||||
|
||||
/**
|
||||
* We don't need values from button-type elements (except submit) and files
|
||||
*/
|
||||
function exportValue(&$submitValues, $assoc = false)
|
||||
{
|
||||
$type = $this->getType();
|
||||
if ('reset' == $type || 'image' == $type || 'button' == $type || 'file' == $type) {
|
||||
return null;
|
||||
} else {
|
||||
return parent::exportValue($submitValues, $assoc);
|
||||
}
|
||||
}
|
||||
|
||||
// }}}
|
||||
} // end class HTML_QuickForm_element
|
||||
?>
|
||||
200
include/pear/HTML/QuickForm/link.php
Normal file
200
include/pear/HTML/QuickForm/link.php
Normal file
@@ -0,0 +1,200 @@
|
||||
<?php
|
||||
/* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4: */
|
||||
|
||||
/**
|
||||
* 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-2007 The PHP Group
|
||||
* @license http://www.php.net/license/3_01.txt PHP License 3.01
|
||||
* @version CVS: $Id: link.php,v 1.3 2007/05/29 18:34:36 avb Exp $
|
||||
* @link http://pear.php.net/package/HTML_QuickForm
|
||||
*/
|
||||
|
||||
/**
|
||||
* HTML class for static data
|
||||
*/
|
||||
require_once 'HTML/QuickForm/static.php';
|
||||
|
||||
/**
|
||||
* 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.10
|
||||
* @since 2.0
|
||||
*/
|
||||
class HTML_QuickForm_link extends HTML_QuickForm_static
|
||||
{
|
||||
// {{{ properties
|
||||
|
||||
/**
|
||||
* Link display text
|
||||
* @var string
|
||||
* @since 1.0
|
||||
* @access private
|
||||
*/
|
||||
var $_text = "";
|
||||
|
||||
// }}}
|
||||
// {{{ constructor
|
||||
|
||||
/**
|
||||
* 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
|
||||
*/
|
||||
function HTML_QuickForm_link($elementName=null, $elementLabel=null, $href=null, $text=null, $attributes=null)
|
||||
{
|
||||
HTML_QuickForm_element::HTML_QuickForm_element($elementName, $elementLabel, $attributes);
|
||||
$this->_persistantFreeze = false;
|
||||
$this->_type = 'link';
|
||||
$this->setHref($href);
|
||||
$this->_text = $text;
|
||||
} //end constructor
|
||||
|
||||
// }}}
|
||||
// {{{ setName()
|
||||
|
||||
/**
|
||||
* 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));
|
||||
} //end func setName
|
||||
|
||||
// }}}
|
||||
// {{{ getName()
|
||||
|
||||
/**
|
||||
* Returns the element name
|
||||
*
|
||||
* @since 1.0
|
||||
* @access public
|
||||
* @return string
|
||||
* @throws
|
||||
*/
|
||||
function getName()
|
||||
{
|
||||
return $this->getAttribute('name');
|
||||
} //end func getName
|
||||
|
||||
// }}}
|
||||
// {{{ setValue()
|
||||
|
||||
/**
|
||||
* Sets value for textarea element
|
||||
*
|
||||
* @param string $value Value for password element
|
||||
* @since 1.0
|
||||
* @access public
|
||||
* @return void
|
||||
* @throws
|
||||
*/
|
||||
function setValue($value)
|
||||
{
|
||||
return;
|
||||
} //end func setValue
|
||||
|
||||
// }}}
|
||||
// {{{ getValue()
|
||||
|
||||
/**
|
||||
* Returns the value of the form element
|
||||
*
|
||||
* @since 1.0
|
||||
* @access public
|
||||
* @return void
|
||||
* @throws
|
||||
*/
|
||||
function getValue()
|
||||
{
|
||||
return;
|
||||
} // end func getValue
|
||||
|
||||
|
||||
// }}}
|
||||
// {{{ setHref()
|
||||
|
||||
/**
|
||||
* Sets the links href
|
||||
*
|
||||
* @param string $href
|
||||
* @since 1.0
|
||||
* @access public
|
||||
* @return void
|
||||
* @throws
|
||||
*/
|
||||
function setHref($href)
|
||||
{
|
||||
$this->updateAttributes(array('href'=>$href));
|
||||
} // end func setHref
|
||||
|
||||
// }}}
|
||||
// {{{ toHtml()
|
||||
|
||||
/**
|
||||
* 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;
|
||||
} //end func toHtml
|
||||
|
||||
// }}}
|
||||
// {{{ getFrozenHtml()
|
||||
|
||||
/**
|
||||
* 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;
|
||||
} //end func getFrozenHtml
|
||||
|
||||
// }}}
|
||||
|
||||
} //end class HTML_QuickForm_textarea
|
||||
?>
|
||||
115
include/pear/HTML/QuickForm/password.php
Normal file
115
include/pear/HTML/QuickForm/password.php
Normal file
@@ -0,0 +1,115 @@
|
||||
<?php
|
||||
/* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4: */
|
||||
|
||||
/**
|
||||
* 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-2007 The PHP Group
|
||||
* @license http://www.php.net/license/3_01.txt PHP License 3.01
|
||||
* @version CVS: $Id: password.php,v 1.7 2007/05/29 18:34:36 avb Exp $
|
||||
* @link http://pear.php.net/package/HTML_QuickForm
|
||||
*/
|
||||
|
||||
/**
|
||||
* Base class for <input /> form elements
|
||||
*/
|
||||
require_once 'HTML/QuickForm/input.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.10
|
||||
* @since 1.0
|
||||
*/
|
||||
class HTML_QuickForm_password extends HTML_QuickForm_input
|
||||
{
|
||||
// {{{ constructor
|
||||
|
||||
/**
|
||||
* 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
|
||||
*/
|
||||
function HTML_QuickForm_password($elementName=null, $elementLabel=null, $attributes=null)
|
||||
{
|
||||
HTML_QuickForm_input::HTML_QuickForm_input($elementName, $elementLabel, $attributes);
|
||||
$this->setType('password');
|
||||
} //end constructor
|
||||
|
||||
// }}}
|
||||
// {{{ setSize()
|
||||
|
||||
/**
|
||||
* Sets size of password element
|
||||
*
|
||||
* @param string $size Size of password field
|
||||
* @since 1.0
|
||||
* @access public
|
||||
* @return void
|
||||
*/
|
||||
function setSize($size)
|
||||
{
|
||||
$this->updateAttributes(array('size'=>$size));
|
||||
} //end func setSize
|
||||
|
||||
// }}}
|
||||
// {{{ setMaxlength()
|
||||
|
||||
/**
|
||||
* Sets maxlength of password element
|
||||
*
|
||||
* @param string $maxlength Maximum length of password field
|
||||
* @since 1.0
|
||||
* @access public
|
||||
* @return void
|
||||
*/
|
||||
function setMaxlength($maxlength)
|
||||
{
|
||||
$this->updateAttributes(array('maxlength'=>$maxlength));
|
||||
} //end func setMaxlength
|
||||
|
||||
// }}}
|
||||
// {{{ getFrozenHtml()
|
||||
|
||||
/**
|
||||
* 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()
|
||||
{
|
||||
$value = $this->getValue();
|
||||
return ('' != $value? '**********': ' ') .
|
||||
$this->_getPersistantData();
|
||||
} //end func getFrozenHtml
|
||||
|
||||
// }}}
|
||||
|
||||
} //end class HTML_QuickForm_password
|
||||
?>
|
||||
251
include/pear/HTML/QuickForm/radio.php
Normal file
251
include/pear/HTML/QuickForm/radio.php
Normal file
@@ -0,0 +1,251 @@
|
||||
<?php
|
||||
/* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4: */
|
||||
|
||||
/**
|
||||
* 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-2007 The PHP Group
|
||||
* @license http://www.php.net/license/3_01.txt PHP License 3.01
|
||||
* @version CVS: $Id: radio.php,v 1.19 2007/05/29 18:34:36 avb Exp $
|
||||
* @link http://pear.php.net/package/HTML_QuickForm
|
||||
*/
|
||||
|
||||
/**
|
||||
* Base class for <input /> form elements
|
||||
*/
|
||||
require_once 'HTML/QuickForm/input.php';
|
||||
|
||||
/**
|
||||
* 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.10
|
||||
* @since 1.0
|
||||
*/
|
||||
class HTML_QuickForm_radio extends HTML_QuickForm_input
|
||||
{
|
||||
// {{{ properties
|
||||
|
||||
/**
|
||||
* Radio display text
|
||||
* @var string
|
||||
* @since 1.1
|
||||
* @access private
|
||||
*/
|
||||
var $_text = '';
|
||||
|
||||
// }}}
|
||||
// {{{ constructor
|
||||
|
||||
/**
|
||||
* 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
|
||||
* @since 1.0
|
||||
* @access public
|
||||
* @return void
|
||||
*/
|
||||
function HTML_QuickForm_radio($elementName=null, $elementLabel=null, $text=null, $value=null, $attributes=null)
|
||||
{
|
||||
$this->HTML_QuickForm_element($elementName, $elementLabel, $attributes);
|
||||
if (isset($value)) {
|
||||
$this->setValue($value);
|
||||
}
|
||||
$this->_persistantFreeze = true;
|
||||
$this->setType('radio');
|
||||
$this->_text = $text;
|
||||
$this->_generateId();
|
||||
} //end constructor
|
||||
|
||||
// }}}
|
||||
// {{{ setChecked()
|
||||
|
||||
/**
|
||||
* Sets whether radio button is checked
|
||||
*
|
||||
* @param bool $checked Whether the field is checked or not
|
||||
* @since 1.0
|
||||
* @access public
|
||||
* @return void
|
||||
*/
|
||||
function setChecked($checked)
|
||||
{
|
||||
if (!$checked) {
|
||||
$this->removeAttribute('checked');
|
||||
} else {
|
||||
$this->updateAttributes(array('checked'=>'checked'));
|
||||
}
|
||||
} //end func setChecked
|
||||
|
||||
// }}}
|
||||
// {{{ getChecked()
|
||||
|
||||
/**
|
||||
* Returns whether radio button is checked
|
||||
*
|
||||
* @since 1.0
|
||||
* @access public
|
||||
* @return string
|
||||
*/
|
||||
function getChecked()
|
||||
{
|
||||
return $this->getAttribute('checked');
|
||||
} //end func getChecked
|
||||
|
||||
// }}}
|
||||
// {{{ toHtml()
|
||||
|
||||
/**
|
||||
* Returns the radio element in HTML
|
||||
*
|
||||
* @since 1.0
|
||||
* @access public
|
||||
* @return string
|
||||
*/
|
||||
function toHtml()
|
||||
{
|
||||
if (0 == strlen($this->_text)) {
|
||||
$label = '';
|
||||
} elseif ($this->_flagFrozen) {
|
||||
$label = $this->_text;
|
||||
} else {
|
||||
$label = '<label for="' . $this->getAttribute('id') . '">' . $this->_text . '</label>';
|
||||
}
|
||||
return HTML_QuickForm_input::toHtml() . $label;
|
||||
} //end func toHtml
|
||||
|
||||
// }}}
|
||||
// {{{ getFrozenHtml()
|
||||
|
||||
/**
|
||||
* Returns the value of field without HTML tags
|
||||
*
|
||||
* @since 1.0
|
||||
* @access public
|
||||
* @return string
|
||||
*/
|
||||
function getFrozenHtml()
|
||||
{
|
||||
if ($this->getChecked()) {
|
||||
return '<tt>(x)</tt>' .
|
||||
$this->_getPersistantData();
|
||||
} else {
|
||||
return '<tt>( )</tt>';
|
||||
}
|
||||
} //end func getFrozenHtml
|
||||
|
||||
// }}}
|
||||
// {{{ setText()
|
||||
|
||||
/**
|
||||
* Sets the radio text
|
||||
*
|
||||
* @param string $text Text to display near the radio button
|
||||
* @since 1.1
|
||||
* @access public
|
||||
* @return void
|
||||
*/
|
||||
function setText($text)
|
||||
{
|
||||
$this->_text = $text;
|
||||
} //end func setText
|
||||
|
||||
// }}}
|
||||
// {{{ getText()
|
||||
|
||||
/**
|
||||
* Returns the radio text
|
||||
*
|
||||
* @since 1.1
|
||||
* @access public
|
||||
* @return string
|
||||
*/
|
||||
function getText()
|
||||
{
|
||||
return $this->_text;
|
||||
} //end func getText
|
||||
|
||||
// }}}
|
||||
// {{{ 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 (!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;
|
||||
} // end func onQuickFormLoad
|
||||
|
||||
// }}}
|
||||
// {{{ exportValue()
|
||||
|
||||
/**
|
||||
* Returns the value attribute if the radio is checked, null if it is not
|
||||
*/
|
||||
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);
|
||||
}
|
||||
|
||||
// }}}
|
||||
} //end class HTML_QuickForm_radio
|
||||
?>
|
||||
79
include/pear/HTML/QuickForm/reset.php
Normal file
79
include/pear/HTML/QuickForm/reset.php
Normal file
@@ -0,0 +1,79 @@
|
||||
<?php
|
||||
/* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4: */
|
||||
|
||||
/**
|
||||
* HTML class for a reset 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-2007 The PHP Group
|
||||
* @license http://www.php.net/license/3_01.txt PHP License 3.01
|
||||
* @version CVS: $Id: reset.php,v 1.5 2007/05/29 18:34:36 avb Exp $
|
||||
* @link http://pear.php.net/package/HTML_QuickForm
|
||||
*/
|
||||
|
||||
/**
|
||||
* Base class for <input /> form elements
|
||||
*/
|
||||
require_once 'HTML/QuickForm/input.php';
|
||||
|
||||
/**
|
||||
* HTML class for a reset type element
|
||||
*
|
||||
* @category HTML
|
||||
* @package HTML_QuickForm
|
||||
* @author Adam Daniel <adaniel1@eesus.jnj.com>
|
||||
* @author Bertrand Mansion <bmansion@mamasam.com>
|
||||
* @version Release: 3.2.10
|
||||
* @since 1.0
|
||||
*/
|
||||
class HTML_QuickForm_reset extends HTML_QuickForm_input
|
||||
{
|
||||
// {{{ constructor
|
||||
|
||||
/**
|
||||
* 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
|
||||
*/
|
||||
function HTML_QuickForm_reset($elementName=null, $value=null, $attributes=null)
|
||||
{
|
||||
HTML_QuickForm_input::HTML_QuickForm_input($elementName, null, $attributes);
|
||||
$this->setValue($value);
|
||||
$this->setType('reset');
|
||||
} //end constructor
|
||||
|
||||
// }}}
|
||||
// {{{ freeze()
|
||||
|
||||
/**
|
||||
* Freeze the element so that only its value is returned
|
||||
*
|
||||
* @access public
|
||||
* @return void
|
||||
*/
|
||||
function freeze()
|
||||
{
|
||||
return false;
|
||||
} //end func freeze
|
||||
|
||||
// }}}
|
||||
|
||||
} //end class HTML_QuickForm_reset
|
||||
?>
|
||||
614
include/pear/HTML/QuickForm/select.php
Normal file
614
include/pear/HTML/QuickForm/select.php
Normal file
@@ -0,0 +1,614 @@
|
||||
<?php
|
||||
/* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4: */
|
||||
|
||||
/**
|
||||
* 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-2007 The PHP Group
|
||||
* @license http://www.php.net/license/3_01.txt PHP License 3.01
|
||||
* @version CVS: $Id: select.php,v 1.33 2007/06/03 15:01:00 avb Exp $
|
||||
* @link http://pear.php.net/package/HTML_QuickForm
|
||||
*/
|
||||
|
||||
/**
|
||||
* Base class for form elements
|
||||
*/
|
||||
require_once 'HTML/QuickForm/element.php';
|
||||
|
||||
/**
|
||||
* 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.10
|
||||
* @since 1.0
|
||||
*/
|
||||
class HTML_QuickForm_select extends HTML_QuickForm_element {
|
||||
|
||||
// {{{ properties
|
||||
|
||||
/**
|
||||
* Contains the select options
|
||||
*
|
||||
* @var array
|
||||
* @since 1.0
|
||||
* @access private
|
||||
*/
|
||||
var $_options = array();
|
||||
|
||||
/**
|
||||
* Default values of the SELECT
|
||||
*
|
||||
* @var string
|
||||
* @since 1.0
|
||||
* @access private
|
||||
*/
|
||||
var $_values = null;
|
||||
|
||||
// }}}
|
||||
// {{{ constructor
|
||||
|
||||
/**
|
||||
* Class constructor
|
||||
*
|
||||
* @param string Select name attribute
|
||||
* @param mixed Label(s) for the select
|
||||
* @param mixed Data to be used to populate options
|
||||
* @param mixed Either a typical HTML attribute string or an associative array
|
||||
* @since 1.0
|
||||
* @access public
|
||||
* @return void
|
||||
*/
|
||||
function HTML_QuickForm_select($elementName=null, $elementLabel=null, $options=null, $attributes=null)
|
||||
{
|
||||
HTML_QuickForm_element::HTML_QuickForm_element($elementName, $elementLabel, $attributes);
|
||||
$this->_persistantFreeze = true;
|
||||
$this->_type = 'select';
|
||||
if (isset($options)) {
|
||||
$this->load($options);
|
||||
}
|
||||
} //end constructor
|
||||
|
||||
// }}}
|
||||
// {{{ apiVersion()
|
||||
|
||||
/**
|
||||
* Returns the current API version
|
||||
*
|
||||
* @since 1.0
|
||||
* @access public
|
||||
* @return double
|
||||
*/
|
||||
function apiVersion()
|
||||
{
|
||||
return 2.3;
|
||||
} //end func apiVersion
|
||||
|
||||
// }}}
|
||||
// {{{ setSelected()
|
||||
|
||||
/**
|
||||
* 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
|
||||
*/
|
||||
function setSelected($values)
|
||||
{
|
||||
if (is_string($values) && $this->getMultiple()) {
|
||||
$values = split("[ ]?,[ ]?", $values);
|
||||
}
|
||||
if (is_array($values)) {
|
||||
$this->_values = array_values($values);
|
||||
} else {
|
||||
$this->_values = array($values);
|
||||
}
|
||||
} //end func setSelected
|
||||
|
||||
// }}}
|
||||
// {{{ getSelected()
|
||||
|
||||
/**
|
||||
* Returns an array of the selected values
|
||||
*
|
||||
* @since 1.0
|
||||
* @access public
|
||||
* @return array of selected values
|
||||
*/
|
||||
function getSelected()
|
||||
{
|
||||
return $this->_values;
|
||||
} // end func getSelected
|
||||
|
||||
// }}}
|
||||
// {{{ setName()
|
||||
|
||||
/**
|
||||
* Sets the input field name
|
||||
*
|
||||
* @param string $name Input field name attribute
|
||||
* @since 1.0
|
||||
* @access public
|
||||
* @return void
|
||||
*/
|
||||
function setName($name)
|
||||
{
|
||||
$this->updateAttributes(array('name' => $name));
|
||||
} //end func setName
|
||||
|
||||
// }}}
|
||||
// {{{ getName()
|
||||
|
||||
/**
|
||||
* Returns the element name
|
||||
*
|
||||
* @since 1.0
|
||||
* @access public
|
||||
* @return string
|
||||
*/
|
||||
function getName()
|
||||
{
|
||||
return $this->getAttribute('name');
|
||||
} //end func getName
|
||||
|
||||
// }}}
|
||||
// {{{ getPrivateName()
|
||||
|
||||
/**
|
||||
* Returns the element name (possibly with brackets appended)
|
||||
*
|
||||
* @since 1.0
|
||||
* @access public
|
||||
* @return string
|
||||
*/
|
||||
function getPrivateName()
|
||||
{
|
||||
if ($this->getAttribute('multiple')) {
|
||||
return $this->getName() . '[]';
|
||||
} else {
|
||||
return $this->getName();
|
||||
}
|
||||
} //end func getPrivateName
|
||||
|
||||
// }}}
|
||||
// {{{ setValue()
|
||||
|
||||
/**
|
||||
* 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
|
||||
*/
|
||||
function setValue($value)
|
||||
{
|
||||
$this->setSelected($value);
|
||||
} // end func setValue
|
||||
|
||||
// }}}
|
||||
// {{{ getValue()
|
||||
|
||||
/**
|
||||
* Returns an array of the selected values
|
||||
*
|
||||
* @since 1.0
|
||||
* @access public
|
||||
* @return array of selected values
|
||||
*/
|
||||
function getValue()
|
||||
{
|
||||
return $this->_values;
|
||||
} // end func getValue
|
||||
|
||||
// }}}
|
||||
// {{{ setSize()
|
||||
|
||||
/**
|
||||
* Sets the select field size, only applies to 'multiple' selects
|
||||
*
|
||||
* @param int $size Size of select field
|
||||
* @since 1.0
|
||||
* @access public
|
||||
* @return void
|
||||
*/
|
||||
function setSize($size)
|
||||
{
|
||||
$this->updateAttributes(array('size' => $size));
|
||||
} //end func setSize
|
||||
|
||||
// }}}
|
||||
// {{{ getSize()
|
||||
|
||||
/**
|
||||
* Returns the select field size
|
||||
*
|
||||
* @since 1.0
|
||||
* @access public
|
||||
* @return int
|
||||
*/
|
||||
function getSize()
|
||||
{
|
||||
return $this->getAttribute('size');
|
||||
} //end func getSize
|
||||
|
||||
// }}}
|
||||
// {{{ setMultiple()
|
||||
|
||||
/**
|
||||
* Sets the select mutiple attribute
|
||||
*
|
||||
* @param bool $multiple Whether the select supports multi-selections
|
||||
* @since 1.2
|
||||
* @access public
|
||||
* @return void
|
||||
*/
|
||||
function setMultiple($multiple)
|
||||
{
|
||||
if ($multiple) {
|
||||
$this->updateAttributes(array('multiple' => 'multiple'));
|
||||
} else {
|
||||
$this->removeAttribute('multiple');
|
||||
}
|
||||
} //end func setMultiple
|
||||
|
||||
// }}}
|
||||
// {{{ getMultiple()
|
||||
|
||||
/**
|
||||
* Returns the select mutiple attribute
|
||||
*
|
||||
* @since 1.2
|
||||
* @access public
|
||||
* @return bool true if multiple select, false otherwise
|
||||
*/
|
||||
function getMultiple()
|
||||
{
|
||||
return (bool)$this->getAttribute('multiple');
|
||||
} //end func getMultiple
|
||||
|
||||
// }}}
|
||||
// {{{ addOption()
|
||||
|
||||
/**
|
||||
* 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
|
||||
*/
|
||||
function addOption($text, $value, $attributes=null)
|
||||
{
|
||||
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));
|
||||
}
|
||||
$this->_options[] = array('text' => $text, 'attr' => $attributes);
|
||||
} // end func addOption
|
||||
|
||||
// }}}
|
||||
// {{{ loadArray()
|
||||
|
||||
/**
|
||||
* 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
|
||||
*/
|
||||
function loadArray($arr, $values=null)
|
||||
{
|
||||
if (!is_array($arr)) {
|
||||
return PEAR::raiseError('Argument 1 of HTML_Select::loadArray is not a valid array');
|
||||
}
|
||||
if (isset($values)) {
|
||||
$this->setSelected($values);
|
||||
}
|
||||
foreach ($arr as $key => $val) {
|
||||
// Warning: new API since release 2.3
|
||||
$this->addOption($val, $key);
|
||||
}
|
||||
return true;
|
||||
} // end func loadArray
|
||||
|
||||
// }}}
|
||||
// {{{ loadDbResult()
|
||||
|
||||
/**
|
||||
* Loads the options from DB_result object
|
||||
*
|
||||
* If no column names are specified the first two columns of the result are
|
||||
* used as the text and value columns respectively
|
||||
* @param object $result DB_result object
|
||||
* @param string $textCol (optional) Name of column to display as the OPTION text
|
||||
* @param string $valueCol (optional) Name of column to use as the OPTION value
|
||||
* @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
|
||||
*/
|
||||
function loadDbResult(&$result, $textCol=null, $valueCol=null, $values=null)
|
||||
{
|
||||
if (!is_object($result) || !is_a($result, 'db_result')) {
|
||||
return PEAR::raiseError('Argument 1 of HTML_Select::loadDbResult is not a valid DB_result');
|
||||
}
|
||||
if (isset($values)) {
|
||||
$this->setValue($values);
|
||||
}
|
||||
$fetchMode = ($textCol && $valueCol) ? DB_FETCHMODE_ASSOC : DB_FETCHMODE_ORDERED;
|
||||
while (is_array($row = $result->fetchRow($fetchMode)) ) {
|
||||
if ($fetchMode == DB_FETCHMODE_ASSOC) {
|
||||
$this->addOption($row[$textCol], $row[$valueCol]);
|
||||
} else {
|
||||
$this->addOption($row[0], $row[1]);
|
||||
}
|
||||
}
|
||||
return true;
|
||||
} // end func loadDbResult
|
||||
|
||||
// }}}
|
||||
// {{{ loadQuery()
|
||||
|
||||
/**
|
||||
* Queries a database and loads the options from the results
|
||||
*
|
||||
* @param mixed $conn Either an existing DB connection or a valid dsn
|
||||
* @param string $sql SQL query string
|
||||
* @param string $textCol (optional) Name of column to display as the OPTION text
|
||||
* @param string $valueCol (optional) Name of column to use as the OPTION value
|
||||
* @param mixed $values (optional) Array or comma delimited string of selected values
|
||||
* @since 1.1
|
||||
* @access public
|
||||
* @return void
|
||||
* @throws PEAR_Error
|
||||
*/
|
||||
function loadQuery(&$conn, $sql, $textCol=null, $valueCol=null, $values=null)
|
||||
{
|
||||
if (is_string($conn)) {
|
||||
require_once('DB.php');
|
||||
$dbConn = &DB::connect($conn, true);
|
||||
if (DB::isError($dbConn)) {
|
||||
return $dbConn;
|
||||
}
|
||||
} elseif (is_subclass_of($conn, "db_common")) {
|
||||
$dbConn = &$conn;
|
||||
} else {
|
||||
return PEAR::raiseError('Argument 1 of HTML_Select::loadQuery is not a valid type');
|
||||
}
|
||||
$result = $dbConn->query($sql);
|
||||
if (DB::isError($result)) {
|
||||
return $result;
|
||||
}
|
||||
$this->loadDbResult($result, $textCol, $valueCol, $values);
|
||||
$result->free();
|
||||
if (is_string($conn)) {
|
||||
$dbConn->disconnect();
|
||||
}
|
||||
return true;
|
||||
} // end func loadQuery
|
||||
|
||||
// }}}
|
||||
// {{{ load()
|
||||
|
||||
/**
|
||||
* 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
|
||||
*/
|
||||
function load(&$options, $param1=null, $param2=null, $param3=null, $param4=null)
|
||||
{
|
||||
switch (true) {
|
||||
case is_array($options):
|
||||
return $this->loadArray($options, $param1);
|
||||
break;
|
||||
case (is_a($options, 'db_result')):
|
||||
return $this->loadDbResult($options, $param1, $param2, $param3);
|
||||
break;
|
||||
case (is_string($options) && !empty($options) || is_subclass_of($options, "db_common")):
|
||||
return $this->loadQuery($options, $param1, $param2, $param3, $param4);
|
||||
break;
|
||||
}
|
||||
} // end func load
|
||||
|
||||
// }}}
|
||||
// {{{ toHtml()
|
||||
|
||||
/**
|
||||
* Returns the SELECT in HTML
|
||||
*
|
||||
* @since 1.0
|
||||
* @access public
|
||||
* @return string
|
||||
*/
|
||||
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 . "\t<option" . $this->_getAttrString($option['attr']) . '>' .
|
||||
$option['text'] . "</option>\n";
|
||||
}
|
||||
|
||||
return $strHtml . $tabs . '</select>';
|
||||
}
|
||||
} //end func toHtml
|
||||
|
||||
// }}}
|
||||
// {{{ getFrozenHtml()
|
||||
|
||||
/**
|
||||
* Returns the value of field without HTML tags
|
||||
*
|
||||
* @since 1.0
|
||||
* @access public
|
||||
* @return string
|
||||
*/
|
||||
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)? ' ': 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;
|
||||
} //end func getFrozenHtml
|
||||
|
||||
// }}}
|
||||
// {{{ exportValue()
|
||||
|
||||
/**
|
||||
* 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"
|
||||
*/
|
||||
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()) {
|
||||
return $this->_prepareValue($cleanValue[0], $assoc);
|
||||
} else {
|
||||
return $this->_prepareValue($cleanValue, $assoc);
|
||||
}
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ onQuickFormEvent()
|
||||
|
||||
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;
|
||||
} else {
|
||||
return parent::onQuickFormEvent($event, $arg, $caller);
|
||||
}
|
||||
}
|
||||
|
||||
// }}}
|
||||
} //end class HTML_QuickForm_select
|
||||
?>
|
||||
201
include/pear/HTML/QuickForm/static.php
Normal file
201
include/pear/HTML/QuickForm/static.php
Normal file
@@ -0,0 +1,201 @@
|
||||
<?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-2007 The PHP Group
|
||||
* @license http://www.php.net/license/3_01.txt PHP License 3.01
|
||||
* @version CVS: $Id: static.php,v 1.7 2007/05/29 18:34:36 avb Exp $
|
||||
* @link http://pear.php.net/package/HTML_QuickForm
|
||||
*/
|
||||
|
||||
/**
|
||||
* Base class for form elements
|
||||
*/
|
||||
require_once 'HTML/QuickForm/element.php';
|
||||
|
||||
/**
|
||||
* HTML class for static data
|
||||
*
|
||||
* @category HTML
|
||||
* @package HTML_QuickForm
|
||||
* @author Wojciech Gdela <eltehaem@poczta.onet.pl>
|
||||
* @version Release: 3.2.10
|
||||
* @since 2.7
|
||||
*/
|
||||
class HTML_QuickForm_static extends HTML_QuickForm_element {
|
||||
|
||||
// {{{ properties
|
||||
|
||||
/**
|
||||
* Display text
|
||||
* @var string
|
||||
* @access private
|
||||
*/
|
||||
var $_text = null;
|
||||
|
||||
// }}}
|
||||
// {{{ constructor
|
||||
|
||||
/**
|
||||
* Class constructor
|
||||
*
|
||||
* @param string $elementLabel (optional)Label
|
||||
* @param string $text (optional)Display text
|
||||
* @access public
|
||||
* @return void
|
||||
*/
|
||||
function HTML_QuickForm_static($elementName=null, $elementLabel=null, $text=null)
|
||||
{
|
||||
HTML_QuickForm_element::HTML_QuickForm_element($elementName, $elementLabel);
|
||||
$this->_persistantFreeze = false;
|
||||
$this->_type = 'static';
|
||||
$this->_text = $text;
|
||||
} //end constructor
|
||||
|
||||
// }}}
|
||||
// {{{ setName()
|
||||
|
||||
/**
|
||||
* Sets the element name
|
||||
*
|
||||
* @param string $name Element name
|
||||
* @access public
|
||||
* @return void
|
||||
*/
|
||||
function setName($name)
|
||||
{
|
||||
$this->updateAttributes(array('name'=>$name));
|
||||
} //end func setName
|
||||
|
||||
// }}}
|
||||
// {{{ getName()
|
||||
|
||||
/**
|
||||
* Returns the element name
|
||||
*
|
||||
* @access public
|
||||
* @return string
|
||||
*/
|
||||
function getName()
|
||||
{
|
||||
return $this->getAttribute('name');
|
||||
} //end func getName
|
||||
|
||||
// }}}
|
||||
// {{{ setText()
|
||||
|
||||
/**
|
||||
* Sets the text
|
||||
*
|
||||
* @param string $text
|
||||
* @access public
|
||||
* @return void
|
||||
*/
|
||||
function setText($text)
|
||||
{
|
||||
$this->_text = $text;
|
||||
} // end func setText
|
||||
|
||||
// }}}
|
||||
// {{{ setValue()
|
||||
|
||||
/**
|
||||
* 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);
|
||||
} // end func setValue
|
||||
|
||||
// }}}
|
||||
// {{{ toHtml()
|
||||
|
||||
/**
|
||||
* Returns the static text element in HTML
|
||||
*
|
||||
* @access public
|
||||
* @return string
|
||||
*/
|
||||
function toHtml()
|
||||
{
|
||||
return $this->_getTabs() . $this->_text;
|
||||
} //end func toHtml
|
||||
|
||||
// }}}
|
||||
// {{{ getFrozenHtml()
|
||||
|
||||
/**
|
||||
* Returns the value of field without HTML tags
|
||||
*
|
||||
* @access public
|
||||
* @return string
|
||||
*/
|
||||
function getFrozenHtml()
|
||||
{
|
||||
return $this->toHtml();
|
||||
} //end func getFrozenHtml
|
||||
|
||||
// }}}
|
||||
// {{{ 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
|
||||
* @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;
|
||||
} // end func onQuickFormEvent
|
||||
|
||||
// }}}
|
||||
// {{{ exportValue()
|
||||
|
||||
/**
|
||||
* We override this here because we don't want any values from static elements
|
||||
*/
|
||||
function exportValue(&$submitValues, $assoc = false)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
// }}}
|
||||
} //end class HTML_QuickForm_static
|
||||
?>
|
||||
89
include/pear/HTML/QuickForm/submit.php
Normal file
89
include/pear/HTML/QuickForm/submit.php
Normal file
@@ -0,0 +1,89 @@
|
||||
<?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-2007 The PHP Group
|
||||
* @license http://www.php.net/license/3_01.txt PHP License 3.01
|
||||
* @version CVS: $Id: submit.php,v 1.5 2007/05/29 18:34:36 avb Exp $
|
||||
* @link http://pear.php.net/package/HTML_QuickForm
|
||||
*/
|
||||
|
||||
/**
|
||||
* Base class for <input /> form elements
|
||||
*/
|
||||
require_once 'HTML/QuickForm/input.php';
|
||||
|
||||
/**
|
||||
* 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.10
|
||||
* @since 1.0
|
||||
*/
|
||||
class HTML_QuickForm_submit extends HTML_QuickForm_input
|
||||
{
|
||||
// {{{ constructor
|
||||
|
||||
/**
|
||||
* 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
|
||||
*/
|
||||
function HTML_QuickForm_submit($elementName=null, $value=null, $attributes=null)
|
||||
{
|
||||
HTML_QuickForm_input::HTML_QuickForm_input($elementName, null, $attributes);
|
||||
$this->setValue($value);
|
||||
$this->setType('submit');
|
||||
} //end constructor
|
||||
|
||||
// }}}
|
||||
// {{{ freeze()
|
||||
|
||||
/**
|
||||
* Freeze the element so that only its value is returned
|
||||
*
|
||||
* @access public
|
||||
* @return void
|
||||
*/
|
||||
function freeze()
|
||||
{
|
||||
return false;
|
||||
} //end func freeze
|
||||
|
||||
// }}}
|
||||
// {{{ exportValue()
|
||||
|
||||
/**
|
||||
* 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);
|
||||
}
|
||||
|
||||
// }}}
|
||||
} //end class HTML_QuickForm_submit
|
||||
?>
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user