/branches/livraison_menes/api/pear/Mail.php |
---|
New file |
0,0 → 1,211 |
<?php |
// |
// +----------------------------------------------------------------------+ |
// | PHP Version 4 | |
// +----------------------------------------------------------------------+ |
// | Copyright (c) 1997-2003 The PHP Group | |
// +----------------------------------------------------------------------+ |
// | This source file is subject to version 2.02 of the PHP license, | |
// | that is bundled with this package in the file LICENSE, and is | |
// | available at through the world-wide-web at | |
// | http://www.php.net/license/2_02.txt. | |
// | If you did not receive a copy of the PHP license and are unable to | |
// | obtain it through the world-wide-web, please send a note to | |
// | license@php.net so we can mail you a copy immediately. | |
// +----------------------------------------------------------------------+ |
// | Author: Chuck Hagenbuch <chuck@horde.org> | |
// +----------------------------------------------------------------------+ |
// |
// $Id: Mail.php,v 1.1 2005-11-24 16:15:46 florian Exp $ |
require_once 'PEAR.php'; |
/** |
* PEAR's Mail:: interface. Defines the interface for implementing |
* mailers under the PEAR hierarchy, and provides supporting functions |
* useful in multiple mailer backends. |
* |
* @access public |
* @version $Revision: 1.1 $ |
* @package Mail |
*/ |
class Mail |
{ |
/** |
* Line terminator used for separating header lines. |
* @var string |
*/ |
var $sep = "\r\n"; |
/** |
* Provides an interface for generating Mail:: objects of various |
* types |
* |
* @param string $driver The kind of Mail:: object to instantiate. |
* @param array $params The parameters to pass to the Mail:: object. |
* @return object Mail a instance of the driver class or if fails a PEAR Error |
* @access public |
*/ |
function &factory($driver, $params = array()) |
{ |
$driver = strtolower($driver); |
@include_once 'Mail/' . $driver . '.php'; |
$class = 'Mail_' . $driver; |
if (class_exists($class)) { |
$mailer = new $class($params); |
return $mailer; |
} else { |
return PEAR::raiseError('Unable to find class for driver ' . $driver); |
} |
} |
/** |
* Implements Mail::send() function using php's built-in mail() |
* command. |
* |
* @param mixed $recipients Either a comma-seperated list of recipients |
* (RFC822 compliant), or an array of recipients, |
* each RFC822 valid. This may contain recipients not |
* specified in the headers, for Bcc:, resending |
* messages, etc. |
* |
* @param array $headers The array of headers to send with the mail, in an |
* associative array, where the array key is the |
* header name (ie, 'Subject'), and the array value |
* is the header value (ie, 'test'). The header |
* produced from those values would be 'Subject: |
* test'. |
* |
* @param string $body The full text of the message body, including any |
* Mime parts, etc. |
* |
* @return mixed Returns true on success, or a PEAR_Error |
* containing a descriptive error message on |
* failure. |
* @access public |
* @deprecated use Mail_mail::send instead |
*/ |
function send($recipients, $headers, $body) |
{ |
// if we're passed an array of recipients, implode it. |
if (is_array($recipients)) { |
$recipients = implode(', ', $recipients); |
} |
// get the Subject out of the headers array so that we can |
// pass it as a seperate argument to mail(). |
$subject = ''; |
if (isset($headers['Subject'])) { |
$subject = $headers['Subject']; |
unset($headers['Subject']); |
} |
// flatten the headers out. |
list(,$text_headers) = Mail::prepareHeaders($headers); |
return mail($recipients, $subject, $body, $text_headers); |
} |
/** |
* Take an array of mail headers and return a string containing |
* text usable in sending a message. |
* |
* @param array $headers The array of headers to prepare, in an associative |
* array, where the array key is the header name (ie, |
* 'Subject'), and the array value is the header |
* value (ie, 'test'). The header produced from those |
* values would be 'Subject: test'. |
* |
* @return mixed Returns false if it encounters a bad address, |
* otherwise returns an array containing two |
* elements: Any From: address found in the headers, |
* and the plain text version of the headers. |
* @access private |
*/ |
function prepareHeaders($headers) |
{ |
$lines = array(); |
$from = null; |
foreach ($headers as $key => $value) { |
if (strcasecmp($key, 'From') === 0) { |
include_once 'Mail/RFC822.php'; |
$parser = &new Mail_RFC822(); |
$addresses = $parser->parseAddressList($value, 'localhost', false); |
if (PEAR::isError($addresses)) { |
return $addresses; |
} |
$from = $addresses[0]->mailbox . '@' . $addresses[0]->host; |
// Reject envelope From: addresses with spaces. |
if (strstr($from, ' ')) { |
return false; |
} |
$lines[] = $key . ': ' . $value; |
} elseif (strcasecmp($key, 'Received') === 0) { |
$received = array(); |
if (is_array($value)) { |
foreach ($value as $line) { |
$received[] = $key . ': ' . $line; |
} |
} |
else { |
$received[] = $key . ': ' . $value; |
} |
// Put Received: headers at the top. Spam detectors often |
// flag messages with Received: headers after the Subject: |
// as spam. |
$lines = array_merge($received, $lines); |
} else { |
// If $value is an array (i.e., a list of addresses), convert |
// it to a comma-delimited string of its elements (addresses). |
if (is_array($value)) { |
$value = implode(', ', $value); |
} |
$lines[] = $key . ': ' . $value; |
} |
} |
return array($from, join($this->sep, $lines) . $this->sep); |
} |
/** |
* Take a set of recipients and parse them, returning an array of |
* bare addresses (forward paths) that can be passed to sendmail |
* or an smtp server with the rcpt to: command. |
* |
* @param mixed Either a comma-seperated list of recipients |
* (RFC822 compliant), or an array of recipients, |
* each RFC822 valid. |
* |
* @return array An array of forward paths (bare addresses). |
* @access private |
*/ |
function parseRecipients($recipients) |
{ |
include_once 'Mail/RFC822.php'; |
// if we're passed an array, assume addresses are valid and |
// implode them before parsing. |
if (is_array($recipients)) { |
$recipients = implode(', ', $recipients); |
} |
// Parse recipients, leaving out all personal info. This is |
// for smtp recipients, etc. All relevant personal information |
// should already be in the headers. |
$addresses = Mail_RFC822::parseAddressList($recipients, 'localhost', false); |
$recipients = array(); |
if (is_array($addresses)) { |
foreach ($addresses as $ob) { |
$recipients[] = $ob->mailbox . '@' . $ob->host; |
} |
} |
return $recipients; |
} |
} |
/branches/livraison_menes/api/pear/A_LIRE.txt |
---|
New file |
0,0 → 1,16 |
Liste des packages PEAR : |
============================== |
Package Version State |
Auth 1.2.3 stable |
Calendar 0.5.2 beta |
DB 1.7.6 stable |
HTML_Common 1.2.1 stable |
HTML_QuickForm 3.2.5 stable |
HTML_Table 1.5 stable |
HTTP 1.3.5 stable |
Net_FTP 1.3.0 stable |
Net_SMTP 1.2.6 stable |
Net_Socket 1.0.6 stable |
Net_URL 1.0.14 stable |
PEAR 1.3.5 stable |
Text_Wiki 1.0.0 stable |
/branches/livraison_menes/api/pear/Calendar/Month/Weekdays.php |
---|
New file |
0,0 → 1,188 |
<?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.1 2005-09-30 14:58:00 ddelon Exp $ |
// |
/** |
* @package Calendar |
* @version $Id: Weekdays.php,v 1.1 2005-09-30 14:58:00 ddelon 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'.DIRECTORY_SEPARATOR.'Month'.DIRECTORY_SEPARATOR.'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=false) |
{ |
Calendar_Month::Calendar_Month($y, $m); |
$this->firstDay = $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'.DIRECTORY_SEPARATOR.'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(); |
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(); |
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(); |
} |
} |
} |
?> |
/branches/livraison_menes/api/pear/Calendar/Month/Weeks.php |
---|
New file |
0,0 → 1,140 |
<?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.1 2005-09-30 14:58:00 ddelon Exp $ |
// |
/** |
* @package Calendar |
* @version $Id: Weeks.php,v 1.1 2005-09-30 14:58:00 ddelon 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=false) |
{ |
Calendar_Month::Calendar_Month($y, $m); |
$this->firstDay = $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'.DIRECTORY_SEPARATOR.'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(); |
} |
} |
} |
} |
} |
?> |
/branches/livraison_menes/api/pear/Calendar/Year.php |
---|
New file |
0,0 → 1,119 |
<?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.1 2005-09-30 14:58:00 ddelon Exp $ |
// |
/** |
* @package Calendar |
* @version $Id: Year.php,v 1.1 2005-09-30 14:58:00 ddelon 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'; |
if (is_null($firstDay)) { |
$firstDay = $this->cE->getFirstDayOfWeek( |
$this->thisYear(), |
$this->thisMonth(), |
$this->thisDay() |
); |
} |
$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; |
} |
} |
} |
} |
} |
?> |
/branches/livraison_menes/api/pear/Calendar/Minute.php |
---|
New 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 2005-09-30 14:58:00 ddelon Exp $ |
// |
/** |
* @package Calendar |
* @version $Id: Minute.php,v 1.1 2005-09-30 14:58:00 ddelon 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; |
} |
} |
} |
} |
} |
?> |
/branches/livraison_menes/api/pear/Calendar/Table/Helper.php |
---|
New 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.1 2005-09-30 14:58:00 ddelon Exp $ |
// |
/** |
* @package Calendar |
* @version $Id: Helper.php,v 1.1 2005-09-30 14:58:00 ddelon 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=false) |
{ |
$this->calendar = & $calendar; |
$this->cE = & $calendar->getEngine(); |
if ($firstDay === false) { |
$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 == true) { |
$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); |
} |
} |
?> |
/branches/livraison_menes/api/pear/Calendar/docs/examples/11.php |
---|
New file |
0,0 → 1,109 |
<?php |
/** |
* Description: demonstrates a decorator used to "attach a payload" to a selection |
* to make it available when iterating over calendar children |
*/ |
if ( !@include 'Calendar/Calendar.php' ) { |
define('CALENDAR_ROOT','../../'); |
} |
require_once CALENDAR_ROOT.'Day.php'; |
require_once CALENDAR_ROOT.'Hour.php'; |
require_once CALENDAR_ROOT.'Decorator.php'; |
// Decorator to "attach" functionality to selected hours |
class DiaryEvent extends Calendar_Decorator { |
var $entry; |
function DiaryEvent($calendar) { |
Calendar_Decorator::Calendar_Decorator($calendar); |
} |
function setEntry($entry) { |
$this->entry = $entry; |
} |
function getEntry() { |
return $this->entry; |
} |
} |
// Create a day to view the hours for |
$Day = & new Calendar_Day(2003,10,24); |
// A sample query to get the data for today (NOT ACTUALLY USED HERE) |
$sql = " |
SELECT |
* |
FROM |
diary |
WHERE |
eventtime >= '".$Day->thisDay(TRUE)."' |
AND |
eventtime < '".$Day->nextDay(TRUE)."';"; |
// An array simulating data from a database |
$result = array ( |
array('eventtime'=>mktime(9,0,0,10,24,2003),'entry'=>'Meeting with sales team'), |
array('eventtime'=>mktime(11,0,0,10,24,2003),'entry'=>'Conference call with Widget Inc.'), |
array('eventtime'=>mktime(15,0,0,10,24,2003),'entry'=>'Presentation to board of directors') |
); |
// An array to place selected hours in |
$selection = array(); |
// Loop through the "database result" |
foreach ( $result as $row ) { |
$Hour = new Calendar_Hour(2000,1,1,1); // Create Hour with dummy values |
$Hour->setTimeStamp($row['eventtime']); // Set the real time with setTimeStamp |
// Create the decorator, passing it the Hour |
$DiaryEvent = new DiaryEvent($Hour); |
// Attach the payload |
$DiaryEvent->setEntry($row['entry']); |
// Add the decorator to the selection |
$selection[] = $DiaryEvent; |
} |
// Build the hours in that day, passing the selection |
$Day->build($selection); |
?> |
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN"> |
<html> |
<head> |
<title> Passing a Selection Payload with a Decorator </title> |
</head> |
<body> |
<h1>Passing a Selection "Payload" using a Decorator</h1> |
<table> |
<caption><b>Your Schedule for <?php echo ( date('D nS F Y',$Day->thisDay(TRUE)) ); ?></b></caption> |
<tr> |
<th width="5%">Time</th> |
<th>Entry</th> |
</tr> |
<?php |
while ( $Hour = & $Day->fetch() ) { |
$hour = $Hour->thisHour(); |
$minute = $Hour->thisMinute(); |
// Office hours only... |
if ( $hour >= 8 && $hour <= 18 ) { |
echo ( "<tr>\n" ); |
echo ( "<td>$hour:$minute</td>\n" ); |
// If the hour is selected, call the decorator method... |
if ( $Hour->isSelected() ) { |
echo ( "<td bgcolor=\"silver\">".$Hour->getEntry()."</td>\n" ); |
} else { |
echo ( "<td> </td>\n" ); |
} |
echo ( "</tr>\n" ); |
} |
} |
?> |
</table> |
<p>The query to fetch this data, with help from PEAR::Calendar, might be;</p> |
<pre> |
<?php echo ( $sql ); ?> |
</pre> |
</body> |
</html> |
/branches/livraison_menes/api/pear/Calendar/docs/examples/12.php |
---|
New file |
0,0 → 1,116 |
<?php |
/** |
* Description: a complete year |
*/ |
function getmicrotime(){ |
list($usec, $sec) = explode(" ",microtime()); |
return ((float)$usec + (float)$sec); |
} |
$start = getmicrotime(); |
if ( !@include 'Calendar/Calendar.php' ) { |
define('CALENDAR_ROOT','../../'); |
} |
require_once CALENDAR_ROOT.'Year.php'; |
define ('CALENDAR_MONTH_STATE',CALENDAR_USE_MONTH_WEEKDAYS); |
if ( !isset($_GET['year']) ) $_GET['year'] = date('Y'); |
$Year = new Calendar_Year($_GET['year']); |
$Year->build(); |
?> |
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN"> |
<html> |
<head> |
<title> <?php echo ( $Year->thisYear() ); ?> </title> |
<style type="text/css"> |
body { |
font-family: Georgia, serif; |
} |
caption.year { |
font-weight: bold; |
font-size: 120%; |
font-color: navy; |
} |
caption.month { |
font-size: 110%; |
font-color: navy; |
} |
table.month { |
border: thin groove #800080 |
} |
tr { |
vertical-align: top; |
} |
th, td { |
text-align: right; |
font-size: 70%; |
} |
#prev { |
float: left; |
font-size: 70%; |
} |
#next { |
float: right; |
font-size: 70%; |
} |
</style> |
</head> |
<body> |
<table> |
<caption class="year"> |
<?php echo ( $Year->thisYear() ); ?> |
<div id="next"> |
<a href="?year=<?php echo ( $Year->nextYear() ); ?>">>></a> |
</div> |
<div id="prev"> |
<a href="?year=<?php echo ( $Year->prevYear() ); ?>"><<</a> |
</div> |
</caption> |
<?php |
$i = 0; |
while ( $Month = $Year->fetch() ) { |
switch ( $i ) { |
case 0: |
echo ( "<tr>\n" ); |
break; |
case 3: |
case 6: |
case 9: |
echo ( "</tr>\n<tr>\n" ); |
break; |
case 12: |
echo ( "</tr>\n" ); |
break; |
} |
echo ( "<td>\n<table class=\"month\">\n" ); |
echo ( "<caption class=\"month\">".date('F',$Month->thisMonth(TRUE))."</caption>" ); |
echo ( "<tr>\n<th>M</th><th>T</th><th>W</th><th>T</th><th>F</th><th>S</th><th>S</th>\n</tr>" ); |
$Month->build(); |
while ( $Day = $Month->fetch() ) { |
if ( $Day->isFirst() ) { |
echo ( "<tr>\n" ); |
} |
if ( $Day->isEmpty() ) { |
echo ( "<td> </td>\n" ); |
} else { |
echo ( "<td>".$Day->thisDay()."</td>\n" ); |
} |
if ( $Day->isLast() ) { |
echo ( "</tr>\n" ); |
} |
} |
echo ( "</table>\n</td>\n" ); |
$i++; |
} |
?> |
</table> |
<p>Took: <?php echo ((getmicrotime()-$start)); ?></p> |
</body> |
</html> |
/branches/livraison_menes/api/pear/Calendar/docs/examples/13.php |
---|
New file |
0,0 → 1,99 |
<?php |
/** |
* Description: same as 1.php, but using the PEAR::Date engine |
* Notice the use of the CALENDAR_ENGINE constant, which |
* switches the calculation "engine" |
* Note: make sure PEAR::Date is a stable release!!! |
*/ |
function getmicrotime(){ |
list($usec, $sec) = explode(" ",microtime()); |
return ((float)$usec + (float)$sec); |
} |
// Switch to PEAR::Date engine |
define('CALENDAR_ENGINE','PearDate'); |
if ( !@include 'Calendar/Calendar.php' ) { |
define('CALENDAR_ROOT','../../'); |
} |
if (!isset($_GET['y'])) $_GET['y'] = 2003; |
if (!isset($_GET['m'])) $_GET['m'] = 8; |
if (!isset($_GET['d'])) $_GET['d'] = 9; |
if (!isset($_GET['h'])) $_GET['h'] = 12; |
if (!isset($_GET['i'])) $_GET['i'] = 34; |
if (!isset($_GET['s'])) $_GET['s'] = 46; |
switch ( @$_GET['view'] ) { |
default: |
$_GET['view'] = 'calendar_year'; |
case 'calendar_year': |
require_once CALENDAR_ROOT.'Year.php'; |
$c = new Calendar_Year($_GET['y']); |
break; |
case 'calendar_month': |
require_once CALENDAR_ROOT.'Month.php'; |
$c = new Calendar_Month($_GET['y'],$_GET['m']); |
break; |
case 'calendar_day': |
require_once CALENDAR_ROOT.'Day.php'; |
$c = new Calendar_Day($_GET['y'],$_GET['m'],$_GET['d']); |
break; |
case 'calendar_hour': |
require_once CALENDAR_ROOT.'Hour.php'; |
$c = new Calendar_Hour($_GET['y'],$_GET['m'],$_GET['d'],$_GET['h']); |
break; |
case 'calendar_minute': |
require_once CALENDAR_ROOT.'Minute.php'; |
$c = new Calendar_Minute($_GET['y'],$_GET['m'],$_GET['d'],$_GET['h'],$_GET['i']); |
break; |
case 'calendar_second': |
require_once CALENDAR_ROOT.'Second.php'; |
$c = new Calendar_Second($_GET['y'],$_GET['m'],$_GET['d'],$_GET['h'],$_GET['i'],$_GET['s']); |
break; |
} |
// Convert timestamp to human readable date |
$date = new Date($c->getTimestamp()); |
echo ( '<h1>Using PEAR::Date engine</h1>' ); |
echo ( 'Viewing: '.@$_GET['view'].'<br />' ); |
echo ( 'The time is now: '.$date->format('%Y %a %e %T').'<br >' ); |
$i = 1; |
echo ( '<h1>First Iteration</h1>' ); |
echo ( '<p>The first iteration is more "expensive", the calendar data |
structures having to be built.</p>' ); |
$start = getmicrotime(); |
$c->build(); |
while ( $e = $c->fetch() ) { |
$class = strtolower(get_class($e)); |
$link ="&y=".$e->thisYear()."&m=".$e->thisMonth()."&d=".$e->thisDay(). |
"&h=".$e->thisHour()."&i=".$e->thisMinute()."&s=".$e->thisSecond(); |
$method = 'this'.str_replace('calendar_','',$class); |
echo ( "<a href=\"".$_SERVER['PHP_SELF']."?view=".$class.$link."\">".$e->{$method}()."</a> : " ); |
if ( ($i % 10) == 0 ) { |
echo ( '<br>' ); |
} |
$i++; |
} |
echo ( '<p><b>Took: '.(getmicrotime()-$start).' seconds</b></p>' ); |
$i = 1; |
echo ( '<h1>Second Iteration</h1>' ); |
echo ( '<p>This second iteration is faster, the data structures |
being re-used</p>' ); |
$start = getmicrotime(); |
while ( $e = $c->fetch() ) { |
$class = strtolower(get_class($e)); |
$link ="&y=".$e->thisYear()."&m=".$e->thisMonth()."&d=".$e->thisDay(). |
"&h=".$e->thisHour()."&i=".$e->thisMinute()."&s=".$e->thisSecond(); |
$method = 'this'.str_replace('calendar_','',$class); |
echo ( "<a href=\"".$_SERVER['PHP_SELF']."?view=".$class.$link."\">".$e->{$method}()."</a> : " ); |
if ( ($i % 10) == 0 ) { |
echo ( '<br>' ); |
} |
$i++; |
} |
echo ( '<p><b>Took: '.(getmicrotime()-$start).' seconds</b></p>' ); |
?> |
/branches/livraison_menes/api/pear/Calendar/docs/examples/1.phps |
---|
Cannot display: file marked as a binary type. |
svn:mime-type = application/octet-stream |
/branches/livraison_menes/api/pear/Calendar/docs/examples/1.phps |
---|
New file |
Property changes: |
Added: svn:mime-type |
+application/octet-stream |
\ No newline at end of property |
/branches/livraison_menes/api/pear/Calendar/docs/examples/index.html |
---|
New file |
0,0 → 1,49 |
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" |
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> |
<html xmlns="http://www.w3.org/1999/xhtml" lang="en" xml:lang="en"> |
<head> |
<title>PEAR::Calendar Examples</title> |
<style type="text/css"> |
body { |
font-family: georgia, serif; |
} |
pre { |
background-color: silver; |
} |
code { |
color: navy; |
background-color: #e2e3e4; |
} |
</style> |
</head> |
<body> |
<h1>PEAR::Calendar Examples</h1> |
<p>$Id: index.html,v 1.1 2005-09-30 14:58:00 ddelon Exp $</p> |
<ul> |
<li><a href="1.php">1.php</a> [<a href="1.phps">src</a>] - shows basic usage, passing all the way down from <code>Calendar_Year</code> to <code>Calendar_Second</code> - more of a quick test it's working</li> |
<li><a href="2.php">2.php</a> [<a href="2.phps">src</a>] - shows how to build a tabular month using <code>Calendar_Month_Weeks</code>, <code>Calendar_Week</code>, <code>Calendar_Day</code> as well as selecting some dates.</li> |
<li><a href="3.php">3.php</a> [<a href="3.phps">src</a>] - shows how to build a tabular month using <code>Calendar_Month_Weekdays</code> and <code>Calendar_Day</code>, as well as selecting some dates (this method is faster).</li> |
<li><a href="4.php">4.php</a> [<a href="4.phps">src</a>] - shows how to use PEAR::Calendar for validation.</li> |
<li><a href="5.php">5.php</a> [<a href="5.phps">src</a>] - shows PEAR::Calendar in use to help generate a form.</li> |
<li><a href="6.php">6.php</a> [<a href="6.phps">src</a>] - a month and day "planner" calendar, which can be rendered both as HTML and WML.</li> |
<li><a href="7.php">7.php</a> [<a href="7.phps">src</a>] - a simple SOAP Calendar Server, using PEAR::SOAP and PEAR::Calendar</li> |
<li><a href="8.php">8.php</a> [<a href="8.phps">src</a>] - a WSDL SOAP client for the SOAP Calendar Server</li> |
<li><a href="9.php">9.php</a> [<a href="9.phps">src</a>] - quick example of i18n with <code>setlocale</code> (not working on SF)</li> |
<li><a href="10.php">10.php</a> [<a href="10.phps">src</a>] - an example of extending <code>Calendar_Decorator</code> to modify output</li> |
<li><a href="11.php">11.php</a> [<a href="11.phps">src</a>] - attaching a "payload" (e.g. results of a DB query) to a calendar using <code>Calendar_Decorator</code> to allow the payload to be available inside the main loop.</li> |
<li><a href="12.php">12.php</a> [<a href="12.phps">src</a>] - a complete year with months.</li> |
<li><a href="13.php">13.php</a> [<a href="13.phps">src</a>] - same as 1.php but using <code>Calendar_Engine_PearDate</code>, (see <a href="http://pear.php.net/Date">PEAR::Date</a>).</li> |
<li><a href="14.php">14.php</a> [<a href="14.phps">src</a>] - same as 3.php but using <code>Calendar_Engine_PearDate</code></li> |
<li><a href="15.php">15.php</a> [<a href="15.phps">src</a>] - paging through weeks </li> |
<li><a href="16.php">16.php</a> [<a href="16.phps">src</a>] - demonstrates using the Uri decorator. <i>Note</i> you should prefer <code>Calendar_Util_Uri</code> (see below) in most cases, for performance </li> |
<li><a href="17.php">17.php</a> [<a href="17.phps">src</a>] - demonstrates using the Textual decorator</li> |
<li><a href="18.php">18.php</a> [<a href="18.phps">src</a>] - demonstrates using the Wrapper decorator</li> |
<li><a href="19.php">19.php</a> [<a href="19.phps">src</a>] - demonstrates using the Weekday decorator</li> |
<li><a href="20.php">20.php</a> [<a href="20.phps">src</a>] - shows how to attach a "payload" spanning multiple days, with more than one entry per day</li> |
<li><a href="21.php">21.php</a> [<a href="21.phps">src</a>] - same as 12.php but using <code>Calendar_Month_Weeks</code> instead of <code>Calendar_Month_Weekdays</code> to allow the week in the year or week in the month to be displayed.</li> |
<li><a href="22.php">22.php</a> [<a href="22.phps">src</a>] - demonstrates use of <code>Calendar_Util_Uri</code>.</li> |
<li><a href="22.php">23.php</a> [<a href="23.phps">src</a>] - demonstrates use of <code>Calendar_Util_Textual</code>.</li> |
</ul> |
</body> |
</html> |
/branches/livraison_menes/api/pear/Calendar/docs/examples/14.php |
---|
New file |
0,0 → 1,141 |
<?php |
/** |
* Description: same as 3.php, but using the PEAR::Date engine |
* Note: make sure PEAR::Date is a stable release!!! |
*/ |
function getmicrotime(){ |
list($usec, $sec) = explode(" ",microtime()); |
return ((float)$usec + (float)$sec); |
} |
$start = getmicrotime(); |
// Switch to PEAR::Date engine |
define('CALENDAR_ENGINE', 'PearDate'); |
if (!@include 'Calendar'.DIRECTORY_SEPARATOR.'Calendar.php') { |
define('CALENDAR_ROOT','../../'); |
} |
require_once CALENDAR_ROOT.'Month/Weekdays.php'; |
require_once CALENDAR_ROOT.'Day.php'; |
// Initialize GET variables if not set |
if (!isset($_GET['y'])) $_GET['y'] = date('Y'); |
if (!isset($_GET['m'])) $_GET['m'] = date('m'); |
if (!isset($_GET['d'])) $_GET['d'] = date('d'); |
// Build the month |
$month = new Calendar_Month_Weekdays($_GET['y'], $_GET['m']); |
// Create an array of days which are "selected" |
// Used for Week::build() below |
$selectedDays = array ( |
new Calendar_Day($_GET['y'], $_GET['m'], $_GET['d']), |
new Calendar_Day($_GET['y'], 12, 25), |
); |
// Build the days in the month |
$month->build($selectedDays); |
// Construct strings for next/previous links |
$PMonth = $month->prevMonth('object'); // Get previous month as object |
$prev = $_SERVER['PHP_SELF'].'?y='.$PMonth->thisYear().'&m='.$PMonth->thisMonth().'&d='.$PMonth->thisDay(); |
$NMonth = $month->nextMonth('object'); |
$next = $_SERVER['PHP_SELF'].'?y='.$NMonth->thisYear().'&m='.$NMonth->thisMonth().'&d='.$NMonth->thisDay(); |
$thisDate = new Date($month->thisMonth('timestamp')); |
?> |
<!doctype html public "-//W3C//DTD HTML 4.0 Transitional//EN"> |
<html> |
<head> |
<title> Calendar using PEAR::Date Engine </title> |
<style text="text/css"> |
table { |
background-color: silver; |
} |
caption { |
font-family: verdana; |
font-size: 12px; |
background-color: while; |
} |
.prevMonth { |
font-size: 10px; |
text-align: left; |
} |
.nextMonth { |
font-size: 10px; |
text-align: right; |
} |
th { |
font-family: verdana; |
font-size: 11px; |
color: navy; |
text-align: right; |
} |
td { |
font-family: verdana; |
font-size: 11px; |
text-align: right; |
} |
.selected { |
background-color: yellow; |
} |
</style> |
</head> |
<body> |
<h2>Calendar using PEAR::Date Engine</h2> |
<table class="calendar"> |
<caption> |
<?php echo $thisDate->format('%B %Y'); ?> |
</caption> |
<tr> |
<th>M</th> |
<th>T</th> |
<th>W</th> |
<th>T</th> |
<th>F</th> |
<th>S</th> |
<th>S</th> |
</tr> |
<?php |
while ($day = $month->fetch()) { |
// Build a link string for each day |
$link = $_SERVER['PHP_SELF']. |
'?y='.$day->thisYear(). |
'&m='.$day->thisMonth(). |
'&d='.$day->thisDay(); |
// isFirst() to find start of week |
if ($day->isFirst()) |
echo "<tr>\n"; |
if ($day->isSelected()) { |
echo '<td class="selected">'.$day->thisDay().'</td>'."\n"; |
} else if ($day->isEmpty()) { |
echo '<td> </td>'."\n"; |
} else { |
echo '<td><a href="'.$link.'">'.$day->thisDay().'</a></td>'."\n"; |
} |
// isLast() to find end of week |
if ($day->isLast()) { |
echo "</tr>\n"; |
} |
} |
?> |
<tr> |
<td> |
<a href="<?php echo $prev; ?>" class="prevMonth"><< </a> |
</td> |
<td colspan="5"> </td> |
<td> |
<a href="<?php echo $next; ?>" class="nextMonth"> >></a> |
</td> |
</tr> |
</table> |
<?php |
echo '<p><b>Took: '.(getmicrotime()-$start).' seconds</b></p>'; |
?> |
</body> |
</html> |
/branches/livraison_menes/api/pear/Calendar/docs/examples/3.phps |
---|
Cannot display: file marked as a binary type. |
svn:mime-type = application/octet-stream |
/branches/livraison_menes/api/pear/Calendar/docs/examples/3.phps |
---|
New file |
Property changes: |
Added: svn:mime-type |
+application/octet-stream |
\ No newline at end of property |
/branches/livraison_menes/api/pear/Calendar/docs/examples/15.php |
---|
New file |
0,0 → 1,58 |
<?php |
/** |
* Shows more on how a week can be used |
*/ |
function getmicrotime() { |
list($usec, $sec) = explode(" ", microtime()); |
return ((float)$usec + (float)$sec); |
} |
$start = getmicrotime(); |
if (!@include 'Calendar/Calendar.php') { |
define('CALENDAR_ROOT', '../../'); |
} |
require_once CALENDAR_ROOT.'Week.php'; |
if (!isset($_GET['y'])) $_GET['y'] = date('Y'); |
if (!isset($_GET['m'])) $_GET['m'] = date('m'); |
if (!isset($_GET['d'])) $_GET['d'] = 1; |
// Build the month |
$Week = new Calendar_Week($_GET['y'], $_GET['m'], $_GET['d']); |
/* |
$Validator = $Week->getValidator(); |
if (!$Validator->isValidWeek()) { |
die ('Please enter a valid week!'); |
} |
*/ |
?> |
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN"> |
<html> |
<head> |
<title> Paging Weeks </title> |
</head> |
<body> |
<h1>Paging Weeks</h1> |
<h2>Week: <?php echo $Week->thisWeek().' '.date('F Y',$Week->thisMonth(true)); ?></h2> |
<?php |
$Week->build(); |
while ($Day = $Week->fetch()) { |
echo '<p>'.date('jS F',$Day->thisDay(true))."</p>\n"; |
} |
$days = $Week->fetchAll(); |
$prevWeek = $Week->prevWeek('array'); |
$prevWeekLink = $_SERVER['PHP_SELF']. |
'?y='.$prevWeek['year']. |
'&m='.$prevWeek['month']. |
'&d='.$prevWeek['day']; |
$nextWeek = $Week->nextWeek('array'); |
$nextWeekLink = $_SERVER['PHP_SELF']. |
'?y='.$nextWeek['year']. |
'&m='.$nextWeek['month']. |
'&d='.$nextWeek['day']; |
?> |
<p><a href="<?php echo $prevWeekLink; ?>"><<</a> | <a href="<?php echo $nextWeekLink; ?>">>></a></p> |
</body> |
</html> |
/branches/livraison_menes/api/pear/Calendar/docs/examples/16.php |
---|
New file |
0,0 → 1,31 |
<?php |
/** |
* Description: demonstrates using the Uri decorator |
*/ |
if (!@include 'Calendar/Calendar.php') { |
define('CALENDAR_ROOT', '../../'); |
} |
require_once CALENDAR_ROOT.'Month/Weekdays.php'; |
require_once CALENDAR_ROOT.'Decorator/Uri.php'; |
if (!isset($_GET['jahr'])) $_GET['jahr'] = date('Y'); |
if (!isset($_GET['monat'])) $_GET['monat'] = date('m'); |
// Build the month |
$Calendar = new Calendar_Month_Weekdays($_GET['jahr'], $_GET['monat']); |
echo ( '<p>The current month is ' |
.$Calendar->thisMonth().' of year '.$Calendar->thisYear().'</p>'); |
$Uri = & new Calendar_Decorator_Uri($Calendar); |
$Uri->setFragments('jahr','monat'); |
// $Uri->setSeperator('/'); // Default is & |
// $Uri->setScalar(); // Omit variable names |
echo ( "<pre>Previous Uri:\t".$Uri->prev('month')."\n" ); |
echo ( "This Uri:\t".$Uri->this('month')."\n" ); |
echo ( "Next Uri:\t".$Uri->next('month')."\n</pre>" ); |
?> |
<p> |
<a href="<?php echo($_SERVER['PHP_SELF'].'?'.$Uri->prev('month'));?>">Prev</a> : |
<a href="<?php echo($_SERVER['PHP_SELF'].'?'.$Uri->next('month'));?>">Next</a> |
</p> |
/branches/livraison_menes/api/pear/Calendar/docs/examples/5.phps |
---|
Cannot display: file marked as a binary type. |
svn:mime-type = application/octet-stream |
/branches/livraison_menes/api/pear/Calendar/docs/examples/5.phps |
---|
New file |
Property changes: |
Added: svn:mime-type |
+application/octet-stream |
\ No newline at end of property |
/branches/livraison_menes/api/pear/Calendar/docs/examples/17.php |
---|
New file |
0,0 → 1,71 |
<?php |
/** |
* Description: demonstrates using the Textual decorator |
*/ |
if (!@include 'Calendar'.DIRECTORY_SEPARATOR.'Calendar.php') { |
define('CALENDAR_ROOT', '../../'); |
} |
require_once CALENDAR_ROOT.'Day.php'; |
require_once CALENDAR_ROOT.'Month'.DIRECTORY_SEPARATOR.'Weekdays.php'; |
require_once CALENDAR_ROOT.'Decorator'.DIRECTORY_SEPARATOR.'Textual.php'; |
// Could change language like this |
// setlocale (LC_TIME, "de_DE"); // Unix based (probably) |
// setlocale (LC_TIME, "ge"); // Windows |
echo "<hr>Calling: Calendar_Decorator_Textual::monthNames('long');<pre>"; |
print_r(Calendar_Decorator_Textual::monthNames('long')); |
echo '</pre>'; |
echo "<hr>Calling: Calendar_Decorator_Textual::weekdayNames('two');<pre>"; |
print_r(Calendar_Decorator_Textual::weekdayNames('two')); |
echo '</pre>'; |
echo "<hr>Creating: new Calendar_Day(date('Y'), date('n'), date('d'));<br />"; |
$Calendar = new Calendar_Day(date('Y'), date('n'), date('d')); |
// Decorate |
$Textual = & new Calendar_Decorator_Textual($Calendar); |
echo '<hr>Previous month is: '.$Textual->prevMonthName('two').'<br />'; |
echo 'This month is: '.$Textual->thisMonthName('short').'<br />'; |
echo 'Next month is: '.$Textual->nextMonthName().'<br /><hr />'; |
echo 'Previous day is: '.$Textual->prevDayName().'<br />'; |
echo 'This day is: '.$Textual->thisDayName('short').'<br />'; |
echo 'Next day is: '.$Textual->nextDayName('one').'<br /><hr />'; |
echo "Creating: new Calendar_Month_Weekdays(date('Y'), date('n'), 6); - Saturday is first day of week<br />"; |
$Calendar = new Calendar_Month_Weekdays(date('Y'), date('n'), 6); |
// Decorate |
$Textual = & new Calendar_Decorator_Textual($Calendar); |
?> |
<p>Rendering calendar....</p> |
<table> |
<caption><?php echo $Textual->thisMonthName().' '.$Textual->thisYear(); ?></caption> |
<tr> |
<?php |
$dayheaders = $Textual->orderedWeekdays('short'); |
foreach ($dayheaders as $dayheader) { |
echo '<th>'.$dayheader.'</th>'; |
} |
?> |
</tr> |
<?php |
$Calendar->build(); |
while ($Day = $Calendar->fetch()) { |
if ($Day->isFirst()) { |
echo "<tr>\n"; |
} |
if ($Day->isEmpty()) { |
echo '<td> </td>'; |
} else { |
echo '<td>'.$Day->thisDay().'</td>'; |
} |
if ($Day->isLast()) { |
echo "</tr>\n"; |
} |
} |
?> |
</table> |
/branches/livraison_menes/api/pear/Calendar/docs/examples/18.php |
---|
New file |
0,0 → 1,36 |
<?php |
/** |
* Description: demonstrates using the Wrapper decorator |
*/ |
if (!@include 'Calendar/Calendar.php') { |
define('CALENDAR_ROOT', '../../'); |
} |
require_once CALENDAR_ROOT.'Month.php'; |
require_once CALENDAR_ROOT.'Decorator.php'; // Not really needed but added to help this make sense |
require_once CALENDAR_ROOT.'Decorator/Wrapper.php'; |
class MyBoldDecorator extends Calendar_Decorator |
{ |
function MyBoldDecorator(&$Calendar) |
{ |
parent::Calendar_Decorator($Calendar); |
} |
function thisDay() |
{ |
return '<b>'.parent::thisDay().'</b>'; |
} |
} |
$Month = new Calendar_Month(date('Y'), date('n')); |
$Wrapper = & new Calendar_Decorator_Wrapper($Month); |
$Wrapper->build(); |
echo '<h2>The Wrapper decorator</h2>'; |
echo '<i>Day numbers are rendered in bold</i><br /> <br />'; |
while ($DecoratedDay = $Wrapper->fetch('MyBoldDecorator')) { |
echo $DecoratedDay->thisDay().'<br />'; |
} |
?> |
/branches/livraison_menes/api/pear/Calendar/docs/examples/7.phps |
---|
Cannot display: file marked as a binary type. |
svn:mime-type = application/octet-stream |
/branches/livraison_menes/api/pear/Calendar/docs/examples/7.phps |
---|
New file |
Property changes: |
Added: svn:mime-type |
+application/octet-stream |
\ No newline at end of property |
/branches/livraison_menes/api/pear/Calendar/docs/examples/19.php |
---|
New file |
0,0 → 1,24 |
<?php |
/** |
* Description: demonstrates using the Weekday decorator |
*/ |
if (!@include 'Calendar'.DIRECTORY_SEPARATOR.'Calendar.php') { |
define('CALENDAR_ROOT', '../../'); |
} |
require_once CALENDAR_ROOT.'Day.php'; |
require_once CALENDAR_ROOT.'Decorator/Weekday.php'; |
$Day = new Calendar_Day(date('Y'), date('n'),date('d')); |
$WeekDay = & new Calendar_Decorator_Weekday($Day); |
// $WeekDay->setFirstDay(0); // Make Sunday first Day |
echo 'Yesterday: '.$WeekDay->prevWeekDay().'<br>'; |
echo 'Today: '.$WeekDay->thisWeekDay().'<br>'; |
echo 'Tomorrow: '.$WeekDay->nextWeekDay().'<br>'; |
$WeekDay->build(); |
echo 'Hours today:<br>'; |
while ( $Hour = $WeekDay->fetch() ) { |
echo $Hour->thisHour().'<br>'; |
} |
?> |
/branches/livraison_menes/api/pear/Calendar/docs/examples/9.phps |
---|
Cannot display: file marked as a binary type. |
svn:mime-type = application/octet-stream |
/branches/livraison_menes/api/pear/Calendar/docs/examples/9.phps |
---|
New file |
Property changes: |
Added: svn:mime-type |
+application/octet-stream |
\ No newline at end of property |
/branches/livraison_menes/api/pear/Calendar/docs/examples/10.phps |
---|
Cannot display: file marked as a binary type. |
svn:mime-type = application/octet-stream |
/branches/livraison_menes/api/pear/Calendar/docs/examples/10.phps |
---|
New file |
Property changes: |
Added: svn:mime-type |
+application/octet-stream |
\ No newline at end of property |
/branches/livraison_menes/api/pear/Calendar/docs/examples/20.phps |
---|
Cannot display: file marked as a binary type. |
svn:mime-type = application/octet-stream |
/branches/livraison_menes/api/pear/Calendar/docs/examples/20.phps |
---|
New file |
Property changes: |
Added: svn:mime-type |
+application/octet-stream |
\ No newline at end of property |
/branches/livraison_menes/api/pear/Calendar/docs/examples/12.phps |
---|
Cannot display: file marked as a binary type. |
svn:mime-type = application/octet-stream |
/branches/livraison_menes/api/pear/Calendar/docs/examples/12.phps |
---|
New file |
Property changes: |
Added: svn:mime-type |
+application/octet-stream |
\ No newline at end of property |
/branches/livraison_menes/api/pear/Calendar/docs/examples/22.phps |
---|
Cannot display: file marked as a binary type. |
svn:mime-type = application/octet-stream |
/branches/livraison_menes/api/pear/Calendar/docs/examples/22.phps |
---|
New file |
Property changes: |
Added: svn:mime-type |
+application/octet-stream |
\ No newline at end of property |
/branches/livraison_menes/api/pear/Calendar/docs/examples/14.phps |
---|
Cannot display: file marked as a binary type. |
svn:mime-type = application/octet-stream |
/branches/livraison_menes/api/pear/Calendar/docs/examples/14.phps |
---|
New file |
Property changes: |
Added: svn:mime-type |
+application/octet-stream |
\ No newline at end of property |
/branches/livraison_menes/api/pear/Calendar/docs/examples/16.phps |
---|
Cannot display: file marked as a binary type. |
svn:mime-type = application/octet-stream |
/branches/livraison_menes/api/pear/Calendar/docs/examples/16.phps |
---|
New file |
Property changes: |
Added: svn:mime-type |
+application/octet-stream |
\ No newline at end of property |
/branches/livraison_menes/api/pear/Calendar/docs/examples/18.phps |
---|
Cannot display: file marked as a binary type. |
svn:mime-type = application/octet-stream |
/branches/livraison_menes/api/pear/Calendar/docs/examples/18.phps |
---|
New file |
Property changes: |
Added: svn:mime-type |
+application/octet-stream |
\ No newline at end of property |
/branches/livraison_menes/api/pear/Calendar/docs/examples/20.php |
---|
New file |
0,0 → 1,314 |
<?php |
/** |
* Description: demonstrates a decorator used to "attach a payload" to a selection |
* to make it available when iterating over calendar children |
*/ |
//if you use ISO-8601 dates, switch to PearDate engine |
define('CALENDAR_ENGINE', 'PearDate'); |
if ( !@include 'Calendar/Calendar.php' ) { |
define('CALENDAR_ROOT','../../'); |
} |
require_once CALENDAR_ROOT . 'Month/Weekdays.php'; |
require_once CALENDAR_ROOT . 'Day.php'; |
require_once CALENDAR_ROOT . 'Decorator.php'; |
// accepts multiple entries |
class DiaryEvent extends Calendar_Decorator |
{ |
var $entries = array(); |
function DiaryEvent($calendar) { |
Calendar_Decorator::Calendar_Decorator($calendar); |
} |
function addEntry($entry) { |
$this->entries[] = $entry; |
} |
function getEntry() { |
$entry = each($this->entries); |
if ($entry) { |
return $entry['value']; |
} else { |
reset($this->entries); |
return false; |
} |
} |
} |
class MonthPayload_Decorator extends Calendar_Decorator |
{ |
//Calendar engine |
var $cE; |
var $tableHelper; |
var $year; |
var $month; |
var $firstDay = false; |
function build($events=array()) |
{ |
require_once CALENDAR_ROOT . 'Day.php'; |
require_once CALENDAR_ROOT . 'Table/Helper.php'; |
$this->tableHelper = & new Calendar_Table_Helper($this, $this->firstDay); |
$this->cE = & $this->getEngine(); |
$this->year = $this->thisYear(); |
$this->month = $this->thisMonth(); |
$daysInMonth = $this->cE->getDaysInMonth($this->year, $this->month); |
for ($i=1; $i<=$daysInMonth; $i++) { |
$Day = new Calendar_Day(2000,1,1); // Create Day with dummy values |
$Day->setTimeStamp($this->cE->dateToStamp($this->year, $this->month, $i)); |
$this->children[$i] = new DiaryEvent($Day); |
} |
if (count($events) > 0) { |
$this->setSelection($events); |
} |
Calendar_Month_Weekdays::buildEmptyDaysBefore(); |
Calendar_Month_Weekdays::shiftDays(); |
Calendar_Month_Weekdays::buildEmptyDaysAfter(); |
Calendar_Month_Weekdays::setWeekMarkers(); |
return true; |
} |
function setSelection($events) |
{ |
$daysInMonth = $this->cE->getDaysInMonth($this->year, $this->month); |
for ($i=1; $i<=$daysInMonth; $i++) { |
$stamp1 = $this->cE->dateToStamp($this->year, $this->month, $i); |
$stamp2 = $this->cE->dateToStamp($this->year, $this->month, $i+1); |
foreach ($events as $event) { |
if (($stamp1 >= $event['start'] && $stamp1 < $event['end']) || |
($stamp2 >= $event['start'] && $stamp2 < $event['end']) || |
($stamp1 <= $event['start'] && $stamp2 > $event['end']) |
) { |
$this->children[$i]->addEntry($event); |
$this->children[$i]->setSelected(); |
} |
} |
} |
} |
function fetch() |
{ |
$child = each($this->children); |
if ($child) { |
return $child['value']; |
} else { |
reset($this->children); |
return false; |
} |
} |
} |
// Calendar instance used to get the dates in the preferred format: |
// you can switch Calendar Engine and the example still works |
$cal = new Calendar; |
$events = array(); |
//add some events |
$events[] = array( |
'start' => $cal->cE->dateToStamp(2004, 6, 1, 10), |
'end' => $cal->cE->dateToStamp(2004, 6, 1, 12), |
'desc' => 'Important meeting' |
); |
$events[] = array( |
'start' => $cal->cE->dateToStamp(2004, 6, 1, 21), |
'end' => $cal->cE->dateToStamp(2004, 6, 1, 23, 59), |
'desc' => 'Dinner with the boss' |
); |
$events[] = array( |
'start' => $cal->cE->dateToStamp(2004, 6, 5), |
'end' => $cal->cE->dateToStamp(2004, 6, 10, 23, 59), |
'desc' => 'Holidays!' |
); |
$Month = & new Calendar_Month_Weekdays(2004, 6); |
$MonthDecorator = new MonthPayload_Decorator($Month); |
$MonthDecorator->build($events); |
?> |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ text-align: center; |
+ background-color: #e7e3e7; |
+ padding: 5pt; |
+ |
+ |
+ |
+ |
+ |
+ |
+ text-align: left; |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+div.dayNumber { |
+ text-align: right; |
+ background-color: #f8f8f8; |
+ border-bottom: 1px solid #ccc; |
+} |
+ul { |
+ margin-left: 0; |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+<body> |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ echo '<td class="calCell'; |
+ if ($Day->isSelected()) { |
+ echo ' calCellBusy'; |
+ } elseif ($Day->isEmpty()) { |
+ echo ' calCellEmpty'; |
+ } |
+ echo '">'; |
+ echo '<div class="dayNumber">'.$Day->thisDay().'</div>'; |
+ |
+ |
+ |
+ |
+ echo '<div class="dayContents"><ul>'; |
+ while ($entry = $Day->getEntry()) { |
+ echo '<li>'.$entry['desc'].'</li>'; |
+ //you can print the time range as well |
+ } |
+ echo '</ul></div>'; |
+ } |
+ |
+ |
+ |
+ echo "</tr>\n"; |
+ |
+ |
+ |
+ |
+ |
+</html> |
\ No newline at end of file |
/branches/livraison_menes/api/pear/Calendar/docs/examples/21.php |
---|
New file |
0,0 → 1,139 |
<?php |
/** |
* Description: a complete year with numeric week numbers |
*/ |
function getmicrotime(){ |
list($usec, $sec) = explode(" ",microtime()); |
return ((float)$usec + (float)$sec); |
} |
$start = getmicrotime(); |
if (!@include 'Calendar/Calendar.php') { |
define('CALENDAR_ROOT', '../../'); |
} |
require_once CALENDAR_ROOT.'Year.php'; |
require_once CALENDAR_ROOT.'Month/Weeks.php'; |
define ('CALENDAR_MONTH_STATE',CALENDAR_USE_MONTH_WEEKS); |
if (!isset($_GET['year'])) $_GET['year'] = date('Y'); |
$week_types = array( |
'n_in_year', |
'n_in_month', |
); |
if (!isset($_GET['week_type']) || !in_array($_GET['week_type'],$week_types) ) { |
$_GET['week_type'] = 'n_in_year'; |
} |
$Year = new Calendar_Year($_GET['year']); |
$Year->build(); |
?> |
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN"> |
<html> |
<head> |
<title> <?php echo $Year->thisYear(); ?> </title> |
<style type="text/css"> |
body { |
font-family: Georgia, serif; |
} |
caption.year { |
font-weight: bold; |
font-size: 120%; |
font-color: navy; |
} |
caption.month { |
font-size: 110%; |
font-color: navy; |
} |
table.month { |
border: thin groove #800080 |
} |
tr { |
vertical-align: top; |
} |
th, td { |
text-align: right; |
font-size: 70%; |
} |
#prev { |
float: left; |
font-size: 70%; |
} |
#next { |
float: right; |
font-size: 70%; |
} |
#week_type { |
float: none; |
font-size: 70%; |
} |
.weekNumbers { |
background-color: #e5e5f5; |
padding-right: 3pt; |
} |
</style> |
</head> |
<body> |
<table> |
<caption class="year"> |
<?php echo $Year->thisYear(); ?> |
<div id="next"> |
<a href="?year=<?php echo $Year->nextYear(); ?>&week_type=<?php echo $_GET['week_type']; ?>">>></a> |
</div> |
<div id="prev"> |
<a href="?year=<?php echo $Year->prevYear(); ?>&week_type=<?php echo $_GET['week_type']; ?>"><<</a> |
</div> |
<div id="week_type"> |
<a href="?year=<?php echo $Year->thisYear(); ?>&week_type=n_in_year">Weeks by Year</a> : |
<a href="?year=<?php echo $Year->thisYear(); ?>&week_type=n_in_month">Weeks by Month</a> |
</div> |
</caption> |
<?php |
$i = 0; |
while ($Month = $Year->fetch()) { |
switch ($i) { |
case 0: |
echo "<tr>\n"; |
break; |
case 3: |
case 6: |
case 9: |
echo "</tr>\n<tr>\n"; |
break; |
case 12: |
echo "</tr>\n"; |
break; |
} |
echo "<td>\n<table class=\"month\">\n"; |
echo '<caption class="month">'.date('F', $Month->thisMonth(TRUE)).'</caption>'; |
echo '<colgroup><col class="weekNumbers"><col span="7"></colgroup>'."\n"; |
echo "<tr>\n<th>Week</th><th>M</th><th>T</th><th>W</th><th>T</th><th>F</th><th>S</th><th>S</th>\n</tr>"; |
$Month->build(); |
while ($Week = $Month->fetch()) { |
echo "<tr>\n"; |
echo '<td>'.$Week->thisWeek($_GET['week_type'])."</td>\n"; |
$Week->build(); |
while ($Day = $Week->fetch()) { |
if ($Day->isEmpty()) { |
echo "<td> </td>\n"; |
} else { |
echo "<td>".$Day->thisDay()."</td>\n"; |
} |
} |
} |
echo "</table>\n</td>\n"; |
$i++; |
} |
?> |
</table> |
<p>Took: <?php echo ((getmicrotime()-$start)); ?></p> |
</body> |
</html> |
/branches/livraison_menes/api/pear/Calendar/docs/examples/22.php |
---|
New file |
0,0 → 1,46 |
<?php |
/** |
* Description: demonstrates using the Uri util |
*/ |
if (!@include 'Calendar/Calendar.php') { |
define('CALENDAR_ROOT', '../../'); |
} |
require_once CALENDAR_ROOT.'Month/Weekdays.php'; |
require_once CALENDAR_ROOT.'Util/Uri.php'; |
if (!isset($_GET['jahr'])) $_GET['jahr'] = date('Y'); |
if (!isset($_GET['monat'])) $_GET['monat'] = date('m'); |
// Build the month |
$Calendar = new Calendar_Month_Weekdays($_GET['jahr'], $_GET['monat']); |
echo ( '<p>The current month is ' |
.$Calendar->thisMonth().' of year '.$Calendar->thisYear().'</p>'); |
$Uri = & new Calendar_Util_Uri('jahr','monat'); |
$Uri->setFragments('jahr','monat'); |
echo "\"Vector\" URIs<pre>"; |
echo ( "Previous Uri:\t".htmlentities($Uri->prev($Calendar, 'month'))."\n" ); |
echo ( "This Uri:\t".htmlentities($Uri->this($Calendar, 'month'))."\n" ); |
echo ( "Next Uri:\t".htmlentities($Uri->next($Calendar, 'month'))."\n" ); |
echo "</pre>"; |
// Switch to scalar URIs |
$Uri->separator = '/'; // Default is & |
$Uri->scalar = true; // Omit variable names |
echo "\"Scalar\" URIs<pre>"; |
echo ( "Previous Uri:\t".$Uri->prev($Calendar, 'month')."\n" ); |
echo ( "This Uri:\t".$Uri->this($Calendar, 'month')."\n" ); |
echo ( "Next Uri:\t".$Uri->next($Calendar, 'month')."\n" ); |
echo "</pre>"; |
// Restore the vector URIs |
$Uri->separator = '&'; |
$Uri->scalar = false; |
?> |
<p> |
<a href="<?php echo($_SERVER['PHP_SELF'].'?'.$Uri->prev($Calendar, 'month'));?>">Prev</a> : |
<a href="<?php echo($_SERVER['PHP_SELF'].'?'.$Uri->next($Calendar, 'month'));?>">Next</a> |
</p> |
/branches/livraison_menes/api/pear/Calendar/docs/examples/23.php |
---|
New file |
0,0 → 1,66 |
<?php |
/** |
* Description: demonstrates using the Textual util |
*/ |
if (!@include 'Calendar'.DIRECTORY_SEPARATOR.'Calendar.php') { |
define('CALENDAR_ROOT', '../../'); |
} |
require_once CALENDAR_ROOT.'Day.php'; |
require_once CALENDAR_ROOT.'Month'.DIRECTORY_SEPARATOR.'Weekdays.php'; |
require_once CALENDAR_ROOT.'Util'.DIRECTORY_SEPARATOR.'Textual.php'; |
// Could change language like this |
// setlocale (LC_TIME, "de_DE"); // Unix based (probably) |
// setlocale (LC_TIME, "ge"); // Windows |
echo "<hr>Calling: Calendar_Util_Textual::monthNames('long');<pre>"; |
print_r(Calendar_Util_Textual::monthNames('long')); |
echo '</pre>'; |
echo "<hr>Calling: Calendar_Util_Textual::weekdayNames('two');<pre>"; |
print_r(Calendar_Util_Textual::weekdayNames('two')); |
echo '</pre>'; |
echo "<hr>Creating: new Calendar_Day(date('Y'), date('n'), date('d'));<br />"; |
$Calendar = new Calendar_Day(date('Y'), date('n'), date('d')); |
echo '<hr>Previous month is: '.Calendar_Util_Textual::prevMonthName($Calendar,'two').'<br />'; |
echo 'This month is: '.Calendar_Util_Textual::thisMonthName($Calendar,'short').'<br />'; |
echo 'Next month is: '.Calendar_Util_Textual::nextMonthName($Calendar).'<br /><hr />'; |
echo 'Previous day is: '.Calendar_Util_Textual::prevDayName($Calendar).'<br />'; |
echo 'This day is: '.Calendar_Util_Textual::thisDayName($Calendar,'short').'<br />'; |
echo 'Next day is: '.Calendar_Util_Textual::nextDayName($Calendar,'one').'<br /><hr />'; |
echo "Creating: new Calendar_Month_Weekdays(date('Y'), date('n'), 6); - Saturday is first day of week<br />"; |
$Calendar = new Calendar_Month_Weekdays(date('Y'), date('n'), 6); |
?> |
<p>Rendering calendar....</p> |
<table> |
<caption><?php echo Calendar_Util_Textual::thisMonthName($Calendar).' '.$Calendar->thisYear(); ?></caption> |
<tr> |
<?php |
$dayheaders = Calendar_Util_Textual::orderedWeekdays($Calendar,'short'); |
foreach ($dayheaders as $dayheader) { |
echo '<th>'.$dayheader.'</th>'; |
} |
?> |
</tr> |
<?php |
$Calendar->build(); |
while ($Day = $Calendar->fetch()) { |
if ($Day->isFirst()) { |
echo "<tr>\n"; |
} |
if ($Day->isEmpty()) { |
echo '<td> </td>'; |
} else { |
echo '<td>'.$Day->thisDay().'</td>'; |
} |
if ($Day->isLast()) { |
echo "</tr>\n"; |
} |
} |
?> |
</table> |
/branches/livraison_menes/api/pear/Calendar/docs/examples/2.phps |
---|
Cannot display: file marked as a binary type. |
svn:mime-type = application/octet-stream |
/branches/livraison_menes/api/pear/Calendar/docs/examples/2.phps |
---|
New file |
Property changes: |
Added: svn:mime-type |
+application/octet-stream |
\ No newline at end of property |
/branches/livraison_menes/api/pear/Calendar/docs/examples/4.phps |
---|
Cannot display: file marked as a binary type. |
svn:mime-type = application/octet-stream |
/branches/livraison_menes/api/pear/Calendar/docs/examples/4.phps |
---|
New file |
Property changes: |
Added: svn:mime-type |
+application/octet-stream |
\ No newline at end of property |
/branches/livraison_menes/api/pear/Calendar/docs/examples/6.phps |
---|
Cannot display: file marked as a binary type. |
svn:mime-type = application/octet-stream |
/branches/livraison_menes/api/pear/Calendar/docs/examples/6.phps |
---|
New file |
Property changes: |
Added: svn:mime-type |
+application/octet-stream |
\ No newline at end of property |
/branches/livraison_menes/api/pear/Calendar/docs/examples/8.phps |
---|
Cannot display: file marked as a binary type. |
svn:mime-type = application/octet-stream |
/branches/livraison_menes/api/pear/Calendar/docs/examples/8.phps |
---|
New file |
Property changes: |
Added: svn:mime-type |
+application/octet-stream |
\ No newline at end of property |
/branches/livraison_menes/api/pear/Calendar/docs/examples/1.php |
---|
New file |
0,0 → 1,92 |
<?php |
/** |
* Description: Passes through all main calendar classes, beginning with year |
* and down to seconds, skipping weeks. Useful to test Calendar is (basically) |
* working correctly |
* |
*/ |
function getmicrotime(){ |
list($usec, $sec) = explode(" ",microtime()); |
return ((float)$usec + (float)$sec); |
} |
if ( !@include 'Calendar/Calendar.php' ) { |
define('CALENDAR_ROOT','../../'); |
} |
if (!isset($_GET['y'])) $_GET['y'] = 2003; |
if (!isset($_GET['m'])) $_GET['m'] = 8; |
if (!isset($_GET['d'])) $_GET['d'] = 9; |
if (!isset($_GET['h'])) $_GET['h'] = 12; |
if (!isset($_GET['i'])) $_GET['i'] = 34; |
if (!isset($_GET['s'])) $_GET['s'] = 46; |
switch ( @$_GET['view'] ) { |
default: |
$_GET['view'] = 'calendar_year'; |
case 'calendar_year': |
require_once CALENDAR_ROOT.'Year.php'; |
$c = new Calendar_Year($_GET['y']); |
break; |
case 'calendar_month': |
require_once CALENDAR_ROOT.'Month.php'; |
$c = new Calendar_Month($_GET['y'],$_GET['m']); |
break; |
case 'calendar_day': |
require_once CALENDAR_ROOT.'Day.php'; |
$c = new Calendar_Day($_GET['y'],$_GET['m'],$_GET['d']); |
break; |
case 'calendar_hour': |
require_once CALENDAR_ROOT.'Hour.php'; |
$c = new Calendar_Hour($_GET['y'],$_GET['m'],$_GET['d'],$_GET['h']); |
break; |
case 'calendar_minute': |
require_once CALENDAR_ROOT.'Minute.php'; |
$c = new Calendar_Minute($_GET['y'],$_GET['m'],$_GET['d'],$_GET['h'],$_GET['i']); |
break; |
case 'calendar_second': |
require_once CALENDAR_ROOT.'Second.php'; |
$c = new Calendar_Second($_GET['y'],$_GET['m'],$_GET['d'],$_GET['h'],$_GET['i'],$_GET['s']); |
break; |
} |
echo ( 'Viewing: '.@$_GET['view'].'<br />' ); |
echo ( 'The time is now: '.date('Y M d H:i:s',$c->getTimestamp()).'<br >' ); |
$i = 1; |
echo ( '<h1>First Iteration</h1>' ); |
echo ( '<p>The first iteration is more "expensive", the calendar data |
structures having to be built.</p>' ); |
$start = getmicrotime(); |
$c->build(); |
while ( $e = $c->fetch() ) { |
$class = strtolower(get_class($e)); |
$link ="&y=".$e->thisYear()."&m=".$e->thisMonth()."&d=".$e->thisDay(). |
"&h=".$e->thisHour()."&i=".$e->thisMinute()."&s=".$e->thisSecond(); |
$method = 'this'.str_replace('calendar_','',$class); |
echo ( "<a href=\"".$_SERVER['PHP_SELF']."?view=".$class.$link."\">".$e->{$method}()."</a> : " ); |
if ( ($i % 10) == 0 ) { |
echo ( '<br>' ); |
} |
$i++; |
} |
echo ( '<p><b>Took: '.(getmicrotime()-$start).' seconds</b></p>' ); |
$i = 1; |
echo ( '<h1>Second Iteration</h1>' ); |
echo ( '<p>This second iteration is faster, the data structures |
being re-used</p>' ); |
$start = getmicrotime(); |
while ( $e = $c->fetch() ) { |
$class = strtolower(get_class($e)); |
$link ="&y=".$e->thisYear()."&m=".$e->thisMonth()."&d=".$e->thisDay(). |
"&h=".$e->thisHour()."&i=".$e->thisMinute()."&s=".$e->thisSecond(); |
$method = 'this'.str_replace('calendar_','',$class); |
echo ( "<a href=\"".$_SERVER['PHP_SELF']."?view=".$class.$link."\">".$e->{$method}()."</a> : " ); |
if ( ($i % 10) == 0 ) { |
echo ( '<br>' ); |
} |
$i++; |
} |
echo ( '<p><b>Took: '.(getmicrotime()-$start).' seconds</b></p>' ); |
?> |
/branches/livraison_menes/api/pear/Calendar/docs/examples/2.php |
---|
New file |
0,0 → 1,142 |
<?php |
/** |
* Description: Demonstrates building a calendar for a month using the Week class |
* Uses UnixTs engine |
*/ |
function getmicrotime(){ |
list($usec, $sec) = explode(" ",microtime()); |
return ((float)$usec + (float)$sec); |
} |
$start = getmicrotime(); |
// Force UnixTs engine (default setting) |
define('CALENDAR_ENGINE','UnixTs'); |
if (!@include 'Calendar'.DIRECTORY_SEPARATOR.'Calendar.php') { |
define('CALENDAR_ROOT', '../../'); |
} |
require_once CALENDAR_ROOT.'Month/Weeks.php'; |
require_once CALENDAR_ROOT.'Day.php'; |
// Initialize GET variables if not set |
if (!isset($_GET['y'])) $_GET['y'] = date('Y'); |
if (!isset($_GET['m'])) $_GET['m'] = date('m'); |
if (!isset($_GET['d'])) $_GET['d'] = date('d'); |
// Build a month object |
$Month = new Calendar_Month_Weeks($_GET['y'], $_GET['m']); |
// Create an array of days which are "selected" |
// Used for Week::build() below |
$selectedDays = array ( |
new Calendar_Day($_GET['y'],$_GET['m'], $_GET['d']), |
new Calendar_Day($_GET['y'], 12, 25), |
new Calendar_Day(date('Y'), date('m'), date('d')), |
); |
// Instruct month to build Week objects |
$Month->build(); |
// Construct strings for next/previous links |
$PMonth = $Month->prevMonth('object'); // Get previous month as object |
$prev = $_SERVER['PHP_SELF'].'?y='.$PMonth->thisYear().'&m='.$PMonth->thisMonth().'&d='.$PMonth->thisDay(); |
$NMonth = $Month->nextMonth('object'); |
$next = $_SERVER['PHP_SELF'].'?y='.$NMonth->thisYear().'&m='.$NMonth->thisMonth().'&d='.$NMonth->thisDay(); |
?> |
<!doctype html public "-//W3C//DTD HTML 4.0 Transitional//EN"> |
<html> |
<head> |
<title> Calendar </title> |
<style text="text/css"> |
table { |
background-color: silver; |
} |
caption { |
font-family: verdana; |
font-size: 12px; |
background-color: while; |
} |
.prevMonth { |
font-size: 10px; |
text-align: left; |
} |
.nextMonth { |
font-size: 10px; |
text-align: right; |
} |
th { |
font-family: verdana; |
font-size: 11px; |
color: navy; |
text-align: right; |
} |
td { |
font-family: verdana; |
font-size: 11px; |
text-align: right; |
} |
.selected { |
background-color: yellow; |
} |
.empty { |
color: white; |
} |
</style> |
</head> |
<body> |
<h2>Build with Calendar_Month_Weeks::build() then Calendar_Week::build()</h2> |
<table class="calendar"> |
<caption> |
<?php echo date('F Y', $Month->getTimeStamp()); ?> |
</caption> |
<tr> |
<th>M</th> |
<th>T</th> |
<th>W</th> |
<th>T</th> |
<th>F</th> |
<th>S</th> |
<th>S</th> |
</tr> |
<?php |
while ($Week = $Month->fetch()) { |
echo "<tr>\n"; |
// Build the days in the week, passing the selected days |
$Week->build($selectedDays); |
while ($Day = $Week->fetch()) { |
// Build a link string for each day |
$link = $_SERVER['PHP_SELF']. |
'?y='.$Day->thisYear(). |
'&m='.$Day->thisMonth(). |
'&d='.$Day->thisDay(); |
// Check to see if day is selected |
if ($Day->isSelected()) { |
echo '<td class="selected">'.$Day->thisDay().'</td>'."\n"; |
// Check to see if day is empty |
} else if ($Day->isEmpty()) { |
echo '<td class="empty">'.$Day->thisDay().'</td>'."\n"; |
} else { |
echo '<td><a href="'.$link.'">'.$Day->thisDay().'</a></td>'."\n"; |
} |
} |
echo '</tr>'."\n"; |
} |
?> |
<tr> |
<td> |
<a href="<?php echo $prev; ?>" class="prevMonth"><< </a> |
</td> |
<td colspan="5"> </td> |
<td> |
<a href="<?php echo $next; ?>" class="nextMonth"> >></a> |
</td> |
</tr> |
</table> |
<?php |
echo '<p><b>Took: '.(getmicrotime()-$start).' seconds</b></p>'; |
?> |
</body> |
</html> |
/branches/livraison_menes/api/pear/Calendar/docs/examples/3.php |
---|
New file |
0,0 → 1,134 |
<?php |
/** |
* Description: Performs same behaviour as 2.php but uses Month::buildWeekDays() |
* and is faster |
*/ |
function getmicrotime(){ |
list($usec, $sec) = explode(" ",microtime()); |
return ((float)$usec + (float)$sec); |
} |
$start = getmicrotime(); |
if ( !@include 'Calendar/Calendar.php' ) { |
define('CALENDAR_ROOT','../../'); |
} |
require_once CALENDAR_ROOT.'Month/Weekdays.php'; |
require_once CALENDAR_ROOT.'Day.php'; |
if (!isset($_GET['y'])) $_GET['y'] = date('Y'); |
if (!isset($_GET['m'])) $_GET['m'] = date('m'); |
if (!isset($_GET['d'])) $_GET['d'] = date('d'); |
// Build the month |
$Month = new Calendar_Month_Weekdays($_GET['y'],$_GET['m']); |
// Construct strings for next/previous links |
$PMonth = $Month->prevMonth('object'); // Get previous month as object |
$prev = $_SERVER['PHP_SELF'].'?y='.$PMonth->thisYear().'&m='.$PMonth->thisMonth().'&d='.$PMonth->thisDay(); |
$NMonth = $Month->nextMonth('object'); |
$next = $_SERVER['PHP_SELF'].'?y='.$NMonth->thisYear().'&m='.$NMonth->thisMonth().'&d='.$NMonth->thisDay(); |
?> |
<!doctype html public "-//W3C//DTD HTML 4.0 Transitional//EN"> |
<html> |
<head> |
<title> Calendar </title> |
<style text="text/css"> |
table { |
background-color: silver; |
} |
caption { |
font-family: verdana; |
font-size: 12px; |
background-color: while; |
} |
.prevMonth { |
font-size: 10px; |
text-align: left; |
} |
.nextMonth { |
font-size: 10px; |
text-align: right; |
} |
th { |
font-family: verdana; |
font-size: 11px; |
color: navy; |
text-align: right; |
} |
td { |
font-family: verdana; |
font-size: 11px; |
text-align: right; |
} |
.selected { |
background-color: yellow; |
} |
</style> |
</head> |
<body> |
<?php |
$selectedDays = array ( |
new Calendar_Day($_GET['y'],$_GET['m'],$_GET['d']), |
new Calendar_Day($_GET['y'],12,25), |
); |
// Build the days in the month |
$Month->build($selectedDays); |
?> |
<h2>Built with Calendar_Month_Weekday::build()</h2> |
<table class="calendar"> |
<caption> |
<?php echo ( date('F Y',$Month->getTimeStamp())); ?> |
</caption> |
<tr> |
<th>M</th> |
<th>T</th> |
<th>W</th> |
<th>T</th> |
<th>F</th> |
<th>S</th> |
<th>S</th> |
</tr> |
<?php |
while ( $Day = $Month->fetch() ) { |
// Build a link string for each day |
$link = $_SERVER['PHP_SELF']. |
'?y='.$Day->thisYear(). |
'&m='.$Day->thisMonth(). |
'&d='.$Day->thisDay(); |
// isFirst() to find start of week |
if ( $Day->isFirst() ) |
echo ( "<tr>\n" ); |
if ( $Day->isSelected() ) { |
echo ( "<td class=\"selected\">".$Day->thisDay()."</td>\n" ); |
} else if ( $Day->isEmpty() ) { |
echo ( "<td> </td>\n" ); |
} else { |
echo ( "<td><a href=\"".$link."\">".$Day->thisDay()."</a></td>\n" ); |
} |
// isLast() to find end of week |
if ( $Day->isLast() ) |
echo ( "</tr>\n" ); |
} |
?> |
<tr> |
<td> |
<a href="<?php echo ($prev);?>" class="prevMonth"><< </a> |
</td> |
<td colspan="5"> </td> |
<td> |
<a href="<?php echo ($next);?>" class="nextMonth"> >></a> |
</td> |
</tr> |
</table> |
<?php |
echo ( '<p><b>Took: '.(getmicrotime()-$start).' seconds</b></p>' ); |
?> |
</body> |
</html> |
/branches/livraison_menes/api/pear/Calendar/docs/examples/4.php |
---|
New file |
0,0 → 1,49 |
<?php |
/** |
* Description: shows how to perform validation with PEAR::Calendar |
*/ |
function getmicrotime(){ |
list($usec, $sec) = explode(' ', microtime()); |
return ((float)$usec + (float)$sec); |
} |
$start = getmicrotime(); |
if ( !@include 'Calendar/Calendar.php' ) { |
define('CALENDAR_ROOT', '../../'); |
} |
require_once CALENDAR_ROOT.'Second.php'; |
if (!isset($_GET['y'])) $_GET['y'] = date('Y'); |
if (!isset($_GET['m'])) $_GET['m'] = date('n'); |
if (!isset($_GET['d'])) $_GET['d'] = date('j'); |
if (!isset($_GET['h'])) $_GET['h'] = date('H'); |
if (!isset($_GET['i'])) $_GET['i'] = date('i'); |
if (!isset($_GET['s'])) $_GET['s'] = date('s'); |
$Unit = & new Calendar_Second($_GET['y'], $_GET['m'], $_GET['d'], $_GET['h'], $_GET['i'], $_GET['s']); |
echo '<p><b>Result:</b> '.$Unit->thisYear().'-'.$Unit->thisMonth().'-'.$Unit->thisDay(). |
' '.$Unit->thisHour().':'.$Unit->thisMinute().':'.$Unit->thisSecond(); |
if ($Unit->isValid()) { |
echo ' is valid!</p>'; |
} else { |
$V= & $Unit->getValidator(); |
echo ' is invalid:</p>'; |
while ($error = $V->fetch()) { |
echo $error->toString() .'<br />'; |
} |
} |
?> |
<p>Enter a date / time to validate:</p> |
<form action="<?php echo $_SERVER['PHP_SELF']; ?>" method="get"> |
Year: <input type="text" name="y" value="2039"><br /> |
Month: <input type="text" name="m" value="13"><br /> |
Day: <input type="text" name="d" value="32"><br /> |
Hour: <input type="text" name="h" value="24"><br /> |
Minute: <input type="text" name="i" value="-1"><br /> |
Second: <input type="text" name="s" value="60"><br /> |
<input type="submit" value="Validate"> |
</form> |
<p><b>Note:</b> Error messages can be controlled with the constants <code>CALENDAR_VALUE_TOOSMALL</code> and <code>CALENDAR_VALUE_TOOLARGE</code> - see <code>Calendar_Validator.php</code></p> |
<?php echo '<p><b>Took: '.(getmicrotime()-$start).' seconds</b></p>'; ?> |
/branches/livraison_menes/api/pear/Calendar/docs/examples/11.phps |
---|
Cannot display: file marked as a binary type. |
svn:mime-type = application/octet-stream |
/branches/livraison_menes/api/pear/Calendar/docs/examples/11.phps |
---|
New file |
Property changes: |
Added: svn:mime-type |
+application/octet-stream |
\ No newline at end of property |
/branches/livraison_menes/api/pear/Calendar/docs/examples/5.php |
---|
New file |
0,0 → 1,132 |
<?php |
/** |
* Description: generating elements of a form with PEAR::Calendar, using |
* selections as well as validating the submission |
*/ |
function getmicrotime(){ |
list($usec, $sec) = explode(" ",microtime()); |
return ((float)$usec + (float)$sec); |
} |
$start = getmicrotime(); |
if ( !@include 'Calendar/Calendar.php' ) { |
define('CALENDAR_ROOT','../../'); |
} |
require_once CALENDAR_ROOT.'Year.php'; |
require_once CALENDAR_ROOT.'Month.php'; |
require_once CALENDAR_ROOT.'Day.php'; |
require_once CALENDAR_ROOT.'Hour.php'; |
require_once CALENDAR_ROOT.'Minute.php'; |
require_once CALENDAR_ROOT.'Second.php'; |
// Initialize if not set |
if (!isset($_POST['y'])) $_POST['y'] = date('Y'); |
if (!isset($_POST['m'])) $_POST['m'] = date('n'); |
if (!isset($_POST['d'])) $_POST['d'] = date('j'); |
if (!isset($_POST['h'])) $_POST['h'] = date('H'); |
if (!isset($_POST['i'])) $_POST['i'] = date('i'); |
if (!isset($_POST['s'])) $_POST['s'] = date('s'); |
?> |
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN"> |
<html> |
<head> |
<title> Select and Update </title> |
</head> |
<body> |
<h1>Select and Update</h1> |
<?php |
if ( isset($_POST['update']) ) { |
$Second = & new Calendar_Second($_POST['y'],$_POST['m'],$_POST['d'],$_POST['h'],$_POST['i'],$_POST['s']); |
if ( !$Second->isValid() ) { |
$V= & $Second->getValidator(); |
echo ('<p>Validation failed:</p>' ); |
while ( $error = $V->fetch() ) { |
echo ( $error->toString() .'<br>' ); |
} |
} else { |
echo ('<p>Validation success.</p>' ); |
echo ( '<p>New timestamp is: '.$Second->getTimeStamp().' which could be used to update a database, for example'); |
} |
} else { |
$Year = new Calendar_Year($_POST['y']); |
$Month = new Calendar_Month($_POST['y'],$_POST['m']); |
$Day = new Calendar_Day($_POST['y'],$_POST['m'],$_POST['d']); |
$Hour = new Calendar_Hour($_POST['y'],$_POST['m'],$_POST['d'],$_POST['h']); |
$Minute = new Calendar_Minute($_POST['y'],$_POST['m'],$_POST['d'],$_POST['h'],$_POST['i']); |
$Second = new Calendar_Second($_POST['y'],$_POST['m'],$_POST['d'],$_POST['h'],$_POST['i'],$_POST['s']); |
?> |
<p><b>Set the alarm clock</p></p> |
<form action="<?php echo ( $_SERVER['PHP_SELF'] ); ?>" method="post"> |
Year: <input type="text" name="y" value="<?php echo ( $_POST['y'] ); ?>" size="4"> |
Month:<select name="m"> |
<?php |
$selection = array($Month); |
$Year->build($selection); |
while ( $Child = & $Year->fetch() ) { |
if ( $Child->isSelected() ) { |
echo ( "<option value=\"".$Child->thisMonth()."\" selected>".$Child->thisMonth()."\n" ); |
} else { |
echo ( "<option value=\"".$Child->thisMonth()."\">".$Child->thisMonth()."\n" ); |
} |
} |
?> |
</select> |
Day:<select name="d"> |
<?php |
$selection = array($Day); |
$Month->build($selection); |
while ( $Child = & $Month->fetch() ) { |
if ( $Child->isSelected() ) { |
echo ( "<option value=\"".$Child->thisDay()."\" selected>".$Child->thisDay()."\n" ); |
} else { |
echo ( "<option value=\"".$Child->thisDay()."\">".$Child->thisDay()."\n" ); |
} |
} |
?> |
</select> |
Hour:<select name="h"> |
<?php |
$selection = array($Hour); |
$Day->build($selection); |
while ( $Child = & $Day->fetch() ) { |
if ( $Child->isSelected() ) { |
echo ( "<option value=\"".$Child->thisHour()."\" selected>".$Child->thisHour()."\n" ); |
} else { |
echo ( "<option value=\"".$Child->thisHour()."\">".$Child->thisHour()."\n" ); |
} |
} |
?> |
</select> |
Minute:<select name="i"> |
<?php |
$selection = array($Minute); |
$Hour->build($selection); |
while ( $Child = & $Hour->fetch() ) { |
if ( $Child->isSelected() ) { |
echo ( "<option value=\"".$Child->thisMinute()."\" selected>".$Child->thisMinute()."\n" ); |
} else { |
echo ( "<option value=\"".$Child->thisMinute()."\">".$Child->thisMinute()."\n" ); |
} |
} |
?> |
</select> |
Second:<select name="s"> |
<?php |
$selection = array($Second); |
$Minute->build($selection); |
while ( $Child = & $Minute->fetch() ) { |
if ( $Child->isSelected() ) { |
echo ( "<option value=\"".$Child->thisSecond()."\" selected>".$Child->thisSecond()."\n" ); |
} else { |
echo ( "<option value=\"".$Child->thisSecond()."\">".$Child->thisSecond()."\n" ); |
} |
} |
?> |
</select> |
<input type="submit" name="update" value="Set Alarm"><br> |
<?php |
} |
?> |
<?php echo ( '<p><b>Took: '.(getmicrotime()-$start).' seconds</b></p>' ); ?> |
</body> |
</html> |
/branches/livraison_menes/api/pear/Calendar/docs/examples/21.phps |
---|
Cannot display: file marked as a binary type. |
svn:mime-type = application/octet-stream |
/branches/livraison_menes/api/pear/Calendar/docs/examples/21.phps |
---|
New file |
Property changes: |
Added: svn:mime-type |
+application/octet-stream |
\ No newline at end of property |
/branches/livraison_menes/api/pear/Calendar/docs/examples/6.php |
---|
New file |
0,0 → 1,210 |
<?php |
/** |
* Description: A "personal planner" with some WML for fun |
* Note this is done the stupid way - a giant if/else for WML or HTML |
* could be greatly simplified with some HTML/WML rendering classes... |
*/ |
function getmicrotime(){ |
list($usec, $sec) = explode(" ",microtime()); |
return ((float)$usec + (float)$sec); |
} |
$start = getmicrotime(); |
if ( !@include 'Calendar/Calendar.php' ) { |
define('CALENDAR_ROOT','../../'); |
} |
require_once CALENDAR_ROOT.'Month/Weekdays.php'; |
require_once CALENDAR_ROOT.'Day.php'; |
if (!isset($_GET['y'])) $_GET['y'] = date('Y'); |
if (!isset($_GET['m'])) $_GET['m'] = date('n'); |
if (!isset($_GET['d'])) $_GET['d'] = date('j'); |
$Month = & new Calendar_Month_Weekdays($_GET['y'],$_GET['m']); |
$Day = & new Calendar_Day($_GET['y'],$_GET['m'],$_GET['d']); |
$selection = array($Day); |
#-----------------------------------------------------------------------------# |
if ( isset($_GET['mime']) && $_GET['mime']=='wml' ) { |
header ('Content-Type: text/vnd.wap.wml'); |
echo ( '<?xml version="1.0"?>' ); |
?> |
<!DOCTYPE wml PUBLIC "-//WAPFORUM//DTD WML 1.1//EN" "http://www.wapforum.org/DTD/wml_1.1.xml"> |
<wml> |
<big><strong>Personal Planner Rendered with WML</strong></big> |
<?php |
if ( isset($_GET['viewday']) ) { |
?> |
<p><strong>Viewing <?php echo ( date('l, jS of F, Y',$Day->getTimeStamp()) ); ?></strong></p> |
<p> |
<anchor> |
Back to Month View |
<go href="<?php |
echo ( "?y=".$Day->thisYear()."&m=". |
$Day->thisMonth()."&d=".$Day->thisDay()."&mime=wml" ); |
?>"/> |
</anchor> |
</p> |
<table> |
<?php |
$Day->build(); |
while ( $Hour = & $Day->fetch() ) { |
echo ( "<tr>\n" ); |
echo ( "<td>".date('g a',$Hour->getTimeStamp())."</td><td>Free time!</td>\n" ); |
echo ( "</tr>\n" ); |
} |
?> |
</table> |
<?php |
} else { |
?> |
<p><strong><?php echo ( date('F Y',$Month->getTimeStamp()) ); ?></strong></p> |
<table> |
<tr> |
<td>M</td><td>T</td><td>W</td><td>T</td><td>F</td><td>S</td><td>S</td> |
</tr> |
<?php |
$Month->build($selection); |
while ( $Day = $Month->fetch() ) { |
if ( $Day->isFirst() ) { |
echo ( "<tr>\n" ); |
} |
if ( $Day->isEmpty() ) { |
echo ( "<td></td>\n" ); |
} else if ( $Day->isSelected() ) { |
echo ( "<td><anchor><strong><u>".$Day->thisDay()."</u></strong>\n<go href=\"".$_SERVER['PHP_SELF']."?viewday=true&y=". |
$Day->thisYear()."&m=".$Day->thisMonth()."&d=".$Day->thisDay(). |
"&mime=wml\" />\n</anchor></td>\n" ); |
} else { |
echo ( "<td><anchor>".$Day->thisDay()."\n<go href=\"?viewday=true&y=". |
$Day->thisYear()."&m=".$Day->thisMonth()."&d=".$Day->thisDay(). |
"&mime=wml\" /></anchor></td>\n" ); |
} |
if ( $Day->isLast() ) { |
echo ( "</tr>\n" ); |
} |
} |
?> |
<tr> |
<td> |
<anchor> |
<< |
<go href="<?php |
echo ( "?y=".$Month->thisYear()."&m=". |
$Month->prevMonth()."&d=".$Month->thisDay()."&mime=wml" ); |
?>"/> |
</anchor> |
</td> |
<td></td><td></td><td></td><td></td><td></td> |
<td> |
<anchor> |
>> |
<go href="<?php |
echo ( "?y=".$Month->thisYear()."&m=". |
$Month->nextMonth()."&d=".$Month->thisDay()."&mime=wml" ); |
?>"/> |
</anchor> |
</td> |
</tr> |
</table> |
<?php |
} |
?> |
<p><a href="<?php echo ( $_SERVER['PHP_SELF'] ); ?>">Back to HTML</a></p> |
<?php echo ( '<p>Took: '.(getmicrotime()-$start).' seconds</p>' ); ?> |
</wml> |
<?php |
#-----------------------------------------------------------------------------# |
} else { |
?> |
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN"> |
<html> |
<head> |
<title> HTML (+WML) Personal Planner </title> |
</head> |
<body> |
<h1>Personal Planner Rendered with HTML</h1> |
<p>To view in WML, click <a href="<?php echo ( $_SERVER['PHP_SELF'] ); ?>?mime=wml">here</a> or place a ?mime=wml at the end of any URL. |
Note that <a href="http://www.opera.com/download">Opera</a> supports WML natively and Mozilla / Firefox has the WMLBrowser |
plugin: <a href="http://wmlbrowser.mozdev.org">wmlbrowser.mozdev.org</a></p> |
<?php |
if ( isset($_GET['viewday']) ) { |
?> |
<p><strong>Viewing <?php echo ( date('l, jS of F, Y',$Day->getTimeStamp()) ); ?></strong></p> |
<p> |
<anchor> |
<a href="<?php |
echo ( "?y=".$Day->thisYear()."&m=". |
$Day->thisMonth()."&d=".$Day->thisDay()); |
?>">Back to Month View</a> |
</p> |
<table> |
<?php |
$Day->build(); |
while ( $Hour = & $Day->fetch() ) { |
echo ( "<tr>\n" ); |
echo ( "<td>".date('g a',$Hour->getTimeStamp())."</td><td>Free time!</td>\n" ); |
echo ( "</tr>\n" ); |
} |
?> |
</table> |
<?php |
} else { |
?> |
<p><strong><?php echo ( date('F Y',$Month->getTimeStamp()) ); ?></strong></p> |
<table> |
<tr> |
<td>M</td><td>T</td><td>W</td><td>T</td><td>F</td><td>S</td><td>S</td> |
</tr> |
<?php |
$Month->build($selection); |
while ( $Day = $Month->fetch() ) { |
if ( $Day->isFirst() ) { |
echo ( "<tr>\n" ); |
} |
if ( $Day->isEmpty() ) { |
echo ( "<td></td>\n" ); |
} else if ( $Day->isSelected() ) { |
echo ( "<td><a href=\"".$_SERVER['PHP_SELF']."?viewday=true&y=". |
$Day->thisYear()."&m=".$Day->thisMonth()."&d=".$Day->thisDay(). |
"&wml\"><strong><u>".$Day->thisDay()."</u></strong></a></td>\n" ); |
} else { |
echo ( "<td><a href=\"".$_SERVER['PHP_SELF']."?viewday=true&y=". |
$Day->thisYear()."&m=".$Day->thisMonth()."&d=".$Day->thisDay(). |
"\">".$Day->thisDay()."</a></td>\n" ); |
} |
if ( $Day->isLast() ) { |
echo ( "</tr>\n" ); |
} |
} |
?> |
<tr> |
<td> |
<a href="<?php |
echo ( "?y=".$Month->thisYear()."&m=". |
$Month->prevMonth()."&d=".$Month->thisDay() ); |
?>"> |
<<</a> |
</td> |
<td></td><td></td><td></td><td></td><td></td> |
<td> |
<a href="<?php |
echo ( "?y=".$Month->thisYear()."&m=". |
$Month->nextMonth()."&d=".$Month->thisDay() ); |
?>">>></a> |
</td> |
</tr> |
</table> |
<?php |
} |
?> |
<?php echo ( '<p><b>Took: '.(getmicrotime()-$start).' seconds</b></p>' ); ?> |
</body> |
</html> |
<?php |
} |
?> |
/branches/livraison_menes/api/pear/Calendar/docs/examples/13.phps |
---|
Cannot display: file marked as a binary type. |
svn:mime-type = application/octet-stream |
/branches/livraison_menes/api/pear/Calendar/docs/examples/13.phps |
---|
New file |
Property changes: |
Added: svn:mime-type |
+application/octet-stream |
\ No newline at end of property |
/branches/livraison_menes/api/pear/Calendar/docs/examples/7.php |
---|
New file |
0,0 → 1,92 |
<?php |
/** |
* Description: a SOAP Calendar Server |
*/ |
if (!@include('SOAP'.DIRECTORY_SEPARATOR.'Server.php')) { |
die('You must have PEAR::SOAP installed'); |
} |
if (!@include 'Calendar'.DIRECTORY_SEPARATOR.'Calendar.php') { |
define('CALENDAR_ROOT', '../../'); |
} |
class Calendar_Server |
{ |
var $__dispatch_map = array(); |
var $__typedef = array(); |
function Calendar_Server() |
{ |
$this->__dispatch_map['getMonth'] = |
array('in' => array('year' => 'int', 'month'=>'int'), |
'out' => array('month' => '{urn:PEAR_SOAP_Calendar}Month'), |
); |
$this->__typedef['Month'] = array ( |
'monthname' => 'string', |
'days' => '{urn:PEAR_SOAP_Calendar}MonthDays' |
); |
$this->__typedef['MonthDays'] = array (array ('{urn:PEAR_SOAP_Calendar}Day')); |
$this->__typedef['Day'] = array ( |
'isFirst' => 'int', |
'isLast' => 'int', |
'isEmpty' => 'int', |
'day' => 'int' ); |
} |
function __dispatch($methodname) |
{ |
if (isset($this->__dispatch_map[$methodname])) |
return $this->__dispatch_map[$methodname]; |
return NULL; |
} |
function getMonth($year, $month) |
{ |
require_once(CALENDAR_ROOT.'Month'.DIRECTORY_SEPARATOR.'Weekdays.php'); |
$Month = & new Calendar_Month_Weekdays($year,$month); |
if (!$Month->isValid()) { |
$V = & $Month->getValidator(); |
$errorMsg = ''; |
while ($error = $V->fetch()) { |
$errorMsg .= $error->toString()."\n"; |
} |
return new SOAP_Fault($errorMsg, 'Client'); |
} else { |
$monthname = date('F Y', $Month->getTimeStamp()); |
$days = array(); |
$Month->build(); |
while ($Day = & $Month->fetch()) { |
$day = array( |
'isFirst' => (int)$Day->isFirst(), |
'isLast' => (int)$Day->isLast(), |
'isEmpty' => (int)$Day->isEmpty(), |
'day' => (int)$Day->thisDay(), |
); |
$days[] = $day; |
} |
return array('monthname' => $monthname, 'days' => $days); |
} |
} |
} |
$server = new SOAP_Server(); |
$server->_auto_translation = true; |
$calendar = new Calendar_Server(); |
$server->addObjectMap($calendar, 'urn:PEAR_SOAP_Calendar'); |
if (strtoupper($_SERVER['REQUEST_METHOD'])=='POST') { |
$server->service($GLOBALS['HTTP_RAW_POST_DATA']); |
} else { |
require_once 'SOAP'.DIRECTORY_SEPARATOR.'Disco.php'; |
$disco = new SOAP_DISCO_Server($server, "PEAR_SOAP_Calendar"); |
if (isset($_SERVER['QUERY_STRING']) && |
strcasecmp($_SERVER['QUERY_STRING'], 'wsdl')==0) { |
header("Content-type: text/xml"); |
echo $disco->getWSDL(); |
} else { |
echo 'This is a PEAR::SOAP Calendar Server. For client try <a href="8.php">here</a><br />'; |
echo 'For WSDL try <a href="?wsdl">here</a>'; |
} |
exit; |
} |
?> |
/branches/livraison_menes/api/pear/Calendar/docs/examples/23.phps |
---|
Cannot display: file marked as a binary type. |
svn:mime-type = application/octet-stream |
/branches/livraison_menes/api/pear/Calendar/docs/examples/23.phps |
---|
New file |
Property changes: |
Added: svn:mime-type |
+application/octet-stream |
\ No newline at end of property |
/branches/livraison_menes/api/pear/Calendar/docs/examples/8.php |
---|
New file |
0,0 → 1,70 |
<?php |
/** |
* Description: client for the SOAP Calendar Server |
*/ |
if ( version_compare(phpversion(), "5.0.0", ">") ) { |
die('PHP 5 has problems with PEAR::SOAP Client (8.0RC3) |
- remove @ before include below to see why'); |
} |
if (!@include('SOAP'.DIRECTORY_SEPARATOR.'Client.php')) { |
die('You must have PEAR::SOAP installed'); |
} |
// Just to save manaul modification... |
$basePath = explode('/', $_SERVER['SCRIPT_NAME']); |
array_pop($basePath); |
$basePath = implode('/', $basePath); |
$url = 'http://'.$_SERVER['SERVER_NAME'].$basePath.'/7.php?wsdl'; |
if (!isset($_GET['y'])) $_GET['y'] = date('Y'); |
if (!isset($_GET['m'])) $_GET['m'] = date('n'); |
$wsdl = new SOAP_WSDL ($url); |
echo ( '<pre>'.$wsdl->generateProxyCode().'</pre>' ); |
$calendarClient = $wsdl->getProxy(); |
$month = $calendarClient->getMonth((int)$_GET['y'],(int)$_GET['m']); |
if ( PEAR::isError($month) ) { |
die ( $month->toString() ); |
} |
?> |
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN"> |
<html> |
<head> |
<title> Calendar over the Wire </title> |
</head> |
<body> |
<h1>Calendar Over the Wire (featuring PEAR::SOAP)</h1> |
<table> |
<caption><b><?php echo ( $month->monthname );?></b></caption> |
<tr> |
<th>M</th><th>T</th><th>W</th><th>T</th><th>F</th><th>S</th><th>S</th> |
</tr> |
<?php |
foreach ( $month->days as $day ) { |
if ( $day->isFirst === 1 ) |
echo ( "<tr>\n" ); |
if ( $day->isEmpty === 1 ) { |
echo ( "<td></td>" ); |
} else { |
echo ( "<td>".$day->day."</td>" ); |
} |
if ( $day->isLast === 1 ) |
echo ( "</tr>\n" ); |
} |
?> |
<tr> |
</table> |
<p>Enter Year and Month to View:</p> |
<form action="<?php echo ( $_SERVER['PHP_SELF'] ); ?>" method="get"> |
Year: <input type="text" size="4" name="y" value="<?php echo ( $_GET['y'] ); ?>"> |
Month: <input type="text" size="2" name="m" value="<?php echo ( $_GET['m'] ); ?>"> |
<input type="submit" value="Fetch Calendar"> |
</form> |
</body> |
</html> |
/branches/livraison_menes/api/pear/Calendar/docs/examples/15.phps |
---|
Cannot display: file marked as a binary type. |
svn:mime-type = application/octet-stream |
/branches/livraison_menes/api/pear/Calendar/docs/examples/15.phps |
---|
New file |
Property changes: |
Added: svn:mime-type |
+application/octet-stream |
\ No newline at end of property |
/branches/livraison_menes/api/pear/Calendar/docs/examples/9.php |
---|
New file |
0,0 → 1,16 |
<?php |
/** |
* Description: simple example on i18N |
*/ |
if ( !@include 'Calendar/Calendar.php' ) { |
define('CALENDAR_ROOT','../../'); |
} |
require_once CALENDAR_ROOT.'Day.php'; |
$Day = & new Calendar_Day(2003,10,23); |
setlocale (LC_TIME, "de_DE"); // Unix based (probably) |
// setlocale (LC_TIME, "ge"); // Windows |
echo ( strftime('%A %d %B %Y',$Day->getTimeStamp())); |
?> |
/branches/livraison_menes/api/pear/Calendar/docs/examples/17.phps |
---|
Cannot display: file marked as a binary type. |
svn:mime-type = application/octet-stream |
/branches/livraison_menes/api/pear/Calendar/docs/examples/17.phps |
---|
New file |
Property changes: |
Added: svn:mime-type |
+application/octet-stream |
\ No newline at end of property |
/branches/livraison_menes/api/pear/Calendar/docs/examples/19.phps |
---|
Cannot display: file marked as a binary type. |
svn:mime-type = application/octet-stream |
/branches/livraison_menes/api/pear/Calendar/docs/examples/19.phps |
---|
New file |
Property changes: |
Added: svn:mime-type |
+application/octet-stream |
\ No newline at end of property |
/branches/livraison_menes/api/pear/Calendar/docs/examples/10.php |
---|
New file |
0,0 → 1,93 |
<?php |
/** |
* Description: demonstrates a decorator to provide simple output formatting |
* on the month while still allowing the days to be accessed via the decorator |
* In practice you _wouldn't_ do this - each decorator comes with a performance |
* hit for extra method calls. For this example some simple functions could help |
* format the month while the days are accessed via the normal Month object |
*/ |
if ( !@include 'Calendar/Calendar.php' ) { |
define('CALENDAR_ROOT','../../'); |
} |
require_once CALENDAR_ROOT.'Month/Weekdays.php'; |
require_once CALENDAR_ROOT.'Decorator.php'; |
// Decorate a Month with methods to improve formatting |
class MonthDecorator extends Calendar_Decorator { |
/** |
* @param Calendar_Month |
*/ |
function MonthDecorator(& $Month) { |
parent::Calendar_Decorator($Month); |
} |
/** |
* Override the prevMonth method to format the output |
*/ |
function prevMonth() { |
$prevStamp = parent::prevMonth(TRUE); |
// Build the URL for the previous month |
return $_SERVER['PHP_SELF'].'?y='.date('Y',$prevStamp). |
'&m='.date('n',$prevStamp).'&d='.date('j',$prevStamp); |
} |
/** |
* Override the thisMonth method to format the output |
*/ |
function thisMonth() { |
$thisStamp = parent::thisMonth(TRUE); |
// A human readable string from this month |
return date('F Y',$thisStamp); |
} |
/** |
* Override the nextMonth method to format the output |
*/ |
function nextMonth() { |
$nextStamp = parent::nextMonth(TRUE); |
// Build the URL for next month |
return $_SERVER['PHP_SELF'].'?y='.date('Y',$nextStamp). |
'&m='.date('n',$nextStamp).'&d='.date('j',$nextStamp); |
} |
} |
if (!isset($_GET['y'])) $_GET['y'] = date('Y'); |
if (!isset($_GET['m'])) $_GET['m'] = date('n'); |
// Creata a month as usual |
$Month = new Calendar_Month_Weekdays($_GET['y'],$_GET['m']); |
// Pass it to the decorator and use the decorator from now on... |
$MonthDecorator = new MonthDecorator($Month); |
$MonthDecorator->build(); |
?> |
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN"> |
<html> |
<head> |
<title> A Simple Decorator </title> |
</head> |
<body> |
<h1>A Simple Decorator</h1> |
<table> |
<caption><?php echo ( $MonthDecorator->thisMonth() ); ?></caption> |
<?php |
while ( $Day = $MonthDecorator->fetch() ) { |
if ( $Day->isFirst() ) { |
echo ( "\n<tr>\n" ); |
} |
if ( $Day->isEmpty() ) { |
echo ( "<td> </td>" ); |
} else { |
echo ( "<td>".$Day->thisDay()."</td>" ); |
} |
if ( $Day->isLast() ) { |
echo ( "\n</tr>\n" ); |
} |
} |
?> |
<tr> |
<td><a href="<?php echo ($MonthDecorator->prevMonth()); ?>">Prev</a></td> |
<td colspan="5"> </td> |
<td><a href="<?php echo ($MonthDecorator->nextMonth()); ?>">Next</a></td> |
</tr> |
</table> |
</body> |
</html> |
/branches/livraison_menes/api/pear/Calendar/docs/Readme |
---|
Cannot display: file marked as a binary type. |
svn:mime-type = application/octet-stream |
/branches/livraison_menes/api/pear/Calendar/docs/Readme |
---|
New file |
Property changes: |
Added: svn:mime-type |
+application/octet-stream |
\ No newline at end of property |
/branches/livraison_menes/api/pear/Calendar/Factory.php |
---|
New file |
0,0 → 1,158 |
<?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.1 2005-09-30 14:58:00 ddelon Exp $ |
// |
/** |
* @package Calendar |
* @version $Id: Factory.php,v 1.1 2005-09-30 14:58:00 ddelon 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'; |
/** |
* Constant for the first day of the week (integer e.g. 0-6) |
*/ |
if ( !defined ('CALENDAR_FIRST_DAY_OF_WEEK') ) { |
define ('CALENDAR_FIRST_DAY_OF_WEEK',1); |
} |
/** |
* 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) |
{ |
switch ( $type ) { |
case 'Day': |
require_once CALENDAR_ROOT.'Day.php'; |
return new Calendar_Day($y,$m,$d); |
break; |
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'.DIRECTORY_SEPARATOR.'Weekdays.php'; |
$class = 'Calendar_Month_Weekdays'; |
break; |
case CALENDAR_USE_MONTH_WEEKS: |
require_once CALENDAR_ROOT.'Month'.DIRECTORY_SEPARATOR.'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,CALENDAR_FIRST_DAY_OF_WEEK); |
break; |
case 'Week': |
require_once CALENDAR_ROOT.'Week.php'; |
return new Calendar_Week($y,$m,$d,CALENDAR_FIRST_DAY_OF_WEEK); |
break; |
case 'Hour': |
require_once CALENDAR_ROOT.'Hour.php'; |
return new Calendar_Hour($y,$m,$d,$h); |
break; |
case 'Minute': |
require_once CALENDAR_ROOT.'Minute.php'; |
return new Calendar_Minute($y,$m,$d,$h,$i); |
break; |
case 'Second': |
require_once CALENDAR_ROOT.'Second.php'; |
return new Calendar_Second($y,$m,$d,$h,$i,$s); |
break; |
case 'Year': |
require_once CALENDAR_ROOT.'Year.php'; |
return new Calendar_Year($y); |
break; |
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; |
break; |
} |
} |
/** |
* 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); |
return Calendar_Factory::create($type, $y, $m, $d, $h, $i, $s); |
} |
} |
?> |
/branches/livraison_menes/api/pear/Calendar/Calendar.php |
---|
New file |
0,0 → 1,654 |
<?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.1 2005-09-30 14:58:00 ddelon Exp $ |
// |
/** |
* @package Calendar |
* @version $Id: Calendar.php,v 1.1 2005-09-30 14:58:00 ddelon 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 Caledar_Validator |
* @return object implementing Calendar_Engine_Inteface |
* @access private |
*/ |
function & getEngine() |
{ |
return $this->cE; |
} |
/** |
* 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)); |
} |
} |
?> |
/branches/livraison_menes/api/pear/Calendar/Second.php |
---|
New 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 2005-09-30 14:58:00 ddelon Exp $ |
// |
/** |
* @package Calendar |
* @version $Id: Second.php,v 1.1 2005-09-30 14:58:00 ddelon 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; |
} |
} |
?> |
/branches/livraison_menes/api/pear/Calendar/tests/decorator_textual_test.php |
---|
New file |
0,0 → 1,174 |
<?php |
// $Id: decorator_textual_test.php,v 1.1 2005-09-30 14:58:00 ddelon Exp $ |
require_once('simple_include.php'); |
require_once('calendar_include.php'); |
require_once('./decorator_test.php'); |
class TestOfDecoratorTextual extends TestOfDecorator { |
function TestOfDecoratorTextual() { |
$this->UnitTestCase('Test of Calendar_Decorator_Textual'); |
} |
function testMonthNamesLong() { |
$Textual = new Calendar_Decorator_Textual($this->mockcal); |
$monthNames = array( |
1=>'January', |
2=>'February', |
3=>'March', |
4=>'April', |
5=>'May', |
6=>'June', |
7=>'July', |
8=>'August', |
9=>'September', |
10=>'October', |
11=>'November', |
12=>'December', |
); |
$this->assertEqual($monthNames,$Textual->monthNames()); |
} |
function testMonthNamesShort() { |
$Textual = new Calendar_Decorator_Textual($this->mockcal); |
$monthNames = array( |
1=>'Jan', |
2=>'Feb', |
3=>'Mar', |
4=>'Apr', |
5=>'May', |
6=>'Jun', |
7=>'Jul', |
8=>'Aug', |
9=>'Sep', |
10=>'Oct', |
11=>'Nov', |
12=>'Dec', |
); |
$this->assertEqual($monthNames,$Textual->monthNames('short')); |
} |
function testMonthNamesTwo() { |
$Textual = new Calendar_Decorator_Textual($this->mockcal); |
$monthNames = array( |
1=>'Ja', |
2=>'Fe', |
3=>'Ma', |
4=>'Ap', |
5=>'Ma', |
6=>'Ju', |
7=>'Ju', |
8=>'Au', |
9=>'Se', |
10=>'Oc', |
11=>'No', |
12=>'De', |
); |
$this->assertEqual($monthNames,$Textual->monthNames('two')); |
} |
function testMonthNamesOne() { |
$Textual = new Calendar_Decorator_Textual($this->mockcal); |
$monthNames = array( |
1=>'J', |
2=>'F', |
3=>'M', |
4=>'A', |
5=>'M', |
6=>'J', |
7=>'J', |
8=>'A', |
9=>'S', |
10=>'O', |
11=>'N', |
12=>'D', |
); |
$this->assertEqual($monthNames,$Textual->monthNames('one')); |
} |
function testWeekdayNamesLong() { |
$Textual = new Calendar_Decorator_Textual($this->mockcal); |
$weekdayNames = array( |
0=>'Sunday', |
1=>'Monday', |
2=>'Tuesday', |
3=>'Wednesday', |
4=>'Thursday', |
5=>'Friday', |
6=>'Saturday', |
); |
$this->assertEqual($weekdayNames,$Textual->weekdayNames()); |
} |
function testWeekdayNamesShort() { |
$Textual = new Calendar_Decorator_Textual($this->mockcal); |
$weekdayNames = array( |
0=>'Sun', |
1=>'Mon', |
2=>'Tue', |
3=>'Wed', |
4=>'Thu', |
5=>'Fri', |
6=>'Sat', |
); |
$this->assertEqual($weekdayNames,$Textual->weekdayNames('short')); |
} |
function testWeekdayNamesTwo() { |
$Textual = new Calendar_Decorator_Textual($this->mockcal); |
$weekdayNames = array( |
0=>'Su', |
1=>'Mo', |
2=>'Tu', |
3=>'We', |
4=>'Th', |
5=>'Fr', |
6=>'Sa', |
); |
$this->assertEqual($weekdayNames,$Textual->weekdayNames('two')); |
} |
function testWeekdayNamesOne() { |
$Textual = new Calendar_Decorator_Textual($this->mockcal); |
$weekdayNames = array( |
0=>'S', |
1=>'M', |
2=>'T', |
3=>'W', |
4=>'T', |
5=>'F', |
6=>'S', |
); |
$this->assertEqual($weekdayNames,$Textual->weekdayNames('one')); |
} |
function testPrevMonthNameShort() { |
$Textual = new Calendar_Decorator_Textual($this->mockcal); |
$this->assertEqual('Sep',$Textual->prevMonthName('short')); |
} |
function testThisMonthNameShort() { |
$Textual = new Calendar_Decorator_Textual($this->mockcal); |
$this->assertEqual('Oct',$Textual->thisMonthName('short')); |
} |
function testNextMonthNameShort() { |
$Textual = new Calendar_Decorator_Textual($this->mockcal); |
$this->assertEqual('Nov',$Textual->nextMonthName('short')); |
} |
function testThisDayNameShort() { |
$Textual = new Calendar_Decorator_Textual($this->mockcal); |
$this->assertEqual('Wed',$Textual->thisDayName('short')); |
} |
function testOrderedWeekdaysShort() { |
$weekdayNames = array( |
0=>'Sun', |
1=>'Mon', |
2=>'Tue', |
3=>'Wed', |
4=>'Thu', |
5=>'Fri', |
6=>'Sat', |
); |
$Textual = new Calendar_Decorator_Textual($this->mockcal); |
$this->assertEqual($weekdayNames,$Textual->orderedWeekdays('short')); |
} |
} |
if (!defined('TEST_RUNNING')) { |
define('TEST_RUNNING', true); |
$test = &new TestOfDecoratorTextual(); |
$test->run(new HtmlReporter()); |
} |
?> |
/branches/livraison_menes/api/pear/Calendar/tests/all_tests.php |
---|
New file |
0,0 → 1,34 |
<?php |
// $Id: all_tests.php,v 1.1 2005-09-30 14:58:00 ddelon Exp $ |
require_once('simple_include.php'); |
require_once('calendar_include.php'); |
define("TEST_RUNNING", true); |
require_once('./calendar_tests.php'); |
require_once('./calendar_tabular_tests.php'); |
require_once('./validator_tests.php'); |
require_once('./calendar_engine_tests.php'); |
require_once('./calendar_engine_tests.php'); |
require_once('./table_helper_tests.php'); |
require_once('./decorator_tests.php'); |
require_once('./util_tests.php'); |
class AllTests extends GroupTest { |
function AllTests() { |
$this->GroupTest('All PEAR::Calendar Tests'); |
$this->AddTestCase(new CalendarTests()); |
$this->AddTestCase(new CalendarTabularTests()); |
$this->AddTestCase(new ValidatorTests()); |
$this->AddTestCase(new CalendarEngineTests()); |
$this->AddTestCase(new TableHelperTests()); |
$this->AddTestCase(new DecoratorTests()); |
$this->AddTestCase(new UtilTests()); |
} |
} |
$test = &new AllTests(); |
$test->run(new HtmlReporter()); |
?> |
/branches/livraison_menes/api/pear/Calendar/tests/week_test.php |
---|
New file |
0,0 → 1,226 |
<?php |
// $Id: week_test.php,v 1.1 2005-09-30 14:58:00 ddelon Exp $ |
require_once('simple_include.php'); |
require_once('calendar_include.php'); |
require_once('./calendar_test.php'); |
class TestOfWeek extends TestOfCalendar { |
function TestOfWeek() { |
$this->UnitTestCase('Test of Week'); |
} |
function setUp() { |
$this->cal = new Calendar_Week(2003, 10, 9, 1); //force firstDay = monday |
//print_r($this->cal); |
} |
function testPrevDay () { |
$this->assertEqual(8, $this->cal->prevDay()); |
} |
function testPrevDay_Array () { |
$this->assertEqual( |
array( |
'year' => 2003, |
'month' => 10, |
'day' => 8, |
'hour' => 0, |
'minute' => 0, |
'second' => 0), |
$this->cal->prevDay('array')); |
} |
function testThisDay () { |
$this->assertEqual(9, $this->cal->thisDay()); |
} |
function testNextDay () { |
$this->assertEqual(10, $this->cal->nextDay()); |
} |
function testPrevHour () { |
$this->assertEqual(23, $this->cal->prevHour()); |
} |
function testThisHour () { |
$this->assertEqual(0, $this->cal->thisHour()); |
} |
function testNextHour () { |
$this->assertEqual(1, $this->cal->nextHour()); |
} |
function testPrevMinute () { |
$this->assertEqual(59, $this->cal->prevMinute()); |
} |
function testThisMinute () { |
$this->assertEqual(0, $this->cal->thisMinute()); |
} |
function testNextMinute () { |
$this->assertEqual(1, $this->cal->nextMinute()); |
} |
function testPrevSecond () { |
$this->assertEqual(59, $this->cal->prevSecond()); |
} |
function testThisSecond () { |
$this->assertEqual(0, $this->cal->thisSecond()); |
} |
function testNextSecond () { |
$this->assertEqual(1, $this->cal->nextSecond()); |
} |
function testGetTimeStamp() { |
$stamp = mktime(0,0,0,10,9,2003); |
$this->assertEqual($stamp,$this->cal->getTimeStamp()); |
} |
function testNewTimeStamp() { |
$stamp = mktime(0,0,0,7,28,2004); |
$this->cal->setTimestamp($stamp); |
$this->assertEqual('30 2004', date('W Y', $this->cal->prevWeek(true))); |
$this->assertEqual('31 2004', date('W Y', $this->cal->thisWeek(true))); |
$this->assertEqual('32 2004', date('W Y', $this->cal->nextWeek(true))); |
} |
function testPrevWeekInMonth() { |
$this->assertEqual(1, $this->cal->prevWeek()); |
} |
function testThisWeekInMonth() { |
$this->assertEqual(2, $this->cal->thisWeek()); |
} |
function testNextWeekInMonth() { |
$this->assertEqual(3, $this->cal->nextWeek()); |
} |
function testPrevWeekInYear() { |
$this->assertEqual(40, $this->cal->prevWeek('n_in_year')); |
} |
function testThisWeekInYear() { |
$this->assertEqual(41, $this->cal->thisWeek('n_in_year')); |
} |
function testNextWeekInYear() { |
$this->assertEqual(42, $this->cal->nextWeek('n_in_year')); |
} |
function testPrevWeekArray() { |
$testArray = array( |
'year'=>2003, |
'month'=>9, |
'day'=>29, |
'hour'=>0, |
'minute'=>0, |
'second'=>0 |
); |
$this->assertEqual($testArray, $this->cal->prevWeek('array')); |
} |
function testThisWeekArray() { |
$testArray = array( |
'year'=>2003, |
'month'=>10, |
'day'=>6, |
'hour'=>0, |
'minute'=>0, |
'second'=>0 |
); |
$this->assertEqual($testArray, $this->cal->thisWeek('array')); |
} |
function testNextWeekArray() { |
$testArray = array( |
'year'=>2003, |
'month'=>10, |
'day'=>13, |
'hour'=>0, |
'minute'=>0, |
'second'=>0 |
); |
$this->assertEqual($testArray, $this->cal->nextWeek('array')); |
} |
function testPrevWeekObject() { |
$testWeek = new Calendar_Week(2003,9,29); |
$Week = $this->cal->prevWeek('object'); |
$this->assertEqual($testWeek->getTimeStamp(),$Week->getTimeStamp()); |
} |
function testThisWeekObject() { |
$testWeek = new Calendar_Week(2003,10,6); |
$Week = $this->cal->thisWeek('object'); |
$this->assertEqual($testWeek->getTimeStamp(),$Week->getTimeStamp()); |
} |
function testNextWeekObject() { |
$testWeek = new Calendar_Week(2003,10,13); |
$Week = $this->cal->nextWeek('object'); |
$this->assertEqual($testWeek->getTimeStamp(),$Week->getTimeStamp()); |
} |
} |
class TestOfWeekBuild extends TestOfWeek { |
function TestOfWeekBuild() { |
$this->UnitTestCase('Test of Week::build()'); |
} |
function testSize() { |
$this->cal->build(); |
$this->assertEqual(7, $this->cal->size()); |
} |
function testFetch() { |
$this->cal->build(); |
$i=0; |
while ($Child = $this->cal->fetch()) { |
$i++; |
} |
$this->assertEqual(7, $i); |
} |
function testFetchAll() { |
$this->cal->build(); |
$children = array(); |
$i = 1; |
while ( $Child = $this->cal->fetch() ) { |
$children[$i]=$Child; |
$i++; |
} |
$this->assertEqual($children,$this->cal->fetchAll()); |
} |
function testSelection() { |
require_once(CALENDAR_ROOT . 'Day.php'); |
$selection = array(new Calendar_Day(2003, 10, 7)); |
$this->cal->build($selection); |
$i = 1; |
while ($Child = $this->cal->fetch()) { |
if ($i == 2) { |
break; //07-10-2003 is the 2nd day of the week |
} |
$i++; |
} |
$this->assertTrue($Child->isSelected()); |
} |
function testSelectionCornerCase() { |
require_once(CALENDAR_ROOT . 'Day.php'); |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ new Calendar_Day(2004, 01, 03) |
+ ); |
+ $this->cal = new Calendar_Week(2003, 12, 31, 0); |
+ |
+ |
+ $this->assertTrue($Day->isSelected()); |
+ } |
+ |
+ |
+ |
+ $this->assertTrue($Day->isSelected()); |
+ } |
+ } |
+} |
+if (!defined('TEST_RUNNING')) { |
+ define('TEST_RUNNING', true); |
+ $test = &new TestOfWeek(); |
+ $test->run(new HtmlReporter()); |
+ $test = &new TestOfWeekBuild(); |
+ $test->run(new HtmlReporter()); |
+} |
+?> |
\ No newline at end of file |
/branches/livraison_menes/api/pear/Calendar/tests/calendar_tests.php |
---|
New file |
0,0 → 1,25 |
<?php |
// $Id: calendar_tests.php,v 1.1 2005-09-30 14:58:00 ddelon Exp $ |
require_once('simple_include.php'); |
require_once('calendar_include.php'); |
class CalendarTests extends GroupTest { |
function CalendarTests() { |
$this->GroupTest('Calendar Tests'); |
$this->addTestFile('calendar_test.php'); |
$this->addTestFile('year_test.php'); |
$this->addTestFile('month_test.php'); |
$this->addTestFile('day_test.php'); |
$this->addTestFile('hour_test.php'); |
$this->addTestFile('minute_test.php'); |
$this->addTestFile('second_test.php'); |
} |
} |
if (!defined('TEST_RUNNING')) { |
define('TEST_RUNNING', true); |
$test = &new CalendarTests(); |
$test->run(new HtmlReporter()); |
} |
?> |
/branches/livraison_menes/api/pear/Calendar/tests/util_uri_test.php |
---|
New file |
0,0 → 1,54 |
<?php |
// $Id: util_uri_test.php,v 1.1 2005-09-30 14:58:00 ddelon Exp $ |
require_once('simple_include.php'); |
require_once('calendar_include.php'); |
Mock::generate('Calendar_Day','Mock_Calendar_Day'); |
Mock::generate('Calendar_Engine_Interface','Mock_Calendar_Engine'); |
class TestOfUtilUri extends UnitTestCase { |
var $MockCal; |
function TestOfUtilUri() { |
$this->UnitTestCase('Test of Calendar_Util_Uri'); |
} |
function setUp() { |
$this->MockCal = & new Mock_Calendar_Day($this); |
$this->MockCal->setReturnValue('getEngine',new Mock_Calendar_Engine($this)); |
} |
function testFragments() { |
$Uri = new Calendar_Util_Uri('y','m','d','h','m','s'); |
$Uri->setFragments('year','month','day','hour','minute','second'); |
$this->assertEqual( |
'year=&month=&day=&hour=&minute=&second=', |
$Uri->this($this->MockCal, 'second') |
); |
} |
function testScalarFragments() { |
$Uri = new Calendar_Util_Uri('year','month','day','hour','minute','second'); |
$Uri->scalar = true; |
$this->assertEqual( |
'&&&&&', |
$Uri->this($this->MockCal, 'second') |
); |
} |
function testSetSeperator() { |
$Uri = new Calendar_Util_Uri('year','month','day','hour','minute','second'); |
$Uri->separator = '/'; |
$this->assertEqual( |
'year=/month=/day=/hour=/minute=/second=', |
$Uri->this($this->MockCal, 'second') |
); |
} |
} |
if (!defined('TEST_RUNNING')) { |
define('TEST_RUNNING', true); |
$test = &new TestOfUtilUri(); |
$test->run(new HtmlReporter()); |
} |
?> |
/branches/livraison_menes/api/pear/Calendar/tests/simple_include.php |
---|
New file |
0,0 → 1,10 |
<?php |
// $Id: simple_include.php,v 1.1 2005-09-30 14:58:00 ddelon Exp $ |
if (!defined('SIMPLE_TEST')) { |
define('SIMPLE_TEST', '../../../simpletest/'); |
} |
require_once(SIMPLE_TEST . 'unit_tester.php'); |
require_once(SIMPLE_TEST . 'reporter.php'); |
require_once(SIMPLE_TEST . 'mock_objects.php'); |
?> |
/branches/livraison_menes/api/pear/Calendar/tests/validator_error_test.php |
---|
New file |
0,0 → 1,34 |
<?php |
// $Id: validator_error_test.php,v 1.1 2005-09-30 14:58:00 ddelon Exp $ |
require_once('simple_include.php'); |
require_once('calendar_include.php'); |
class TestOfValidationError extends UnitTestCase { |
var $vError; |
function TestOfValidationError() { |
$this->UnitTestCase('Test of Validation Error'); |
} |
function setUp() { |
$this->vError = new Calendar_Validation_Error('foo',20,'bar'); |
} |
function testGetUnit() { |
$this->assertEqual($this->vError->getUnit(),'foo'); |
} |
function testGetValue() { |
$this->assertEqual($this->vError->getValue(),20); |
} |
function testGetMessage() { |
$this->assertEqual($this->vError->getMessage(),'bar'); |
} |
function testToString() { |
$this->assertEqual($this->vError->toString(),'foo = 20 [bar]'); |
} |
} |
if (!defined('TEST_RUNNING')) { |
define('TEST_RUNNING', true); |
$test = &new TestOfValidationError(); |
$test->run(new HtmlReporter()); |
} |
?> |
/branches/livraison_menes/api/pear/Calendar/tests/util_tests.php |
---|
New file |
0,0 → 1,20 |
<?php |
// $Id: util_tests.php,v 1.1 2005-09-30 14:58:00 ddelon Exp $ |
require_once('simple_include.php'); |
require_once('calendar_include.php'); |
class UtilTests extends GroupTest { |
function UtilTests() { |
$this->GroupTest('Util Tests'); |
$this->addTestFile('util_uri_test.php'); |
$this->addTestFile('util_textual_test.php'); |
} |
} |
if (!defined('TEST_RUNNING')) { |
define('TEST_RUNNING', true); |
$test = &new UtilTests(); |
$test->run(new HtmlReporter()); |
} |
?> |
/branches/livraison_menes/api/pear/Calendar/tests/year_test.php |
---|
New file |
0,0 → 1,142 |
<?php |
// $Id: year_test.php,v 1.1 2005-09-30 14:58:00 ddelon Exp $ |
require_once('simple_include.php'); |
require_once('calendar_include.php'); |
require_once('./calendar_test.php'); |
class TestOfYear extends TestOfCalendar { |
function TestOfYear() { |
$this->UnitTestCase('Test of Year'); |
} |
function setUp() { |
$this->cal = new Calendar_Year(2003); |
} |
function testPrevYear_Object() { |
$this->assertEqual(new Calendar_Year(2002), $this->cal->prevYear('object')); |
} |
function testThisYear_Object() { |
$this->assertEqual(new Calendar_Year(2003), $this->cal->thisYear('object')); |
} |
function testPrevMonth () { |
$this->assertEqual(12,$this->cal->prevMonth()); |
} |
function testPrevMonth_Array () { |
$this->assertEqual( |
array( |
'year' => 2002, |
'month' => 12, |
'day' => 1, |
'hour' => 0, |
'minute' => 0, |
'second' => 0), |
$this->cal->prevMonth('array')); |
} |
function testThisMonth () { |
$this->assertEqual(1,$this->cal->thisMonth()); |
} |
function testNextMonth () { |
$this->assertEqual(2,$this->cal->nextMonth()); |
} |
function testPrevDay () { |
$this->assertEqual(31,$this->cal->prevDay()); |
} |
function testPrevDay_Array () { |
$this->assertEqual( |
array( |
'year' => 2002, |
'month' => 12, |
'day' => 31, |
'hour' => 0, |
'minute' => 0, |
'second' => 0), |
$this->cal->prevDay('array')); |
} |
function testThisDay () { |
$this->assertEqual(1,$this->cal->thisDay()); |
} |
function testNextDay () { |
$this->assertEqual(2,$this->cal->nextDay()); |
} |
function testPrevHour () { |
$this->assertEqual(23,$this->cal->prevHour()); |
} |
function testThisHour () { |
$this->assertEqual(0,$this->cal->thisHour()); |
} |
function testNextHour () { |
$this->assertEqual(1,$this->cal->nextHour()); |
} |
function testPrevMinute () { |
$this->assertEqual(59,$this->cal->prevMinute()); |
} |
function testThisMinute () { |
$this->assertEqual(0,$this->cal->thisMinute()); |
} |
function testNextMinute () { |
$this->assertEqual(1,$this->cal->nextMinute()); |
} |
function testPrevSecond () { |
$this->assertEqual(59,$this->cal->prevSecond()); |
} |
function testThisSecond () { |
$this->assertEqual(0,$this->cal->thisSecond()); |
} |
function testNextSecond () { |
$this->assertEqual(1,$this->cal->nextSecond()); |
} |
function testGetTimeStamp() { |
$stamp = mktime(0,0,0,1,1,2003); |
$this->assertEqual($stamp,$this->cal->getTimeStamp()); |
} |
} |
class TestOfYearBuild extends TestOfYear { |
function TestOfYearBuild() { |
$this->UnitTestCase('Test of Year::build()'); |
} |
function testSize() { |
$this->cal->build(); |
$this->assertEqual(12,$this->cal->size()); |
} |
function testFetch() { |
$this->cal->build(); |
$i=0; |
while ( $Child = $this->cal->fetch() ) { |
$i++; |
} |
$this->assertEqual(12,$i); |
} |
function testFetchAll() { |
$this->cal->build(); |
$children = array(); |
$i = 1; |
while ( $Child = $this->cal->fetch() ) { |
$children[$i]=$Child; |
$i++; |
} |
$this->assertEqual($children,$this->cal->fetchAll()); |
} |
function testSelection() { |
require_once(CALENDAR_ROOT . 'Month.php'); |
$selection = array(new Calendar_Month(2003,10)); |
$this->cal->build($selection); |
$i = 1; |
while ( $Child = $this->cal->fetch() ) { |
if ( $i == 10 ) |
break; |
$i++; |
} |
$this->assertTrue($Child->isSelected()); |
} |
} |
if (!defined('TEST_RUNNING')) { |
define('TEST_RUNNING', true); |
$test = &new TestOfYear(); |
$test->run(new HtmlReporter()); |
$test = &new TestOfYearBuild(); |
$test->run(new HtmlReporter()); |
} |
?> |
/branches/livraison_menes/api/pear/Calendar/tests/minute_test.php |
---|
New file |
0,0 → 1,99 |
<?php |
// $Id: minute_test.php,v 1.1 2005-09-30 14:58:00 ddelon Exp $ |
require_once('simple_include.php'); |
require_once('calendar_include.php'); |
require_once('./calendar_test.php'); |
class TestOfMinute extends TestOfCalendar { |
function TestOfMinute() { |
$this->UnitTestCase('Test of Minute'); |
} |
function setUp() { |
$this->cal = new Calendar_Minute(2003,10,25,13,32); |
} |
function testPrevDay_Array () { |
$this->assertEqual( |
array( |
'year' => 2003, |
'month' => 10, |
'day' => 24, |
'hour' => 0, |
'minute' => 0, |
'second' => 0), |
$this->cal->prevDay('array')); |
} |
function testPrevSecond () { |
$this->assertEqual(59,$this->cal->prevSecond()); |
} |
function testThisSecond () { |
$this->assertEqual(0,$this->cal->thisSecond()); |
} |
function testThisSecond_Timestamp () { |
$this->assertEqual($this->cal->cE->dateToStamp( |
2003, 10, 25, 13, 32, 0), |
$this->cal->thisSecond('timestamp')); |
} |
function testNextSecond () { |
$this->assertEqual(1,$this->cal->nextSecond()); |
} |
function testNextSecond_Timestamp () { |
$this->assertEqual($this->cal->cE->dateToStamp( |
2003, 10, 25, 13, 32, 1), |
$this->cal->nextSecond('timestamp')); |
} |
function testGetTimeStamp() { |
$stamp = mktime(13,32,0,10,25,2003); |
$this->assertEqual($stamp,$this->cal->getTimeStamp()); |
} |
} |
class TestOfMinuteBuild extends TestOfMinute { |
function TestOfMinuteBuild() { |
$this->UnitTestCase('Test of Minute::build()'); |
} |
function testSize() { |
$this->cal->build(); |
$this->assertEqual(60,$this->cal->size()); |
} |
function testFetch() { |
$this->cal->build(); |
$i=0; |
while ( $Child = $this->cal->fetch() ) { |
$i++; |
} |
$this->assertEqual(60,$i); |
} |
function testFetchAll() { |
$this->cal->build(); |
$children = array(); |
$i = 0; |
while ( $Child = $this->cal->fetch() ) { |
$children[$i]=$Child; |
$i++; |
} |
$this->assertEqual($children,$this->cal->fetchAll()); |
} |
function testSelection() { |
require_once(CALENDAR_ROOT . 'Second.php'); |
$selection = array(new Calendar_Second(2003,10,25,13,32,43)); |
$this->cal->build($selection); |
$i = 0; |
while ( $Child = $this->cal->fetch() ) { |
if ( $i == 43 ) |
break; |
$i++; |
} |
$this->assertTrue($Child->isSelected()); |
} |
} |
if (!defined('TEST_RUNNING')) { |
define('TEST_RUNNING', true); |
$test = &new TestOfMinute(); |
$test->run(new HtmlReporter()); |
$test = &new TestOfMinuteBuild(); |
$test->run(new HtmlReporter()); |
} |
?> |
/branches/livraison_menes/api/pear/Calendar/tests/decorator_uri_test.php |
---|
New file |
0,0 → 1,37 |
<?php |
// $Id: decorator_uri_test.php,v 1.1 2005-09-30 14:58:00 ddelon Exp $ |
require_once('simple_include.php'); |
require_once('calendar_include.php'); |
require_once('./decorator_test.php'); |
class TestOfDecoratorUri extends TestOfDecorator { |
function TestOfDecoratorUri() { |
$this->UnitTestCase('Test of Calendar_Decorator_Uri'); |
} |
function testFragments() { |
$Uri = new Calendar_Decorator_Uri($this->mockcal); |
$Uri->setFragments('year','month','day','hour','minute','second'); |
$this->assertEqual('year=&month=&day=&hour=&minute=&second=',$Uri->this('second')); |
} |
function testScalarFragments() { |
$Uri = new Calendar_Decorator_Uri($this->mockcal); |
$Uri->setFragments('year','month','day','hour','minute','second'); |
$Uri->setScalar(); |
$this->assertEqual('&&&&&',$Uri->this('second')); |
} |
function testSetSeperator() { |
$Uri = new Calendar_Decorator_Uri($this->mockcal); |
$Uri->setFragments('year','month','day','hour','minute','second'); |
$Uri->setSeparator('/'); |
$this->assertEqual('year=/month=/day=/hour=/minute=/second=',$Uri->this('second')); |
} |
} |
if (!defined('TEST_RUNNING')) { |
define('TEST_RUNNING', true); |
$test = &new TestOfDecoratorUri(); |
$test->run(new HtmlReporter()); |
} |
?> |
/branches/livraison_menes/api/pear/Calendar/tests/decorator_tests.php |
---|
New file |
0,0 → 1,21 |
<?php |
// $Id: decorator_tests.php,v 1.1 2005-09-30 14:58:00 ddelon Exp $ |
require_once('simple_include.php'); |
require_once('calendar_include.php'); |
class DecoratorTests extends GroupTest { |
function DecoratorTests() { |
$this->GroupTest('Decorator Tests'); |
$this->addTestFile('decorator_test.php'); |
$this->addTestFile('decorator_textual_test.php'); |
$this->addTestFile('decorator_uri_test.php'); |
} |
} |
if (!defined('TEST_RUNNING')) { |
define('TEST_RUNNING', true); |
$test = &new DecoratorTests(); |
$test->run(new HtmlReporter()); |
} |
?> |
/branches/livraison_menes/api/pear/Calendar/tests/calendar_tabular_tests.php |
---|
New file |
0,0 → 1,21 |
<?php |
// $Id: calendar_tabular_tests.php,v 1.1 2005-09-30 14:58:00 ddelon Exp $ |
require_once('simple_include.php'); |
require_once('calendar_include.php'); |
class CalendarTabularTests extends GroupTest { |
function CalendarTabularTests() { |
$this->GroupTest('Calendar Tabular Tests'); |
$this->addTestFile('month_weekdays_test.php'); |
$this->addTestFile('month_weeks_test.php'); |
$this->addTestFile('week_test.php'); |
} |
} |
if (!defined('TEST_RUNNING')) { |
define('TEST_RUNNING', true); |
$test = &new CalendarTabularTests(); |
$test->run(new HtmlReporter()); |
} |
?> |
/branches/livraison_menes/api/pear/Calendar/tests/validator_tests.php |
---|
New file |
0,0 → 1,20 |
<?php |
// $Id: validator_tests.php,v 1.1 2005-09-30 14:58:00 ddelon Exp $ |
require_once('simple_include.php'); |
require_once('calendar_include.php'); |
class ValidatorTests extends GroupTest { |
function ValidatorTests() { |
$this->GroupTest('Validator Tests'); |
$this->addTestFile('validator_unit_test.php'); |
$this->addTestFile('validator_error_test.php'); |
} |
} |
if (!defined('TEST_RUNNING')) { |
define('TEST_RUNNING', true); |
$test = &new ValidatorTests(); |
$test->run(new HtmlReporter()); |
} |
?> |
/branches/livraison_menes/api/pear/Calendar/tests/README |
---|
New file |
0,0 → 1,7 |
These tests require Simple Test: http://www.lastcraft.com/simple_test.php |
Ideally they would use PEAR::PHPUnit but the current version has bugs and |
lacks alot of the functionality (e.g. Mock Objects) which Simple Test |
provides. |
Modifying the simple_include.php script for your simple test install dir |
/branches/livraison_menes/api/pear/Calendar/tests/table_helper_tests.php |
---|
New file |
0,0 → 1,19 |
<?php |
// $Id: table_helper_tests.php,v 1.1 2005-09-30 14:58:00 ddelon Exp $ |
require_once('simple_include.php'); |
require_once('calendar_include.php'); |
class TableHelperTests extends GroupTest { |
function TableHelperTests() { |
$this->GroupTest('Table Helper Tests'); |
$this->addTestFile('helper_test.php'); |
} |
} |
if (!defined('TEST_RUNNING')) { |
define('TEST_RUNNING', true); |
$test = &new TableHelperTests(); |
$test->run(new HtmlReporter()); |
} |
?> |
/branches/livraison_menes/api/pear/Calendar/tests/calendar_test.php |
---|
New file |
0,0 → 1,115 |
<?php |
// $Id: calendar_test.php,v 1.1 2005-09-30 14:58:00 ddelon Exp $ |
require_once('simple_include.php'); |
require_once('calendar_include.php'); |
class TestOfCalendar extends UnitTestCase { |
var $cal; |
function TestOfCalendar($name='Test of Calendar') { |
$this->UnitTestCase($name); |
} |
function setUp() { |
$this->cal = new Calendar(2003,10,25,13,32,43); |
} |
function tearDown() { |
unset($this->cal); |
} |
function testPrevYear () { |
$this->assertEqual(2002,$this->cal->prevYear()); |
} |
function testPrevYear_Array () { |
$this->assertEqual( |
array( |
'year' => 2002, |
'month' => 1, |
'day' => 1, |
'hour' => 0, |
'minute' => 0, |
'second' => 0), |
$this->cal->prevYear('array')); |
} |
function testThisYear () { |
$this->assertEqual(2003,$this->cal->thisYear()); |
} |
function testNextYear () { |
$this->assertEqual(2004,$this->cal->nextYear()); |
} |
function testPrevMonth () { |
$this->assertEqual(9,$this->cal->prevMonth()); |
} |
function testPrevMonth_Array () { |
$this->assertEqual( |
array( |
'year' => 2003, |
'month' => 9, |
'day' => 1, |
'hour' => 0, |
'minute' => 0, |
'second' => 0), |
$this->cal->prevMonth('array')); |
} |
function testThisMonth () { |
$this->assertEqual(10,$this->cal->thisMonth()); |
} |
function testNextMonth () { |
$this->assertEqual(11,$this->cal->nextMonth()); |
} |
function testPrevDay () { |
$this->assertEqual(24,$this->cal->prevDay()); |
} |
function testPrevDay_Array () { |
$this->assertEqual( |
array( |
'year' => 2003, |
'month' => 10, |
'day' => 24, |
'hour' => 0, |
'minute' => 0, |
'second' => 0), |
$this->cal->prevDay('array')); |
} |
function testThisDay () { |
$this->assertEqual(25,$this->cal->thisDay()); |
} |
function testNextDay () { |
$this->assertEqual(26,$this->cal->nextDay()); |
} |
function testPrevHour () { |
$this->assertEqual(12,$this->cal->prevHour()); |
} |
function testThisHour () { |
$this->assertEqual(13,$this->cal->thisHour()); |
} |
function testNextHour () { |
$this->assertEqual(14,$this->cal->nextHour()); |
} |
function testPrevMinute () { |
$this->assertEqual(31,$this->cal->prevMinute()); |
} |
function testThisMinute () { |
$this->assertEqual(32,$this->cal->thisMinute()); |
} |
function testNextMinute () { |
$this->assertEqual(33,$this->cal->nextMinute()); |
} |
function testPrevSecond () { |
$this->assertEqual(42,$this->cal->prevSecond()); |
} |
function testThisSecond () { |
$this->assertEqual(43,$this->cal->thisSecond()); |
} |
function testNextSecond () { |
$this->assertEqual(44,$this->cal->nextSecond()); |
} |
function testSetTimeStamp() { |
$stamp = mktime(13,32,43,10,25,2003); |
$this->cal->setTimeStamp($stamp); |
$this->assertEqual($stamp,$this->cal->getTimeStamp()); |
} |
function testGetTimeStamp() { |
$stamp = mktime(13,32,43,10,25,2003); |
$this->assertEqual($stamp,$this->cal->getTimeStamp()); |
} |
} |
?> |
/branches/livraison_menes/api/pear/Calendar/tests/peardate_engine_test.php |
---|
New file |
0,0 → 1,124 |
<?php |
// $Id: peardate_engine_test.php,v 1.1 2005-09-30 14:58:00 ddelon Exp $ |
require_once('simple_include.php'); |
require_once('calendar_include.php'); |
class TestOfPearDateEngine extends UnitTestCase { |
var $engine; |
function TestOfPearDateEngine() { |
$this->UnitTestCase('Test of Calendar_Engine_PearDate'); |
} |
function setUp() { |
$this->engine = new Calendar_Engine_PearDate(); |
} |
function testGetSecondsInMinute() { |
$this->assertEqual($this->engine->getSecondsInMinute(),60); |
} |
function testGetMinutesInHour() { |
$this->assertEqual($this->engine->getMinutesInHour(),60); |
} |
function testGetHoursInDay() { |
$this->assertEqual($this->engine->getHoursInDay(),24); |
} |
function testGetFirstDayOfWeek() { |
$this->assertEqual($this->engine->getFirstDayOfWeek(),1); |
} |
function testGetWeekDays() { |
$this->assertEqual($this->engine->getWeekDays(),array(0,1,2,3,4,5,6)); |
} |
function testGetDaysInWeek() { |
$this->assertEqual($this->engine->getDaysInWeek(),7); |
} |
function testGetWeekNInYear() { |
$this->assertEqual($this->engine->getWeekNInYear(2003, 11, 3), 45); |
} |
function testGetWeekNInMonth() { |
$this->assertEqual($this->engine->getWeekNInMonth(2003, 11, 3), 2); |
} |
function testGetWeeksInMonth0() { |
$this->assertEqual($this->engine->getWeeksInMonth(2003, 11, 0), 6); //week starts on sunday |
} |
function testGetWeeksInMonth1() { |
$this->assertEqual($this->engine->getWeeksInMonth(2003, 11, 1), 5); //week starts on monday |
} |
function testGetWeeksInMonth2() { |
$this->assertEqual($this->engine->getWeeksInMonth(2003, 2, 6), 4); //week starts on saturday |
} |
function testGetWeeksInMonth3() { |
// Unusual cases that can cause fails (shows up with example 21.php) |
$this->assertEqual($this->engine->getWeeksInMonth(2004,2,1),5); |
$this->assertEqual($this->engine->getWeeksInMonth(2004,8,1),6); |
} |
function testGetDayOfWeek() { |
$this->assertEqual($this->engine->getDayOfWeek(2003, 11, 18), 2); |
} |
function testGetFirstDayInMonth() { |
$this->assertEqual($this->engine->getFirstDayInMonth(2003,10),3); |
} |
function testGetDaysInMonth() { |
$this->assertEqual($this->engine->getDaysInMonth(2003,10),31); |
} |
function testGetMinYears() { |
$this->assertEqual($this->engine->getMinYears(),0); |
} |
function testGetMaxYears() { |
$this->assertEqual($this->engine->getMaxYears(),9999); |
} |
function testDateToStamp() { |
$stamp = '2003-10-15 13:30:45'; |
$this->assertEqual($this->engine->dateToStamp(2003,10,15,13,30,45),$stamp); |
} |
function testStampToSecond() { |
$stamp = '2003-10-15 13:30:45'; |
$this->assertEqual($this->engine->stampToSecond($stamp),45); |
} |
function testStampToMinute() { |
$stamp = '2003-10-15 13:30:45'; |
$this->assertEqual($this->engine->stampToMinute($stamp),30); |
} |
function testStampToHour() { |
$stamp = '2003-10-15 13:30:45'; |
$this->assertEqual($this->engine->stampToHour($stamp),13); |
} |
function testStampToDay() { |
$stamp = '2003-10-15 13:30:45'; |
$this->assertEqual($this->engine->stampToDay($stamp),15); |
} |
function testStampToMonth() { |
$stamp = '2003-10-15 13:30:45'; |
$this->assertEqual($this->engine->stampToMonth($stamp),10); |
} |
function testStampToYear() { |
$stamp = '2003-10-15 13:30:45'; |
$this->assertEqual($this->engine->stampToYear($stamp),2003); |
} |
function testAdjustDate() { |
$stamp = '2004-01-01 13:30:45'; |
$y = $this->engine->stampToYear($stamp); |
$m = $this->engine->stampToMonth($stamp); |
$d = $this->engine->stampToDay($stamp); |
//the first day of the month should be thursday |
$this->assertEqual($this->engine->getDayOfWeek($y, $m, $d), 4); |
$m--; // 2004-00-01 => 2003-12-01 |
$this->engine->adjustDate($y, $m, $d, $dummy, $dummy, $dummy); |
$this->assertEqual($y, 2003); |
$this->assertEqual($m, 12); |
$this->assertEqual($d, 1); |
// get last day and check if it's wednesday |
$d = $this->engine->getDaysInMonth($y, $m); |
$this->assertEqual($this->engine->getDayOfWeek($y, $m, $d), 3); |
} |
} |
if (!defined('TEST_RUNNING')) { |
define('TEST_RUNNING', true); |
$test = &new TestOfPearDateEngine(); |
$test->run(new HtmlReporter()); |
} |
?> |
/branches/livraison_menes/api/pear/Calendar/tests/second_test.php |
---|
New file |
0,0 → 1,34 |
<?php |
// $Id: second_test.php,v 1.1 2005-09-30 14:58:00 ddelon Exp $ |
require_once('simple_include.php'); |
require_once('calendar_include.php'); |
require_once('./calendar_test.php'); |
class TestOfSecond extends TestOfCalendar { |
function TestOfSecond() { |
$this->UnitTestCase('Test of Second'); |
} |
function setUp() { |
$this->cal = new Calendar_Second(2003,10,25,13,32,43); |
} |
function testPrevDay_Array () { |
$this->assertEqual( |
array( |
'year' => 2003, |
'month' => 10, |
'day' => 24, |
'hour' => 0, |
'minute' => 0, |
'second' => 0), |
$this->cal->prevDay('array')); |
} |
} |
if (!defined('TEST_RUNNING')) { |
define('TEST_RUNNING', true); |
$test = &new TestOfSecond(); |
$test->run(new HtmlReporter()); |
} |
?> |
/branches/livraison_menes/api/pear/Calendar/tests/calendar_include.php |
---|
New file |
0,0 → 1,28 |
<?php |
// $Id: calendar_include.php,v 1.1 2005-09-30 14:58:00 ddelon Exp $ |
if ( !@include 'Calendar/Calendar.php' ) { |
@define('CALENDAR_ROOT','../'); |
} |
require_once(CALENDAR_ROOT . 'Year.php'); |
require_once(CALENDAR_ROOT . 'Month.php'); |
require_once(CALENDAR_ROOT . 'Day.php'); |
require_once(CALENDAR_ROOT . 'Week.php'); |
require_once(CALENDAR_ROOT . 'Hour.php'); |
require_once(CALENDAR_ROOT . 'Minute.php'); |
require_once(CALENDAR_ROOT . 'Second.php'); |
require_once(CALENDAR_ROOT . 'Month.php'); |
require_once(CALENDAR_ROOT . 'Decorator.php'); |
require_once(CALENDAR_ROOT . 'Month/Weekdays.php'); |
require_once(CALENDAR_ROOT . 'Month/Weeks.php'); |
require_once(CALENDAR_ROOT . 'Validator.php'); |
require_once(CALENDAR_ROOT . 'Engine/Interface.php'); |
require_once(CALENDAR_ROOT . 'Engine/UnixTs.php'); |
require_once(CALENDAR_ROOT . 'Engine/PearDate.php'); |
require_once(CALENDAR_ROOT . 'Table/Helper.php'); |
require_once(CALENDAR_ROOT . 'Decorator/Textual.php'); |
require_once(CALENDAR_ROOT . 'Decorator/Uri.php'); |
require_once(CALENDAR_ROOT . 'Decorator/Weekday.php'); |
require_once(CALENDAR_ROOT . 'Decorator/Wrapper.php'); |
require_once(CALENDAR_ROOT . 'Util/Uri.php'); |
require_once(CALENDAR_ROOT . 'Util/Textual.php'); |
?> |
/branches/livraison_menes/api/pear/Calendar/tests/day_test.php |
---|
New file |
0,0 → 1,107 |
<?php |
// $Id: day_test.php,v 1.1 2005-09-30 14:58:00 ddelon Exp $ |
require_once('simple_include.php'); |
require_once('calendar_include.php'); |
require_once('./calendar_test.php'); |
class TestOfDay extends TestOfCalendar { |
function TestOfDay() { |
$this->UnitTestCase('Test of Day'); |
} |
function setUp() { |
$this->cal = new Calendar_Day(2003,10,25); |
} |
function testPrevDay_Array () { |
$this->assertEqual( |
array( |
'year' => 2003, |
'month' => 10, |
'day' => 24, |
'hour' => 0, |
'minute' => 0, |
'second' => 0), |
$this->cal->prevDay('array')); |
} |
function testPrevHour () { |
$this->assertEqual(23,$this->cal->prevHour()); |
} |
function testThisHour () { |
$this->assertEqual(0,$this->cal->thisHour()); |
} |
function testNextHour () { |
$this->assertEqual(1,$this->cal->nextHour()); |
} |
function testPrevMinute () { |
$this->assertEqual(59,$this->cal->prevMinute()); |
} |
function testThisMinute () { |
$this->assertEqual(0,$this->cal->thisMinute()); |
} |
function testNextMinute () { |
$this->assertEqual(1,$this->cal->nextMinute()); |
} |
function testPrevSecond () { |
$this->assertEqual(59,$this->cal->prevSecond()); |
} |
function testThisSecond () { |
$this->assertEqual(0,$this->cal->thisSecond()); |
} |
function testNextSecond () { |
$this->assertEqual(1,$this->cal->nextSecond()); |
} |
function testGetTimeStamp() { |
$stamp = mktime(0,0,0,10,25,2003); |
$this->assertEqual($stamp,$this->cal->getTimeStamp()); |
} |
} |
class TestOfDayBuild extends TestOfDay { |
function TestOfDayBuild() { |
$this->UnitTestCase('Test of Day::build()'); |
} |
function testSize() { |
$this->cal->build(); |
$this->assertEqual(24,$this->cal->size()); |
} |
function testFetch() { |
$this->cal->build(); |
$i=0; |
while ( $Child = $this->cal->fetch() ) { |
$i++; |
} |
$this->assertEqual(24,$i); |
} |
function testFetchAll() { |
$this->cal->build(); |
$children = array(); |
$i = 0; |
while ( $Child = $this->cal->fetch() ) { |
$children[$i]=$Child; |
$i++; |
} |
$this->assertEqual($children,$this->cal->fetchAll()); |
} |
function testSelection() { |
require_once(CALENDAR_ROOT . 'Hour.php'); |
$selection = array(new Calendar_Hour(2003,10,25,13)); |
$this->cal->build($selection); |
$i = 0; |
while ( $Child = $this->cal->fetch() ) { |
if ( $i == 13 ) |
break; |
$i++; |
} |
$this->assertTrue($Child->isSelected()); |
} |
} |
if (!defined('TEST_RUNNING')) { |
define('TEST_RUNNING', true); |
$test = &new TestOfDay(); |
$test->run(new HtmlReporter()); |
$test = &new TestOfDayBuild(); |
$test->run(new HtmlReporter()); |
} |
?> |
/branches/livraison_menes/api/pear/Calendar/tests/hour_test.php |
---|
New file |
0,0 → 1,98 |
<?php |
// $Id: hour_test.php,v 1.1 2005-09-30 14:58:00 ddelon Exp $ |
require_once('simple_include.php'); |
require_once('calendar_include.php'); |
require_once('./calendar_test.php'); |
class TestOfHour extends TestOfCalendar { |
function TestOfHour() { |
$this->UnitTestCase('Test of Hour'); |
} |
function setUp() { |
$this->cal = new Calendar_Hour(2003,10,25,13); |
} |
function testPrevDay_Array () { |
$this->assertEqual( |
array( |
'year' => 2003, |
'month' => 10, |
'day' => 24, |
'hour' => 0, |
'minute' => 0, |
'second' => 0), |
$this->cal->prevDay('array')); |
} |
function testPrevMinute () { |
$this->assertEqual(59,$this->cal->prevMinute()); |
} |
function testThisMinute () { |
$this->assertEqual(0,$this->cal->thisMinute()); |
} |
function testNextMinute () { |
$this->assertEqual(1,$this->cal->nextMinute()); |
} |
function testPrevSecond () { |
$this->assertEqual(59,$this->cal->prevSecond()); |
} |
function testThisSecond () { |
$this->assertEqual(0,$this->cal->thisSecond()); |
} |
function testNextSecond () { |
$this->assertEqual(1,$this->cal->nextSecond()); |
} |
function testGetTimeStamp() { |
$stamp = mktime(13,0,0,10,25,2003); |
$this->assertEqual($stamp,$this->cal->getTimeStamp()); |
} |
} |
class TestOfHourBuild extends TestOfHour { |
function TestOfHourBuild() { |
$this->UnitTestCase('Test of Hour::build()'); |
} |
function testSize() { |
$this->cal->build(); |
$this->assertEqual(60,$this->cal->size()); |
} |
function testFetch() { |
$this->cal->build(); |
$i=0; |
while ( $Child = $this->cal->fetch() ) { |
$i++; |
} |
$this->assertEqual(60,$i); |
} |
function testFetchAll() { |
$this->cal->build(); |
$children = array(); |
$i = 0; |
while ( $Child = $this->cal->fetch() ) { |
$children[$i]=$Child; |
$i++; |
} |
$this->assertEqual($children,$this->cal->fetchAll()); |
} |
function testSelection() { |
require_once(CALENDAR_ROOT . 'Minute.php'); |
$selection = array(new Calendar_Minute(2003,10,25,13,32)); |
$this->cal->build($selection); |
$i = 0; |
while ( $Child = $this->cal->fetch() ) { |
if ( $i == 32 ) |
break; |
$i++; |
} |
$this->assertTrue($Child->isSelected()); |
} |
} |
if (!defined('TEST_RUNNING')) { |
define('TEST_RUNNING', true); |
$test = &new TestOfHour(); |
$test->run(new HtmlReporter()); |
$test = &new TestOfHourBuild(); |
$test->run(new HtmlReporter()); |
} |
?> |
/branches/livraison_menes/api/pear/Calendar/tests/unixts_engine_test.php |
---|
New file |
0,0 → 1,104 |
<?php |
// $Id: unixts_engine_test.php,v 1.1 2005-09-30 14:58:00 ddelon Exp $ |
require_once('simple_include.php'); |
require_once('calendar_include.php'); |
class TestOfUnixTsEngine extends UnitTestCase { |
var $engine; |
function TestOfUnixTsEngine() { |
$this->UnitTestCase('Test of Calendar_Engine_UnixTs'); |
} |
function setUp() { |
$this->engine = new Calendar_Engine_UnixTs(); |
} |
function testGetSecondsInMinute() { |
$this->assertEqual($this->engine->getSecondsInMinute(),60); |
} |
function testGetMinutesInHour() { |
$this->assertEqual($this->engine->getMinutesInHour(),60); |
} |
function testGetHoursInDay() { |
$this->assertEqual($this->engine->getHoursInDay(),24); |
} |
function testGetFirstDayOfWeek() { |
$this->assertEqual($this->engine->getFirstDayOfWeek(),1); |
} |
function testGetWeekDays() { |
$this->assertEqual($this->engine->getWeekDays(),array(0,1,2,3,4,5,6)); |
} |
function testGetDaysInWeek() { |
$this->assertEqual($this->engine->getDaysInWeek(),7); |
} |
function testGetWeekNInYear() { |
$this->assertEqual($this->engine->getWeekNInYear(2003, 11, 3), 45); |
} |
function testGetWeekNInMonth() { |
$this->assertEqual($this->engine->getWeekNInMonth(2003, 11, 3), 2); |
} |
function testGetWeeksInMonth0() { |
$this->assertEqual($this->engine->getWeeksInMonth(2003, 11, 0), 6); //week starts on sunday |
} |
function testGetWeeksInMonth1() { |
$this->assertEqual($this->engine->getWeeksInMonth(2003, 11, 1), 5); //week starts on monday |
} |
function testGetWeeksInMonth2() { |
$this->assertEqual($this->engine->getWeeksInMonth(2003, 2, 6), 4); //week starts on saturday |
} |
function testGetWeeksInMonth3() { |
// Unusual cases that can cause fails (shows up with example 21.php) |
$this->assertEqual($this->engine->getWeeksInMonth(2004,2,1),5); |
$this->assertEqual($this->engine->getWeeksInMonth(2004,8,1),6); |
} |
function testGetDayOfWeek() { |
$this->assertEqual($this->engine->getDayOfWeek(2003, 11, 18), 2); |
} |
function testGetFirstDayInMonth() { |
$this->assertEqual($this->engine->getFirstDayInMonth(2003,10),3); |
} |
function testGetDaysInMonth() { |
$this->assertEqual($this->engine->getDaysInMonth(2003,10),31); |
} |
function testGetMinYears() { |
$test = strpos(PHP_OS, 'WIN') >= 0 ? 1970 : 1902; |
$this->assertEqual($this->engine->getMinYears(),$test); |
} |
function testGetMaxYears() { |
$this->assertEqual($this->engine->getMaxYears(),2037); |
} |
function testDateToStamp() { |
$stamp = mktime(0,0,0,10,15,2003); |
$this->assertEqual($this->engine->dateToStamp(2003,10,15,0,0,0),$stamp); |
} |
function testStampToSecond() { |
$stamp = mktime(13,30,45,10,15,2003); |
$this->assertEqual($this->engine->stampToSecond($stamp),45); |
} |
function testStampToMinute() { |
$stamp = mktime(13,30,45,10,15,2003); |
$this->assertEqual($this->engine->stampToMinute($stamp),30); |
} |
function testStampToHour() { |
$stamp = mktime(13,30,45,10,15,2003); |
$this->assertEqual($this->engine->stampToHour($stamp),13); |
} |
function testStampToDay() { |
$stamp = mktime(13,30,45,10,15,2003); |
$this->assertEqual($this->engine->stampToDay($stamp),15); |
} |
function testStampToMonth() { |
$stamp = mktime(13,30,45,10,15,2003); |
$this->assertEqual($this->engine->stampToMonth($stamp),10); |
} |
function testStampToYear() { |
$stamp = mktime(13,30,45,10,15,2003); |
$this->assertEqual($this->engine->stampToYear($stamp),2003); |
} |
} |
if (!defined('TEST_RUNNING')) { |
define('TEST_RUNNING', true); |
$test = &new TestOfUnixTsEngine(); |
$test->run(new HtmlReporter()); |
} |
?> |
/branches/livraison_menes/api/pear/Calendar/tests/helper_test.php |
---|
New file |
0,0 → 1,83 |
<?php |
// $Id: helper_test.php,v 1.1 2005-09-30 14:58:00 ddelon Exp $ |
require_once('simple_include.php'); |
require_once('calendar_include.php'); |
Mock::generate('Calendar_Engine_Interface','Mock_Calendar_Engine'); |
Mock::generate('Calendar_Second','Mock_Calendar_Second'); |
class TestOfTableHelper extends UnitTestCase { |
var $mockengine; |
var $mockcal; |
function TestOfTableHelper() { |
$this->UnitTestCase('Test of Calendar_Table_Helper'); |
} |
function setUp() { |
$this->mockengine = new Mock_Calendar_Engine($this); |
$this->mockengine->setReturnValue('getMinYears',1970); |
$this->mockengine->setReturnValue('getMaxYears',2037); |
$this->mockengine->setReturnValue('getMonthsInYear',12); |
$this->mockengine->setReturnValue('getDaysInMonth',31); |
$this->mockengine->setReturnValue('getHoursInDay',24); |
$this->mockengine->setReturnValue('getMinutesInHour',60); |
$this->mockengine->setReturnValue('getSecondsInMinute',60); |
$this->mockengine->setReturnValue('getWeekDays',array(0,1,2,3,4,5,6)); |
$this->mockengine->setReturnValue('getDaysInWeek',7); |
$this->mockengine->setReturnValue('getFirstDayOfWeek',1); |
$this->mockengine->setReturnValue('getFirstDayInMonth',3); |
$this->mockcal = new Mock_Calendar_Second($this); |
$this->mockcal->setReturnValue('thisYear',2003); |
$this->mockcal->setReturnValue('thisMonth',10); |
$this->mockcal->setReturnValue('thisDay',15); |
$this->mockcal->setReturnValue('thisHour',13); |
$this->mockcal->setReturnValue('thisMinute',30); |
$this->mockcal->setReturnValue('thisSecond',45); |
$this->mockcal->setReturnValue('getEngine',$this->mockengine); |
} |
function testGetFirstDay() { |
for ( $i = 0; $i <= 7; $i++ ) { |
$Helper = & new Calendar_Table_Helper($this->mockcal,$i); |
$this->assertEqual($Helper->getFirstDay(),$i); |
} |
} |
function testGetDaysOfWeekMonday() { |
$Helper = & new Calendar_Table_Helper($this->mockcal); |
$this->assertEqual($Helper->getDaysOfWeek(),array(1,2,3,4,5,6,0)); |
} |
function testGetDaysOfWeekSunday() { |
$Helper = & new Calendar_Table_Helper($this->mockcal,0); |
$this->assertEqual($Helper->getDaysOfWeek(),array(0,1,2,3,4,5,6)); |
} |
function testGetDaysOfWeekThursday() { |
$Helper = & new Calendar_Table_Helper($this->mockcal,4); |
$this->assertEqual($Helper->getDaysOfWeek(),array(4,5,6,0,1,2,3)); |
} |
function testGetNumWeeks() { |
$Helper = & new Calendar_Table_Helper($this->mockcal); |
$this->assertEqual($Helper->getNumWeeks(),5); |
} |
function testGetNumTableDaysInMonth() { |
$Helper = & new Calendar_Table_Helper($this->mockcal); |
$this->assertEqual($Helper->getNumTableDaysInMonth(),35); |
} |
function testGetEmptyDaysBefore() { |
$Helper = & new Calendar_Table_Helper($this->mockcal); |
$this->assertEqual($Helper->getEmptyDaysBefore(),2); |
} |
function testGetEmptyDaysAfter() { |
$Helper = & new Calendar_Table_Helper($this->mockcal); |
$this->assertEqual($Helper->getEmptyDaysAfter(),33); |
} |
function testGetEmptyDaysAfterOffset() { |
$Helper = & new Calendar_Table_Helper($this->mockcal); |
$this->assertEqual($Helper->getEmptyDaysAfterOffset(),5); |
} |
} |
if (!defined('TEST_RUNNING')) { |
define('TEST_RUNNING', true); |
$test = &new TestOfTableHelper(); |
$test->run(new HtmlReporter()); |
} |
?> |
/branches/livraison_menes/api/pear/Calendar/tests/month_weekdays_test.php |
---|
New file |
0,0 → 1,130 |
<?php |
// $Id: month_weekdays_test.php,v 1.1 2005-09-30 14:58:00 ddelon Exp $ |
require_once('simple_include.php'); |
require_once('calendar_include.php'); |
require_once('./calendar_test.php'); |
class TestOfMonthWeekdays extends TestOfCalendar { |
function TestOfMonthWeekdays() { |
$this->UnitTestCase('Test of Month Weekdays'); |
} |
function setUp() { |
$this->cal = new Calendar_Month_Weekdays(2003,10); |
} |
function testPrevDay () { |
$this->assertEqual(30,$this->cal->prevDay()); |
} |
function testPrevDay_Array () { |
$this->assertEqual( |
array( |
'year' => 2003, |
'month' => 9, |
'day' => 30, |
'hour' => 0, |
'minute' => 0, |
'second' => 0), |
$this->cal->prevDay('array')); |
} |
function testThisDay () { |
$this->assertEqual(1,$this->cal->thisDay()); |
} |
function testNextDay () { |
$this->assertEqual(2,$this->cal->nextDay()); |
} |
function testPrevHour () { |
$this->assertEqual(23,$this->cal->prevHour()); |
} |
function testThisHour () { |
$this->assertEqual(0,$this->cal->thisHour()); |
} |
function testNextHour () { |
$this->assertEqual(1,$this->cal->nextHour()); |
} |
function testPrevMinute () { |
$this->assertEqual(59,$this->cal->prevMinute()); |
} |
function testThisMinute () { |
$this->assertEqual(0,$this->cal->thisMinute()); |
} |
function testNextMinute () { |
$this->assertEqual(1,$this->cal->nextMinute()); |
} |
function testPrevSecond () { |
$this->assertEqual(59,$this->cal->prevSecond()); |
} |
function testThisSecond () { |
$this->assertEqual(0,$this->cal->thisSecond()); |
} |
function testNextSecond () { |
$this->assertEqual(1,$this->cal->nextSecond()); |
} |
function testGetTimeStamp() { |
$stamp = mktime(0,0,0,10,1,2003); |
$this->assertEqual($stamp,$this->cal->getTimeStamp()); |
} |
} |
class TestOfMonthWeekdaysBuild extends TestOfMonthWeekdays { |
function TestOfMonthWeekdaysBuild() { |
$this->UnitTestCase('Test of Month_Weekdays::build()'); |
} |
function testSize() { |
$this->cal->build(); |
$this->assertEqual(35,$this->cal->size()); |
} |
function testFetch() { |
$this->cal->build(); |
$i=0; |
while ( $Child = $this->cal->fetch() ) { |
$i++; |
} |
$this->assertEqual(35,$i); |
} |
function testFetchAll() { |
$this->cal->build(); |
$children = array(); |
$i = 1; |
while ( $Child = $this->cal->fetch() ) { |
$children[$i]=$Child; |
$i++; |
} |
$this->assertEqual($children,$this->cal->fetchAll()); |
} |
function testSelection() { |
require_once(CALENDAR_ROOT . 'Day.php'); |
$selection = array(new Calendar_Day(2003,10,25)); |
$this->cal->build($selection); |
$i = 1; |
while ( $Child = $this->cal->fetch() ) { |
if ( $i == 27 ) |
break; |
$i++; |
} |
$this->assertTrue($Child->isSelected()); |
} |
function testEmptyCount() { |
$this->cal->build(); |
$empty = 0; |
while ( $Child = $this->cal->fetch() ) { |
if ( $Child->isEmpty() ) |
$empty++; |
} |
$this->assertEqual(4,$empty); |
} |
function testEmptyDaysBefore_AfterAdjust() { |
$this->cal = new Calendar_Month_Weekdays(2004,0); |
$this->cal->build(); |
$this->assertEqual(0,$this->cal->tableHelper->getEmptyDaysBefore()); |
} |
} |
if (!defined('TEST_RUNNING')) { |
define('TEST_RUNNING', true); |
$test = &new TestOfMonthWeekdays(); |
$test->run(new HtmlReporter()); |
$test = &new TestOfMonthWeekdaysBuild(); |
$test->run(new HtmlReporter()); |
} |
?> |
/branches/livraison_menes/api/pear/Calendar/tests/calendar_engine_tests.php |
---|
New file |
0,0 → 1,20 |
<?php |
// $Id: calendar_engine_tests.php,v 1.1 2005-09-30 14:58:00 ddelon Exp $ |
require_once('simple_include.php'); |
require_once('calendar_include.php'); |
class CalendarEngineTests extends GroupTest { |
function CalendarEngineTests() { |
$this->GroupTest('Calendar Engine Tests'); |
$this->addTestFile('peardate_engine_test.php'); |
$this->addTestFile('unixts_engine_test.php'); |
} |
} |
if (!defined('TEST_RUNNING')) { |
define('TEST_RUNNING', true); |
$test = &new CalendarEngineTests(); |
$test->run(new HtmlReporter()); |
} |
?> |
/branches/livraison_menes/api/pear/Calendar/tests/decorator_test.php |
---|
New file |
0,0 → 1,268 |
<?php |
// $Id: decorator_test.php,v 1.1 2005-09-30 14:58:00 ddelon Exp $ |
require_once('simple_include.php'); |
require_once('calendar_include.php'); |
Mock::generate('Calendar_Engine_Interface','Mock_Calendar_Engine'); |
Mock::generate('Calendar_Second','Mock_Calendar_Second'); |
Mock::generate('Calendar_Week','Mock_Calendar_Week'); |
Mock::generate('Calendar_Day','Mock_Calendar_Day'); |
class TestOfDecorator extends UnitTestCase { |
var $mockengine; |
var $mockcal; |
var $decorator; |
function TestOfDecorator() { |
$this->UnitTestCase('Test of Calendar_Decorator'); |
} |
function setUp() { |
$this->mockengine = new Mock_Calendar_Engine($this); |
$this->mockcal = new Mock_Calendar_Second($this); |
$this->mockcal->setReturnValue('prevYear',2002); |
$this->mockcal->setReturnValue('thisYear',2003); |
$this->mockcal->setReturnValue('nextYear',2004); |
$this->mockcal->setReturnValue('prevMonth',9); |
$this->mockcal->setReturnValue('thisMonth',10); |
$this->mockcal->setReturnValue('nextMonth',11); |
$this->mockcal->setReturnValue('prevDay',14); |
$this->mockcal->setReturnValue('thisDay',15); |
$this->mockcal->setReturnValue('nextDay',16); |
$this->mockcal->setReturnValue('prevHour',12); |
$this->mockcal->setReturnValue('thisHour',13); |
$this->mockcal->setReturnValue('nextHour',14); |
$this->mockcal->setReturnValue('prevMinute',29); |
$this->mockcal->setReturnValue('thisMinute',30); |
$this->mockcal->setReturnValue('nextMinute',31); |
$this->mockcal->setReturnValue('prevSecond',44); |
$this->mockcal->setReturnValue('thisSecond',45); |
$this->mockcal->setReturnValue('nextSecond',46); |
$this->mockcal->setReturnValue('getEngine',$this->mockengine); |
$this->mockcal->setReturnValue('getTimestamp',12345); |
} |
function tearDown() { |
unset ( $this->engine ); |
unset ( $this->mockcal ); |
} |
function testPrevYear() { |
$this->mockcal->expectOnce('prevYear',array('int')); |
$Decorator =& new Calendar_Decorator($this->mockcal); |
$this->assertEqual(2002,$Decorator->prevYear()); |
} |
function testThisYear() { |
$this->mockcal->expectOnce('thisYear',array('int')); |
$Decorator =& new Calendar_Decorator($this->mockcal); |
$this->assertEqual(2003,$Decorator->thisYear()); |
} |
function testNextYear() { |
$this->mockcal->expectOnce('nextYear',array('int')); |
$Decorator =& new Calendar_Decorator($this->mockcal); |
$this->assertEqual(2004,$Decorator->nextYear()); |
} |
function testPrevMonth() { |
$this->mockcal->expectOnce('prevMonth',array('int')); |
$Decorator =& new Calendar_Decorator($this->mockcal); |
$this->assertEqual(9,$Decorator->prevMonth()); |
} |
function testThisMonth() { |
$this->mockcal->expectOnce('thisMonth',array('int')); |
$Decorator =& new Calendar_Decorator($this->mockcal); |
$this->assertEqual(10,$Decorator->thisMonth()); |
} |
function testNextMonth() { |
$this->mockcal->expectOnce('nextMonth',array('int')); |
$Decorator =& new Calendar_Decorator($this->mockcal); |
$this->assertEqual(11,$Decorator->nextMonth()); |
} |
function testPrevWeek() { |
$mockweek = & new Mock_Calendar_Week($this); |
$mockweek->setReturnValue('prevWeek',1); |
$mockweek->expectOnce('prevWeek',array('n_in_month')); |
$Decorator =& new Calendar_Decorator($mockweek); |
$this->assertEqual(1,$Decorator->prevWeek()); |
} |
function testThisWeek() { |
$mockweek = & new Mock_Calendar_Week($this); |
$mockweek->setReturnValue('thisWeek',2); |
$mockweek->expectOnce('thisWeek',array('n_in_month')); |
$Decorator =& new Calendar_Decorator($mockweek); |
$this->assertEqual(2,$Decorator->thisWeek()); |
} |
function testNextWeek() { |
$mockweek = & new Mock_Calendar_Week($this); |
$mockweek->setReturnValue('nextWeek',3); |
$mockweek->expectOnce('nextWeek',array('n_in_month')); |
$Decorator =& new Calendar_Decorator($mockweek); |
$this->assertEqual(3,$Decorator->nextWeek()); |
} |
function testPrevDay() { |
$this->mockcal->expectOnce('prevDay',array('int')); |
$Decorator =& new Calendar_Decorator($this->mockcal); |
$this->assertEqual(14,$Decorator->prevDay()); |
} |
function testThisDay() { |
$this->mockcal->expectOnce('thisDay',array('int')); |
$Decorator =& new Calendar_Decorator($this->mockcal); |
$this->assertEqual(15,$Decorator->thisDay()); |
} |
function testNextDay() { |
$this->mockcal->expectOnce('nextDay',array('int')); |
$Decorator =& new Calendar_Decorator($this->mockcal); |
$this->assertEqual(16,$Decorator->nextDay()); |
} |
function testPrevHour() { |
$this->mockcal->expectOnce('prevHour',array('int')); |
$Decorator =& new Calendar_Decorator($this->mockcal); |
$this->assertEqual(12,$Decorator->prevHour()); |
} |
function testThisHour() { |
$this->mockcal->expectOnce('thisHour',array('int')); |
$Decorator =& new Calendar_Decorator($this->mockcal); |
$this->assertEqual(13,$Decorator->thisHour()); |
} |
function testNextHour() { |
$this->mockcal->expectOnce('nextHour',array('int')); |
$Decorator =& new Calendar_Decorator($this->mockcal); |
$this->assertEqual(14,$Decorator->nextHour()); |
} |
function testPrevMinute() { |
$this->mockcal->expectOnce('prevMinute',array('int')); |
$Decorator =& new Calendar_Decorator($this->mockcal); |
$this->assertEqual(29,$Decorator->prevMinute()); |
} |
function testThisMinute() { |
$this->mockcal->expectOnce('thisMinute',array('int')); |
$Decorator =& new Calendar_Decorator($this->mockcal); |
$this->assertEqual(30,$Decorator->thisMinute()); |
} |
function testNextMinute() { |
$this->mockcal->expectOnce('nextMinute',array('int')); |
$Decorator =& new Calendar_Decorator($this->mockcal); |
$this->assertEqual(31,$Decorator->nextMinute()); |
} |
function testPrevSecond() { |
$this->mockcal->expectOnce('prevSecond',array('int')); |
$Decorator =& new Calendar_Decorator($this->mockcal); |
$this->assertEqual(44,$Decorator->prevSecond()); |
} |
function testThisSecond() { |
$this->mockcal->expectOnce('thisSecond',array('int')); |
$Decorator =& new Calendar_Decorator($this->mockcal); |
$this->assertEqual(45,$Decorator->thisSecond()); |
} |
function testNextSecond() { |
$this->mockcal->expectOnce('nextSecond',array('int')); |
$Decorator =& new Calendar_Decorator($this->mockcal); |
$this->assertEqual(46,$Decorator->nextSecond()); |
} |
function testGetEngine() { |
$Decorator =& new Calendar_Decorator($this->mockcal); |
$this->assertIsA($Decorator->getEngine(),'Mock_Calendar_Engine'); |
} |
function testSetTimestamp() { |
$this->mockcal->expectOnce('setTimestamp',array('12345')); |
$Decorator =& new Calendar_Decorator($this->mockcal); |
$Decorator->setTimestamp('12345'); |
} |
function testGetTimestamp() { |
$Decorator =& new Calendar_Decorator($this->mockcal); |
$this->assertEqual(12345,$Decorator->getTimestamp()); |
} |
function testSetSelected() { |
$this->mockcal->expectOnce('setSelected',array(true)); |
$Decorator =& new Calendar_Decorator($this->mockcal); |
$Decorator->setSelected(); |
} |
function testIsSelected() { |
$this->mockcal->setReturnValue('isSelected',true); |
$Decorator =& new Calendar_Decorator($this->mockcal); |
$this->assertTrue($Decorator->isSelected()); |
} |
function testAdjust() { |
$this->mockcal->expectOnce('adjust',array()); |
$Decorator =& new Calendar_Decorator($this->mockcal); |
$Decorator->adjust(); |
} |
function testToArray() { |
$this->mockcal->expectOnce('toArray',array(12345)); |
$testArray = array('foo'=>'bar'); |
$this->mockcal->setReturnValue('toArray',$testArray); |
$Decorator =& new Calendar_Decorator($this->mockcal); |
$this->assertEqual($testArray,$Decorator->toArray(12345)); |
} |
function testReturnValue() { |
$this->mockcal->expectOnce('returnValue',array('a','b','c','d')); |
$this->mockcal->setReturnValue('returnValue','foo'); |
$Decorator =& new Calendar_Decorator($this->mockcal); |
$this->assertEqual('foo',$Decorator->returnValue('a','b','c','d')); |
} |
function testSetFirst() { |
$mockday = & new Mock_Calendar_Day($this); |
$mockday->expectOnce('setFirst',array(true)); |
$Decorator =& new Calendar_Decorator($mockday); |
$Decorator->setFirst(); |
} |
function testSetLast() { |
$mockday = & new Mock_Calendar_Day($this); |
$mockday->expectOnce('setLast',array(true)); |
$Decorator =& new Calendar_Decorator($mockday); |
$Decorator->setLast(); |
} |
function testIsFirst() { |
$mockday = & new Mock_Calendar_Day($this); |
$mockday->setReturnValue('isFirst',TRUE); |
$Decorator =& new Calendar_Decorator($mockday); |
$this->assertTrue($Decorator->isFirst()); |
} |
function testIsLast() { |
$mockday = & new Mock_Calendar_Day($this); |
$mockday->setReturnValue('isLast',TRUE); |
$Decorator =& new Calendar_Decorator($mockday); |
$this->assertTrue($Decorator->isLast()); |
} |
function testSetEmpty() { |
$mockday = & new Mock_Calendar_Day($this); |
$mockday->expectOnce('setEmpty',array(true)); |
$Decorator =& new Calendar_Decorator($mockday); |
$Decorator->setEmpty(); |
} |
function testIsEmpty() { |
$mockday = & new Mock_Calendar_Day($this); |
$mockday->setReturnValue('isEmpty',TRUE); |
$Decorator =& new Calendar_Decorator($mockday); |
$this->assertTrue($Decorator->isEmpty()); |
} |
function testBuild() { |
$testArray=array('foo'=>'bar'); |
$this->mockcal->expectOnce('build',array($testArray)); |
$Decorator =& new Calendar_Decorator($this->mockcal); |
$Decorator->build($testArray); |
} |
function testFetch() { |
$this->mockcal->expectOnce('fetch',array()); |
$Decorator =& new Calendar_Decorator($this->mockcal); |
$Decorator->fetch(); |
} |
function testFetchAll() { |
$this->mockcal->expectOnce('fetchAll',array()); |
$Decorator =& new Calendar_Decorator($this->mockcal); |
$Decorator->fetchAll(); |
} |
function testSize() { |
$this->mockcal->expectOnce('size',array()); |
$Decorator =& new Calendar_Decorator($this->mockcal); |
$Decorator->size(); |
} |
function testIsValid() { |
$this->mockcal->expectOnce('isValid',array()); |
$Decorator =& new Calendar_Decorator($this->mockcal); |
$Decorator->isValid(); |
} |
function testGetValidator() { |
$this->mockcal->expectOnce('getValidator',array()); |
$Decorator =& new Calendar_Decorator($this->mockcal); |
$Decorator->getValidator(); |
} |
} |
?> |
/branches/livraison_menes/api/pear/Calendar/tests/month_weeks_test.php |
---|
New file |
0,0 → 1,125 |
<?php |
// $Id: month_weeks_test.php,v 1.1 2005-09-30 14:58:00 ddelon Exp $ |
require_once('simple_include.php'); |
require_once('calendar_include.php'); |
require_once('./calendar_test.php'); |
class TestOfMonthWeeks extends TestOfCalendar { |
function TestOfMonthWeeks() { |
$this->UnitTestCase('Test of Month Weeks'); |
} |
function setUp() { |
$this->cal = new Calendar_Month_Weeks(2003,10); |
} |
function testPrevDay () { |
$this->assertEqual(30,$this->cal->prevDay()); |
} |
function testPrevDay_Array () { |
$this->assertEqual( |
array( |
'year' => 2003, |
'month' => 9, |
'day' => 30, |
'hour' => 0, |
'minute' => 0, |
'second' => 0), |
$this->cal->prevDay('array')); |
} |
function testThisDay () { |
$this->assertEqual(1,$this->cal->thisDay()); |
} |
function testNextDay () { |
$this->assertEqual(2,$this->cal->nextDay()); |
} |
function testPrevHour () { |
$this->assertEqual(23,$this->cal->prevHour()); |
} |
function testThisHour () { |
$this->assertEqual(0,$this->cal->thisHour()); |
} |
function testNextHour () { |
$this->assertEqual(1,$this->cal->nextHour()); |
} |
function testPrevMinute () { |
$this->assertEqual(59,$this->cal->prevMinute()); |
} |
function testThisMinute () { |
$this->assertEqual(0,$this->cal->thisMinute()); |
} |
function testNextMinute () { |
$this->assertEqual(1,$this->cal->nextMinute()); |
} |
function testPrevSecond () { |
$this->assertEqual(59,$this->cal->prevSecond()); |
} |
function testThisSecond () { |
$this->assertEqual(0,$this->cal->thisSecond()); |
} |
function testNextSecond () { |
$this->assertEqual(1,$this->cal->nextSecond()); |
} |
function testGetTimeStamp() { |
$stamp = mktime(0,0,0,10,1,2003); |
$this->assertEqual($stamp,$this->cal->getTimeStamp()); |
} |
} |
class TestOfMonthWeeksBuild extends TestOfMonthWeeks { |
function TestOfMonthWeeksBuild() { |
$this->UnitTestCase('Test of Month_Weeks::build()'); |
} |
function testSize() { |
$this->cal->build(); |
$this->assertEqual(5,$this->cal->size()); |
} |
function testFetch() { |
$this->cal->build(); |
$i=0; |
while ( $Child = $this->cal->fetch() ) { |
$i++; |
} |
$this->assertEqual(5,$i); |
} |
/* Recusive dependency issue with SimpleTest |
function testFetchAll() { |
$this->cal->build(); |
$children = array(); |
$i = 1; |
while ( $Child = $this->cal->fetch() ) { |
$children[$i]=$Child; |
$i++; |
} |
$this->assertEqual($children,$this->cal->fetchAll()); |
} |
*/ |
function testSelection() { |
require_once(CALENDAR_ROOT . 'Week.php'); |
$selection = array(new Calendar_Week(2003, 10, 12)); |
$this->cal->build($selection); |
$i = 1; |
while ($Child = $this->cal->fetch()) { |
if ($i == 2) { |
break; //12-10-2003 is the 2nd day of the week |
} |
$i++; |
} |
$this->assertTrue($Child->isSelected()); |
} |
function testEmptyDaysBefore_AfterAdjust() { |
$this->cal = new Calendar_Month_Weeks(2004,0); |
$this->cal->build(); |
$this->assertEqual(0,$this->cal->tableHelper->getEmptyDaysBefore()); |
} |
} |
if (!defined('TEST_RUNNING')) { |
define('TEST_RUNNING', true); |
$test = &new TestOfMonthWeeks(); |
$test->run(new HtmlReporter()); |
$test = &new TestOfMonthWeeksBuild(); |
$test->run(new HtmlReporter()); |
} |
?> |
/branches/livraison_menes/api/pear/Calendar/tests/util_textual_test.php |
---|
New file |
0,0 → 1,191 |
<?php |
// $Id: util_textual_test.php,v 1.1 2005-09-30 14:58:00 ddelon Exp $ |
require_once('simple_include.php'); |
require_once('calendar_include.php'); |
require_once('./decorator_test.php'); |
class TestOfUtilTextual extends UnitTestCase { |
var $mockengine; |
var $mockcal; |
function TestOfUtilTextual() { |
$this->UnitTestCase('Test of Calendar_Util_Textual'); |
} |
function setUp() { |
$this->mockengine = new Mock_Calendar_Engine($this); |
$this->mockcal = new Mock_Calendar_Second($this); |
$this->mockcal->setReturnValue('prevYear',2002); |
$this->mockcal->setReturnValue('thisYear',2003); |
$this->mockcal->setReturnValue('nextYear',2004); |
$this->mockcal->setReturnValue('prevMonth',9); |
$this->mockcal->setReturnValue('thisMonth',10); |
$this->mockcal->setReturnValue('nextMonth',11); |
$this->mockcal->setReturnValue('prevDay',14); |
$this->mockcal->setReturnValue('thisDay',15); |
$this->mockcal->setReturnValue('nextDay',16); |
$this->mockcal->setReturnValue('prevHour',12); |
$this->mockcal->setReturnValue('thisHour',13); |
$this->mockcal->setReturnValue('nextHour',14); |
$this->mockcal->setReturnValue('prevMinute',29); |
$this->mockcal->setReturnValue('thisMinute',30); |
$this->mockcal->setReturnValue('nextMinute',31); |
$this->mockcal->setReturnValue('prevSecond',44); |
$this->mockcal->setReturnValue('thisSecond',45); |
$this->mockcal->setReturnValue('nextSecond',46); |
$this->mockcal->setReturnValue('getEngine',$this->mockengine); |
$this->mockcal->setReturnValue('getTimestamp',12345); |
} |
function tearDown() { |
unset ( $this->engine ); |
unset ( $this->mockcal ); |
} |
function testMonthNamesLong() { |
$monthNames = array( |
1=>'January', |
2=>'February', |
3=>'March', |
4=>'April', |
5=>'May', |
6=>'June', |
7=>'July', |
8=>'August', |
9=>'September', |
10=>'October', |
11=>'November', |
12=>'December', |
); |
$this->assertEqual($monthNames,Calendar_Util_Textual::monthNames()); |
} |
function testMonthNamesShort() { |
$monthNames = array( |
1=>'Jan', |
2=>'Feb', |
3=>'Mar', |
4=>'Apr', |
5=>'May', |
6=>'Jun', |
7=>'Jul', |
8=>'Aug', |
9=>'Sep', |
10=>'Oct', |
11=>'Nov', |
12=>'Dec', |
); |
$this->assertEqual($monthNames,Calendar_Util_Textual::monthNames('short')); |
} |
function testMonthNamesTwo() { |
$monthNames = array( |
1=>'Ja', |
2=>'Fe', |
3=>'Ma', |
4=>'Ap', |
5=>'Ma', |
6=>'Ju', |
7=>'Ju', |
8=>'Au', |
9=>'Se', |
10=>'Oc', |
11=>'No', |
12=>'De', |
); |
$this->assertEqual($monthNames,Calendar_Util_Textual::monthNames('two')); |
} |
function testMonthNamesOne() { |
$monthNames = array( |
1=>'J', |
2=>'F', |
3=>'M', |
4=>'A', |
5=>'M', |
6=>'J', |
7=>'J', |
8=>'A', |
9=>'S', |
10=>'O', |
11=>'N', |
12=>'D', |
); |
$this->assertEqual($monthNames,Calendar_Util_Textual::monthNames('one')); |
} |
function testWeekdayNamesLong() { |
$weekdayNames = array( |
0=>'Sunday', |
1=>'Monday', |
2=>'Tuesday', |
3=>'Wednesday', |
4=>'Thursday', |
5=>'Friday', |
6=>'Saturday', |
); |
$this->assertEqual($weekdayNames,Calendar_Util_Textual::weekdayNames()); |
} |
function testWeekdayNamesShort() { |
$weekdayNames = array( |
0=>'Sun', |
1=>'Mon', |
2=>'Tue', |
3=>'Wed', |
4=>'Thu', |
5=>'Fri', |
6=>'Sat', |
); |
$this->assertEqual($weekdayNames,Calendar_Util_Textual::weekdayNames('short')); |
} |
function testWeekdayNamesTwo() { |
$weekdayNames = array( |
0=>'Su', |
1=>'Mo', |
2=>'Tu', |
3=>'We', |
4=>'Th', |
5=>'Fr', |
6=>'Sa', |
); |
$this->assertEqual($weekdayNames,Calendar_Util_Textual::weekdayNames('two')); |
} |
function testWeekdayNamesOne() { |
$weekdayNames = array( |
0=>'S', |
1=>'M', |
2=>'T', |
3=>'W', |
4=>'T', |
5=>'F', |
6=>'S', |
); |
$this->assertEqual($weekdayNames,Calendar_Util_Textual::weekdayNames('one')); |
} |
function testPrevMonthNameShort() { |
$this->assertEqual('Sep',Calendar_Util_Textual::prevMonthName($this->mockcal,'short')); |
} |
function testThisMonthNameShort() { |
$this->assertEqual('Oct',Calendar_Util_Textual::thisMonthName($this->mockcal,'short')); |
} |
function testNextMonthNameShort() { |
$this->assertEqual('Nov',Calendar_Util_Textual::nextMonthName($this->mockcal,'short')); |
} |
function testThisDayNameShort() { |
$this->assertEqual('Wed',Calendar_Util_Textual::thisDayName($this->mockcal,'short')); |
} |
function testOrderedWeekdaysShort() { |
$weekdayNames = array( |
0=>'Sun', |
1=>'Mon', |
2=>'Tue', |
3=>'Wed', |
4=>'Thu', |
5=>'Fri', |
6=>'Sat', |
); |
$this->assertEqual($weekdayNames,Calendar_Util_Textual::orderedWeekdays($this->mockcal,'short')); |
} |
} |
if (!defined('TEST_RUNNING')) { |
define('TEST_RUNNING', true); |
$test = &new TestOfUtilTextual(); |
$test->run(new HtmlReporter()); |
} |
?> |
/branches/livraison_menes/api/pear/Calendar/tests/validator_unit_test.php |
---|
New file |
0,0 → 1,210 |
<?php |
// $Id: validator_unit_test.php,v 1.1 2005-09-30 14:58:00 ddelon Exp $ |
require_once('simple_include.php'); |
require_once('calendar_include.php'); |
Mock::generate('Calendar_Engine_Interface','Mock_Calendar_Engine'); |
Mock::generate('Calendar_Second','Mock_Calendar_Second'); |
class TestOfValidator extends UnitTestCase { |
var $mockengine; |
var $mockcal; |
function TestOfValidator() { |
$this->UnitTestCase('Test of Validator'); |
} |
function setUp() { |
$this->mockengine = new Mock_Calendar_Engine($this); |
$this->mockengine->setReturnValue('getMinYears',1970); |
$this->mockengine->setReturnValue('getMaxYears',2037); |
$this->mockengine->setReturnValue('getMonthsInYear',12); |
$this->mockengine->setReturnValue('getDaysInMonth',30); |
$this->mockengine->setReturnValue('getHoursInDay',24); |
$this->mockengine->setReturnValue('getMinutesInHour',60); |
$this->mockengine->setReturnValue('getSecondsInMinute',60); |
$this->mockcal = new Mock_Calendar_Second($this); |
$this->mockcal->setReturnValue('getEngine',$this->mockengine); |
} |
function tearDown() { |
unset ($this->mockengine); |
unset ($this->mocksecond); |
} |
function testIsValidYear() { |
$this->mockcal->setReturnValue('thisYear',2000); |
$Validator = & new Calendar_Validator($this->mockcal); |
$this->assertTrue($Validator->isValidYear()); |
} |
function testIsValidYearTooSmall() { |
$this->mockcal->setReturnValue('thisYear',1969); |
$Validator = & new Calendar_Validator($this->mockcal); |
$this->assertFalse($Validator->isValidYear()); |
} |
function testIsValidYearTooLarge() { |
$this->mockcal->setReturnValue('thisYear',2038); |
$Validator = & new Calendar_Validator($this->mockcal); |
$this->assertFalse($Validator->isValidYear()); |
} |
function testIsValidMonth() { |
$this->mockcal->setReturnValue('thisMonth',10); |
$Validator = & new Calendar_Validator($this->mockcal); |
$this->assertTrue($Validator->isValidMonth()); |
} |
function testIsValidMonthTooSmall() { |
$this->mockcal->setReturnValue('thisMonth',0); |
$Validator = & new Calendar_Validator($this->mockcal); |
$this->assertFalse($Validator->isValidMonth()); |
} |
function testIsValidMonthTooLarge() { |
$this->mockcal->setReturnValue('thisMonth',13); |
$Validator = & new Calendar_Validator($this->mockcal); |
$this->assertFalse($Validator->isValidMonth()); |
} |
function testIsValidDay() { |
$this->mockcal->setReturnValue('thisDay',10); |
$Validator = & new Calendar_Validator($this->mockcal); |
$this->assertTrue($Validator->isValidDay()); |
} |
function testIsValidDayTooSmall() { |
$this->mockcal->setReturnValue('thisDay',0); |
$Validator = & new Calendar_Validator($this->mockcal); |
$this->assertFalse($Validator->isValidDay()); |
} |
function testIsValidDayTooLarge() { |
$this->mockcal->setReturnValue('thisDay',31); |
$Validator = & new Calendar_Validator($this->mockcal); |
$this->assertFalse($Validator->isValidDay()); |
} |
function testIsValidHour() { |
$this->mockcal->setReturnValue('thisHour',10); |
$Validator = & new Calendar_Validator($this->mockcal); |
$this->assertTrue($Validator->isValidHour()); |
} |
function testIsValidHourTooSmall() { |
$this->mockcal->setReturnValue('thisHour',-1); |
$Validator = & new Calendar_Validator($this->mockcal); |
$this->assertFalse($Validator->isValidHour()); |
} |
function testIsValidHourTooLarge() { |
$this->mockcal->setReturnValue('thisHour',24); |
$Validator = & new Calendar_Validator($this->mockcal); |
$this->assertFalse($Validator->isValidHour()); |
} |
function testIsValidMinute() { |
$this->mockcal->setReturnValue('thisMinute',30); |
$Validator = & new Calendar_Validator($this->mockcal); |
$this->assertTrue($Validator->isValidMinute()); |
} |
function testIsValidMinuteTooSmall() { |
$this->mockcal->setReturnValue('thisMinute',-1); |
$Validator = & new Calendar_Validator($this->mockcal); |
$this->assertFalse($Validator->isValidMinute()); |
} |
function testIsValidMinuteTooLarge() { |
$this->mockcal->setReturnValue('thisMinute',60); |
$Validator = & new Calendar_Validator($this->mockcal); |
$this->assertFalse($Validator->isValidMinute()); |
} |
function testIsValidSecond() { |
$this->mockcal->setReturnValue('thisSecond',30); |
$Validator = & new Calendar_Validator($this->mockcal); |
$this->assertTrue($Validator->isValidSecond()); |
} |
function testIsValidSecondTooSmall() { |
$this->mockcal->setReturnValue('thisSecond',-1); |
$Validator = & new Calendar_Validator($this->mockcal); |
$this->assertFalse($Validator->isValidSecond()); |
} |
function testIsValidSecondTooLarge() { |
$this->mockcal->setReturnValue('thisSecond',60); |
$Validator = & new Calendar_Validator($this->mockcal); |
$this->assertFalse($Validator->isValidSecond()); |
} |
function testIsValid() { |
$this->mockcal->setReturnValue('thisYear',2000); |
$this->mockcal->setReturnValue('thisMonth',5); |
$this->mockcal->setReturnValue('thisDay',15); |
$this->mockcal->setReturnValue('thisHour',13); |
$this->mockcal->setReturnValue('thisMinute',30); |
$this->mockcal->setReturnValue('thisSecond',40); |
$Validator = & new Calendar_Validator($this->mockcal); |
$this->assertTrue($Validator->isValid()); |
} |
function testIsValidAllWrong() { |
$this->mockcal->setReturnValue('thisYear',2038); |
$this->mockcal->setReturnValue('thisMonth',13); |
$this->mockcal->setReturnValue('thisDay',31); |
$this->mockcal->day = 31; |
$this->mockcal->setReturnValue('thisHour',24); |
$this->mockcal->setReturnValue('thisMinute',60); |
$this->mockcal->setReturnValue('thisSecond',60); |
$Validator = & new Calendar_Validator($this->mockcal); |
$this->assertFalse($Validator->isValid()); |
$i = 0; |
while ( $Validator->fetch() ) { |
$i++; |
} |
$this->assertEqual($i,6); |
} |
} |
class TestOfValidatorLive extends UnitTestCase { |
function TestOfValidatorLive() { |
$this->UnitTestCase('Test of Validator Live'); |
} |
function testYear() { |
$Unit = new Calendar_Year(2038); |
$Validator = & $Unit->getValidator(); |
$this->assertFalse($Validator->isValidYear()); |
} |
function testMonth() { |
$Unit = new Calendar_Month(2000,13); |
$Validator = & $Unit->getValidator(); |
$this->assertFalse($Validator->isValidMonth()); |
} |
/* |
function testWeek() { |
$Unit = new Calendar_Week(2000,12,7); |
$Validator = & $Unit->getValidator(); |
$this->assertFalse($Validator->isValidWeek()); |
} |
*/ |
function testDay() { |
$Unit = new Calendar_Day(2000,12,32); |
$Validator = & $Unit->getValidator(); |
$this->assertFalse($Validator->isValidDay()); |
} |
function testHour() { |
$Unit = new Calendar_Hour(2000,12,20,24); |
$Validator = & $Unit->getValidator(); |
$this->assertFalse($Validator->isValidHour()); |
} |
function testMinute() { |
$Unit = new Calendar_Minute(2000,12,20,23,60); |
$Validator = & $Unit->getValidator(); |
$this->assertFalse($Validator->isValidMinute()); |
} |
function testSecond() { |
$Unit = new Calendar_Second(2000,12,20,23,59,60); |
$Validator = & $Unit->getValidator(); |
$this->assertFalse($Validator->isValidSecond()); |
} |
function testAllBad() { |
$Unit = new Calendar_Second(2000,13,32,24,60,60); |
$this->assertFalse($Unit->isValid()); |
$Validator = & $Unit->getValidator(); |
$i = 0; |
while ( $Validator->fetch() ) { |
$i++; |
} |
$this->assertEqual($i,5); |
} |
} |
if (!defined('TEST_RUNNING')) { |
define('TEST_RUNNING', true); |
$test = &new TestOfValidator(); |
$test->run(new HtmlReporter()); |
$test = &new TestOfValidatorLive(); |
$test->run(new HtmlReporter()); |
} |
?> |
/branches/livraison_menes/api/pear/Calendar/tests/month_test.php |
---|
New file |
0,0 → 1,119 |
<?php |
// $Id: month_test.php,v 1.1 2005-09-30 14:58:00 ddelon Exp $ |
require_once('simple_include.php'); |
require_once('calendar_include.php'); |
require_once('./calendar_test.php'); |
class TestOfMonth extends TestOfCalendar { |
function TestOfMonth() { |
$this->UnitTestCase('Test of Month'); |
} |
function setUp() { |
$this->cal = new Calendar_Month(2003,10); |
} |
function testPrevMonth_Object() { |
$this->assertEqual(new Calendar_Month(2003, 9), $this->cal->prevMonth('object')); |
} |
function testPrevDay () { |
$this->assertEqual(30,$this->cal->prevDay()); |
} |
function testPrevDay_Array () { |
$this->assertEqual( |
array( |
'year' => 2003, |
'month' => 9, |
'day' => 30, |
'hour' => 0, |
'minute' => 0, |
'second' => 0), |
$this->cal->prevDay('array')); |
} |
function testThisDay () { |
$this->assertEqual(1,$this->cal->thisDay()); |
} |
function testNextDay () { |
$this->assertEqual(2,$this->cal->nextDay()); |
} |
function testPrevHour () { |
$this->assertEqual(23,$this->cal->prevHour()); |
} |
function testThisHour () { |
$this->assertEqual(0,$this->cal->thisHour()); |
} |
function testNextHour () { |
$this->assertEqual(1,$this->cal->nextHour()); |
} |
function testPrevMinute () { |
$this->assertEqual(59,$this->cal->prevMinute()); |
} |
function testThisMinute () { |
$this->assertEqual(0,$this->cal->thisMinute()); |
} |
function testNextMinute () { |
$this->assertEqual(1,$this->cal->nextMinute()); |
} |
function testPrevSecond () { |
$this->assertEqual(59,$this->cal->prevSecond()); |
} |
function testThisSecond () { |
$this->assertEqual(0,$this->cal->thisSecond()); |
} |
function testNextSecond () { |
$this->assertEqual(1,$this->cal->nextSecond()); |
} |
function testGetTimeStamp() { |
$stamp = mktime(0,0,0,10,1,2003); |
$this->assertEqual($stamp,$this->cal->getTimeStamp()); |
} |
} |
class TestOfMonthBuild extends TestOfMonth { |
function TestOfMonthBuild() { |
$this->UnitTestCase('Test of Month::build()'); |
} |
function testSize() { |
$this->cal->build(); |
$this->assertEqual(31,$this->cal->size()); |
} |
function testFetch() { |
$this->cal->build(); |
$i=0; |
while ( $Child = $this->cal->fetch() ) { |
$i++; |
} |
$this->assertEqual(31,$i); |
} |
function testFetchAll() { |
$this->cal->build(); |
$children = array(); |
$i = 1; |
while ( $Child = $this->cal->fetch() ) { |
$children[$i]=$Child; |
$i++; |
} |
$this->assertEqual($children,$this->cal->fetchAll()); |
} |
function testSelection() { |
require_once(CALENDAR_ROOT . 'Day.php'); |
$selection = array(new Calendar_Day(2003,10,25)); |
$this->cal->build($selection); |
$i = 1; |
while ( $Child = $this->cal->fetch() ) { |
if ( $i == 25 ) |
break; |
$i++; |
} |
$this->assertTrue($Child->isSelected()); |
} |
} |
if (!defined('TEST_RUNNING')) { |
define('TEST_RUNNING', true); |
$test = &new TestOfMonth(); |
$test->run(new HtmlReporter()); |
$test = &new TestOfMonthBuild(); |
$test->run(new HtmlReporter()); |
} |
?> |
/branches/livraison_menes/api/pear/Calendar/Day.php |
---|
New 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 2005-09-30 14:58:00 ddelon Exp $ |
// |
/** |
* @package Calendar |
* @version $Id: Day.php,v 1.1 2005-09-30 14:58:00 ddelon 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; |
} |
} |
?> |
/branches/livraison_menes/api/pear/Calendar/Hour.php |
---|
New 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 2005-09-30 14:58:00 ddelon Exp $ |
// |
/** |
* @package Calendar |
* @version $Id: Hour.php,v 1.1 2005-09-30 14:58:00 ddelon 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; |
} |
} |
} |
} |
} |
?> |
/branches/livraison_menes/api/pear/Calendar/Engine/PearDate.php |
---|
New file |
0,0 → 1,413 |
<?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.1 2005-09-30 14:58:00 ddelon Exp $ |
// |
/** |
* @package Calendar |
* @version $Id: PearDate.php,v 1.1 2005-09-30 14:58:00 ddelon 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 > $firstDay) { |
$firstWeekDays = $this->getDaysInWeek() - $FDOM + $firstDay; |
$weeks = 1; |
} else { |
$firstWeekDays = $firstDay - $FDOM; |
$weeks = 0; |
} |
$firstWeekDays %= $this->getDaysInWeek(); |
$result = (int)(ceil(($this->getDaysInMonth($y, $m) - $firstWeekDays) / |
$this->getDaysInWeek()) + $weeks); |
if ( $FDOM != 0 ) { |
return $result; |
} else { |
return $result + 1; |
} |
} |
/** |
* 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; |
} |
} |
?> |
/branches/livraison_menes/api/pear/Calendar/Engine/UnixTS.php |
---|
New file |
0,0 → 1,372 |
<?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.1 2005-09-30 14:58:00 ddelon Exp $ |
// |
/** |
* @package Calendar |
* @version $Id: UnixTS.php,v 1.1 2005-09-30 14:58:00 ddelon 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 > $firstDay) { |
$firstWeekDays = $this->getDaysInWeek() - $FDOM + $firstDay; |
$weeks = 1; |
} else { |
$firstWeekDays = $firstDay - $FDOM; |
$weeks = 0; |
} |
$firstWeekDays %= $this->getDaysInWeek(); |
$result = (int)(ceil(($this->getDaysInMonth($y, $m) - $firstWeekDays) / |
$this->getDaysInWeek()) + $weeks); |
// Hack - 0 as FDOM is a special case |
if ( $FDOM != 0 ) { |
return $result; |
} else { |
return $result + 1; |
} |
} |
/** |
* 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; |
} |
} |
?> |
/branches/livraison_menes/api/pear/Calendar/Engine/Interface.php |
---|
New 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.1 2005-09-30 14:58:00 ddelon Exp $ |
// |
/** |
* @package Calendar |
* @version $Id: Interface.php,v 1.1 2005-09-30 14:58:00 ddelon 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) |
{ |
} |
} |
?> |
/branches/livraison_menes/api/pear/Calendar/Decorator.php |
---|
New file |
0,0 → 1,557 |
<?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.1 2005-09-30 14:58:00 ddelon Exp $ |
// |
/** |
* @package Calendar |
* @version $Id: Decorator.php,v 1.1 2005-09-30 14:58:00 ddelon 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() |
{ |
return $this->calendar->getValidator(); |
} |
/** |
* Returns a reference to the current Calendar_Engine being used. Useful |
* for Calendar_Table_Helper and Caledar_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); |
} |
} |
?> |
/branches/livraison_menes/api/pear/Calendar/Month.php |
---|
New 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: Month.php,v 1.1 2005-09-30 14:58:00 ddelon Exp $ |
// |
/** |
* @package Calendar |
* @version $Id: Month.php,v 1.1 2005-09-30 14:58:00 ddelon 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'.DIRECTORY_SEPARATOR.'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 year e.g. 2003 |
* @param int month e.g. 5 |
* @param int (optional) unused in this class |
* @access public |
*/ |
function Calendar_Month($y, $m, $firstDay=null) |
{ |
Calendar::Calendar($y, $m); |
} |
/** |
* 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; |
} |
} |
} |
} |
} |
?> |
/branches/livraison_menes/api/pear/Calendar/Validator.php |
---|
New 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 2005-09-30 14:58:00 ddelon Exp $ |
// |
/** |
* @package Calendar |
* @version $Id: Validator.php,v 1.1 2005-09-30 14:58:00 ddelon 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.']'; |
} |
} |
?> |
/branches/livraison_menes/api/pear/Calendar/Util/Uri.php |
---|
New 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 2005-09-30 14:58:00 ddelon Exp $ |
// |
/** |
* @package Calendar |
* @version $Id: Uri.php,v 1.1 2005-09-30 14:58:00 ddelon 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; |
} |
} |
?> |
/branches/livraison_menes/api/pear/Calendar/Util/Textual.php |
---|
New 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.1 2005-09-30 14:58:00 ddelon Exp $ |
// |
/** |
* @package Calendar |
* @version $Id: Textual.php,v 1.1 2005-09-30 14:58:00 ddelon 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; |
} |
} |
?> |
/branches/livraison_menes/api/pear/Calendar/Week.php |
---|
New file |
0,0 → 1,410 |
<?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.1 2005-09-30 14:58:00 ddelon Exp $ |
// |
/** |
* @package Calendar |
* @version $Id: Week.php,v 1.1 2005-09-30 14:58:00 ddelon 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=false) |
{ |
require_once CALENDAR_ROOT.'Table'.DIRECTORY_SEPARATOR.'Helper.php'; |
Calendar::Calendar($y, $m, $d); |
if ($firstDay !== false) { |
$this->firstDay = $firstDay; |
} |
$this->tableHelper = & new Calendar_Table_Helper($this, $firstDay); |
$this->thisWeek = $this->tableHelper->getWeekStart($y, $m, $d, $firstDay); |
$this->prevWeek = $this->tableHelper->getWeekStart($y, $m, $d - $this->cE->getDaysInWeek( |
$this->thisYear(), |
$this->thisMonth(), |
$this->thisDay()), $firstDay); |
$this->nextWeek = $this->tableHelper->getWeekStart($y, $m, $d + $this->cE->getDaysInWeek( |
$this->thisYear(), |
$this->thisMonth(), |
$this->thisDay()), $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) |
{ |
+ |
+ $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) |
+ { |
+ |
+ |
+ |
+ |
+ $child->thisYear() == $sDate->thisYear() |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ } |
+ |
+ /** |
+ * 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->cE->stampToYear($this->thisWeek), |
+ $this->cE->stampToMonth($this->thisWeek), |
+ $this->firstDay); |
+ } |
+ return $this->cE->getWeekNInMonth( |
+ $this->cE->stampToYear($this->thisWeek), |
+ $this->cE->stampToMonth($this->thisWeek), |
+ $this->cE->stampToDay($this->thisWeek), |
+ $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; |
+ } |
+ } |
+ } |
+ } |
+} |
+?> |
\ No newline at end of file |
/branches/livraison_menes/api/pear/Calendar/Decorator/Textual.php |
---|
New 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.1 2005-09-30 14:58:00 ddelon Exp $ |
// |
/** |
* @package Calendar |
* @version $Id: Textual.php,v 1.1 2005-09-30 14:58:00 ddelon 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); |
} |
} |
?> |
/branches/livraison_menes/api/pear/Calendar/Decorator/Weekday.php |
---|
New 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.1 2005-09-30 14:58:00 ddelon Exp $ |
// |
/** |
* @package Calendar |
* @version $Id: Weekday.php,v 1.1 2005-09-30 14:58:00 ddelon 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; |
} |
} |
} |
?> |
/branches/livraison_menes/api/pear/Calendar/Decorator/Uri.php |
---|
New 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.1 2005-09-30 14:58:00 ddelon Exp $ |
// |
/** |
* @package Calendar |
* @version $Id: Uri.php,v 1.1 2005-09-30 14:58:00 ddelon 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); |
} |
} |
?> |
/branches/livraison_menes/api/pear/Calendar/Decorator/Wrapper.php |
---|
New file |
0,0 → 1,89 |
<?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.1 2005-09-30 14:58:00 ddelon Exp $ |
// |
/** |
* @package Calendar |
* @version $Id: Wrapper.php,v 1.1 2005-09-30 14:58:00 ddelon 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) { |
return new $decorator($Calendar); |
} else { |
return false; |
} |
} |
/** |
* 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; |
} |
} |
?> |
/branches/livraison_menes/api/pear/DB.php |
---|
New file |
0,0 → 1,1388 |
<?php |
/* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4: */ |
/** |
* Database independent query interface |
* |
* 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 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: DB.php,v 1.2 2005-09-20 17:01:22 ddelon Exp $ |
* @link http://pear.php.net/package/DB |
*/ |
/** |
* Obtain the PEAR class so it can be extended from |
*/ |
require_once 'PEAR.php'; |
// {{{ constants |
// {{{ error codes |
/**#@+ |
* One of PEAR DB's portable error codes. |
* @see DB_common::errorCode(), DB::errorMessage() |
* |
* {@internal If you add an error code here, make sure you also add a textual |
* version of it in DB::errorMessage().}} |
*/ |
/** |
* The code returned by many methods upon success |
*/ |
define('DB_OK', 1); |
/** |
* Unkown error |
*/ |
define('DB_ERROR', -1); |
/** |
* Syntax error |
*/ |
define('DB_ERROR_SYNTAX', -2); |
/** |
* Tried to insert a duplicate value into a primary or unique index |
*/ |
define('DB_ERROR_CONSTRAINT', -3); |
/** |
* An identifier in the query refers to a non-existant object |
*/ |
define('DB_ERROR_NOT_FOUND', -4); |
/** |
* Tried to create a duplicate object |
*/ |
define('DB_ERROR_ALREADY_EXISTS', -5); |
/** |
* The current driver does not support the action you attempted |
*/ |
define('DB_ERROR_UNSUPPORTED', -6); |
/** |
* The number of parameters does not match the number of placeholders |
*/ |
define('DB_ERROR_MISMATCH', -7); |
/** |
* A literal submitted did not match the data type expected |
*/ |
define('DB_ERROR_INVALID', -8); |
/** |
* The current DBMS does not support the action you attempted |
*/ |
define('DB_ERROR_NOT_CAPABLE', -9); |
/** |
* A literal submitted was too long so the end of it was removed |
*/ |
define('DB_ERROR_TRUNCATED', -10); |
/** |
* A literal number submitted did not match the data type expected |
*/ |
define('DB_ERROR_INVALID_NUMBER', -11); |
/** |
* A literal date submitted did not match the data type expected |
*/ |
define('DB_ERROR_INVALID_DATE', -12); |
/** |
* Attempt to divide something by zero |
*/ |
define('DB_ERROR_DIVZERO', -13); |
/** |
* A database needs to be selected |
*/ |
define('DB_ERROR_NODBSELECTED', -14); |
/** |
* Could not create the object requested |
*/ |
define('DB_ERROR_CANNOT_CREATE', -15); |
/** |
* Could not drop the database requested because it does not exist |
*/ |
define('DB_ERROR_CANNOT_DROP', -17); |
/** |
* An identifier in the query refers to a non-existant table |
*/ |
define('DB_ERROR_NOSUCHTABLE', -18); |
/** |
* An identifier in the query refers to a non-existant column |
*/ |
define('DB_ERROR_NOSUCHFIELD', -19); |
/** |
* The data submitted to the method was inappropriate |
*/ |
define('DB_ERROR_NEED_MORE_DATA', -20); |
/** |
* The attempt to lock the table failed |
*/ |
define('DB_ERROR_NOT_LOCKED', -21); |
/** |
* The number of columns doesn't match the number of values |
*/ |
define('DB_ERROR_VALUE_COUNT_ON_ROW', -22); |
/** |
* The DSN submitted has problems |
*/ |
define('DB_ERROR_INVALID_DSN', -23); |
/** |
* Could not connect to the database |
*/ |
define('DB_ERROR_CONNECT_FAILED', -24); |
/** |
* The PHP extension needed for this DBMS could not be found |
*/ |
define('DB_ERROR_EXTENSION_NOT_FOUND',-25); |
/** |
* The present user has inadequate permissions to perform the task requestd |
*/ |
define('DB_ERROR_ACCESS_VIOLATION', -26); |
/** |
* The database requested does not exist |
*/ |
define('DB_ERROR_NOSUCHDB', -27); |
/** |
* Tried to insert a null value into a column that doesn't allow nulls |
*/ |
define('DB_ERROR_CONSTRAINT_NOT_NULL',-29); |
/**#@-*/ |
// }}} |
// {{{ prepared statement-related |
/**#@+ |
* Identifiers for the placeholders used in prepared statements. |
* @see DB_common::prepare() |
*/ |
/** |
* Indicates a scalar (<kbd>?</kbd>) placeholder was used |
* |
* Quote and escape the value as necessary. |
*/ |
define('DB_PARAM_SCALAR', 1); |
/** |
* Indicates an opaque (<kbd>&</kbd>) placeholder was used |
* |
* The value presented is a file name. Extract the contents of that file |
* and place them in this column. |
*/ |
define('DB_PARAM_OPAQUE', 2); |
/** |
* Indicates a misc (<kbd>!</kbd>) placeholder was used |
* |
* The value should not be quoted or escaped. |
*/ |
define('DB_PARAM_MISC', 3); |
/**#@-*/ |
// }}} |
// {{{ binary data-related |
/**#@+ |
* The different ways of returning binary data from queries. |
*/ |
/** |
* Sends the fetched data straight through to output |
*/ |
define('DB_BINMODE_PASSTHRU', 1); |
/** |
* Lets you return data as usual |
*/ |
define('DB_BINMODE_RETURN', 2); |
/** |
* Converts the data to hex format before returning it |
* |
* For example the string "123" would become "313233". |
*/ |
define('DB_BINMODE_CONVERT', 3); |
/**#@-*/ |
// }}} |
// {{{ fetch modes |
/**#@+ |
* Fetch Modes. |
* @see DB_common::setFetchMode() |
*/ |
/** |
* Indicates the current default fetch mode should be used |
* @see DB_common::$fetchmode |
*/ |
define('DB_FETCHMODE_DEFAULT', 0); |
/** |
* Column data indexed by numbers, ordered from 0 and up |
*/ |
define('DB_FETCHMODE_ORDERED', 1); |
/** |
* Column data indexed by column names |
*/ |
define('DB_FETCHMODE_ASSOC', 2); |
/** |
* Column data as object properties |
*/ |
define('DB_FETCHMODE_OBJECT', 3); |
/** |
* For multi-dimensional results, make the column name the first level |
* of the array and put the row number in the second level of the array |
* |
* This is flipped from the normal behavior, which puts the row numbers |
* in the first level of the array and the column names in the second level. |
*/ |
define('DB_FETCHMODE_FLIPPED', 4); |
/**#@-*/ |
/**#@+ |
* Old fetch modes. Left here for compatibility. |
*/ |
define('DB_GETMODE_ORDERED', DB_FETCHMODE_ORDERED); |
define('DB_GETMODE_ASSOC', DB_FETCHMODE_ASSOC); |
define('DB_GETMODE_FLIPPED', DB_FETCHMODE_FLIPPED); |
/**#@-*/ |
// }}} |
// {{{ tableInfo() && autoPrepare()-related |
/**#@+ |
* The type of information to return from the tableInfo() method. |
* |
* Bitwised constants, so they can be combined using <kbd>|</kbd> |
* and removed using <kbd>^</kbd>. |
* |
* @see DB_common::tableInfo() |
* |
* {@internal Since the TABLEINFO constants are bitwised, if more of them are |
* added in the future, make sure to adjust DB_TABLEINFO_FULL accordingly.}} |
*/ |
define('DB_TABLEINFO_ORDER', 1); |
define('DB_TABLEINFO_ORDERTABLE', 2); |
define('DB_TABLEINFO_FULL', 3); |
/**#@-*/ |
/**#@+ |
* The type of query to create with the automatic query building methods. |
* @see DB_common::autoPrepare(), DB_common::autoExecute() |
*/ |
define('DB_AUTOQUERY_INSERT', 1); |
define('DB_AUTOQUERY_UPDATE', 2); |
/**#@-*/ |
// }}} |
// {{{ portability modes |
/**#@+ |
* Portability Modes. |
* |
* Bitwised constants, so they can be combined using <kbd>|</kbd> |
* and removed using <kbd>^</kbd>. |
* |
* @see DB_common::setOption() |
* |
* {@internal Since the PORTABILITY constants are bitwised, if more of them are |
* added in the future, make sure to adjust DB_PORTABILITY_ALL accordingly.}} |
*/ |
/** |
* Turn off all portability features |
*/ |
define('DB_PORTABILITY_NONE', 0); |
/** |
* Convert names of tables and fields to lower case |
* when using the get*(), fetch*() and tableInfo() methods |
*/ |
define('DB_PORTABILITY_LOWERCASE', 1); |
/** |
* Right trim the data output by get*() and fetch*() |
*/ |
define('DB_PORTABILITY_RTRIM', 2); |
/** |
* Force reporting the number of rows deleted |
*/ |
define('DB_PORTABILITY_DELETE_COUNT', 4); |
/** |
* Enable hack that makes numRows() work in Oracle |
*/ |
define('DB_PORTABILITY_NUMROWS', 8); |
/** |
* Makes certain error messages in certain drivers compatible |
* with those from other DBMS's |
* |
* + mysql, mysqli: change unique/primary key constraints |
* DB_ERROR_ALREADY_EXISTS -> DB_ERROR_CONSTRAINT |
* |
* + odbc(access): MS's ODBC driver reports 'no such field' as code |
* 07001, which means 'too few parameters.' When this option is on |
* that code gets mapped to DB_ERROR_NOSUCHFIELD. |
*/ |
define('DB_PORTABILITY_ERRORS', 16); |
/** |
* Convert null values to empty strings in data output by |
* get*() and fetch*() |
*/ |
define('DB_PORTABILITY_NULL_TO_EMPTY', 32); |
/** |
* Turn on all portability features |
*/ |
define('DB_PORTABILITY_ALL', 63); |
/**#@-*/ |
// }}} |
// }}} |
// {{{ class DB |
/** |
* Database independent query interface |
* |
* The main "DB" class is simply a container class with some static |
* methods for creating DB objects as well as some utility functions |
* common to all parts of DB. |
* |
* The object model of DB is as follows (indentation means inheritance): |
* <pre> |
* DB The main DB class. This is simply a utility class |
* with some "static" methods for creating DB objects as |
* well as common utility functions for other DB classes. |
* |
* DB_common The base for each DB implementation. Provides default |
* | implementations (in OO lingo virtual methods) for |
* | the actual DB implementations as well as a bunch of |
* | query utility functions. |
* | |
* +-DB_mysql The DB implementation for MySQL. Inherits DB_common. |
* When calling DB::factory or DB::connect for MySQL |
* connections, the object returned is an instance of this |
* class. |
* </pre> |
* |
* @category Database |
* @package DB |
* @author Stig Bakken <ssb@php.net> |
* @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 |
{ |
// {{{ &factory() |
/** |
* Create a new DB object for the specified database type but don't |
* connect to the database |
* |
* @param string $type the database type (eg "mysql") |
* @param array $options an associative array of option names and values |
* |
* @return object a new DB object. A DB_Error object on failure. |
* |
* @see DB_common::setOption() |
*/ |
function &factory($type, $options = false) |
{ |
if (!is_array($options)) { |
$options = array('persistent' => $options); |
} |
if (isset($options['debug']) && $options['debug'] >= 2) { |
// expose php errors with sufficient debug level |
include_once "DB/{$type}.php"; |
} else { |
@include_once "DB/{$type}.php"; |
} |
$classname = "DB_${type}"; |
if (!class_exists($classname)) { |
$tmp = PEAR::raiseError(null, DB_ERROR_NOT_FOUND, null, null, |
"Unable to include the DB/{$type}.php" |
. " file for '$dsn'", |
'DB_Error', true); |
return $tmp; |
} |
@$obj =& new $classname; |
foreach ($options as $option => $value) { |
$test = $obj->setOption($option, $value); |
if (DB::isError($test)) { |
return $test; |
} |
} |
return $obj; |
} |
// }}} |
// {{{ &connect() |
/** |
* Create a new DB object including a connection to the specified database |
* |
* Example 1. |
* <code> |
* require_once 'DB.php'; |
* |
* $dsn = 'pgsql://user:password@host/database'; |
* $options = array( |
* 'debug' => 2, |
* 'portability' => DB_PORTABILITY_ALL, |
* ); |
* |
* $db =& DB::connect($dsn, $options); |
* if (PEAR::isError($db)) { |
* die($db->getMessage()); |
* } |
* </code> |
* |
* @param mixed $dsn the string "data source name" or array in the |
* format returned by DB::parseDSN() |
* @param array $options an associative array of option names and values |
* |
* @return object a new DB object. A DB_Error object on failure. |
* |
* @uses DB_dbase::connect(), DB_fbsql::connect(), DB_ibase::connect(), |
* DB_ifx::connect(), DB_msql::connect(), DB_mssql::connect(), |
* DB_mysql::connect(), DB_mysqli::connect(), DB_oci8::connect(), |
* DB_odbc::connect(), DB_pgsql::connect(), DB_sqlite::connect(), |
* DB_sybase::connect() |
* |
* @uses DB::parseDSN(), DB_common::setOption(), PEAR::isError() |
*/ |
function &connect($dsn, $options = array()) |
{ |
$dsninfo = DB::parseDSN($dsn); |
$type = $dsninfo['phptype']; |
if (!is_array($options)) { |
/* |
* For backwards compatibility. $options used to be boolean, |
* indicating whether the connection should be persistent. |
*/ |
$options = array('persistent' => $options); |
} |
if (isset($options['debug']) && $options['debug'] >= 2) { |
// expose php errors with sufficient debug level |
include_once "DB/${type}.php"; |
} else { |
@include_once "DB/${type}.php"; |
} |
$classname = "DB_${type}"; |
if (!class_exists($classname)) { |
$tmp = PEAR::raiseError(null, DB_ERROR_NOT_FOUND, null, null, |
"Unable to include the DB/{$type}.php" |
. " file for '$dsn'", |
'DB_Error', true); |
return $tmp; |
} |
@$obj =& new $classname; |
foreach ($options as $option => $value) { |
$test = $obj->setOption($option, $value); |
if (DB::isError($test)) { |
return $test; |
} |
} |
$err = $obj->connect($dsninfo, $obj->getOption('persistent')); |
if (DB::isError($err)) { |
$err->addUserInfo($dsn); |
return $err; |
} |
return $obj; |
} |
// }}} |
// {{{ apiVersion() |
/** |
* Return the DB API version |
* |
* @return string the DB API version number |
*/ |
function apiVersion() |
{ |
return '@package_version@'; |
} |
// }}} |
// {{{ isError() |
/** |
* Determines if a variable is a DB_Error object |
* |
* @param mixed $value the variable to check |
* |
* @return bool whether $value is DB_Error object |
*/ |
function isError($value) |
{ |
return is_a($value, 'DB_Error'); |
} |
// }}} |
// {{{ isConnection() |
/** |
* Determines if a value is a DB_<driver> object |
* |
* @param mixed $value the value to test |
* |
* @return bool whether $value is a DB_<driver> object |
*/ |
function isConnection($value) |
{ |
return (is_object($value) && |
is_subclass_of($value, 'db_common') && |
method_exists($value, 'simpleQuery')); |
} |
// }}} |
// {{{ isManip() |
/** |
* Tell whether a query is a data manipulation or data definition query |
* |
* Examples of data manipulation queries are INSERT, UPDATE and DELETE. |
* Examples of data definition queries are CREATE, DROP, ALTER, GRANT, |
* REVOKE. |
* |
* @param string $query the query |
* |
* @return boolean whether $query is a data manipulation query |
*/ |
function isManip($query) |
{ |
$manips = 'INSERT|UPDATE|DELETE|REPLACE|' |
. 'CREATE|DROP|' |
. 'LOAD DATA|SELECT .* INTO|COPY|' |
. 'ALTER|GRANT|REVOKE|' |
. 'LOCK|UNLOCK'; |
if (preg_match('/^\s*"?(' . $manips . ')\s+/i', $query)) { |
return true; |
} |
return false; |
} |
// }}} |
// {{{ errorMessage() |
/** |
* Return a textual error message for a DB error code |
* |
* @param integer $value the DB error code |
* |
* @return string the error message or false if the error code was |
* not recognized |
*/ |
function errorMessage($value) |
{ |
static $errorMessages; |
if (!isset($errorMessages)) { |
$errorMessages = array( |
DB_ERROR => 'unknown error', |
DB_ERROR_ACCESS_VIOLATION => 'insufficient permissions', |
DB_ERROR_ALREADY_EXISTS => 'already exists', |
DB_ERROR_CANNOT_CREATE => 'can not create', |
DB_ERROR_CANNOT_DROP => 'can not drop', |
DB_ERROR_CONNECT_FAILED => 'connect failed', |
DB_ERROR_CONSTRAINT => 'constraint violation', |
DB_ERROR_CONSTRAINT_NOT_NULL=> 'null value violates not-null constraint', |
DB_ERROR_DIVZERO => 'division by zero', |
DB_ERROR_EXTENSION_NOT_FOUND=> 'extension not found', |
DB_ERROR_INVALID => 'invalid', |
DB_ERROR_INVALID_DATE => 'invalid date or time', |
DB_ERROR_INVALID_DSN => 'invalid DSN', |
DB_ERROR_INVALID_NUMBER => 'invalid number', |
DB_ERROR_MISMATCH => 'mismatch', |
DB_ERROR_NEED_MORE_DATA => 'insufficient data supplied', |
DB_ERROR_NODBSELECTED => 'no database selected', |
DB_ERROR_NOSUCHDB => 'no such database', |
DB_ERROR_NOSUCHFIELD => 'no such field', |
DB_ERROR_NOSUCHTABLE => 'no such table', |
DB_ERROR_NOT_CAPABLE => 'DB backend not capable', |
DB_ERROR_NOT_FOUND => 'not found', |
DB_ERROR_NOT_LOCKED => 'not locked', |
DB_ERROR_SYNTAX => 'syntax error', |
DB_ERROR_UNSUPPORTED => 'not supported', |
DB_ERROR_TRUNCATED => 'truncated', |
DB_ERROR_VALUE_COUNT_ON_ROW => 'value count on row', |
DB_OK => 'no error', |
); |
} |
if (DB::isError($value)) { |
$value = $value->getCode(); |
} |
return isset($errorMessages[$value]) ? $errorMessages[$value] |
: $errorMessages[DB_ERROR]; |
} |
// }}} |
// {{{ parseDSN() |
/** |
* Parse a data source name |
* |
* Additional keys can be added by appending a URI query string to the |
* end of the DSN. |
* |
* The format of the supplied DSN is in its fullest form: |
* <code> |
* phptype(dbsyntax)://username:password@protocol+hostspec/database?option=8&another=true |
* </code> |
* |
* Most variations are allowed: |
* <code> |
* phptype://username:password@protocol+hostspec:110//usr/db_file.db?mode=0644 |
* phptype://username:password@hostspec/database_name |
* phptype://username:password@hostspec |
* phptype://username@hostspec |
* phptype://hostspec/database |
* phptype://hostspec |
* phptype(dbsyntax) |
* phptype |
* </code> |
* |
* @param string $dsn Data Source Name to be parsed |
* |
* @return array an associative array with the following keys: |
* + phptype: Database backend used in PHP (mysql, odbc etc.) |
* + dbsyntax: Database used with regards to SQL syntax etc. |
* + protocol: Communication protocol to use (tcp, unix etc.) |
* + hostspec: Host specification (hostname[:port]) |
* + database: Database to use on the DBMS server |
* + username: User name for login |
* + password: Password for login |
*/ |
function parseDSN($dsn) |
{ |
$parsed = array( |
'phptype' => false, |
'dbsyntax' => false, |
'username' => false, |
'password' => false, |
'protocol' => false, |
'hostspec' => false, |
'port' => false, |
'socket' => false, |
'database' => false, |
); |
if (is_array($dsn)) { |
$dsn = array_merge($parsed, $dsn); |
if (!$dsn['dbsyntax']) { |
$dsn['dbsyntax'] = $dsn['phptype']; |
} |
return $dsn; |
} |
// Find phptype and dbsyntax |
if (($pos = strpos($dsn, '://')) !== false) { |
$str = substr($dsn, 0, $pos); |
$dsn = substr($dsn, $pos + 3); |
} else { |
$str = $dsn; |
$dsn = null; |
} |
// Get phptype and dbsyntax |
// $str => phptype(dbsyntax) |
if (preg_match('|^(.+?)\((.*?)\)$|', $str, $arr)) { |
$parsed['phptype'] = $arr[1]; |
$parsed['dbsyntax'] = !$arr[2] ? $arr[1] : $arr[2]; |
} else { |
$parsed['phptype'] = $str; |
$parsed['dbsyntax'] = $str; |
} |
if (!count($dsn)) { |
return $parsed; |
} |
// Get (if found): username and password |
// $dsn => username:password@protocol+hostspec/database |
if (($at = strrpos($dsn,'@')) !== false) { |
$str = substr($dsn, 0, $at); |
$dsn = substr($dsn, $at + 1); |
if (($pos = strpos($str, ':')) !== false) { |
$parsed['username'] = rawurldecode(substr($str, 0, $pos)); |
$parsed['password'] = rawurldecode(substr($str, $pos + 1)); |
} else { |
$parsed['username'] = rawurldecode($str); |
} |
} |
// Find protocol and hostspec |
if (preg_match('|^([^(]+)\((.*?)\)/?(.*?)$|', $dsn, $match)) { |
// $dsn => proto(proto_opts)/database |
$proto = $match[1]; |
$proto_opts = $match[2] ? $match[2] : false; |
$dsn = $match[3]; |
} else { |
// $dsn => protocol+hostspec/database (old format) |
if (strpos($dsn, '+') !== false) { |
list($proto, $dsn) = explode('+', $dsn, 2); |
} |
if (strpos($dsn, '/') !== false) { |
list($proto_opts, $dsn) = explode('/', $dsn, 2); |
} else { |
$proto_opts = $dsn; |
$dsn = null; |
} |
} |
// process the different protocol options |
$parsed['protocol'] = (!empty($proto)) ? $proto : 'tcp'; |
$proto_opts = rawurldecode($proto_opts); |
if ($parsed['protocol'] == 'tcp') { |
if (strpos($proto_opts, ':') !== false) { |
list($parsed['hostspec'], |
$parsed['port']) = explode(':', $proto_opts); |
} else { |
$parsed['hostspec'] = $proto_opts; |
} |
} elseif ($parsed['protocol'] == 'unix') { |
$parsed['socket'] = $proto_opts; |
} |
// Get dabase if any |
// $dsn => database |
if ($dsn) { |
if (($pos = strpos($dsn, '?')) === false) { |
// /database |
$parsed['database'] = rawurldecode($dsn); |
} else { |
// /database?param1=value1¶m2=value2 |
$parsed['database'] = rawurldecode(substr($dsn, 0, $pos)); |
$dsn = substr($dsn, $pos + 1); |
if (strpos($dsn, '&') !== false) { |
$opts = explode('&', $dsn); |
} else { // database?param1=value1 |
$opts = array($dsn); |
} |
foreach ($opts as $opt) { |
list($key, $value) = explode('=', $opt); |
if (!isset($parsed[$key])) { |
// don't allow params overwrite |
$parsed[$key] = rawurldecode($value); |
} |
} |
} |
} |
return $parsed; |
} |
// }}} |
} |
// }}} |
// {{{ class DB_Error |
/** |
* DB_Error implements a class for reporting portable database error |
* messages |
* |
* @category Database |
* @package DB |
* @author Stig Bakken <ssb@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_Error extends PEAR_Error |
{ |
// {{{ constructor |
/** |
* DB_Error constructor |
* |
* @param mixed $code DB error code, or string with error message |
* @param int $mode what "error mode" to operate in |
* @param int $level what error level to use for $mode & |
* PEAR_ERROR_TRIGGER |
* @param mixed $debuginfo additional debug info, such as the last query |
* |
* @see PEAR_Error |
*/ |
function DB_Error($code = DB_ERROR, $mode = PEAR_ERROR_RETURN, |
$level = E_USER_NOTICE, $debuginfo = null) |
{ |
if (is_int($code)) { |
$this->PEAR_Error('DB Error: ' . DB::errorMessage($code), $code, |
$mode, $level, $debuginfo); |
} else { |
$this->PEAR_Error("DB Error: $code", DB_ERROR, |
$mode, $level, $debuginfo); |
} |
} |
// }}} |
} |
// }}} |
// {{{ class DB_result |
/** |
* This class implements a wrapper for a DB result set |
* |
* A new instance of this class will be returned by the DB implementation |
* after processing a query that returns data. |
* |
* @category Database |
* @package DB |
* @author Stig Bakken <ssb@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_result |
{ |
// {{{ properties |
/** |
* Should results be freed automatically when there are no more rows? |
* @var boolean |
* @see DB_common::$options |
*/ |
var $autofree; |
/** |
* A reference to the DB_<driver> object |
* @var object |
*/ |
var $dbh; |
/** |
* The current default fetch mode |
* @var integer |
* @see DB_common::$fetchmode |
*/ |
var $fetchmode; |
/** |
* The name of the class into which results should be fetched when |
* DB_FETCHMODE_OBJECT is in effect |
* |
* @var string |
* @see DB_common::$fetchmode_object_class |
*/ |
var $fetchmode_object_class; |
/** |
* The number of rows to fetch from a limit query |
* @var integer |
*/ |
var $limit_count = null; |
/** |
* The row to start fetching from in limit queries |
* @var integer |
*/ |
var $limit_from = null; |
/** |
* The execute parameters that created this result |
* @var array |
* @since Property available since Release 1.7.0 |
*/ |
var $parameters; |
/** |
* The query string that created this result |
* |
* Copied here incase it changes in $dbh, which is referenced |
* |
* @var string |
* @since Property available since Release 1.7.0 |
*/ |
var $query; |
/** |
* The query result resource id created by PHP |
* @var resource |
*/ |
var $result; |
/** |
* The present row being dealt with |
* @var integer |
*/ |
var $row_counter = null; |
/** |
* The prepared statement resource id created by PHP in $dbh |
* |
* This resource is only available when the result set was created using |
* a driver's native execute() method, not PEAR DB's emulated one. |
* |
* Copied here incase it changes in $dbh, which is referenced |
* |
* {@internal Mainly here because the InterBase/Firebird API is only |
* able to retrieve data from result sets if the statemnt handle is |
* still in scope.}} |
* |
* @var resource |
* @since Property available since Release 1.7.0 |
*/ |
var $statement; |
// }}} |
// {{{ constructor |
/** |
* This constructor sets the object's properties |
* |
* @param object &$dbh the DB object reference |
* @param resource $result the result resource id |
* @param array $options an associative array with result options |
* |
* @return void |
*/ |
function DB_result(&$dbh, $result, $options = array()) |
{ |
$this->autofree = $dbh->options['autofree']; |
$this->dbh = &$dbh; |
$this->fetchmode = $dbh->fetchmode; |
$this->fetchmode_object_class = $dbh->fetchmode_object_class; |
$this->parameters = $dbh->last_parameters; |
$this->query = $dbh->last_query; |
$this->result = $result; |
$this->statement = empty($dbh->last_stmt) ? null : $dbh->last_stmt; |
foreach ($options as $key => $value) { |
$this->setOption($key, $value); |
} |
} |
/** |
* Set options for the DB_result object |
* |
* @param string $key the option to set |
* @param mixed $value the value to set the option to |
* |
* @return void |
*/ |
function setOption($key, $value = null) |
{ |
switch ($key) { |
case 'limit_from': |
$this->limit_from = $value; |
break; |
case 'limit_count': |
$this->limit_count = $value; |
} |
} |
// }}} |
// {{{ fetchRow() |
/** |
* Fetch a row of data and return it by reference into an array |
* |
* The type of array returned can be controlled either by setting this |
* method's <var>$fetchmode</var> parameter or by changing the default |
* fetch mode setFetchMode() before calling this method. |
* |
* There are two options for standardizing the information returned |
* from databases, ensuring their values are consistent when changing |
* DBMS's. These portability options can be turned on when creating a |
* new DB object or by using setOption(). |
* |
* + <var>DB_PORTABILITY_LOWERCASE</var> |
* convert names of fields to lower case |
* |
* + <var>DB_PORTABILITY_RTRIM</var> |
* right trim the data |
* |
* @param int $fetchmode the constant indicating how to format the data |
* @param int $rownum the row number to fetch (index starts at 0) |
* |
* @return mixed an array or object containing the row's data, |
* NULL when the end of the result set is reached |
* or a DB_Error object on failure. |
* |
* @see DB_common::setOption(), DB_common::setFetchMode() |
*/ |
function &fetchRow($fetchmode = DB_FETCHMODE_DEFAULT, $rownum = null) |
{ |
if ($fetchmode === DB_FETCHMODE_DEFAULT) { |
$fetchmode = $this->fetchmode; |
} |
if ($fetchmode === DB_FETCHMODE_OBJECT) { |
$fetchmode = DB_FETCHMODE_ASSOC; |
$object_class = $this->fetchmode_object_class; |
} |
if ($this->limit_from !== null) { |
if ($this->row_counter === null) { |
$this->row_counter = $this->limit_from; |
// Skip rows |
if ($this->dbh->features['limit'] === false) { |
$i = 0; |
while ($i++ < $this->limit_from) { |
$this->dbh->fetchInto($this->result, $arr, $fetchmode); |
} |
} |
} |
if ($this->row_counter >= ($this->limit_from + $this->limit_count)) |
{ |
if ($this->autofree) { |
$this->free(); |
} |
$tmp = null; |
return $tmp; |
} |
if ($this->dbh->features['limit'] === 'emulate') { |
$rownum = $this->row_counter; |
} |
$this->row_counter++; |
} |
$res = $this->dbh->fetchInto($this->result, $arr, $fetchmode, $rownum); |
if ($res === DB_OK) { |
if (isset($object_class)) { |
// The default mode is specified in the |
// DB_common::fetchmode_object_class property |
if ($object_class == 'stdClass') { |
$arr = (object) $arr; |
} else { |
$arr = &new $object_class($arr); |
} |
} |
return $arr; |
} |
if ($res == null && $this->autofree) { |
$this->free(); |
} |
return $res; |
} |
// }}} |
// {{{ fetchInto() |
/** |
* Fetch a row of data into an array which is passed by reference |
* |
* The type of array returned can be controlled either by setting this |
* method's <var>$fetchmode</var> parameter or by changing the default |
* fetch mode setFetchMode() before calling this method. |
* |
* There are two options for standardizing the information returned |
* from databases, ensuring their values are consistent when changing |
* DBMS's. These portability options can be turned on when creating a |
* new DB object or by using setOption(). |
* |
* + <var>DB_PORTABILITY_LOWERCASE</var> |
* convert names of fields to lower case |
* |
* + <var>DB_PORTABILITY_RTRIM</var> |
* right trim the data |
* |
* @param array &$arr the variable where the data should be placed |
* @param int $fetchmode the constant indicating how to format the data |
* @param int $rownum the row number to fetch (index starts at 0) |
* |
* @return mixed DB_OK if a row is processed, NULL when the end of the |
* result set is reached or a DB_Error object on failure |
* |
* @see DB_common::setOption(), DB_common::setFetchMode() |
*/ |
function fetchInto(&$arr, $fetchmode = DB_FETCHMODE_DEFAULT, $rownum = null) |
{ |
if ($fetchmode === DB_FETCHMODE_DEFAULT) { |
$fetchmode = $this->fetchmode; |
} |
if ($fetchmode === DB_FETCHMODE_OBJECT) { |
$fetchmode = DB_FETCHMODE_ASSOC; |
$object_class = $this->fetchmode_object_class; |
} |
if ($this->limit_from !== null) { |
if ($this->row_counter === null) { |
$this->row_counter = $this->limit_from; |
// Skip rows |
if ($this->dbh->features['limit'] === false) { |
$i = 0; |
while ($i++ < $this->limit_from) { |
$this->dbh->fetchInto($this->result, $arr, $fetchmode); |
} |
} |
} |
if ($this->row_counter >= ( |
$this->limit_from + $this->limit_count)) |
{ |
if ($this->autofree) { |
$this->free(); |
} |
return null; |
} |
if ($this->dbh->features['limit'] === 'emulate') { |
$rownum = $this->row_counter; |
} |
$this->row_counter++; |
} |
$res = $this->dbh->fetchInto($this->result, $arr, $fetchmode, $rownum); |
if ($res === DB_OK) { |
if (isset($object_class)) { |
// default mode specified in the |
// DB_common::fetchmode_object_class property |
if ($object_class == 'stdClass') { |
$arr = (object) $arr; |
} else { |
$arr = new $object_class($arr); |
} |
} |
return DB_OK; |
} |
if ($res == null && $this->autofree) { |
$this->free(); |
} |
return $res; |
} |
// }}} |
// {{{ numCols() |
/** |
* Get the the number of columns in a result set |
* |
* @return int the number of columns. A DB_Error object on failure. |
*/ |
function numCols() |
{ |
return $this->dbh->numCols($this->result); |
} |
// }}} |
// {{{ numRows() |
/** |
* Get the number of rows in a result set |
* |
* @return int the number of rows. A DB_Error object on failure. |
*/ |
function numRows() |
{ |
if ($this->dbh->features['numrows'] === 'emulate' |
&& $this->dbh->options['portability'] & DB_PORTABILITY_NUMROWS) |
{ |
if ($this->dbh->features['prepare']) { |
$res = $this->dbh->query($this->query, $this->parameters); |
} else { |
$res = $this->dbh->query($this->query); |
} |
if (DB::isError($res)) { |
return $res; |
} |
$i = 0; |
while ($res->fetchInto($tmp, DB_FETCHMODE_ORDERED)) { |
$i++; |
} |
return $i; |
} else { |
return $this->dbh->numRows($this->result); |
} |
} |
// }}} |
// {{{ nextResult() |
/** |
* Get the next result if a batch of queries was executed |
* |
* @return bool true if a new result is available or false if not |
*/ |
function nextResult() |
{ |
return $this->dbh->nextResult($this->result); |
} |
// }}} |
// {{{ free() |
/** |
* Frees the resources allocated for this result set |
* |
* @return bool true on success. A DB_Error object on failure. |
*/ |
function free() |
{ |
$err = $this->dbh->freeResult($this->result); |
if (DB::isError($err)) { |
return $err; |
} |
$this->result = false; |
$this->statement = false; |
return true; |
} |
// }}} |
// {{{ tableInfo() |
/** |
* @see DB_common::tableInfo() |
* @deprecated Method deprecated some time before Release 1.2 |
*/ |
function tableInfo($mode = null) |
{ |
if (is_string($mode)) { |
return $this->dbh->raiseError(DB_ERROR_NEED_MORE_DATA); |
} |
return $this->dbh->tableInfo($this, $mode); |
} |
// }}} |
// {{{ getQuery() |
/** |
* Determine the query string that created this result |
* |
* @return string the query string |
* |
* @since Method available since Release 1.7.0 |
*/ |
function getQuery() |
{ |
return $this->query; |
} |
// }}} |
// {{{ getRowCounter() |
/** |
* Tells which row number is currently being processed |
* |
* @return integer the current row being looked at. Starts at 1. |
*/ |
function getRowCounter() |
{ |
return $this->row_counter; |
} |
// }}} |
} |
// }}} |
// {{{ class DB_row |
/** |
* PEAR DB Row Object |
* |
* The object contains a row of data from a result set. Each column's data |
* is placed in a property named for the column. |
* |
* @category Database |
* @package DB |
* @author Stig Bakken <ssb@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 |
* @see DB_common::setFetchMode() |
*/ |
class DB_row |
{ |
// {{{ constructor |
/** |
* The constructor places a row's data into properties of this object |
* |
* @param array the array containing the row's data |
* |
* @return void |
*/ |
function DB_row(&$arr) |
{ |
foreach ($arr as $key => $value) { |
$this->$key = &$arr[$key]; |
} |
} |
// }}} |
} |
// }}} |
/* |
* Local variables: |
* tab-width: 4 |
* c-basic-offset: 4 |
* End: |
*/ |
?> |
/branches/livraison_menes/api/pear/PEAR.php |
---|
New file |
0,0 → 1,1055 |
<?php |
// |
// +--------------------------------------------------------------------+ |
// | PEAR, the PHP Extension and Application Repository | |
// +--------------------------------------------------------------------+ |
// | Copyright (c) 1997-2004 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. | |
// +--------------------------------------------------------------------+ |
// | Authors: Sterling Hughes <sterling@php.net> | |
// | Stig Bakken <ssb@php.net> | |
// | Tomas V.V.Cox <cox@idecnet.com> | |
// +--------------------------------------------------------------------+ |
// |
// $Id: PEAR.php,v 1.1 2005-03-30 08:50:19 jpm Exp $ |
// |
define('PEAR_ERROR_RETURN', 1); |
define('PEAR_ERROR_PRINT', 2); |
define('PEAR_ERROR_TRIGGER', 4); |
define('PEAR_ERROR_DIE', 8); |
define('PEAR_ERROR_CALLBACK', 16); |
/** |
* WARNING: obsolete |
* @deprecated |
*/ |
define('PEAR_ERROR_EXCEPTION', 32); |
define('PEAR_ZE2', (function_exists('version_compare') && |
version_compare(zend_version(), "2-dev", "ge"))); |
if (substr(PHP_OS, 0, 3) == 'WIN') { |
define('OS_WINDOWS', true); |
define('OS_UNIX', false); |
define('PEAR_OS', 'Windows'); |
} else { |
define('OS_WINDOWS', false); |
define('OS_UNIX', true); |
define('PEAR_OS', 'Unix'); // blatant assumption |
} |
// instant backwards compatibility |
if (!defined('PATH_SEPARATOR')) { |
if (OS_WINDOWS) { |
define('PATH_SEPARATOR', ';'); |
} else { |
define('PATH_SEPARATOR', ':'); |
} |
} |
$GLOBALS['_PEAR_default_error_mode'] = PEAR_ERROR_RETURN; |
$GLOBALS['_PEAR_default_error_options'] = E_USER_NOTICE; |
$GLOBALS['_PEAR_destructor_object_list'] = array(); |
$GLOBALS['_PEAR_shutdown_funcs'] = array(); |
$GLOBALS['_PEAR_error_handler_stack'] = array(); |
@ini_set('track_errors', true); |
/** |
* Base class for other PEAR classes. Provides rudimentary |
* emulation of destructors. |
* |
* If you want a destructor in your class, inherit PEAR and make a |
* destructor method called _yourclassname (same name as the |
* constructor, but with a "_" prefix). Also, in your constructor you |
* have to call the PEAR constructor: $this->PEAR();. |
* The destructor method will be called without parameters. Note that |
* at in some SAPI implementations (such as Apache), any output during |
* the request shutdown (in which destructors are called) seems to be |
* discarded. If you need to get any debug information from your |
* destructor, use error_log(), syslog() or something similar. |
* |
* IMPORTANT! To use the emulated destructors you need to create the |
* objects by reference: $obj =& new PEAR_child; |
* |
* @since PHP 4.0.2 |
* @author Stig Bakken <ssb@php.net> |
* @see http://pear.php.net/manual/ |
*/ |
class PEAR |
{ |
// {{{ properties |
/** |
* Whether to enable internal debug messages. |
* |
* @var bool |
* @access private |
*/ |
var $_debug = false; |
/** |
* Default error mode for this object. |
* |
* @var int |
* @access private |
*/ |
var $_default_error_mode = null; |
/** |
* Default error options used for this object when error mode |
* is PEAR_ERROR_TRIGGER. |
* |
* @var int |
* @access private |
*/ |
var $_default_error_options = null; |
/** |
* Default error handler (callback) for this object, if error mode is |
* PEAR_ERROR_CALLBACK. |
* |
* @var string |
* @access private |
*/ |
var $_default_error_handler = ''; |
/** |
* Which class to use for error objects. |
* |
* @var string |
* @access private |
*/ |
var $_error_class = 'PEAR_Error'; |
/** |
* An array of expected errors. |
* |
* @var array |
* @access private |
*/ |
var $_expected_errors = array(); |
// }}} |
// {{{ constructor |
/** |
* Constructor. Registers this object in |
* $_PEAR_destructor_object_list for destructor emulation if a |
* destructor object exists. |
* |
* @param string $error_class (optional) which class to use for |
* error objects, defaults to PEAR_Error. |
* @access public |
* @return void |
*/ |
function PEAR($error_class = null) |
{ |
$classname = strtolower(get_class($this)); |
if ($this->_debug) { |
print "PEAR constructor called, class=$classname\n"; |
} |
if ($error_class !== null) { |
$this->_error_class = $error_class; |
} |
while ($classname && strcasecmp($classname, "pear")) { |
$destructor = "_$classname"; |
if (method_exists($this, $destructor)) { |
global $_PEAR_destructor_object_list; |
$_PEAR_destructor_object_list[] = &$this; |
if (!isset($GLOBALS['_PEAR_SHUTDOWN_REGISTERED'])) { |
register_shutdown_function("_PEAR_call_destructors"); |
$GLOBALS['_PEAR_SHUTDOWN_REGISTERED'] = true; |
} |
break; |
} else { |
$classname = get_parent_class($classname); |
} |
} |
} |
// }}} |
// {{{ destructor |
/** |
* Destructor (the emulated type of...). Does nothing right now, |
* but is included for forward compatibility, so subclass |
* destructors should always call it. |
* |
* See the note in the class desciption about output from |
* destructors. |
* |
* @access public |
* @return void |
*/ |
function _PEAR() { |
if ($this->_debug) { |
printf("PEAR destructor called, class=%s\n", strtolower(get_class($this))); |
} |
} |
// }}} |
// {{{ getStaticProperty() |
/** |
* If you have a class that's mostly/entirely static, and you need static |
* properties, you can use this method to simulate them. Eg. in your method(s) |
* do this: $myVar = &PEAR::getStaticProperty('myclass', 'myVar'); |
* You MUST use a reference, or they will not persist! |
* |
* @access public |
* @param string $class The calling classname, to prevent clashes |
* @param string $var The variable to retrieve. |
* @return mixed A reference to the variable. If not set it will be |
* auto initialised to NULL. |
*/ |
function &getStaticProperty($class, $var) |
{ |
static $properties; |
return $properties[$class][$var]; |
} |
// }}} |
// {{{ registerShutdownFunc() |
/** |
* Use this function to register a shutdown method for static |
* classes. |
* |
* @access public |
* @param mixed $func The function name (or array of class/method) to call |
* @param mixed $args The arguments to pass to the function |
* @return void |
*/ |
function registerShutdownFunc($func, $args = array()) |
{ |
$GLOBALS['_PEAR_shutdown_funcs'][] = array($func, $args); |
} |
// }}} |
// {{{ isError() |
/** |
* Tell whether a value is a PEAR error. |
* |
* @param mixed $data the value to test |
* @param int $code if $data is an error object, return true |
* only if $code is a string and |
* $obj->getMessage() == $code or |
* $code is an integer and $obj->getCode() == $code |
* @access public |
* @return bool true if parameter is an error |
*/ |
function isError($data, $code = null) |
{ |
if (is_a($data, 'PEAR_Error')) { |
if (is_null($code)) { |
return true; |
} elseif (is_string($code)) { |
return $data->getMessage() == $code; |
} else { |
return $data->getCode() == $code; |
} |
} |
return false; |
} |
// }}} |
// {{{ setErrorHandling() |
/** |
* Sets how errors generated by this object should be handled. |
* Can be invoked both in objects and statically. If called |
* statically, setErrorHandling sets the default behaviour for all |
* PEAR objects. If called in an object, setErrorHandling sets |
* the default behaviour for that object. |
* |
* @param int $mode |
* One of PEAR_ERROR_RETURN, PEAR_ERROR_PRINT, |
* PEAR_ERROR_TRIGGER, PEAR_ERROR_DIE, |
* PEAR_ERROR_CALLBACK or PEAR_ERROR_EXCEPTION. |
* |
* @param mixed $options |
* When $mode is PEAR_ERROR_TRIGGER, this is the error level (one |
* of E_USER_NOTICE, E_USER_WARNING or E_USER_ERROR). |
* |
* When $mode is PEAR_ERROR_CALLBACK, this parameter is expected |
* to be the callback function or method. A callback |
* function is a string with the name of the function, a |
* callback method is an array of two elements: the element |
* at index 0 is the object, and the element at index 1 is |
* the name of the method to call in the object. |
* |
* When $mode is PEAR_ERROR_PRINT or PEAR_ERROR_DIE, this is |
* a printf format string used when printing the error |
* message. |
* |
* @access public |
* @return void |
* @see PEAR_ERROR_RETURN |
* @see PEAR_ERROR_PRINT |
* @see PEAR_ERROR_TRIGGER |
* @see PEAR_ERROR_DIE |
* @see PEAR_ERROR_CALLBACK |
* @see PEAR_ERROR_EXCEPTION |
* |
* @since PHP 4.0.5 |
*/ |
function setErrorHandling($mode = null, $options = null) |
{ |
if (isset($this) && is_a($this, 'PEAR')) { |
$setmode = &$this->_default_error_mode; |
$setoptions = &$this->_default_error_options; |
} else { |
$setmode = &$GLOBALS['_PEAR_default_error_mode']; |
$setoptions = &$GLOBALS['_PEAR_default_error_options']; |
} |
switch ($mode) { |
case PEAR_ERROR_EXCEPTION: |
case PEAR_ERROR_RETURN: |
case PEAR_ERROR_PRINT: |
case PEAR_ERROR_TRIGGER: |
case PEAR_ERROR_DIE: |
case null: |
$setmode = $mode; |
$setoptions = $options; |
break; |
case PEAR_ERROR_CALLBACK: |
$setmode = $mode; |
// class/object method callback |
if (is_callable($options)) { |
$setoptions = $options; |
} else { |
trigger_error("invalid error callback", E_USER_WARNING); |
} |
break; |
default: |
trigger_error("invalid error mode", E_USER_WARNING); |
break; |
} |
} |
// }}} |
// {{{ expectError() |
/** |
* This method is used to tell which errors you expect to get. |
* Expected errors are always returned with error mode |
* PEAR_ERROR_RETURN. Expected error codes are stored in a stack, |
* and this method pushes a new element onto it. The list of |
* expected errors are in effect until they are popped off the |
* stack with the popExpect() method. |
* |
* Note that this method can not be called statically |
* |
* @param mixed $code a single error code or an array of error codes to expect |
* |
* @return int the new depth of the "expected errors" stack |
* @access public |
*/ |
function expectError($code = '*') |
{ |
if (is_array($code)) { |
array_push($this->_expected_errors, $code); |
} else { |
array_push($this->_expected_errors, array($code)); |
} |
return sizeof($this->_expected_errors); |
} |
// }}} |
// {{{ popExpect() |
/** |
* This method pops one element off the expected error codes |
* stack. |
* |
* @return array the list of error codes that were popped |
*/ |
function popExpect() |
{ |
return array_pop($this->_expected_errors); |
} |
// }}} |
// {{{ _checkDelExpect() |
/** |
* This method checks unsets an error code if available |
* |
* @param mixed error code |
* @return bool true if the error code was unset, false otherwise |
* @access private |
* @since PHP 4.3.0 |
*/ |
function _checkDelExpect($error_code) |
{ |
$deleted = false; |
foreach ($this->_expected_errors AS $key => $error_array) { |
if (in_array($error_code, $error_array)) { |
unset($this->_expected_errors[$key][array_search($error_code, $error_array)]); |
$deleted = true; |
} |
// clean up empty arrays |
if (0 == count($this->_expected_errors[$key])) { |
unset($this->_expected_errors[$key]); |
} |
} |
return $deleted; |
} |
// }}} |
// {{{ delExpect() |
/** |
* This method deletes all occurences of the specified element from |
* the expected error codes stack. |
* |
* @param mixed $error_code error code that should be deleted |
* @return mixed list of error codes that were deleted or error |
* @access public |
* @since PHP 4.3.0 |
*/ |
function delExpect($error_code) |
{ |
$deleted = false; |
if ((is_array($error_code) && (0 != count($error_code)))) { |
// $error_code is a non-empty array here; |
// we walk through it trying to unset all |
// values |
foreach($error_code as $key => $error) { |
if ($this->_checkDelExpect($error)) { |
$deleted = true; |
} else { |
$deleted = false; |
} |
} |
return $deleted ? true : PEAR::raiseError("The expected error you submitted does not exist"); // IMPROVE ME |
} elseif (!empty($error_code)) { |
// $error_code comes alone, trying to unset it |
if ($this->_checkDelExpect($error_code)) { |
return true; |
} else { |
return PEAR::raiseError("The expected error you submitted does not exist"); // IMPROVE ME |
} |
} else { |
// $error_code is empty |
return PEAR::raiseError("The expected error you submitted is empty"); // IMPROVE ME |
} |
} |
// }}} |
// {{{ raiseError() |
/** |
* This method is a wrapper that returns an instance of the |
* configured error class with this object's default error |
* handling applied. If the $mode and $options parameters are not |
* specified, the object's defaults are used. |
* |
* @param mixed $message a text error message or a PEAR error object |
* |
* @param int $code a numeric error code (it is up to your class |
* to define these if you want to use codes) |
* |
* @param int $mode One of PEAR_ERROR_RETURN, PEAR_ERROR_PRINT, |
* PEAR_ERROR_TRIGGER, PEAR_ERROR_DIE, |
* PEAR_ERROR_CALLBACK, PEAR_ERROR_EXCEPTION. |
* |
* @param mixed $options If $mode is PEAR_ERROR_TRIGGER, this parameter |
* specifies the PHP-internal error level (one of |
* E_USER_NOTICE, E_USER_WARNING or E_USER_ERROR). |
* If $mode is PEAR_ERROR_CALLBACK, this |
* parameter specifies the callback function or |
* method. In other error modes this parameter |
* is ignored. |
* |
* @param string $userinfo If you need to pass along for example debug |
* information, this parameter is meant for that. |
* |
* @param string $error_class The returned error object will be |
* instantiated from this class, if specified. |
* |
* @param bool $skipmsg If true, raiseError will only pass error codes, |
* the error message parameter will be dropped. |
* |
* @access public |
* @return object a PEAR error object |
* @see PEAR::setErrorHandling |
* @since PHP 4.0.5 |
*/ |
function raiseError($message = null, |
$code = null, |
$mode = null, |
$options = null, |
$userinfo = null, |
$error_class = null, |
$skipmsg = false) |
{ |
// The error is yet a PEAR error object |
if (is_object($message)) { |
$code = $message->getCode(); |
$userinfo = $message->getUserInfo(); |
$error_class = $message->getType(); |
$message->error_message_prefix = ''; |
$message = $message->getMessage(); |
} |
if (isset($this) && isset($this->_expected_errors) && sizeof($this->_expected_errors) > 0 && sizeof($exp = end($this->_expected_errors))) { |
if ($exp[0] == "*" || |
(is_int(reset($exp)) && in_array($code, $exp)) || |
(is_string(reset($exp)) && in_array($message, $exp))) { |
$mode = PEAR_ERROR_RETURN; |
} |
} |
// No mode given, try global ones |
if ($mode === null) { |
// Class error handler |
if (isset($this) && isset($this->_default_error_mode)) { |
$mode = $this->_default_error_mode; |
$options = $this->_default_error_options; |
// Global error handler |
} elseif (isset($GLOBALS['_PEAR_default_error_mode'])) { |
$mode = $GLOBALS['_PEAR_default_error_mode']; |
$options = $GLOBALS['_PEAR_default_error_options']; |
} |
} |
if ($error_class !== null) { |
$ec = $error_class; |
} elseif (isset($this) && isset($this->_error_class)) { |
$ec = $this->_error_class; |
} else { |
$ec = 'PEAR_Error'; |
} |
if ($skipmsg) { |
return new $ec($code, $mode, $options, $userinfo); |
} else { |
return new $ec($message, $code, $mode, $options, $userinfo); |
} |
} |
// }}} |
// {{{ throwError() |
/** |
* Simpler form of raiseError with fewer options. In most cases |
* message, code and userinfo are enough. |
* |
* @param string $message |
* |
*/ |
function throwError($message = null, |
$code = null, |
$userinfo = null) |
{ |
if (isset($this) && is_a($this, 'PEAR')) { |
return $this->raiseError($message, $code, null, null, $userinfo); |
} else { |
return PEAR::raiseError($message, $code, null, null, $userinfo); |
} |
} |
// }}} |
function staticPushErrorHandling($mode, $options = null) |
{ |
$stack = &$GLOBALS['_PEAR_error_handler_stack']; |
$def_mode = &$GLOBALS['_PEAR_default_error_mode']; |
$def_options = &$GLOBALS['_PEAR_default_error_options']; |
$stack[] = array($def_mode, $def_options); |
switch ($mode) { |
case PEAR_ERROR_EXCEPTION: |
case PEAR_ERROR_RETURN: |
case PEAR_ERROR_PRINT: |
case PEAR_ERROR_TRIGGER: |
case PEAR_ERROR_DIE: |
case null: |
$def_mode = $mode; |
$def_options = $options; |
break; |
case PEAR_ERROR_CALLBACK: |
$def_mode = $mode; |
// class/object method callback |
if (is_callable($options)) { |
$def_options = $options; |
} else { |
trigger_error("invalid error callback", E_USER_WARNING); |
} |
break; |
default: |
trigger_error("invalid error mode", E_USER_WARNING); |
break; |
} |
$stack[] = array($mode, $options); |
return true; |
} |
function staticPopErrorHandling() |
{ |
$stack = &$GLOBALS['_PEAR_error_handler_stack']; |
$setmode = &$GLOBALS['_PEAR_default_error_mode']; |
$setoptions = &$GLOBALS['_PEAR_default_error_options']; |
array_pop($stack); |
list($mode, $options) = $stack[sizeof($stack) - 1]; |
array_pop($stack); |
switch ($mode) { |
case PEAR_ERROR_EXCEPTION: |
case PEAR_ERROR_RETURN: |
case PEAR_ERROR_PRINT: |
case PEAR_ERROR_TRIGGER: |
case PEAR_ERROR_DIE: |
case null: |
$setmode = $mode; |
$setoptions = $options; |
break; |
case PEAR_ERROR_CALLBACK: |
$setmode = $mode; |
// class/object method callback |
if (is_callable($options)) { |
$setoptions = $options; |
} else { |
trigger_error("invalid error callback", E_USER_WARNING); |
} |
break; |
default: |
trigger_error("invalid error mode", E_USER_WARNING); |
break; |
} |
return true; |
} |
// {{{ pushErrorHandling() |
/** |
* Push a new error handler on top of the error handler options stack. With this |
* you can easily override the actual error handler for some code and restore |
* it later with popErrorHandling. |
* |
* @param mixed $mode (same as setErrorHandling) |
* @param mixed $options (same as setErrorHandling) |
* |
* @return bool Always true |
* |
* @see PEAR::setErrorHandling |
*/ |
function pushErrorHandling($mode, $options = null) |
{ |
$stack = &$GLOBALS['_PEAR_error_handler_stack']; |
if (isset($this) && is_a($this, 'PEAR')) { |
$def_mode = &$this->_default_error_mode; |
$def_options = &$this->_default_error_options; |
} else { |
$def_mode = &$GLOBALS['_PEAR_default_error_mode']; |
$def_options = &$GLOBALS['_PEAR_default_error_options']; |
} |
$stack[] = array($def_mode, $def_options); |
if (isset($this) && is_a($this, 'PEAR')) { |
$this->setErrorHandling($mode, $options); |
} else { |
PEAR::setErrorHandling($mode, $options); |
} |
$stack[] = array($mode, $options); |
return true; |
} |
// }}} |
// {{{ popErrorHandling() |
/** |
* Pop the last error handler used |
* |
* @return bool Always true |
* |
* @see PEAR::pushErrorHandling |
*/ |
function popErrorHandling() |
{ |
$stack = &$GLOBALS['_PEAR_error_handler_stack']; |
array_pop($stack); |
list($mode, $options) = $stack[sizeof($stack) - 1]; |
array_pop($stack); |
if (isset($this) && is_a($this, 'PEAR')) { |
$this->setErrorHandling($mode, $options); |
} else { |
PEAR::setErrorHandling($mode, $options); |
} |
return true; |
} |
// }}} |
// {{{ loadExtension() |
/** |
* OS independant PHP extension load. Remember to take care |
* on the correct extension name for case sensitive OSes. |
* |
* @param string $ext The extension name |
* @return bool Success or not on the dl() call |
*/ |
function loadExtension($ext) |
{ |
if (!extension_loaded($ext)) { |
// if either returns true dl() will produce a FATAL error, stop that |
if ((ini_get('enable_dl') != 1) || (ini_get('safe_mode') == 1)) { |
return false; |
} |
if (OS_WINDOWS) { |
$suffix = '.dll'; |
} elseif (PHP_OS == 'HP-UX') { |
$suffix = '.sl'; |
} elseif (PHP_OS == 'AIX') { |
$suffix = '.a'; |
} elseif (PHP_OS == 'OSX') { |
$suffix = '.bundle'; |
} else { |
$suffix = '.so'; |
} |
return @dl('php_'.$ext.$suffix) || @dl($ext.$suffix); |
} |
return true; |
} |
// }}} |
} |
// {{{ _PEAR_call_destructors() |
function _PEAR_call_destructors() |
{ |
global $_PEAR_destructor_object_list; |
if (is_array($_PEAR_destructor_object_list) && |
sizeof($_PEAR_destructor_object_list)) |
{ |
reset($_PEAR_destructor_object_list); |
if (@PEAR::getStaticProperty('PEAR', 'destructlifo')) { |
$_PEAR_destructor_object_list = array_reverse($_PEAR_destructor_object_list); |
} |
while (list($k, $objref) = each($_PEAR_destructor_object_list)) { |
$classname = get_class($objref); |
while ($classname) { |
$destructor = "_$classname"; |
if (method_exists($objref, $destructor)) { |
$objref->$destructor(); |
break; |
} else { |
$classname = get_parent_class($classname); |
} |
} |
} |
// Empty the object list to ensure that destructors are |
// not called more than once. |
$_PEAR_destructor_object_list = array(); |
} |
// Now call the shutdown functions |
if (is_array($GLOBALS['_PEAR_shutdown_funcs']) AND !empty($GLOBALS['_PEAR_shutdown_funcs'])) { |
foreach ($GLOBALS['_PEAR_shutdown_funcs'] as $value) { |
call_user_func_array($value[0], $value[1]); |
} |
} |
} |
// }}} |
class PEAR_Error |
{ |
// {{{ properties |
var $error_message_prefix = ''; |
var $mode = PEAR_ERROR_RETURN; |
var $level = E_USER_NOTICE; |
var $code = -1; |
var $message = ''; |
var $userinfo = ''; |
var $backtrace = null; |
// }}} |
// {{{ constructor |
/** |
* PEAR_Error constructor |
* |
* @param string $message message |
* |
* @param int $code (optional) error code |
* |
* @param int $mode (optional) error mode, one of: PEAR_ERROR_RETURN, |
* PEAR_ERROR_PRINT, PEAR_ERROR_DIE, PEAR_ERROR_TRIGGER, |
* PEAR_ERROR_CALLBACK or PEAR_ERROR_EXCEPTION |
* |
* @param mixed $options (optional) error level, _OR_ in the case of |
* PEAR_ERROR_CALLBACK, the callback function or object/method |
* tuple. |
* |
* @param string $userinfo (optional) additional user/debug info |
* |
* @access public |
* |
*/ |
function PEAR_Error($message = 'unknown error', $code = null, |
$mode = null, $options = null, $userinfo = null) |
{ |
if ($mode === null) { |
$mode = PEAR_ERROR_RETURN; |
} |
$this->message = $message; |
$this->code = $code; |
$this->mode = $mode; |
$this->userinfo = $userinfo; |
if (function_exists("debug_backtrace")) { |
if (@!PEAR::getStaticProperty('PEAR_Error', 'skiptrace')) { |
$this->backtrace = debug_backtrace(); |
} |
} |
if ($mode & PEAR_ERROR_CALLBACK) { |
$this->level = E_USER_NOTICE; |
$this->callback = $options; |
} else { |
if ($options === null) { |
$options = E_USER_NOTICE; |
} |
$this->level = $options; |
$this->callback = null; |
} |
if ($this->mode & PEAR_ERROR_PRINT) { |
if (is_null($options) || is_int($options)) { |
$format = "%s"; |
} else { |
$format = $options; |
} |
printf($format, $this->getMessage()); |
} |
if ($this->mode & PEAR_ERROR_TRIGGER) { |
trigger_error($this->getMessage(), $this->level); |
} |
if ($this->mode & PEAR_ERROR_DIE) { |
$msg = $this->getMessage(); |
if (is_null($options) || is_int($options)) { |
$format = "%s"; |
if (substr($msg, -1) != "\n") { |
$msg .= "\n"; |
} |
} else { |
$format = $options; |
} |
die(sprintf($format, $msg)); |
} |
if ($this->mode & PEAR_ERROR_CALLBACK) { |
if (is_callable($this->callback)) { |
call_user_func($this->callback, $this); |
} |
} |
if ($this->mode & PEAR_ERROR_EXCEPTION) { |
trigger_error("PEAR_ERROR_EXCEPTION is obsolete, use class PEAR_ErrorStack for exceptions", E_USER_WARNING); |
eval('$e = new Exception($this->message, $this->code);$e->PEAR_Error = $this;throw($e);'); |
} |
} |
// }}} |
// {{{ getMode() |
/** |
* Get the error mode from an error object. |
* |
* @return int error mode |
* @access public |
*/ |
function getMode() { |
return $this->mode; |
} |
// }}} |
// {{{ getCallback() |
/** |
* Get the callback function/method from an error object. |
* |
* @return mixed callback function or object/method array |
* @access public |
*/ |
function getCallback() { |
return $this->callback; |
} |
// }}} |
// {{{ getMessage() |
/** |
* Get the error message from an error object. |
* |
* @return string full error message |
* @access public |
*/ |
function getMessage() |
{ |
return ($this->error_message_prefix . $this->message); |
} |
// }}} |
// {{{ getCode() |
/** |
* Get error code from an error object |
* |
* @return int error code |
* @access public |
*/ |
function getCode() |
{ |
return $this->code; |
} |
// }}} |
// {{{ getType() |
/** |
* Get the name of this error/exception. |
* |
* @return string error/exception name (type) |
* @access public |
*/ |
function getType() |
{ |
return get_class($this); |
} |
// }}} |
// {{{ getUserInfo() |
/** |
* Get additional user-supplied information. |
* |
* @return string user-supplied information |
* @access public |
*/ |
function getUserInfo() |
{ |
return $this->userinfo; |
} |
// }}} |
// {{{ getDebugInfo() |
/** |
* Get additional debug information supplied by the application. |
* |
* @return string debug information |
* @access public |
*/ |
function getDebugInfo() |
{ |
return $this->getUserInfo(); |
} |
// }}} |
// {{{ getBacktrace() |
/** |
* Get the call backtrace from where the error was generated. |
* Supported with PHP 4.3.0 or newer. |
* |
* @param int $frame (optional) what frame to fetch |
* @return array Backtrace, or NULL if not available. |
* @access public |
*/ |
function getBacktrace($frame = null) |
{ |
if ($frame === null) { |
return $this->backtrace; |
} |
return $this->backtrace[$frame]; |
} |
// }}} |
// {{{ addUserInfo() |
function addUserInfo($info) |
{ |
if (empty($this->userinfo)) { |
$this->userinfo = $info; |
} else { |
$this->userinfo .= " ** $info"; |
} |
} |
// }}} |
// {{{ toString() |
/** |
* Make a string representation of this object. |
* |
* @return string a string with an object summary |
* @access public |
*/ |
function toString() { |
$modes = array(); |
$levels = array(E_USER_NOTICE => 'notice', |
E_USER_WARNING => 'warning', |
E_USER_ERROR => 'error'); |
if ($this->mode & PEAR_ERROR_CALLBACK) { |
if (is_array($this->callback)) { |
$callback = (is_object($this->callback[0]) ? |
strtolower(get_class($this->callback[0])) : |
$this->callback[0]) . '::' . |
$this->callback[1]; |
} else { |
$callback = $this->callback; |
} |
return sprintf('[%s: message="%s" code=%d mode=callback '. |
'callback=%s prefix="%s" info="%s"]', |
strtolower(get_class($this)), $this->message, $this->code, |
$callback, $this->error_message_prefix, |
$this->userinfo); |
} |
if ($this->mode & PEAR_ERROR_PRINT) { |
$modes[] = 'print'; |
} |
if ($this->mode & PEAR_ERROR_TRIGGER) { |
$modes[] = 'trigger'; |
} |
if ($this->mode & PEAR_ERROR_DIE) { |
$modes[] = 'die'; |
} |
if ($this->mode & PEAR_ERROR_RETURN) { |
$modes[] = 'return'; |
} |
return sprintf('[%s: message="%s" code=%d mode=%s level=%s '. |
'prefix="%s" info="%s"]', |
strtolower(get_class($this)), $this->message, $this->code, |
implode("|", $modes), $levels[$this->level], |
$this->error_message_prefix, |
$this->userinfo); |
} |
// }}} |
} |
/* |
* Local Variables: |
* mode: php |
* tab-width: 4 |
* c-basic-offset: 4 |
* End: |
*/ |
?> |
/branches/livraison_menes/api/pear/Pager/HtmlWidgets.php |
---|
New file |
0,0 → 1,217 |
<?php |
/* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4: */ |
/** |
* Contains the Pager_HtmlWidgets class |
* |
* PHP versions 4 and 5 |
* |
* LICENSE: Redistribution and use in source and binary forms, with or without |
* modification, are permitted provided that the following conditions are met: |
* 1. Redistributions of source code must retain the above copyright |
* notice, this list of conditions and the following disclaimer. |
* 2. Redistributions in binary form must reproduce the above copyright |
* notice, this list of conditions and the following disclaimer in the |
* documentation and/or other materials provided with the distribution. |
* 3. The name of the author may not be used to endorse or promote products |
* derived from this software without specific prior written permission. |
* |
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR "AS IS" AND ANY EXPRESS OR IMPLIED |
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF |
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. |
* IN NO EVENT SHALL THE FREEBSD PROJECT OR CONTRIBUTORS BE LIABLE FOR ANY |
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES |
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; |
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND |
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF |
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
* |
* @category HTML |
* @package Pager |
* @author Lorenzo Alberton <l dot alberton at quipo dot it> |
* @copyright 2003-2006 Lorenzo Alberton |
* @license http://www.debian.org/misc/bsd.license BSD License (3 Clause) |
* @version CVS: $Id$ |
* @link http://pear.php.net/package/Pager |
*/ |
/** |
* Two constants used to guess the path- and file-name of the page |
* when the user doesn't set any other value |
*/ |
class Pager_HtmlWidgets |
{ |
var $pager = null; |
// {{{ constructor |
function Pager_HtmlWidgets(&$pager) |
{ |
$this->pager =& $pager; |
} |
// }}} |
// {{{ getPerPageSelectBox() |
/** |
* Returns a string with a XHTML SELECT menu, |
* useful for letting the user choose how many items per page should be |
* displayed. If parameter useSessions is TRUE, this value is stored in |
* a session var. The string isn't echoed right now so you can use it |
* with template engines. |
* |
* @param integer $start |
* @param integer $end |
* @param integer $step |
* @param boolean $showAllData If true, perPage is set equal to totalItems. |
* @param array (or string $optionText for BC reasons) |
* - 'optionText': text to show in each option. |
* Use '%d' where you want to see the number of pages selected. |
* - 'attributes': (html attributes) Tag attributes or |
* HTML attributes (id="foo" pairs), will be inserted in the |
* <select> tag |
* @return string xhtml select box |
* @access public |
*/ |
function getPerPageSelectBox($start=5, $end=30, $step=5, $showAllData=false, $extraParams=array()) |
{ |
// FIXME: needs POST support |
$optionText = '%d'; |
$attributes = ''; |
if (is_string($extraParams)) { |
//old behavior, BC maintained |
$optionText = $extraParams; |
} else { |
if (array_key_exists('optionText', $extraParams)) { |
$optionText = $extraParams['optionText']; |
} |
if (array_key_exists('attributes', $extraParams)) { |
$attributes = $extraParams['attributes']; |
} |
} |
if (!strstr($optionText, '%d')) { |
return $this->pager->raiseError( |
$this->pager->errorMessage(ERROR_PAGER_INVALID_PLACEHOLDER), |
ERROR_PAGER_INVALID_PLACEHOLDER |
); |
} |
$start = (int)$start; |
$end = (int)$end; |
$step = (int)$step; |
if (!empty($_SESSION[$this->pager->_sessionVar])) { |
$selected = (int)$_SESSION[$this->pager->_sessionVar]; |
} else { |
$selected = $this->pager->_perPage; |
} |
$tmp = '<select name="'.$this->pager->_sessionVar.'"'; |
if (!empty($attributes)) { |
$tmp .= ' '.$attributes; |
} |
$tmp .= '>'; |
for ($i=$start; $i<=$end; $i+=$step) { |
$tmp .= '<option value="'.$i.'"'; |
if ($i == $selected) { |
$tmp .= ' selected="selected"'; |
} |
$tmp .= '>'.sprintf($optionText, $i).'</option>'; |
} |
if ($showAllData && $end < $this->pager->_totalItems) { |
$tmp .= '<option value="'.$this->pager->_totalItems.'"'; |
if ($this->pager->_totalItems == $selected) { |
$tmp .= ' selected="selected"'; |
} |
$tmp .= '>'; |
if (empty($this->pager->_showAllText)) { |
$tmp .= str_replace('%d', $this->pager->_totalItems, $optionText); |
} else { |
$tmp .= $this->pager->_showAllText; |
} |
$tmp .= '</option>'; |
} |
$tmp .= '</select>'; |
return $tmp; |
} |
// }}} |
// {{{ getPageSelectBox() |
/** |
* Returns a string with a XHTML SELECT menu with the page numbers, |
* useful as an alternative to the links |
* |
* @param array - 'optionText': text to show in each option. |
* Use '%d' where you want to see the number of pages selected. |
* - 'autoSubmit': if TRUE, add some js code to submit the |
* form on the onChange event |
* @param string $extraAttributes (html attributes) Tag attributes or |
* HTML attributes (id="foo" pairs), will be inserted in the |
* <select> tag |
* @return string xhtml select box |
* @access public |
*/ |
function getPageSelectBox($params = array(), $extraAttributes = '') |
{ |
$optionText = '%d'; |
if (array_key_exists('optionText', $params)) { |
$optionText = $params['optionText']; |
} |
if (!strstr($optionText, '%d')) { |
return $this->pager->raiseError( |
$this->pager->errorMessage(ERROR_PAGER_INVALID_PLACEHOLDER), |
ERROR_PAGER_INVALID_PLACEHOLDER |
); |
} |
$tmp = '<select name="'.$this->pager->_urlVar.'"'; |
if (!empty($extraAttributes)) { |
$tmp .= ' '.$extraAttributes; |
} |
if (!empty($params['autoSubmit'])) { |
if ($this->pager->_httpMethod == 'GET') { |
$selector = '\' + '.'this.options[this.selectedIndex].value + \''; |
if ($this->pager->_append) { |
$href = '?' . $this->pager->_http_build_query_wrapper($this->pager->_linkData); |
$href = htmlentities($this->pager->_url). preg_replace( |
'/(&|&|\?)('.$this->pager->_urlVar.'=)(\d+)/', |
'\\1\\2'.$selector, |
htmlentities($href) |
); |
} else { |
$href = htmlentities($this->pager->_url . str_replace('%d', $selector, $this->pager->_fileName)); |
} |
$tmp .= ' onchange="document.location.href=\'' |
. $href .'\'' |
. '"'; |
} elseif ($this->pager->_httpMethod == 'POST') { |
$tmp .= " onchange='" |
. $this->pager->_generateFormOnClick($this->pager->_url, $this->pager->_linkData) |
. "'"; |
$tmp = preg_replace( |
'/(input\.name = \"'.$this->pager->_urlVar.'\"; input\.value =) \"(\d+)\";/', |
'\\1 this.options[this.selectedIndex].value;', |
$tmp |
); |
} |
} |
$tmp .= '>'; |
$start = 1; |
$end = $this->pager->numPages(); |
$selected = $this->pager->getCurrentPageID(); |
for ($i=$start; $i<=$end; $i++) { |
$tmp .= '<option value="'.$i.'"'; |
if ($i == $selected) { |
$tmp .= ' selected="selected"'; |
} |
$tmp .= '>'.sprintf($optionText, $i).'</option>'; |
} |
$tmp .= '</select>'; |
return $tmp; |
} |
// }}} |
} |
?> |
/branches/livraison_menes/api/pear/Pager/tests/pager_tests.php |
---|
New file |
0,0 → 1,20 |
<?php |
// $Id$ |
require_once 'simple_include.php'; |
require_once 'pager_include.php'; |
class PagerTests extends GroupTest { |
function PagerTests() { |
$this->GroupTest('Pager Tests'); |
$this->addTestFile('pager_test.php'); |
$this->addTestFile('pager_noData_test.php'); |
} |
} |
if (!defined('TEST_RUNNING')) { |
define('TEST_RUNNING', true); |
$test = &new PagerTests(); |
$test->run(new HtmlReporter()); |
} |
?> |
/branches/livraison_menes/api/pear/Pager/tests/multibyte_post.php |
---|
New file |
0,0 → 1,48 |
<?php |
require_once 'Pager/Pager.php'; |
//create dummy array of data |
$myData = array(); |
for ($i=0; $i<200; $i++) { |
$myData[] = $i; |
} |
//set a string |
$test_strings_encoded = array( |
'encoded1' => '测试', |
'encoded2' => '안녕', |
); |
$test_strings_plain = array( |
'plain1' => '안녕', |
'plain2' => '더보기', |
// 'plain3' => '이젠 전화도 |
//로 걸면 무료', |
); |
$params = array( |
'itemData' => $myData, |
'perPage' => 10, |
'delta' => 2, |
'append' => true, |
'clearIfVoid' => false, |
'extraVars' => array_merge($test_strings_plain, $test_strings_encoded), |
'httpMethod' => 'POST', |
'path' => 'http://'.$_SERVER['HTTP_HOST'].substr($_SERVER['PHP_SELF'], 0, strrpos($_SERVER['PHP_SELF'], '/')), |
'fileName' => basename(__FILE__), |
); |
//var_dump($params['fileName']);exit; |
$pager = & Pager::factory($params); |
$page_data = $pager->getPageData(); |
?> |
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 |
Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> |
<html xmlns="http://www.w3.org/1999/xhtml"> |
<head> |
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /> |
<title>Pager Test: page <?php echo $pager->getCurrentPageID(); ?></title> |
</head> |
<body> |
<?php echo $pager->links; ?> |
<hr /> |
<pre><?php print_r($page_data); ?></pre> |
</body> |
</html> |
/branches/livraison_menes/api/pear/Pager/tests/pager_noData_test.php |
---|
New file |
0,0 → 1,48 |
<?php |
// $Id$ |
require_once 'simple_include.php'; |
require_once 'pager_include.php'; |
class TestOfPagerNoData extends UnitTestCase { |
var $pager; |
function TestOfPagerNoData($name='Test of Pager - no data') { |
$this->UnitTestCase($name); |
} |
function setUp() { |
$options = array( |
'totalItems' => 0, |
'perPage' => 5, |
'mode' => 'Sliding', |
); |
$this->pager = Pager::factory($options); |
} |
function tearDown() { |
unset($this->pager); |
} |
function testCurrentPageID () { |
$this->assertEqual(0, $this->pager->getCurrentPageID()); |
} |
function testNextPageID () { |
$this->assertEqual(false, $this->pager->getNextPageID()); |
} |
function testPrevPageID () { |
$this->assertEqual(false, $this->pager->getPreviousPageID()); |
} |
function testNumItems () { |
$this->assertEqual(0, $this->pager->numItems()); |
} |
function testNumPages () { |
$this->assertEqual(0, $this->pager->numPages()); |
} |
function testFirstPage () { |
$this->assertEqual(true, $this->pager->isFirstPage()); |
} |
function testLastPage () { |
$this->assertEqual(true, $this->pager->isLastPage()); |
} |
function testLastPageComplete () { |
$this->assertEqual(true, $this->pager->isLastPageComplete()); |
} |
} |
?> |
/branches/livraison_menes/api/pear/Pager/tests/pager_post_tests.php |
---|
New file |
0,0 → 1,11 |
<?php |
// $Id$ |
require_once 'simple_include.php'; |
require_once 'pager_include.php'; |
$test = &new GroupTest('Pager POST tests'); |
$test->addTestFile('pager_post_test.php'); |
exit ($test->run(new HTMLReporter()) ? 0 : 1); |
?> |
/branches/livraison_menes/api/pear/Pager/tests/pager_jumping_test.php |
---|
New file |
0,0 → 1,83 |
<?php |
// $Id$ |
require_once 'simple_include.php'; |
require_once 'pager_include.php'; |
class TestOfPagerJumping extends UnitTestCase { |
var $pager; |
function TestOfPagerJumping($name='Test of Pager_Jumping') { |
$this->UnitTestCase($name); |
} |
function setUp() { |
$options = array( |
'itemData' => array(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12), |
'perPage' => 5, |
'mode' => 'Jumping', |
'delta' => 2 |
); |
$this->pager = Pager::factory($options); |
} |
function tearDown() { |
unset($this->pager); |
} |
function testPageIdByOffset1() { |
$this->assertEqual(1, $this->pager->getPageIdByOffset(1)); |
} |
function testPageIdByOffset5() { |
$this->assertEqual(1, $this->pager->getPageIdByOffset(5)); |
} |
function testPageIdByOffset6() { |
$this->assertEqual(2, $this->pager->getPageIdByOffset(6)); |
} |
function testPageRangeByPageId1() { |
$this->assertEqual(array(1, 2), $this->pager->getPageRangeByPageId(1)); |
} |
function testPageRangeByPageId2() { |
$this->assertEqual(array(1, 2), $this->pager->getPageRangeByPageId(2)); |
} |
function testPageRangeByPageId3() { |
$this->assertEqual(array(3, 3), $this->pager->getPageRangeByPageId(3)); |
} |
function testPageRangeByPageId_outOfRange() { |
$this->assertEqual(array(0, 0), $this->pager->getPageRangeByPageId(20)); |
} |
function testGetPageData() { |
$this->assertEqual(array(0=>1, 1=>2, 2=>3, 3=>4, 4=>5), $this->pager->getPageData()); |
} |
function testGetPageData2() { |
$this->assertEqual(array(5=>6, 6=>7, 7=>8, 8=>9, 9=>10), $this->pager->getPageData(2)); |
} |
function testGetPageData_OutOfRange() { |
$this->assertEqual(false, $this->pager->getPageData(4)); |
} |
/** |
* Returns offsets for given pageID. Eg, if you pass pageID=5 and your |
* delta is 2, it will return 3 and 7. A pageID of 6 would give you 4 and 8 |
* If the method is called without parameter, pageID is set to currentPage#. |
* |
* Given a PageId, it returns the limits of the range of pages displayed. |
* While getOffsetByPageId() returns the offset of the data within the current |
* page, this method returns the offsets of the page numbers interval. |
* E.g., if you have perPage=10 and pageId=3, it will return you 1 and 10. |
* PageID of 8 would give you 1 and 10 as well, because 1 <= 8 <= 10. |
* PageID of 11 would give you 11 and 20. |
* |
* @param pageID PageID to get offsets for |
* @return array First and last offsets |
* @access public |
*/ |
/** |
* Given a PageId, it returns the limits of the range of pages displayed. |
* While getOffsetByPageId() returns the offset of the data within the |
* current page, this method returns the offsets of the page numbers interval. |
* E.g., if you have perPage=10 and pageId=3, it will return you 1 and 10. |
* PageID of 8 would give you 1 and 10 as well, because 1 <= 8 <= 10. |
* PageID of 11 would give you 11 and 20. |
* |
* @param pageID PageID to get offsets for |
* @return array First and last offsets |
* @access public |
*/ |
} |
?> |
/branches/livraison_menes/api/pear/Pager/tests/pager_sliding_tests.php |
---|
New file |
0,0 → 1,21 |
<?php |
// $Id$ |
require_once 'simple_include.php'; |
require_once 'pager_include.php'; |
class PagerSlidingTests extends GroupTest { |
function PagerSlidingTests() { |
$this->GroupTest('Pager_Sliding Tests'); |
$this->addTestFile('pager_sliding_test.php'); |
$this->addTestFile('pager_sliding_notExpanded_test.php'); |
$this->addTestFile('pager_sliding_noData_test.php'); |
} |
} |
if (!defined('TEST_RUNNING')) { |
define('TEST_RUNNING', true); |
$test = &new PagerTests(); |
$test->run(new HtmlReporter()); |
} |
?> |
/branches/livraison_menes/api/pear/Pager/tests/all_tests.php |
---|
New file |
0,0 → 1,25 |
<?php |
// $Id$ |
require_once 'simple_include.php'; |
require_once 'pager_include.php'; |
define('TEST_RUNNING', true); |
require_once './pager_tests.php'; |
require_once './pager_jumping_tests.php'; |
require_once './pager_sliding_tests.php'; |
class AllTests extends GroupTest { |
function AllTests() { |
$this->GroupTest('All PEAR::Pager Tests'); |
$this->AddTestCase(new PagerTests()); |
$this->AddTestCase(new PagerJumpingTests()); |
$this->AddTestCase(new PagerSlidingTests()); |
} |
} |
$test = &new AllTests(); |
$test->run(new HtmlReporter()); |
?> |
/branches/livraison_menes/api/pear/Pager/tests/pager_test_xss.php |
---|
New file |
0,0 → 1,43 |
<?php |
// $Id$ |
//override url |
$_SERVER['PHP_SELF'] = '">test'; |
require_once 'simple_include.php'; |
require_once 'pager_include.php'; |
class TestOfPagerXSS extends UnitTestCase { |
var $pager; |
var $baseurl; |
function TestOfPagerXSS($name='Test of Pager - XSS attacks') { |
$this->UnitTestCase($name); |
} |
function setUp() { |
$options = array( |
'itemData' => array(1, 2, 3, 4, 5, 6, 7, 8, 9, 10), |
'perPage' => 5, |
); |
$this->pager = Pager::factory($options); |
$this->baseurl = substr($_SERVER['PHP_SELF'], 0, strrpos($_SERVER['PHP_SELF'], '/')); |
} |
function tearDown() { |
unset($this->pager); |
} |
function testXSS() { |
$options = array( |
'itemData' => array(1, 2, 3, 4, 5, 6, 7, 8, 9, 10), |
'perPage' => 5, |
'nextImg' => '»' |
); |
$this->pager = Pager::factory($options); |
$expected = ' <a href="./">test?pageID=2" title="next page">»</a> '; |
$this->assertEqual($expected, $this->pager->_getNextLink()); |
} |
} |
if (!defined('TEST_RUNNING')) { |
define('TEST_RUNNING', true); |
$test = &new TestOfPagerXSS(); |
$test->run(new HtmlReporter()); |
} |
?> |
/branches/livraison_menes/api/pear/Pager/tests/pager_sliding_noData_test.php |
---|
New file |
0,0 → 1,30 |
<?php |
// $Id$ |
require_once 'simple_include.php'; |
require_once 'pager_include.php'; |
class TestOfPagerSlidingNoData extends UnitTestCase { |
var $pager; |
function TestOfPagerSlidingNoData($name='Test of Pager_Sliding - no data') { |
$this->UnitTestCase($name); |
} |
function setUp() { |
$options = array( |
'totalItems' => 0, |
'perPage' => 2, |
'mode' => 'Sliding', |
); |
$this->pager = Pager::factory($options); |
} |
function tearDown() { |
unset($this->pager); |
} |
function testOffsetByPageId() { |
$this->assertEqual(array(1, 0), $this->pager->getOffsetByPageId()); |
} |
function testPageIdByOffset() { |
$this->assertNull($this->pager->getPageIdByOffset()); |
} |
} |
?> |
/branches/livraison_menes/api/pear/Pager/tests/simple_include.php |
---|
New file |
0,0 → 1,17 |
<?php |
// $Id$ |
// |
// This testsuite requires SimpleTest. |
// You can find it here: |
// http://www.lastcraft.com/simple_test.php |
// |
if (!defined('SIMPLE_TEST')) { |
define('SIMPLE_TEST', '../simpletest/'); |
} |
require_once(SIMPLE_TEST . 'unit_tester.php'); |
require_once(SIMPLE_TEST . 'reporter.php'); |
require_once(SIMPLE_TEST . 'mock_objects.php'); |
require_once(SIMPLE_TEST . 'web_tester.php'); |
require_once(SIMPLE_TEST . 'reporter.php'); |
?> |
/branches/livraison_menes/api/pear/Pager/tests/pager_test.php |
---|
New file |
0,0 → 1,553 |
<?php |
// $Id$ |
require_once 'simple_include.php'; |
require_once 'pager_include.php'; |
class TestOfPager extends UnitTestCase { |
var $pager; |
var $baseurl; |
function TestOfPager($name='Test of Pager') { |
$this->UnitTestCase($name); |
} |
function setUp() { |
$options = array( |
'itemData' => array(1, 2, 3, 4, 5, 6, 7, 8, 9, 10), |
'perPage' => 5, |
); |
$this->pager = Pager::factory($options); |
$this->baseurl = substr($_SERVER['PHP_SELF'], 0, strrpos($_SERVER['PHP_SELF'], '/')); |
} |
function tearDown() { |
unset($this->pager); |
} |
function testCurrentPageID () { |
$this->assertEqual(1, $this->pager->getCurrentPageID()); |
} |
function testNextPageID () { |
$this->assertEqual(2, $this->pager->getNextPageID()); |
} |
function testPrevPageID () { |
$this->assertEqual(false, $this->pager->getPreviousPageID()); |
} |
function testNumItems () { |
$this->assertEqual(10, $this->pager->numItems()); |
} |
function testNumPages () { |
$this->assertEqual(2, $this->pager->numPages()); |
} |
function testFirstPage () { |
$this->assertEqual(true, $this->pager->isFirstPage()); |
} |
function testLastPage () { |
$this->assertEqual(false, $this->pager->isLastPage()); |
} |
function testLastPageComplete () { |
$this->assertEqual(true, $this->pager->isLastPageComplete()); |
} |
function testOffsetByPageId() { |
$this->assertEqual(array(1, 5), $this->pager->getOffsetByPageId(1)); |
$this->assertEqual(array(6, 10), $this->pager->getOffsetByPageId(2)); |
} |
function testOffsetByPageId_outOfRange() { |
$this->assertEqual(array(0, 0), $this->pager->getOffsetByPageId(20)); |
} |
function testGetPageData() { |
$this->assertEqual(array(0=>1, 1=>2, 2=>3, 3=>4, 4=>5), $this->pager->getPageData()); |
$this->assertEqual(array(5=>6, 6=>7, 7=>8, 8=>9, 9=>10), $this->pager->getPageData(2)); |
} |
function testGetPageData_OutOfRange() { |
$this->assertEqual(array(), $this->pager->getPageData(3)); |
} |
function testSelectBox() { |
$selectBox = '<select name="'.$this->pager->_sessionVar.'">'; |
$selectBox .= '<option value="5" selected="selected">5</option>'; |
$selectBox .= '<option value="10">10</option>'; |
$selectBox .= '<option value="15">15</option>'; |
$selectBox .= '</select>'; |
$this->assertEqual($selectBox, $this->pager->getPerPageSelectBox(5, 15, 5)); |
} |
function testSelectBoxWithString() { |
$selectBox = '<select name="'.$this->pager->_sessionVar.'">'; |
$selectBox .= '<option value="5" selected="selected">5 bugs</option>'; |
$selectBox .= '<option value="10">10 bugs</option>'; |
$selectBox .= '<option value="15">15 bugs</option>'; |
$selectBox .= '</select>'; |
$this->assertEqual($selectBox, $this->pager->getPerPageSelectBox(5, 15, 5, false, '%d bugs')); |
} |
function testSelectBoxWithShowAll() { |
$selectBox = '<select name="'.$this->pager->_sessionVar.'">'; |
$selectBox .= '<option value="3">3</option>'; |
$selectBox .= '<option value="4">4</option>'; |
$selectBox .= '<option value="5" selected="selected">5</option>'; |
$selectBox .= '<option value="6">6</option>'; |
$selectBox .= '<option value="10">10</option>'; |
$selectBox .= '</select>'; |
$this->assertEqual($selectBox, $this->pager->getPerPageSelectBox(3, 6, 1, true)); |
} |
function testSelectBoxWithShowAllAndText() { |
$this->pager->_showAllText = 'Show All'; |
$selectBox = '<select name="'.$this->pager->_sessionVar.'">'; |
$selectBox .= '<option value="3">3 bugs</option>'; |
$selectBox .= '<option value="4">4 bugs</option>'; |
$selectBox .= '<option value="5" selected="selected">5 bugs</option>'; |
$selectBox .= '<option value="6">6 bugs</option>'; |
$selectBox .= '<option value="10">Show All</option>'; |
$selectBox .= '</select>'; |
$this->assertEqual($selectBox, $this->pager->getPerPageSelectBox(3, 6, 1, true, '%d bugs')); |
} |
function testSelectBoxWithShowAllWithExtraAttribs() { |
$this->pager->_showAllText = 'Show All'; |
$selectBox = '<select name="'.$this->pager->_sessionVar.'" onmouseover="doSth">'; |
$selectBox .= '<option value="3">3 bugs</option>'; |
$selectBox .= '<option value="4">4 bugs</option>'; |
$selectBox .= '<option value="5" selected="selected">5 bugs</option>'; |
$selectBox .= '<option value="6">6 bugs</option>'; |
$selectBox .= '<option value="10">Show All</option>'; |
$selectBox .= '</select>'; |
$params = array('optionText' => '%d bugs', 'attributes' => 'onmouseover="doSth"'); |
$this->assertEqual($selectBox, $this->pager->getPerPageSelectBox(3, 6, 1, true, $params)); |
} |
function testSelectBoxInvalid() { |
$err = $this->pager->getPerPageSelectBox(5, 15, 5, false, '%s bugs'); |
$this->assertEqual(ERROR_PAGER_INVALID_PLACEHOLDER, $err->getCode()); |
} |
function testAppendInvalid() { |
$options = array( |
'totalItems' => 10, |
'append' => false, |
'fileName' => 'invalidFileName' |
); |
$err =& Pager::factory($options); //ERROR_PAGER_INVALID_USAGE |
$this->assertError(); |
} |
function testAppendValid() { |
$options = array( |
'totalItems' => 10, |
'append' => false, |
'fileName' => 'valid_%d_FileName' |
); |
$err =& Pager::factory($options); |
$this->assertNoErrors(); |
} |
function testEscapeEntities() { |
//encode special chars |
$options = array( |
'extraVars' => array( |
'request' => array('aRequest'), |
'escape' => 'äö%<>+', |
), |
'perPage' => 5, |
); |
$this->pager =& Pager::factory($options); |
//$expected = '?request[]=aRequest&escape=äö%<>+&pageID='; |
//$this->assertEqual($expected, $this->pager->_getLinksUrl()); |
$expected = 'request%5B0%5D=aRequest&escape=%E4%F6%25%3C%3E%2B'; |
$rendered = $this->pager->_renderLink('', ''); |
preg_match('/href="(.*)"/U', $rendered, $matches); |
$actual = str_replace($_SERVER['PHP_SELF'].'?', '', $matches[1]); |
$this->assertEqual($expected, $actual); |
//don't encode slashes |
$options = array( |
'extraVars' => array( |
'request' => 'cat/subcat', |
), |
'perPage' => 5, |
); |
$this->pager =& Pager::factory($options); |
//$expected = '?request=cat/subcat&pageID='; |
//$this->assertEqual($expected, $this->pager->_getLinksUrl()); |
$expected = '<a href="'.$_SERVER['PHP_SELF'].'?request=cat/subcat" title=""></a>'; |
$actual = $this->pager->_renderLink('', ''); |
$this->assertEqual($expected, $actual); |
} |
function testMultibyteStrings() { |
$options = array( |
'extraVars' => array( |
'test' => '测试', |
), |
'perPage' => 5, |
); |
$this->pager =& Pager::factory($options); |
//$expected = '<a href="'.$_SERVER['PHP_SELF'].'?test=测试" title=""></a>'; |
$rendered = $this->pager->_renderLink('', ''); |
preg_match('/href="(.*)"/U', $rendered, $matches); |
$actual = str_replace($_SERVER['PHP_SELF'].'?test=', '', $matches[1]); |
$this->assertEqual(urlencode($options['extraVars']['test']), $actual); |
} |
function testCurrentPage() { |
$options = array( |
'itemData' => array(1, 2, 3, 4, 5, 6, 7, 8, 9, 10), |
'perPage' => 2, |
'currentPage' => 2, |
); |
$this->pager =& Pager::factory($options); |
$this->assertEqual(3, $this->pager->getNextPageID()); |
$this->assertEqual(1, $this->pager->getPreviousPageID()); |
$this->assertEqual(2, $this->pager->_currentPage); |
} |
function testArrayExtraVars() { |
$arr = array( |
'apple', |
'orange', |
); |
$options = array( |
'itemData' => array(1, 2, 3, 4, 5, 6, 7, 8, 9, 10), |
'perPage' => 5, |
'extraVars' => array('arr' => $arr, 'no' => 'test'), |
); |
$this->pager =& Pager::factory($options); |
/* |
//old |
$expected = '?arr[0]=apple&arr[1]=orange&pageID='; |
$this->assertEqual($expected, $this->pager->_getLinksUrl()); |
*/ |
$expected = $options['extraVars']; |
$this->assertEqual($expected, $this->pager->_getLinksData()); |
$expected = '<a href="'.$_SERVER['PHP_SELF'].'?arr%5B0%5D=apple&arr%5B1%5D=orange&no=test&pageID=2" title=""></a>'; |
$actual = $this->pager->_renderLink('', ''); |
$this->assertEqual($expected, $actual); |
} |
function testExcludeVars() { |
$arr = array( |
'apple', |
'orange', |
); |
$options = array( |
'itemData' => array(1, 2, 3, 4, 5, 6, 7, 8, 9, 10), |
'perPage' => 5, |
'extraVars' => array('arr' => $arr, 'no' => 'test'), |
'excludeVars' => array('no'), |
); |
$this->pager =& Pager::factory($options); |
$expected = array( |
'arr' => array( |
0 => 'apple', |
1 => 'orange' |
), |
); |
$actual = $this->pager->_getLinksData(); |
$this->assertEqual($expected, $this->pager->_getLinksData()); |
$expected = '<a href="'.$_SERVER['PHP_SELF'].'?arr%5B0%5D=apple&arr%5B1%5D=orange&pageID=2" title=""></a>'; |
$actual = $this->pager->_renderLink('', ''); |
$this->assertEqual($expected, $actual); |
} |
function testArgSeparator() { |
$bkp_arg_separator = ini_get('arg_separator.output'); |
ini_set('arg_separator.output', '&'); |
$options = array( |
'itemData' => array(1, 2, 3, 4, 5, 6, 7, 8, 9, 10), |
'perPage' => 5, |
'extraVars' => array('apple' => 1), |
); |
$this->pager =& Pager::factory($options); |
$expected = '<a href="'.$_SERVER['PHP_SELF'].'?apple=1&pageID=2" title=""></a>'; |
$actual = $this->pager->_renderLink('', ''); |
$this->assertEqual($expected, $actual); |
ini_set('arg_separator.output', $bkp_arg_separator); |
} |
function testAttributes() { |
$options = array( |
'itemData' => array(1, 2, 3, 4, 5, 6, 7, 8, 9, 10), |
'perPage' => 5, |
'linkClass' => 'testclass', |
'attributes' => 'target="_blank"', |
); |
$this->pager =& Pager::factory($options); |
$expected = '<a href="'.$_SERVER['PHP_SELF'].'?pageID=2" class="testclass" target="_blank" title=""></a>'; |
$actual = $this->pager->_renderLink('', ''); |
$this->assertEqual($expected, $actual); |
} |
function testImportQuery() { |
//add some fake url vars |
$_GET['arr'] = array( |
'apple', |
'orange', |
); |
$options = array( |
'itemData' => array(1, 2, 3, 4, 5, 6, 7, 8, 9, 10), |
'perPage' => 5, |
'importQuery' => false, |
); |
$this->pager =& Pager::factory($options); |
$expected = array(); |
$actual = $this->pager->_getLinksData(); |
$this->assertEqual($expected, $this->pager->_getLinksData()); |
$expected = '<a href="'.$_SERVER['PHP_SELF'].'?pageID=2" title=""></a>'; |
$actual = $this->pager->_renderLink('', ''); |
$this->assertEqual($expected, $actual); |
//remove fake url vars |
unset($_GET['arr']); |
} |
function testGetNextLinkTag() { |
//append = true |
$expected = '<link rel="next" href="'.$_SERVER['PHP_SELF'].'?pageID=2" title="next page" />'."\n"; |
$this->assertEqual($expected, $this->pager->_getNextLinkTag()); |
//append = false |
$options = array( |
'itemData' => array(1, 2, 3, 4, 5, 6, 7, 8, 9, 10), |
'perPage' => 5, |
'currentPage' => 1, |
'append' => false, |
'fileName' => 'myfile.%d.php', |
); |
$this->pager = Pager::factory($options); |
$expected = '<link rel="next" href="'.$this->baseurl.'/myfile.2.php" title="next page" />'."\n"; |
$this->assertEqual($expected, $this->pager->_getNextLinkTag()); |
//test empty tag |
$options['currentPage'] = 2; |
$this->pager = Pager::factory($options); |
$this->assertEqual('', $this->pager->_getNextLinkTag()); |
} |
function testGetLastLinkTag() { |
//append = true |
$expected = '<link rel="last" href="'.$_SERVER['PHP_SELF'].'?pageID=2" title="last page" />'."\n"; |
$this->assertEqual($expected, $this->pager->_getLastLinkTag()); |
//append = false |
$options = array( |
'itemData' => array(1, 2, 3, 4, 5, 6, 7, 8, 9, 10), |
'perPage' => 5, |
'currentPage' => 1, |
'append' => false, |
'fileName' => 'myfile.%d.php', |
); |
$this->pager = Pager::factory($options); |
$expected = '<link rel="last" href="'.$this->baseurl.'/myfile.2.php" title="last page" />'."\n"; |
$this->assertEqual($expected, $this->pager->_getLastLinkTag()); |
//test empty tag |
$options['currentPage'] = 2; |
$this->pager = Pager::factory($options); |
$this->assertEqual('', $this->pager->_getLastLinkTag()); |
} |
function testGetFirstLinkTag() { |
//append = true |
$options = array( |
'itemData' => array(1, 2, 3, 4, 5, 6, 7, 8, 9, 10), |
'perPage' => 5, |
'currentPage' => 2, |
); |
$this->pager = Pager::factory($options); |
$expected = '<link rel="first" href="'.$_SERVER['PHP_SELF'].'?pageID=1" title="first page" />'."\n"; |
$this->assertEqual($expected, $this->pager->_getFirstLinkTag()); |
//append = false |
$options = array( |
'itemData' => array(1, 2, 3, 4, 5, 6, 7, 8, 9, 10), |
'perPage' => 5, |
'currentPage' => 2, |
'append' => false, |
'fileName' => 'myfile.%d.php', |
); |
$this->pager = Pager::factory($options); |
$expected = '<link rel="first" href="'.$this->baseurl.'/myfile.1.php" title="first page" />'."\n"; |
$this->assertEqual($expected, $this->pager->_getFirstLinkTag()); |
//test empty tag |
$options['currentPage'] = 1; |
$this->pager = Pager::factory($options); |
$this->assertEqual('', $this->pager->_getFirstLinkTag()); |
} |
function testGetPrevLinkTag() { |
//append = true |
$options = array( |
'itemData' => array(1, 2, 3, 4, 5, 6, 7, 8, 9, 10), |
'perPage' => 5, |
'currentPage' => 2, |
); |
$this->pager = Pager::factory($options); |
$expected = '<link rel="previous" href="'.$_SERVER['PHP_SELF'].'?pageID=1" title="previous page" />'."\n"; |
$this->assertEqual($expected, $this->pager->_getPrevLinkTag()); |
//append = false |
$options = array( |
'itemData' => array(1, 2, 3, 4, 5, 6, 7, 8, 9, 10), |
'perPage' => 5, |
'currentPage' => 2, |
'append' => false, |
'fileName' => 'myfile.%d.php', |
); |
$this->pager = Pager::factory($options); |
$expected = '<link rel="previous" href="'.$this->baseurl.'/myfile.1.php" title="previous page" />'."\n"; |
$this->assertEqual($expected, $this->pager->_getPrevLinkTag()); |
//test empty tag |
$options['currentPage'] = 1; |
$this->pager = Pager::factory($options); |
$this->assertEqual('', $this->pager->_getPrevLinkTag()); |
} |
function testPrintFirstPage() { |
$options = array( |
'itemData' => array(1, 2, 3, 4, 5, 6, 7, 8, 9, 10), |
'perPage' => 5, |
'currentPage' => 2, |
); |
$this->pager = Pager::factory($options); |
$expected = '<a href="' . $_SERVER['PHP_SELF'] . '?pageID=1" title="first page">[1]</a> '; |
$this->assertEqual($expected, $this->pager->_printFirstPage()); |
$this->pager->_firstPageText = 'FIRST'; |
$expected = '<a href="' . $_SERVER['PHP_SELF'] . '?pageID=1" title="first page">[FIRST]</a> '; |
$this->assertEqual($expected, $this->pager->_printFirstPage()); |
$options = array( |
'itemData' => array(1, 2, 3, 4, 5, 6, 7, 8, 9, 10), |
'perPage' => 5, |
'currentPage' => 2, |
'altFirst' => 'page %d', |
); |
$this->pager = Pager::factory($options); |
$expected = '<a href="' . $_SERVER['PHP_SELF'] . '?pageID=1" title="page 1">[1]</a> '; |
$this->assertEqual($expected, $this->pager->_printFirstPage()); |
} |
function testPrintLastPage() { |
$expected = '<a href="' . $_SERVER['PHP_SELF'] . '?pageID=2" title="last page">[2]</a>'; |
$this->assertEqual($expected, $this->pager->_printLastPage()); |
$this->pager->_lastPageText = 'LAST'; |
$expected = '<a href="' . $_SERVER['PHP_SELF'] . '?pageID=2" title="last page">[LAST]</a>'; |
$this->assertEqual($expected, $this->pager->_printLastPage()); |
$this->pager->_altLast = 'page %d'; |
$expected = '<a href="' . $_SERVER['PHP_SELF'] . '?pageID=2" title="page 2">[LAST]</a>'; |
$this->assertEqual($expected, $this->pager->_printLastPage()); |
} |
function testGetBackLink() { |
$img = '«'; |
$options = array( |
'itemData' => array(1, 2, 3, 4, 5, 6, 7, 8, 9, 10), |
'perPage' => 5, |
'currentPage' => 2, |
'prevImg' => $img, |
); |
$this->pager = Pager::factory($options); |
$expected = '<a href="' . $_SERVER['PHP_SELF'] . '?pageID=1" title="previous page">'.$img.'</a> '; |
$this->assertEqual($expected, $this->pager->_getBackLink()); |
} |
function testGetNexLink() { |
$img = '»'; |
$options = array( |
'itemData' => array(1, 2, 3, 4, 5, 6, 7, 8, 9, 10), |
'perPage' => 5, |
'currentPage' => 1, |
'nextImg' => $img, |
); |
$this->pager = Pager::factory($options); |
$expected = ' <a href="' . $_SERVER['PHP_SELF'] . '?pageID=2" title="next page">'.$img.'</a> '; |
$this->assertEqual($expected, $this->pager->_getNextLink()); |
} |
function testHttpMethodAutoDetect() { |
$_POST['pageID'] = 3; |
$options = array( |
'itemData' => array(1, 2, 3, 4, 5, 6, 7, 8, 9, 10), |
'perPage' => 5, |
); |
$this->pager = Pager::factory($options); |
$this->assertEqual('POST', $this->pager->_httpMethod); |
$options = array( |
'itemData' => array(1, 2, 3, 4, 5, 6, 7, 8, 9, 10), |
'perPage' => 5, |
'httpMethod' => 'GET', |
); |
$this->pager = Pager::factory($options); |
$this->assertEqual('GET', $this->pager->_httpMethod); |
unset($_POST['pageID']); |
$options = array( |
'itemData' => array(1, 2, 3, 4, 5, 6, 7, 8, 9, 10), |
'perPage' => 5, |
'httpMethod' => 'POST', |
); |
$this->pager = Pager::factory($options); |
$this->assertEqual('POST', $this->pager->_httpMethod); |
$options = array( |
'itemData' => array(1, 2, 3, 4, 5, 6, 7, 8, 9, 10), |
'perPage' => 5, |
); |
$this->pager = Pager::factory($options); |
$this->assertEqual('GET', $this->pager->_httpMethod); |
} |
function testAccesskey() { |
$options = array( |
'itemData' => array(1, 2, 3, 4, 5, 6, 7, 8, 9, 10), |
'perPage' => 5, |
'accesskey' => true, |
); |
$this->pager = Pager::factory($options); |
$this->assertWantedPattern('/accesskey="\d"/i', $this->pager->links); |
//var_dump($this->pager->links); |
} |
function testIsEncoded() { |
//var_dump(urlencode('안녕')); |
$test_strings_encoded = array( |
'encoded0' => '试', |
'encoded1' => '测试', |
'encoded2' => '안녕', |
'encoded3' => '안 녕', |
'encoded4' => '안 |
녕', |
); |
$test_strings_plain = array( |
'plain1' => '안녕', |
'plain2' => '더보기', |
// 'plain3' => '이젠 전화도 |
//로 걸면 무료', |
'plain4' => 'abcde', //not multibyte |
'plain5' => '&#abcfg;', //invalid hex-encoded char |
'plain5' => '안 nasty 녕', //mixed plain/encoded text |
); |
foreach ($test_strings_encoded as $string) { |
//echo '<hr />'.str_replace('&', '&', $string); |
$this->assertTrue($this->pager->_isEncoded($string)); |
} |
foreach ($test_strings_plain as $string) { |
$this->assertFalse($this->pager->_isEncoded($string)); |
} |
} |
function testGetOption() { |
$this->assertEqual(5, $this->pager->getOption('perPage')); |
$err = $this->pager->getOption('non_existent_option'); |
$this->assertEqual(ERROR_PAGER_INVALID, $err->getCode()); |
} |
function testGetOptions() { |
$options = $this->pager->getOptions(); |
$this->assertTrue(is_array($options)); |
$this->assertEqual(5, $options['perPage']); |
} |
function testSetOptionsAndBuild() { |
$options = array( |
'perPage' => 2, |
); |
$this->pager->setOptions($options); |
$this->pager->build(); |
$this->assertEqual(2, $this->pager->getOption('perPage')); |
$this->assertEqual(array(0=>1, 1=>2), $this->pager->getPageData()); |
$this->assertEqual(array(2=>3, 3=>4), $this->pager->getPageData(2)); |
$options = array( |
'currentPage' => 2, |
'append' => false, |
'fileName' => 'myfile.%d.php', |
); |
$this->pager->setOptions($options); |
$this->pager->build(); |
$expected = '<link rel="previous" href="'.$this->baseurl.'/myfile.1.php" title="previous page" />'."\n"; |
$this->assertEqual($expected, $this->pager->_getPrevLinkTag()); |
} |
} |
?> |
/branches/livraison_menes/api/pear/Pager/tests/pager_wrapper_test.php |
---|
New file |
0,0 → 1,205 |
<?php |
// $Id$ |
require_once 'simple_include.php'; |
require_once 'pager_wrapper_include.php'; |
class TestOfPagerWrapper extends UnitTestCase |
{ |
function TestOfPagerWrapper($name='Test of Pager_Wrapper') { |
$this->UnitTestCase($name); |
} |
function setUp() { } |
function tearDown() { } |
/** |
* Basic tests for rewriteCountQuery() |
*/ |
function testRewriteCountQuery() { |
//test LIMIT |
$query = 'SELECT a, b, c, d FROM mytable WHERE a=1 AND c="g" LIMIT 2'; |
$expected = 'SELECT COUNT(*) FROM mytable WHERE a=1 AND c="g"'; |
$this->assertEqual($expected, rewriteCountQuery($query)); |
//test ORDER BY and quotes |
$query = 'SELECT a, b, c, d FROM mytable WHERE a=1 AND c="g" ORDER BY (a, b)'; |
$expected = 'SELECT COUNT(*) FROM mytable WHERE a=1 AND c="g"'; |
$this->assertEqual($expected, rewriteCountQuery($query)); |
//test CR/LF |
$query = 'SELECT a, b, c, d FROM mytable |
WHERE a=1 |
AND c="g" |
ORDER BY (a, b)'; |
$expected = 'SELECT COUNT(*) FROM mytable |
WHERE a=1 |
AND c="g"'; |
$this->assertEqual($expected, rewriteCountQuery($query)); |
//test GROUP BY |
$query = 'SELECT a, b, c, d FROM mytable WHERE a=1 GROUP BY c'; |
$this->assertFalse(rewriteCountQuery($query)); |
//test DISTINCT |
$query = 'SELECT DISTINCT a, b, c, d FROM mytable WHERE a=1 GROUP BY c'; |
$this->assertFalse(rewriteCountQuery($query)); |
//test MiXeD Keyword CaSe |
$query = 'SELECT a, b, c, d from mytable WHERE a=1 AND c="g"'; |
$expected = 'SELECT COUNT(*) FROM mytable WHERE a=1 AND c="g"'; |
$this->assertEqual($expected, rewriteCountQuery($query)); |
//test function speed... this query used to be very slow to parse |
$query = "SELECT i.item_id, |
ia.addition, |
u.username, |
i.date_created, |
i.start_date, |
i.expiry_date |
FROM item i, item_addition ia, item_type it, item_type_mapping itm, usr u, category c |
WHERE ia.item_type_mapping_id = itm.item_type_mapping_id |
AND i.updated_by_id = u.usr_id |
AND it.item_type_id = itm.item_type_id |
AND i.item_id = ia.item_id |
AND i.item_type_id = it.item_type_id |
AND itm.field_name = 'title' AND it.item_type_id = 2 AND i.category_id = 1 AND i.status = 4 |
AND i.category_id = c.category_id |
AND 0 NOT IN (COALESCE(c.perms, '-1')) |
ORDER BY i.last_updated DESC"; |
$expected = "SELECT COUNT(*) FROM item i, item_addition ia, item_type it, item_type_mapping itm, usr u, category c |
WHERE ia.item_type_mapping_id = itm.item_type_mapping_id |
AND i.updated_by_id = u.usr_id |
AND it.item_type_id = itm.item_type_id |
AND i.item_id = ia.item_id |
AND i.item_type_id = it.item_type_id |
AND itm.field_name = 'title' AND it.item_type_id = 2 AND i.category_id = 1 AND i.status = 4 |
AND i.category_id = c.category_id |
AND 0 NOT IN (COALESCE(c.perms, '-1'))"; |
$this->assertEqual($expected, rewriteCountQuery($query)); |
} |
/** |
* Test rewriteCountQuery() with queries having a subquery in the SELECT clause |
*/ |
function testRewriteCountQuery_SubqueriesInSelectClause() { |
$query = 'SELECT a, (SELECT a FROM b) AS b, c, d FROM mytable WHERE a=1 AND c="g" LIMIT 2'; |
$expected = 'SELECT COUNT(*) FROM mytable WHERE a=1 AND c="g"'; |
$this->assertFalse(rewriteCountQuery($query)); |
$query = 'SELECT a, (SELECT a FROM b) AS b, (SELECT c FROM c) AS c, d FROM mytable WHERE a=1 AND c="g" LIMIT 2'; |
//$expected = 'SELECT COUNT(*) FROM mytable WHERE a=1 AND c="g"'; |
$this->assertFalse(rewriteCountQuery($query)); |
$query = 'SELECT `id`, `ip`, ( |
SELECT TIMEDIFF(MAX(P.`time`), MIN(P.`time`)) |
FROM `przejscia` as P |
WHERE P.`id_wejscia`=W.`id` |
) as `czas` |
FROM `wejscia` as W |
WHERE W.id_domeny=? |
ORDER BY W.czas_wejscia DESC'; |
$expected = 'SELECT COUNT(*) |
FROM `wejscia` as W |
WHERE W.id_domeny=? |
ORDER BY W.czas_wejscia DESC'; |
$this->assertFalse(rewriteCountQuery($query)); |
} |
/** |
* Test rewriteCountQuery() with queries having a subquery in the FROM clause |
*/ |
function testRewriteCountQuery_SubqueriesInFromClause() { |
$query = 'SELECT a, b, c, d FROM (SELECT a, b, c, d FROM mytable WHERE a=1) AS tbl_alias WHERE a=1'; |
$expected = 'SELECT COUNT(*) FROM (SELECT a, b, c, d FROM mytable WHERE a=1) AS tbl_alias WHERE a=1'; |
$this->assertEqual($expected, rewriteCountQuery($query)); |
} |
/** |
* Test rewriteCountQuery() with queries having a subquery in the WHERE clause |
*/ |
function testRewriteCountQuery_SubqueriesInWhereClause() { |
//this one is not rewritten: subqueries with ORDER BY clauses might get truncated |
$query = 'SELECT Version.VersionId, Version.Identifier,News.* |
FROM VersionBroker |
JOIN ObjectType ON ObjectType.ObjectTypeId = VersionBroker.ObjectTypeId |
JOIN Version ON VersionBroker.Identifier = Version.Identifier |
JOIN News ON Version.ObjectId = News.NewsId |
WHERE Version.Status = \'Approved\' |
AND ObjectType.Name = \'News\' |
AND Version.ApprovedTS = ( |
SELECT SubV.ApprovedTS |
FROM Version SubV |
WHERE SubV.Identifier = VersionBroker.Identifier |
ORDER BY ApprovedTS DESC |
LIMIT 1) |
ORDER BY ApprovedTS DESC'; |
$expected = 'SELECT COUNT(*) |
FROM VersionBroker |
JOIN ObjectType ON ObjectType.ObjectTypeId = VersionBroker.ObjectTypeId |
JOIN Version ON VersionBroker.Identifier = Version.Identifier |
JOIN News ON Version.ObjectId = News.NewsId |
WHERE Version.Status = \'Approved\' |
AND ObjectType.Name = \'News\' |
AND Version.ApprovedTS = ( |
SELECT SubV.ApprovedTS |
FROM Version SubV |
WHERE SubV.Identifier = VersionBroker.Identifier |
ORDER BY ApprovedTS DESC |
LIMIT 1) |
ORDER BY ApprovedTS DESC'; |
//$this->assertEqual($expected, rewriteCountQuery($query)); |
$this->assertFalse(rewriteCountQuery($query)); |
//this one should pass... subquery without ORDER BY or LIMIT clause |
$query = 'SELECT Version.VersionId, Version.Identifier,News.* FROM VersionBroker JOIN |
ObjectType ON ObjectType.ObjectTypeId = VersionBroker.ObjectTypeId JOIN |
Version ON VersionBroker.Identifier = Version.Identifier JOIN News ON |
Version.ObjectId = News.NewsId WHERE Version.Status = \'Approved\' AND |
ObjectType.Name = \'News\' AND Version.ApprovedTS = ( SELECT SubV.ApprovedTS |
FROM Version SubV WHERE SubV.Identifier = VersionBroker.Identifier ) ORDER BY ApprovedTS DESC'; |
$expected = 'SELECT COUNT(*) FROM VersionBroker JOIN |
ObjectType ON ObjectType.ObjectTypeId = VersionBroker.ObjectTypeId JOIN |
Version ON VersionBroker.Identifier = Version.Identifier JOIN News ON |
Version.ObjectId = News.NewsId WHERE Version.Status = \'Approved\' AND |
ObjectType.Name = \'News\' AND Version.ApprovedTS = ( SELECT SubV.ApprovedTS |
FROM Version SubV WHERE SubV.Identifier = VersionBroker.Identifier )'; |
$this->assertEqual($expected, rewriteCountQuery($query)); |
} |
/** |
* Test rewriteCountQuery() with queries having keywords embedded in other words |
*/ |
function testRewriteCountQuery_EmbeddedKeywords() { |
$query = 'SELECT afieldFROM, b, c, d FROM mytable WHERE a=1 AND c="g"'; |
$expected = 'SELECT COUNT(*) FROM mytable WHERE a=1 AND c="g"'; |
$this->assertEqual($expected, rewriteCountQuery($query)); |
$query = 'SELECT FROMafield, b, c, d FROM mytable WHERE a=1 AND c="g"'; |
$expected = 'SELECT COUNT(*) FROM mytable WHERE a=1 AND c="g"'; |
$this->assertEqual($expected, rewriteCountQuery($query)); |
$query = 'SELECT afieldFROMaaa, b, c, d FROM mytable WHERE a=1 AND c="gLIMIT"'; |
$expected = 'SELECT COUNT(*) FROM mytable WHERE a=1 AND c="gLIMIT"'; |
$this->assertEqual($expected, rewriteCountQuery($query)); |
$query = 'SELECT DISTINCTaaa, b, c, d FROM mytable WHERE a=1 AND c="g"'; |
$expected = 'SELECT COUNT(*) FROM mytable WHERE a=1 AND c="g"'; |
$this->assertEqual($expected, rewriteCountQuery($query)); |
//this one fails... the regexp should NOT match keywords within quotes. |
//we need a full blown stack-based parser to catch this... |
$query = 'SELECT afieldFROMaaa, b, c, d FROM mytable WHERE a=1 AND c="g LIMIT a"'; |
$expected = 'SELECT COUNT(*) FROM mytable WHERE a=1 AND c="g LIMIT a"'; |
$this->assertEqual($expected, rewriteCountQuery($query)); |
} |
} |
if (!defined('TEST_RUNNING')) { |
define('TEST_RUNNING', true); |
$test = &new TestOfPagerWrapper(); |
$test->run(new HtmlReporter()); |
} |
?> |
/branches/livraison_menes/api/pear/Pager/tests/pager_sliding_notExpanded_test.php |
---|
New file |
0,0 → 1,49 |
<?php |
// $Id$ |
require_once 'simple_include.php'; |
require_once 'pager_include.php'; |
class TestOfPagerSlidingNotExpanded extends UnitTestCase { |
var $pager; |
function TestOfPagerSlidingNotExpanded($name='Test of Pager_Sliding - expanded=false') { |
$this->UnitTestCase($name); |
} |
function setUp() { |
$options = array( |
'itemData' => array(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21), |
'perPage' => 2, |
'mode' => 'Sliding', |
'expanded' => false |
); |
$this->pager = new Pager($options); |
} |
function tearDown() { |
unset($this->pager); |
} |
function testPageRangeByPageId1() { |
$this->assertEqual(array(1, 3), $this->pager->getPageRangeByPageId(1)); |
} |
function testPageRangeByPageId2() { |
$this->assertEqual(array(1, 4), $this->pager->getPageRangeByPageId(2)); |
} |
function testPageRangeByPageId3() { |
$this->assertEqual(array(1, 5), $this->pager->getPageRangeByPageId(3)); |
} |
function testPageRangeByPageId4() { |
$this->assertEqual(array(2, 6), $this->pager->getPageRangeByPageId(4)); |
} |
function testPageRangeByPageId9() { |
$this->assertEqual(array(7, 11), $this->pager->getPageRangeByPageId(9)); |
} |
function testPageRangeByPageId10() { |
$this->assertEqual(array(8, 11), $this->pager->getPageRangeByPageId(10)); |
} |
function testPageRangeByPageId11() { |
$this->assertEqual(array(9, 11), $this->pager->getPageRangeByPageId(11)); |
} |
function testPageRangeByPageId_outOfRange() { |
$this->assertEqual(array(0, 0), $this->pager->getPageRangeByPageId(20)); |
} |
} |
?> |
/branches/livraison_menes/api/pear/Pager/tests/pager_wrapper_include.php |
---|
New file |
0,0 → 1,5 |
<?php |
// $Id$ |
require_once 'Pager/Pager.php'; |
require_once 'Pager/Wrapper.php'; |
?> |
/branches/livraison_menes/api/pear/Pager/tests/pager_include.php |
---|
New file |
0,0 → 1,4 |
<?php |
// $Id$ |
require_once 'Pager/Pager.php'; |
?> |
/branches/livraison_menes/api/pear/Pager/tests/pager_post_test.php |
---|
New file |
0,0 → 1,67 |
<?php |
// $Id$ |
require_once 'simple_include.php'; |
require_once 'pager_include.php'; |
class TestOfPagerPOST extends WebTestCase { |
var $pager; |
var $baseurl; |
var $options = array(); |
function TestOfPagerPOST($name='Test of Pager with httpMethod="POST"') { |
$this->WebTestCase($name); |
} |
function setUp() { |
$this->options = array( |
'itemData' => array(1, 2, 3, 4, 5, 6, 7, 8, 9, 10), |
'perPage' => 1, |
'clearIfVoid' => false, |
'httpMethod' => 'POST', |
); |
//$this->pager = Pager::factory($this->options); |
$this->baseurl = 'http://'.$_SERVER['HTTP_HOST'].substr($_SERVER['PHP_SELF'], 0, strrpos($_SERVER['PHP_SELF'], '/')); |
} |
function tearDown() { |
unset($this->pager); |
} |
function testMultibyteEncoded() { |
$test_strings_encoded = array( |
'encoded1' => '测试', |
'encoded2' => '안녕', |
); |
$loaded = $this->get($this->baseurl.'/multibyte_post.php'); |
$this->assertTrue($loaded); |
$this->assertResponse(200); |
$this->assertTitle('Pager Test: page 1'); |
$this->assertNoLink('1'); |
$this->assertLink('2'); |
$this->assertLink('Next >>'); |
//$this->showSource(); |
foreach ($test_strings_encoded as $name => $value) { |
$this->assertWantedPattern('/'.$name.'.*'.preg_quote(str_replace('&', '&', $value)).'/Uims'); |
} |
} |
function testMultibytePlain() { |
$test_strings_plain = array( |
'plain1' => '안녕', |
'plain2' => '더보기', |
// 'plain3' => '이젠 전화도 |
//로 걸면 무료', |
); |
$loaded = $this->get($this->baseurl.'/multibyte_post.php'); |
$this->assertTrue($loaded); |
$this->assertResponse(200); |
$this->assertTitle('Pager Test: page 1'); |
$this->assertNoLink('1'); |
$this->assertLink('2'); |
$this->assertLink('Next >>'); |
//$this->showSource(); |
foreach ($test_strings_plain as $name => $value) { |
$this->assertWantedPattern('/'.$name.'.*'.preg_quote(urlencode($value)).'/Uims'); |
} |
} |
} |
?> |
/branches/livraison_menes/api/pear/Pager/tests/pager_sliding_test.php |
---|
New file |
0,0 → 1,56 |
<?php |
// $Id$ |
require_once 'simple_include.php'; |
require_once 'pager_include.php'; |
class TestOfPagerSliding extends UnitTestCase { |
var $pager; |
function TestOfPagerSliding($name='Test of Pager_Sliding') { |
$this->UnitTestCase($name); |
} |
function setUp() { |
$options = array( |
'itemData' => array(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12), |
'perPage' => 2, |
'mode' => 'Sliding', |
); |
$this->pager = Pager::factory($options); |
} |
function tearDown() { |
unset($this->pager); |
} |
function testPageRangeByPageId1() { |
$this->assertEqual(array(1, 5), $this->pager->getPageRangeByPageId(1)); |
} |
function testPageRangeByPageId4() { |
$this->assertEqual(array(2, 6), $this->pager->getPageRangeByPageId(4)); |
} |
function testPageRangeByPageId_outOfRange() { |
$this->assertEqual(array(0, 0), $this->pager->getPageRangeByPageId(20)); |
} |
function testPageRangeByPageId2() { |
$this->assertEqual(array(2, 6), $this->pager->getPageRangeByPageId(4)); |
} |
function testGetPageData() { |
$this->assertEqual(array(0=>1, 1=>2), $this->pager->getPageData()); |
} |
function testGetPageData2() { |
$this->assertEqual(array(2=>3, 3=>4), $this->pager->getPageData(2)); |
} |
function testGetPageData_OutOfRange() { |
$this->assertEqual(false, $this->pager->getPageData(20)); |
} |
function testClearIfVoid() { |
$this->assertTrue(strlen($this->pager->links) > 0); |
$options = array( |
'itemData' => array(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12), |
'perPage' => 20, |
'mode' => 'Sliding', |
); |
$this->pager = Pager::factory($options); |
$this->assertEqual('', $this->pager->links); |
} |
} |
?> |
/branches/livraison_menes/api/pear/Pager/tests/README |
---|
New file |
0,0 → 1,5 |
These tests require Simple Test: http://www.lastcraft.com/simple_test.php |
- edit the simple_include.php script and set your SimpleTest install dir; |
- edit the pager_include.php and pager_wrapper_include.php scripts to set |
your Pager directory. |
/branches/livraison_menes/api/pear/Pager/tests/pager_jumping_tests.php |
---|
New file |
0,0 → 1,20 |
<?php |
// $Id$ |
require_once 'simple_include.php'; |
require_once 'pager_include.php'; |
class PagerJumpingTests extends GroupTest { |
function PagerJumpingTests() { |
$this->GroupTest('Pager_Jumping Tests'); |
$this->addTestFile('pager_jumping_test.php'); |
$this->addTestFile('pager_jumping_noData_test.php'); |
} |
} |
if (!defined('TEST_RUNNING')) { |
define('TEST_RUNNING', true); |
$test = &new PagerTests(); |
$test->run(new HtmlReporter()); |
} |
?> |
/branches/livraison_menes/api/pear/Pager/tests/pager_jumping_noData_test.php |
---|
New file |
0,0 → 1,36 |
<?php |
// $Id$ |
require_once 'simple_include.php'; |
require_once 'pager_include.php'; |
class TestOfPagerJumpingNoData extends UnitTestCase { |
var $pager; |
function TestOfPagerJumpingNoData($name='Test of Pager_Jumping - no data') { |
$this->UnitTestCase($name); |
} |
function setUp() { |
$options = array( |
'totalItems' => 0, |
'perPage' => 2, |
'mode' => 'Jumping', |
); |
$this->pager = Pager::factory($options); |
} |
function tearDown() { |
unset($this->pager); |
} |
function testOffsetByPageId() { |
$this->assertEqual(array(1, 0), $this->pager->getOffsetByPageId()); |
} |
function testPageIdByOffset() { |
$this->assertEqual(false, $this->pager->getPageIdByOffset(0)); |
} |
function testPageIdByOffset2() { |
$this->assertEqual(1, $this->pager->getPageIdByOffset(1)); |
} |
function testPageIdByOffset3() { |
$this->assertEqual(1, $this->pager->getPageIdByOffset(2)); |
} |
} |
?> |
/branches/livraison_menes/api/pear/Pager/Pager.php |
---|
New file |
0,0 → 1,193 |
<?php |
/* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4: */ |
/** |
* Contains the Pager class |
* |
* PHP versions 4 and 5 |
* |
* LICENSE: Redistribution and use in source and binary forms, with or without |
* modification, are permitted provided that the following conditions are met: |
* 1. Redistributions of source code must retain the above copyright |
* notice, this list of conditions and the following disclaimer. |
* 2. Redistributions in binary form must reproduce the above copyright |
* notice, this list of conditions and the following disclaimer in the |
* documentation and/or other materials provided with the distribution. |
* 3. The name of the author may not be used to endorse or promote products |
* derived from this software without specific prior written permission. |
* |
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR "AS IS" AND ANY EXPRESS OR IMPLIED |
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF |
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. |
* IN NO EVENT SHALL THE FREEBSD PROJECT OR CONTRIBUTORS BE LIABLE FOR ANY |
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES |
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; |
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND |
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF |
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
* |
* @category HTML |
* @package Pager |
* @author Lorenzo Alberton <l dot alberton at quipo dot it> |
* @author Richard Heyes <richard@phpguru.org> |
* @copyright 2003-2006 Lorenzo Alberton, Richard Heyes |
* @license http://www.debian.org/misc/bsd.license BSD License (3 Clause) |
* @version CVS: $Id$ |
* @link http://pear.php.net/package/Pager |
*/ |
/** |
* Pager - Wrapper class for [Sliding|Jumping]-window Pager |
* Usage examples can be found in the PEAR manual |
* |
* @category HTML |
* @package Pager |
* @author Lorenzo Alberton <l dot alberton at quipo dot it> |
* @author Richard Heyes <richard@phpguru.org>, |
* @copyright 2003-2005 Lorenzo Alberton, Richard Heyes |
* @license http://www.php.net/license/3_0.txt PHP License 3.0 |
* @link http://pear.php.net/package/Pager |
*/ |
class Pager |
{ |
// {{{ Pager() |
/** |
* Constructor |
* |
* ------------------------------------------------------------------------- |
* VALID options are (default values are set some lines before): |
* - mode (string): "Jumping" or "Sliding" -window - It determines |
* pager behaviour. See the manual for more details |
* - totalItems (int): # of items to page. |
* - perPage (int): # of items per page. |
* - delta (int): # of page #s to show before and after the current |
* one |
* - linkClass (string): name of CSS class used for link styling. |
* - append (bool): if true pageID is appended as GET value to the |
* URL - if false it is embedded in the URL |
* according to "fileName" specs |
* - httpMethod (string): Specifies the HTTP method to use. Valid values |
* are 'GET' or 'POST' |
* according to "fileName" specs |
* - importQuery (bool): if true (default behaviour), variables and |
* values are imported from the submitted data |
* (query string) and used in the generated links |
* otherwise they're ignored completely |
* - path (string): complete path to the page (without the page name) |
* - fileName (string): name of the page, with a %d if append=true |
* - urlVar (string): name of pageNumber URL var, for example "pageID" |
* - altPrev (string): alt text to display for prev page, on prev link. |
* - altNext (string): alt text to display for next page, on next link. |
* - altPage (string): alt text to display before the page number. |
* - prevImg (string): sth (it can be text such as "<< PREV" or an |
* <img/> as well...) to display instead of "<<". |
* - nextImg (string): same as prevImg, used for NEXT link, instead of |
* the default value, which is ">>". |
* - separator (string): what to use to separate numbers (can be an |
* <img/>, a comma, an hyphen, or whatever. |
* - spacesBeforeSeparator |
* (int): number of spaces before the separator. |
* - firstPagePre (string): |
* string used before first page number (can be an |
* <img/>, a "{", an empty string, or whatever. |
* - firstPageText (string): |
* string used in place of first page number |
* - firstPagePost (string): |
* string used after first page number (can be an |
* <img/>, a "}", an empty string, or whatever. |
* - lastPagePre (string): |
* similar to firstPagePre. |
* - lastPageText (string): |
* similar to firstPageText. |
* - lastPagePost (string): |
* similar to firstPagePost. |
* - spacesAfterSeparator |
* (int): number of spaces after the separator. |
* - firstLinkTitle (string): |
* string used as title in <link rel="first"> tag |
* - lastLinkTitle (string): |
* string used as title in <link rel="last"> tag |
* - prevLinkTitle (string): |
* string used as title in <link rel="prev"> tag |
* - nextLinkTitle (string): |
* string used as title in <link rel="next"> tag |
* - curPageLinkClassName |
* (string): name of CSS class used for current page link. |
* - clearIfVoid(bool): if there's only one page, don't display pager. |
* - extraVars (array): additional URL vars to be added to the querystring |
* - excludeVars (array): URL vars to be excluded in the querystring |
* - itemData (array): array of items to page. |
* - useSessions (bool): if true, number of items to display per page is |
* stored in the $_SESSION[$_sessionVar] var. |
* - closeSession (bool): if true, the session is closed just after R/W. |
* - sessionVar (string): name of the session var for perPage value. |
* A value != from default can be useful when |
* using more than one Pager istance in the page. |
* - pearErrorMode (constant): |
* PEAR_ERROR mode for raiseError(). |
* Default is PEAR_ERROR_RETURN. |
* ------------------------------------------------------------------------- |
* REQUIRED options are: |
* - fileName IF append==false (default is true) |
* - itemData OR totalItems (if itemData is set, totalItems is overwritten) |
* ------------------------------------------------------------------------- |
* |
* @param mixed $options An associative array of option names and |
* their values. |
* @access public |
*/ |
function Pager($options = array()) |
{ |
//this check evaluates to true on 5.0.0RC-dev, |
//so i'm using another one, for now... |
//if (version_compare(phpversion(), '5.0.0') == -1) { |
if (get_class($this) == 'pager') { //php4 lowers class names |
// assign factoried method to this for PHP 4 |
eval('$this = Pager::factory($options);'); |
} else { //php5 is case sensitive |
$msg = 'Pager constructor is deprecated.' |
.' You must use the "Pager::factory($params)" method' |
.' instead of "new Pager($params)"'; |
trigger_error($msg, E_USER_ERROR); |
} |
} |
// }}} |
// {{{ factory() |
/** |
* Return a pager based on $mode and $options |
* |
* @param array $options Optional parameters for the storage class |
* @return object Object Storage object |
* @static |
* @access public |
*/ |
function &factory($options = array()) |
{ |
$mode = (isset($options['mode']) ? ucfirst($options['mode']) : 'Jumping'); |
$classname = 'Pager_' . $mode; |
$classfile = 'Pager' . DIRECTORY_SEPARATOR . $mode . '.php'; |
// Attempt to include a custom version of the named class, but don't treat |
// a failure as fatal. The caller may have already included their own |
// version of the named class. |
if (!class_exists($classname)) { |
include_once $classfile; |
} |
// If the class exists, return a new instance of it. |
if (class_exists($classname)) { |
$pager =& new $classname($options); |
return $pager; |
} |
$null = null; |
return $null; |
} |
// }}} |
} |
?> |
/branches/livraison_menes/api/pear/Pager/Common.php |
---|
New file |
0,0 → 1,1502 |
<?php |
/* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4: */ |
/** |
* Contains the Pager_Common class |
* |
* PHP versions 4 and 5 |
* |
* LICENSE: Redistribution and use in source and binary forms, with or without |
* modification, are permitted provided that the following conditions are met: |
* 1. Redistributions of source code must retain the above copyright |
* notice, this list of conditions and the following disclaimer. |
* 2. Redistributions in binary form must reproduce the above copyright |
* notice, this list of conditions and the following disclaimer in the |
* documentation and/or other materials provided with the distribution. |
* 3. The name of the author may not be used to endorse or promote products |
* derived from this software without specific prior written permission. |
* |
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR "AS IS" AND ANY EXPRESS OR IMPLIED |
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF |
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. |
* IN NO EVENT SHALL THE FREEBSD PROJECT OR CONTRIBUTORS BE LIABLE FOR ANY |
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES |
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; |
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND |
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF |
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
* |
* @category HTML |
* @package Pager |
* @author Lorenzo Alberton <l dot alberton at quipo dot it> |
* @author Richard Heyes <richard@phpguru.org> |
* @copyright 2003-2006 Lorenzo Alberton, Richard Heyes |
* @license http://www.debian.org/misc/bsd.license BSD License (3 Clause) |
* @version CVS: $Id$ |
* @link http://pear.php.net/package/Pager |
*/ |
/** |
* Two constants used to guess the path- and file-name of the page |
* when the user doesn't set any other value |
*/ |
if (substr($_SERVER['PHP_SELF'], -1) == '/') { |
define('CURRENT_FILENAME', ''); |
define('CURRENT_PATHNAME', 'http://'.$_SERVER['HTTP_HOST'].str_replace('\\', '/', $_SERVER['PHP_SELF'])); |
} else { |
define('CURRENT_FILENAME', preg_replace('/(.*)\?.*/', '\\1', basename($_SERVER['PHP_SELF']))); |
define('CURRENT_PATHNAME', str_replace('\\', '/', dirname($_SERVER['PHP_SELF']))); |
} |
/** |
* Error codes |
*/ |
define('PAGER_OK', 0); |
define('ERROR_PAGER', -1); |
define('ERROR_PAGER_INVALID', -2); |
define('ERROR_PAGER_INVALID_PLACEHOLDER', -3); |
define('ERROR_PAGER_INVALID_USAGE', -4); |
define('ERROR_PAGER_NOT_IMPLEMENTED', -5); |
/** |
* Pager_Common - Common base class for [Sliding|Jumping] Window Pager |
* Extend this class to write a custom paging class |
* |
* @category HTML |
* @package Pager |
* @author Lorenzo Alberton <l dot alberton at quipo dot it> |
* @author Richard Heyes <richard@phpguru.org> |
* @copyright 2003-2005 Lorenzo Alberton, Richard Heyes |
* @license http://www.php.net/license/3_0.txt PHP License 3.0 |
* @link http://pear.php.net/package/Pager |
*/ |
class Pager_Common |
{ |
// {{{ class vars |
/** |
* @var integer number of items |
* @access private |
*/ |
var $_totalItems; |
/** |
* @var integer number of items per page |
* @access private |
*/ |
var $_perPage = 10; |
/** |
* @var integer number of page links for each window |
* @access private |
*/ |
var $_delta = 10; |
/** |
* @var integer current page number |
* @access private |
*/ |
var $_currentPage = 1; |
/** |
* @var integer total pages number |
* @access private |
*/ |
var $_totalPages = 1; |
/** |
* @var string CSS class for links |
* @access private |
*/ |
var $_linkClass = ''; |
/** |
* @var string wrapper for CSS class name |
* @access private |
*/ |
var $_classString = ''; |
/** |
* @var string path name |
* @access private |
*/ |
var $_path = CURRENT_PATHNAME; |
/** |
* @var string file name |
* @access private |
*/ |
var $_fileName = CURRENT_FILENAME; |
/** |
* @var boolean If false, don't override the fileName option. Use at your own risk. |
* @access private |
*/ |
var $_fixFileName = true; |
/** |
* @var boolean you have to use FALSE with mod_rewrite |
* @access private |
*/ |
var $_append = true; |
/** |
* @var string specifies which HTTP method to use |
* @access private |
*/ |
var $_httpMethod = 'GET'; |
/** |
* @var string specifies which HTML form to use |
* @access private |
*/ |
var $_formID = ''; |
/** |
* @var boolean whether or not to import submitted data |
* @access private |
*/ |
var $_importQuery = true; |
/** |
* @var string name of the querystring var for pageID |
* @access private |
*/ |
var $_urlVar = 'pageID'; |
/** |
* @var array data to pass through the link |
* @access private |
*/ |
var $_linkData = array(); |
/** |
* @var array additional URL vars |
* @access private |
*/ |
var $_extraVars = array(); |
/** |
* @var array URL vars to ignore |
* @access private |
*/ |
var $_excludeVars = array(); |
/** |
* @var boolean TRUE => expanded mode (for Pager_Sliding) |
* @access private |
*/ |
var $_expanded = true; |
/** |
* @var boolean TRUE => show accesskey attribute on <a> tags |
* @access private |
*/ |
var $_accesskey = false; |
/** |
* @var string extra attributes for the <a> tag |
* @access private |
*/ |
var $_attributes = ''; |
/** |
* @var string alt text for "first page" (use "%d" placeholder for page number) |
* @access private |
*/ |
var $_altFirst = 'first page'; |
/** |
* @var string alt text for "previous page" |
* @access private |
*/ |
var $_altPrev = 'previous page'; |
/** |
* @var string alt text for "next page" |
* @access private |
*/ |
var $_altNext = 'next page'; |
/** |
* @var string alt text for "last page" (use "%d" placeholder for page number) |
* @access private |
*/ |
var $_altLast = 'last page'; |
/** |
* @var string alt text for "page" |
* @access private |
*/ |
var $_altPage = 'page'; |
/** |
* @var string image/text to use as "prev" link |
* @access private |
*/ |
var $_prevImg = '<< Back'; |
/** |
* @var string image/text to use as "next" link |
* @access private |
*/ |
var $_nextImg = 'Next >>'; |
/** |
* @var string link separator |
* @access private |
*/ |
var $_separator = ''; |
/** |
* @var integer number of spaces before separator |
* @access private |
*/ |
var $_spacesBeforeSeparator = 0; |
/** |
* @var integer number of spaces after separator |
* @access private |
*/ |
var $_spacesAfterSeparator = 1; |
/** |
* @var string CSS class name for current page link |
* @access private |
*/ |
var $_curPageLinkClassName = ''; |
/** |
* @var string Text before current page link |
* @access private |
*/ |
var $_curPageSpanPre = ''; |
/** |
* @var string Text after current page link |
* @access private |
*/ |
var $_curPageSpanPost = ''; |
/** |
* @var string Text before first page link |
* @access private |
*/ |
var $_firstPagePre = '['; |
/** |
* @var string Text to be used for first page link |
* @access private |
*/ |
var $_firstPageText = ''; |
/** |
* @var string Text after first page link |
* @access private |
*/ |
var $_firstPagePost = ']'; |
/** |
* @var string Text before last page link |
* @access private |
*/ |
var $_lastPagePre = '['; |
/** |
* @var string Text to be used for last page link |
* @access private |
*/ |
var $_lastPageText = ''; |
/** |
* @var string Text after last page link |
* @access private |
*/ |
var $_lastPagePost = ']'; |
/** |
* @var string Will contain the HTML code for the spaces |
* @access private |
*/ |
var $_spacesBefore = ''; |
/** |
* @var string Will contain the HTML code for the spaces |
* @access private |
*/ |
var $_spacesAfter = ''; |
/** |
* @var string $_firstLinkTitle |
* @access private |
*/ |
var $_firstLinkTitle = 'first page'; |
/** |
* @var string $_nextLinkTitle |
* @access private |
*/ |
var $_nextLinkTitle = 'next page'; |
/** |
* @var string $_prevLinkTitle |
* @access private |
*/ |
var $_prevLinkTitle = 'previous page'; |
/** |
* @var string $_lastLinkTitle |
* @access private |
*/ |
var $_lastLinkTitle = 'last page'; |
/** |
* @var string Text to be used for the 'show all' option in the select box |
* @access private |
*/ |
var $_showAllText = ''; |
/** |
* @var array data to be paged |
* @access private |
*/ |
var $_itemData = null; |
/** |
* @var boolean If TRUE and there's only one page, links aren't shown |
* @access private |
*/ |
var $_clearIfVoid = true; |
/** |
* @var boolean Use session for storing the number of items per page |
* @access private |
*/ |
var $_useSessions = false; |
/** |
* @var boolean Close the session when finished reading/writing data |
* @access private |
*/ |
var $_closeSession = false; |
/** |
* @var string name of the session var for number of items per page |
* @access private |
*/ |
var $_sessionVar = 'setPerPage'; |
/** |
* Pear error mode (when raiseError is called) |
* (see PEAR doc) |
* |
* @var int $_pearErrorMode |
* @access private |
*/ |
var $_pearErrorMode = null; |
// }}} |
// {{{ public vars |
/** |
* @var string Complete set of links |
* @access public |
*/ |
var $links = ''; |
/** |
* @var string Complete set of link tags |
* @access public |
*/ |
var $linkTags = ''; |
/** |
* @var array Array with a key => value pair representing |
* page# => bool value (true if key==currentPageNumber). |
* can be used for extreme customization. |
* @access public |
*/ |
var $range = array(); |
/** |
* @var array list of available options (safety check) |
* @access private |
*/ |
var $_allowed_options = array( |
'totalItems', |
'perPage', |
'delta', |
'linkClass', |
'path', |
'fileName', |
'fixFileName', |
'append', |
'httpMethod', |
'formID', |
'importQuery', |
'urlVar', |
'altFirst', |
'altPrev', |
'altNext', |
'altLast', |
'altPage', |
'prevImg', |
'nextImg', |
'expanded', |
'accesskey', |
'attributes', |
'separator', |
'spacesBeforeSeparator', |
'spacesAfterSeparator', |
'curPageLinkClassName', |
'curPageSpanPre', |
'curPageSpanPost', |
'firstPagePre', |
'firstPageText', |
'firstPagePost', |
'lastPagePre', |
'lastPageText', |
'lastPagePost', |
'firstLinkTitle', |
'nextLinkTitle', |
'prevLinkTitle', |
'lastLinkTitle', |
'showAllText', |
'itemData', |
'clearIfVoid', |
'useSessions', |
'closeSession', |
'sessionVar', |
'pearErrorMode', |
'extraVars', |
'excludeVars', |
'currentPage', |
); |
// }}} |
// {{{ build() |
/** |
* Generate or refresh the links and paged data after a call to setOptions() |
* |
* @access public |
*/ |
function build() |
{ |
$msg = '<b>PEAR::Pager Error:</b>' |
.' function "build()" not implemented.'; |
return $this->raiseError($msg, ERROR_PAGER_NOT_IMPLEMENTED); |
} |
// }}} |
// {{{ getPageData() |
/** |
* Returns an array of current pages data |
* |
* @param $pageID Desired page ID (optional) |
* @return array Page data |
* @access public |
*/ |
function getPageData($pageID = null) |
{ |
$pageID = empty($pageID) ? $this->_currentPage : $pageID; |
if (!isset($this->_pageData)) { |
$this->_generatePageData(); |
} |
if (!empty($this->_pageData[$pageID])) { |
return $this->_pageData[$pageID]; |
} |
return array(); |
} |
// }}} |
// {{{ getPageIdByOffset() |
/** |
* Returns pageID for given offset |
* |
* @param $index Offset to get pageID for |
* @return int PageID for given offset |
*/ |
function getPageIdByOffset($index) |
{ |
$msg = '<b>PEAR::Pager Error:</b>' |
.' function "getPageIdByOffset()" not implemented.'; |
return $this->raiseError($msg, ERROR_PAGER_NOT_IMPLEMENTED); |
} |
// }}} |
// {{{ getOffsetByPageId() |
/** |
* Returns offsets for given pageID. Eg, if you |
* pass it pageID one and your perPage limit is 10 |
* it will return (1, 10). PageID of 2 would |
* give you (11, 20). |
* |
* @param integer PageID to get offsets for |
* @return array First and last offsets |
* @access public |
*/ |
function getOffsetByPageId($pageid = null) |
{ |
$pageid = isset($pageid) ? $pageid : $this->_currentPage; |
if (!isset($this->_pageData)) { |
$this->_generatePageData(); |
} |
if (isset($this->_pageData[$pageid]) || is_null($this->_itemData)) { |
return array( |
max(($this->_perPage * ($pageid - 1)) + 1, 1), |
min($this->_totalItems, $this->_perPage * $pageid) |
); |
} else { |
return array(0, 0); |
} |
} |
// }}} |
// {{{ getPageRangeByPageId() |
/** |
* @param integer PageID to get offsets for |
* @return array First and last offsets |
*/ |
function getPageRangeByPageId($pageID) |
{ |
$msg = '<b>PEAR::Pager Error:</b>' |
.' function "getPageRangeByPageId()" not implemented.'; |
return $this->raiseError($msg, ERROR_PAGER_NOT_IMPLEMENTED); |
} |
// }}} |
// {{{ getLinks() |
/** |
* Returns back/next/first/last and page links, |
* both as ordered and associative array. |
* |
* NB: in original PEAR::Pager this method accepted two parameters, |
* $back_html and $next_html. Now the only parameter accepted is |
* an integer ($pageID), since the html text for prev/next links can |
* be set in the factory. If a second parameter is provided, then |
* the method act as it previously did. This hack was done to mantain |
* backward compatibility only. |
* |
* @param integer $pageID Optional pageID. If specified, links |
* for that page are provided instead of current one. [ADDED IN NEW PAGER VERSION] |
* @param string $next_html HTML to put inside the next link [deprecated: use the factory instead] |
* @return array back/next/first/last and page links |
*/ |
function getLinks($pageID=null, $next_html='') |
{ |
$msg = '<b>PEAR::Pager Error:</b>' |
.' function "getLinks()" not implemented.'; |
return $this->raiseError($msg, ERROR_PAGER_NOT_IMPLEMENTED); |
} |
// }}} |
// {{{ getCurrentPageID() |
/** |
* Returns ID of current page |
* |
* @return integer ID of current page |
*/ |
function getCurrentPageID() |
{ |
return $this->_currentPage; |
} |
// }}} |
// {{{ getNextPageID() |
/** |
* Returns next page ID. If current page is last page |
* this function returns FALSE |
* |
* @return mixed Next page ID |
*/ |
function getNextPageID() |
{ |
return ($this->getCurrentPageID() == $this->numPages() ? false : $this->getCurrentPageID() + 1); |
} |
// }}} |
// {{{ getPreviousPageID() |
/** |
* Returns previous page ID. If current page is first page |
* this function returns FALSE |
* |
* @return mixed Previous pages' ID |
*/ |
function getPreviousPageID() |
{ |
return $this->isFirstPage() ? false : $this->getCurrentPageID() - 1; |
} |
// }}} |
// {{{ numItems() |
/** |
* Returns number of items |
* |
* @return int Number of items |
*/ |
function numItems() |
{ |
return $this->_totalItems; |
} |
// }}} |
// {{{ numPages() |
/** |
* Returns number of pages |
* |
* @return int Number of pages |
*/ |
function numPages() |
{ |
return (int)$this->_totalPages; |
} |
// }}} |
// {{{ isFirstPage() |
/** |
* Returns whether current page is first page |
* |
* @return bool First page or not |
*/ |
function isFirstPage() |
{ |
return ($this->_currentPage < 2); |
} |
// }}} |
// {{{ isLastPage() |
/** |
* Returns whether current page is last page |
* |
* @return bool Last page or not |
*/ |
function isLastPage() |
{ |
return ($this->_currentPage == $this->_totalPages); |
} |
// }}} |
// {{{ isLastPageComplete() |
/** |
* Returns whether last page is complete |
* |
* @return bool Last age complete or not |
*/ |
function isLastPageComplete() |
{ |
return !($this->_totalItems % $this->_perPage); |
} |
// }}} |
// {{{ _generatePageData() |
/** |
* Calculates all page data |
* @access private |
*/ |
function _generatePageData() |
{ |
// Been supplied an array of data? |
if (!is_null($this->_itemData)) { |
$this->_totalItems = count($this->_itemData); |
} |
$this->_totalPages = ceil((float)$this->_totalItems / (float)$this->_perPage); |
$i = 1; |
if (!empty($this->_itemData)) { |
foreach ($this->_itemData as $key => $value) { |
$this->_pageData[$i][$key] = $value; |
if (count($this->_pageData[$i]) >= $this->_perPage) { |
$i++; |
} |
} |
} else { |
$this->_pageData = array(); |
} |
//prevent URL modification |
$this->_currentPage = min($this->_currentPage, $this->_totalPages); |
} |
// }}} |
// {{{ _renderLink() |
/** |
* Renders a link using the appropriate method |
* |
* @param altText Alternative text for this link (title property) |
* @param linkText Text contained by this link |
* @return string The link in string form |
* @access private |
*/ |
function _renderLink($altText, $linkText) |
{ |
if ($this->_httpMethod == 'GET') { |
if ($this->_append) { |
$href = '?' . $this->_http_build_query_wrapper($this->_linkData); |
} else { |
$href = str_replace('%d', $this->_linkData[$this->_urlVar], $this->_fileName); |
} |
return sprintf('<a href="%s"%s%s%s title="%s">%s</a>', |
htmlentities($this->_url . $href), |
empty($this->_classString) ? '' : ' '.$this->_classString, |
empty($this->_attributes) ? '' : ' '.$this->_attributes, |
empty($this->_accesskey) ? '' : ' accesskey="'.$this->_linkData[$this->_urlVar].'"', |
$altText, |
$linkText |
); |
} elseif ($this->_httpMethod == 'POST') { |
return sprintf("<a href='javascript:void(0)' onclick='%s'%s%s%s title='%s'>%s</a>", |
$this->_generateFormOnClick($this->_url, $this->_linkData), |
empty($this->_classString) ? '' : ' '.$this->_classString, |
empty($this->_attributes) ? '' : ' '.$this->_attributes, |
empty($this->_accesskey) ? '' : ' accesskey=\''.$this->_linkData[$this->_urlVar].'\'', |
$altText, |
$linkText |
); |
} |
return ''; |
} |
// }}} |
// {{{ _generateFormOnClick() |
/** |
* Mimics http_build_query() behavior in the way the data |
* in $data will appear when it makes it back to the server. |
* For example: |
* $arr = array('array' => array(array('hello', 'world'), |
* 'things' => array('stuff', 'junk')); |
* http_build_query($arr) |
* and _generateFormOnClick('foo.php', $arr) |
* will yield |
* $_REQUEST['array'][0][0] === 'hello' |
* $_REQUEST['array'][0][1] === 'world' |
* $_REQUEST['array']['things'][0] === 'stuff' |
* $_REQUEST['array']['things'][1] === 'junk' |
* |
* However, instead of generating a query string, it generates |
* Javascript to create and submit a form. |
* |
* @param string $formAction where the form should be submitted |
* @param array $data the associative array of names and values |
* @return string A string of javascript that generates a form and submits it |
* @access private |
*/ |
function _generateFormOnClick($formAction, $data) |
{ |
// Check we have an array to work with |
if (!is_array($data)) { |
trigger_error( |
'_generateForm() Parameter 1 expected to be Array or Object. Incorrect value given.', |
E_USER_WARNING |
); |
return false; |
} |
if (!empty($this->_formID)) { |
$str = 'var form = document.getElementById("'.$this->_formID.'"); var input = ""; '; |
} else { |
$str = 'var form = document.createElement("form"); var input = ""; '; |
} |
// We /shouldn't/ need to escape the URL ... |
$str .= sprintf('form.action = "%s"; ', htmlentities($formAction)); |
$str .= sprintf('form.method = "%s"; ', $this->_httpMethod); |
foreach ($data as $key => $val) { |
$str .= $this->_generateFormOnClickHelper($val, $key); |
} |
if (empty($this->_formID)) { |
$str .= 'document.getElementsByTagName("body")[0].appendChild(form);'; |
} |
$str .= 'form.submit(); return false;'; |
return $str; |
} |
// }}} |
// {{{ _generateFormOnClickHelper |
/** |
* This is used by _generateFormOnClick(). |
* Recursively processes the arrays, objects, and literal values. |
* |
* @param data Data that should be rendered |
* @param prev The name so far |
* @return string A string of Javascript that creates form inputs |
* representing the data |
* @access private |
*/ |
function _generateFormOnClickHelper($data, $prev = '') |
{ |
$str = ''; |
if (is_array($data) || is_object($data)) { |
// foreach key/visible member |
foreach ((array)$data as $key => $val) { |
// append [$key] to prev |
$tempKey = sprintf('%s[%s]', $prev, $key); |
$str .= $this->_generateFormOnClickHelper($val, $tempKey); |
} |
} else { // must be a literal value |
// escape newlines and carriage returns |
$search = array("\n", "\r"); |
$replace = array('\n', '\n'); |
$escapedData = str_replace($search, $replace, $data); |
// am I forgetting any dangerous whitespace? |
// would a regex be faster? |
// if it's already encoded, don't encode it again |
if (!$this->_isEncoded($escapedData)) { |
$escapedData = urlencode($escapedData); |
} |
$escapedData = htmlentities($escapedData, ENT_QUOTES, 'UTF-8'); |
$str .= 'input = document.createElement("input"); '; |
$str .= 'input.type = "hidden"; '; |
$str .= sprintf('input.name = "%s"; ', $prev); |
$str .= sprintf('input.value = "%s"; ', $escapedData); |
$str .= 'form.appendChild(input); '; |
} |
return $str; |
} |
// }}} |
// {{{ _getLinksData() |
/** |
* Returns the correct link for the back/pages/next links |
* |
* @return array Data |
* @access private |
*/ |
function _getLinksData() |
{ |
$qs = array(); |
if ($this->_importQuery) { |
if ($this->_httpMethod == 'POST') { |
$qs = $_POST; |
} elseif ($this->_httpMethod == 'GET') { |
$qs = $_GET; |
} |
} |
if (count($this->_extraVars)){ |
$this->_recursive_urldecode($this->_extraVars); |
} |
$qs = array_merge($qs, $this->_extraVars); |
foreach ($this->_excludeVars as $exclude) { |
if (array_key_exists($exclude, $qs)) { |
unset($qs[$exclude]); |
} |
} |
if (count($qs) && get_magic_quotes_gpc()){ |
$this->_recursive_stripslashes($qs); |
} |
return $qs; |
} |
// }}} |
// {{{ _recursive_stripslashes() |
/** |
* Helper method |
* @param mixed $var |
* @access private |
*/ |
function _recursive_stripslashes(&$var) |
{ |
if (is_array($var)) { |
foreach (array_keys($var) as $k) { |
$this->_recursive_stripslashes($var[$k]); |
} |
} else { |
$var = stripslashes($var); |
} |
} |
// }}} |
// {{{ _recursive_urldecode() |
/** |
* Helper method |
* @param mixed $var |
* @access private |
*/ |
function _recursive_urldecode(&$var) |
{ |
if (is_array($var)) { |
foreach (array_keys($var) as $k) { |
$this->_recursive_urldecode($var[$k]); |
} |
} else { |
$trans_tbl = array_flip(get_html_translation_table(HTML_ENTITIES)); |
$var = strtr($var, $trans_tbl); |
} |
} |
// }}} |
// {{{ _getBackLink() |
/** |
* Returns back link |
* |
* @param $url URL to use in the link [deprecated: use the factory instead] |
* @param $link HTML to use as the link [deprecated: use the factory instead] |
* @return string The link |
* @access private |
*/ |
function _getBackLink($url='', $link='') |
{ |
//legacy settings... the preferred way to set an option |
//now is passing it to the factory |
if (!empty($url)) { |
$this->_path = $url; |
} |
if (!empty($link)) { |
$this->_prevImg = $link; |
} |
$back = ''; |
if ($this->_currentPage > 1) { |
$this->_linkData[$this->_urlVar] = $this->getPreviousPageID(); |
$back = $this->_renderLink($this->_altPrev, $this->_prevImg) |
. $this->_spacesBefore . $this->_spacesAfter; |
} |
return $back; |
} |
// }}} |
// {{{ _getPageLinks() |
/** |
* Returns pages link |
* |
* @param $url URL to use in the link [deprecated: use the factory instead] |
* @return string Links |
* @access private |
*/ |
function _getPageLinks($url='') |
{ |
$msg = '<b>PEAR::Pager Error:</b>' |
.' function "_getPageLinks()" not implemented.'; |
return $this->raiseError($msg, ERROR_PAGER_NOT_IMPLEMENTED); |
} |
// }}} |
// {{{ _getNextLink() |
/** |
* Returns next link |
* |
* @param $url URL to use in the link [deprecated: use the factory instead] |
* @param $link HTML to use as the link [deprecated: use the factory instead] |
* @return string The link |
* @access private |
*/ |
function _getNextLink($url='', $link='') |
{ |
//legacy settings... the preferred way to set an option |
//now is passing it to the factory |
if (!empty($url)) { |
$this->_path = $url; |
} |
if (!empty($link)) { |
$this->_nextImg = $link; |
} |
$next = ''; |
if ($this->_currentPage < $this->_totalPages) { |
$this->_linkData[$this->_urlVar] = $this->getNextPageID(); |
$next = $this->_spacesAfter |
. $this->_renderLink($this->_altNext, $this->_nextImg) |
. $this->_spacesBefore . $this->_spacesAfter; |
} |
return $next; |
} |
// }}} |
// {{{ _getFirstLinkTag() |
/** |
* @return string |
* @access private |
*/ |
function _getFirstLinkTag() |
{ |
if ($this->isFirstPage() || ($this->_httpMethod != 'GET')) { |
return ''; |
} |
return sprintf('<link rel="first" href="%s" title="%s" />'."\n", |
$this->_getLinkTagUrl(1), |
$this->_firstLinkTitle |
); |
} |
// }}} |
// {{{ _getPrevLinkTag() |
/** |
* Returns previous link tag |
* |
* @return string the link tag |
* @access private |
*/ |
function _getPrevLinkTag() |
{ |
if ($this->isFirstPage() || ($this->_httpMethod != 'GET')) { |
return ''; |
} |
return sprintf('<link rel="previous" href="%s" title="%s" />'."\n", |
$this->_getLinkTagUrl($this->getPreviousPageID()), |
$this->_prevLinkTitle |
); |
} |
// }}} |
// {{{ _getNextLinkTag() |
/** |
* Returns next link tag |
* |
* @return string the link tag |
* @access private |
*/ |
function _getNextLinkTag() |
{ |
if ($this->isLastPage() || ($this->_httpMethod != 'GET')) { |
return ''; |
} |
return sprintf('<link rel="next" href="%s" title="%s" />'."\n", |
$this->_getLinkTagUrl($this->getNextPageID()), |
$this->_nextLinkTitle |
); |
} |
// }}} |
// {{{ _getLastLinkTag() |
/** |
* @return string the link tag |
* @access private |
*/ |
function _getLastLinkTag() |
{ |
if ($this->isLastPage() || ($this->_httpMethod != 'GET')) { |
return ''; |
} |
return sprintf('<link rel="last" href="%s" title="%s" />'."\n", |
$this->_getLinkTagUrl($this->_totalPages), |
$this->_lastLinkTitle |
); |
} |
// }}} |
// {{{ _getLinkTagUrl() |
/** |
* Helper method |
* @return string the link tag url |
* @access private |
*/ |
function _getLinkTagUrl($pageID) |
{ |
$this->_linkData[$this->_urlVar] = $pageID; |
if ($this->_append) { |
$href = '?' . $this->_http_build_query_wrapper($this->_linkData); |
} else { |
$href = str_replace('%d', $this->_linkData[$this->_urlVar], $this->_fileName); |
} |
return htmlentities($this->_url . $href); |
} |
// }}} |
// {{{ getPerPageSelectBox() |
/** |
* Returns a string with a XHTML SELECT menu, |
* useful for letting the user choose how many items per page should be |
* displayed. If parameter useSessions is TRUE, this value is stored in |
* a session var. The string isn't echoed right now so you can use it |
* with template engines. |
* |
* @param integer $start |
* @param integer $end |
* @param integer $step |
* @param boolean $showAllData If true, perPage is set equal to totalItems. |
* @param array (or string $optionText for BC reasons) |
* - 'optionText': text to show in each option. |
* Use '%d' where you want to see the number of pages selected. |
* - 'attributes': (html attributes) Tag attributes or |
* HTML attributes (id="foo" pairs), will be inserted in the |
* <select> tag |
* @return string xhtml select box |
* @access public |
*/ |
function getPerPageSelectBox($start=5, $end=30, $step=5, $showAllData=false, $extraParams=array()) |
{ |
require_once 'Pager/HtmlWidgets.php'; |
$widget =& new Pager_HtmlWidgets($this); |
return $widget->getPerPageSelectBox($start, $end, $step, $showAllData, $extraParams); |
} |
// }}} |
// {{{ getPageSelectBox() |
/** |
* Returns a string with a XHTML SELECT menu with the page numbers, |
* useful as an alternative to the links |
* |
* @param array - 'optionText': text to show in each option. |
* Use '%d' where you want to see the number of pages selected. |
* - 'autoSubmit': if TRUE, add some js code to submit the |
* form on the onChange event |
* @param string $extraAttributes (html attributes) Tag attributes or |
* HTML attributes (id="foo" pairs), will be inserted in the |
* <select> tag |
* @return string xhtml select box |
* @access public |
*/ |
function getPageSelectBox($params = array(), $extraAttributes = '') |
{ |
require_once 'Pager/HtmlWidgets.php'; |
$widget =& new Pager_HtmlWidgets($this); |
return $widget->getPageSelectBox($params, $extraAttributes); |
} |
// }}} |
// {{{ _printFirstPage() |
/** |
* Print [1] |
* |
* @return string String with link to 1st page, |
* or empty string if this is the 1st page. |
* @access private |
*/ |
function _printFirstPage() |
{ |
if ($this->isFirstPage()) { |
return ''; |
} |
$this->_linkData[$this->_urlVar] = 1; |
return $this->_renderLink( |
str_replace('%d', 1, $this->_altFirst), |
$this->_firstPagePre . $this->_firstPageText . $this->_firstPagePost |
) . $this->_spacesBefore . $this->_spacesAfter; |
} |
// }}} |
// {{{ _printLastPage() |
/** |
* Print [numPages()] |
* |
* @return string String with link to last page, |
* or empty string if this is the 1st page. |
* @access private |
*/ |
function _printLastPage() |
{ |
if ($this->isLastPage()) { |
return ''; |
} |
$this->_linkData[$this->_urlVar] = $this->_totalPages; |
return $this->_renderLink( |
str_replace('%d', $this->_totalPages, $this->_altLast), |
$this->_lastPagePre . $this->_lastPageText . $this->_lastPagePost |
); |
} |
// }}} |
// {{{ _setFirstLastText() |
/** |
* sets the private _firstPageText, _lastPageText variables |
* based on whether they were set in the options |
* |
* @access private |
*/ |
function _setFirstLastText() |
{ |
if ($this->_firstPageText == '') { |
$this->_firstPageText = '1'; |
} |
if ($this->_lastPageText == '') { |
$this->_lastPageText = $this->_totalPages; |
} |
} |
// }}} |
// {{{ _http_build_query_wrapper() |
/** |
* This is a slightly modified version of the http_build_query() function; |
* it heavily borrows code from PHP_Compat's http_build_query(). |
* The main change is the usage of htmlentities instead of urlencode, |
* since it's too aggressive |
* |
* @author Stephan Schmidt <schst@php.net> |
* @author Aidan Lister <aidan@php.net> |
* @author Lorenzo Alberton <l dot alberton at quipo dot it> |
* @param array $data |
* @return string |
* @access private |
*/ |
function _http_build_query_wrapper($data) |
{ |
$data = (array)$data; |
if (empty($data)) { |
return ''; |
} |
$separator = ini_get('arg_separator.output'); |
if ($separator == '&') { |
$separator = '&'; //the string is escaped by htmlentities anyway... |
} |
$tmp = array (); |
foreach ($data as $key => $val) { |
if (is_scalar($val)) { |
//array_push($tmp, $key.'='.$val); |
$val = urlencode($val); |
array_push($tmp, $key .'='. str_replace('%2F', '/', $val)); |
continue; |
} |
// If the value is an array, recursively parse it |
if (is_array($val)) { |
array_push($tmp, $this->__http_build_query($val, htmlentities($key))); |
continue; |
} |
} |
return implode($separator, $tmp); |
} |
// }}} |
// {{{ __http_build_query() |
/** |
* Helper function |
* @author Stephan Schmidt <schst@php.net> |
* @author Aidan Lister <aidan@php.net> |
* @access private |
*/ |
function __http_build_query($array, $name) |
{ |
$tmp = array (); |
foreach ($array as $key => $value) { |
if (is_array($value)) { |
//array_push($tmp, $this->__http_build_query($value, sprintf('%s[%s]', $name, $key))); |
array_push($tmp, $this->__http_build_query($value, $name.'%5B'.$key.'%5D')); |
} elseif (is_scalar($value)) { |
//array_push($tmp, sprintf('%s[%s]=%s', $name, htmlentities($key), htmlentities($value))); |
array_push($tmp, $name.'%5B'.htmlentities($key).'%5D='.htmlentities($value)); |
} elseif (is_object($value)) { |
//array_push($tmp, $this->__http_build_query(get_object_vars($value), sprintf('%s[%s]', $name, $key))); |
array_push($tmp, $this->__http_build_query(get_object_vars($value), $name.'%5B'.$key.'%5D')); |
} |
} |
return implode(ini_get('arg_separator.output'), $tmp); |
} |
// }}} |
// {{{ _isEncoded() |
/** |
* Helper function |
* Check if a string is an encoded multibyte string |
* @param string $string |
* @return boolean |
* @access private |
*/ |
function _isEncoded($string) |
{ |
$hexchar = '&#[\dA-Fx]{2,};'; |
return preg_match("/^(\s|($hexchar))*$/Uims", $string) ? true : false; |
} |
// }}} |
// {{{ raiseError() |
/** |
* conditionally includes PEAR base class and raise an error |
* |
* @param string $msg Error message |
* @param int $code Error code |
* @access private |
*/ |
function raiseError($msg, $code) |
{ |
include_once 'PEAR.php'; |
if (empty($this->_pearErrorMode)) { |
$this->_pearErrorMode = PEAR_ERROR_RETURN; |
} |
return PEAR::raiseError($msg, $code, $this->_pearErrorMode); |
} |
// }}} |
// {{{ setOptions() |
/** |
* Set and sanitize options |
* |
* @param mixed $options An associative array of option names and |
* their values. |
* @return integer error code (PAGER_OK on success) |
* @access public |
*/ |
function setOptions($options) |
{ |
foreach ($options as $key => $value) { |
if (in_array($key, $this->_allowed_options) && (!is_null($value))) { |
$this->{'_' . $key} = $value; |
} |
} |
//autodetect http method |
if (!isset($options['httpMethod']) |
&& !isset($_GET[$this->_urlVar]) |
&& isset($_POST[$this->_urlVar]) |
) { |
$this->_httpMethod = 'POST'; |
} else { |
$this->_httpMethod = strtoupper($this->_httpMethod); |
} |
$this->_fileName = ltrim($this->_fileName, '/'); //strip leading slash |
$this->_path = rtrim($this->_path, '/'); //strip trailing slash |
if ($this->_append) { |
if ($this->_fixFileName) { |
$this->_fileName = CURRENT_FILENAME; //avoid possible user error; |
} |
$this->_url = $this->_path.'/'.$this->_fileName; |
} else { |
$this->_url = $this->_path; |
if (strncasecmp($this->_fileName, 'javascript', 10) != 0) { |
$this->_url .= '/'; |
} |
if (!strstr($this->_fileName, '%d')) { |
trigger_error($this->errorMessage(ERROR_PAGER_INVALID_USAGE), E_USER_WARNING); |
} |
} |
$this->_classString = ''; |
if (strlen($this->_linkClass)) { |
$this->_classString = 'class="'.$this->_linkClass.'"'; |
} |
if (strlen($this->_curPageLinkClassName)) { |
$this->_curPageSpanPre = '<span class="'.$this->_curPageLinkClassName.'">'; |
$this->_curPageSpanPost = '</span>'; |
} |
$this->_perPage = max($this->_perPage, 1); //avoid possible user errors |
if ($this->_useSessions && !isset($_SESSION)) { |
session_start(); |
} |
if (!empty($_REQUEST[$this->_sessionVar])) { |
$this->_perPage = max(1, (int)$_REQUEST[$this->_sessionVar]); |
if ($this->_useSessions) { |
$_SESSION[$this->_sessionVar] = $this->_perPage; |
} |
} |
if (!empty($_SESSION[$this->_sessionVar])) { |
$this->_perPage = $_SESSION[$this->_sessionVar]; |
} |
if ($this->_closeSession) { |
session_write_close(); |
} |
$this->_spacesBefore = str_repeat(' ', $this->_spacesBeforeSeparator); |
$this->_spacesAfter = str_repeat(' ', $this->_spacesAfterSeparator); |
if (isset($_REQUEST[$this->_urlVar]) && empty($options['currentPage'])) { |
$this->_currentPage = (int)$_REQUEST[$this->_urlVar]; |
} |
$this->_currentPage = max($this->_currentPage, 1); |
$this->_linkData = $this->_getLinksData(); |
return PAGER_OK; |
} |
// }}} |
// {{{ getOption() |
/** |
* Return the current value of a given option |
* |
* @param string option name |
* @return mixed option value |
*/ |
function getOption($name) |
{ |
if (!in_array($name, $this->_allowed_options)) { |
$msg = '<b>PEAR::Pager Error:</b>' |
.' invalid option: '.$name; |
return $this->raiseError($msg, ERROR_PAGER_INVALID); |
} |
return $this->{'_' . $name}; |
} |
// }}} |
// {{{ getOptions() |
/** |
* Return an array with all the current pager options |
* |
* @return array list of all the pager options |
*/ |
function getOptions() |
{ |
$options = array(); |
foreach ($this->_allowed_options as $option) { |
$options[$option] = $this->{'_' . $option}; |
} |
return $options; |
} |
// }}} |
// {{{ errorMessage() |
/** |
* Return a textual error message for a PAGER error code |
* |
* @param int $code error code |
* @return string error message |
* @access public |
*/ |
function errorMessage($code) |
{ |
static $errorMessages; |
if (!isset($errorMessages)) { |
$errorMessages = array( |
ERROR_PAGER => 'unknown error', |
ERROR_PAGER_INVALID => 'invalid', |
ERROR_PAGER_INVALID_PLACEHOLDER => 'invalid format - use "%d" as placeholder.', |
ERROR_PAGER_INVALID_USAGE => 'if $options[\'append\'] is set to false, ' |
.' $options[\'fileName\'] MUST contain the "%d" placeholder.', |
ERROR_PAGER_NOT_IMPLEMENTED => 'not implemented' |
); |
} |
return '<b>PEAR::Pager error:</b> '. (isset($errorMessages[$code]) ? |
$errorMessages[$code] : $errorMessages[ERROR_PAGER]); |
} |
// }}} |
} |
?> |
/branches/livraison_menes/api/pear/Pager/examples/example.php |
---|
New file |
0,0 → 1,78 |
<?php |
require_once 'Pager/Pager.php'; |
//create dummy array of data |
$myData = array(); |
for ($i=0; $i<200; $i++) { |
$myData[] = $i; |
} |
$params = array( |
'itemData' => $myData, |
'perPage' => 10, |
'delta' => 8, // for 'Jumping'-style a lower number is better |
'append' => true, |
//'separator' => ' | ', |
'clearIfVoid' => false, |
'urlVar' => 'entrant', |
'useSessions' => true, |
'closeSession' => true, |
//'mode' => 'Sliding', //try switching modes |
'mode' => 'Jumping', |
); |
$pager = & Pager::factory($params); |
$page_data = $pager->getPageData(); |
$links = $pager->getLinks(); |
$selectBox = $pager->getPerPageSelectBox(); |
?> |
<html> |
<head> |
<title>new PEAR::Pager example</title> |
</head> |
<body> |
<table border="1" width="500" summary="example 1"> |
<tr> |
<td colspan="3" align="center"> |
<?php echo $links['all']; ?> |
</td> |
</tr> |
<tr> |
<td colspan="3"> |
<pre><?php print_r($page_data); ?></pre> |
</td> |
</tr> |
</table> |
<h4>Results from methods:</h4> |
<pre> |
getCurrentPageID()...: <?php var_dump($pager->getCurrentPageID()); ?> |
getNextPageID()......: <?php var_dump($pager->getNextPageID()); ?> |
getPreviousPageID()..: <?php var_dump($pager->getPreviousPageID()); ?> |
numItems()...........: <?php var_dump($pager->numItems()); ?> |
numPages()...........: <?php var_dump($pager->numPages()); ?> |
isFirstPage()........: <?php var_dump($pager->isFirstPage()); ?> |
isLastPage().........: <?php var_dump($pager->isLastPage()); ?> |
isLastPageComplete().: <?php var_dump($pager->isLastPageComplete()); ?> |
$pager->range........: <?php var_dump($pager->range); ?> |
</pre> |
<hr /> |
<form action="<?php echo $_SERVER['PHP_SELF']; ?>" method="GET"> |
Select how many items per page should be shown:<br /> |
<?php echo $selectBox; ?> |
<input type="submit" value="submit" /> |
</form> |
<hr /> |
</body> |
</html> |
/branches/livraison_menes/api/pear/Pager/examples/Pager_Wrapper.php |
---|
New file |
0,0 → 1,339 |
<?php |
// CVS: $Id$ |
// |
// Pager_Wrapper |
// ------------- |
// |
// Ready-to-use wrappers for paging the result of a query, |
// when fetching the whole resultset is NOT an option. |
// This is a performance- and memory-savvy method |
// to use PEAR::Pager with a database. |
// With this approach, the network load can be |
// consistently smaller than with PEAR::DB_Pager. |
// |
// The following wrappers are provided: one for each PEAR |
// db abstraction layer (DB, MDB and MDB2), one for |
// PEAR::DB_DataObject, and one for the PHP Eclipse library |
// |
// |
// SAMPLE USAGE |
// ------------ |
// |
// $query = 'SELECT this, that FROM mytable'; |
// require_once 'Pager_Wrapper.php'; //this file |
// $pagerOptions = array( |
// 'mode' => 'Sliding', |
// 'delta' => 2, |
// 'perPage' => 15, |
// ); |
// $paged_data = Pager_Wrapper_MDB2($db, $query, $pagerOptions); |
// //$paged_data['data']; //paged data |
// //$paged_data['links']; //xhtml links for page navigation |
// //$paged_data['page_numbers']; //array('current', 'total'); |
// |
/** |
* Helper method - Rewrite the query into a "SELECT COUNT(*)" query. |
* @param string $sql query |
* @return string rewritten query OR false if the query can't be rewritten |
* @access private |
*/ |
function rewriteCountQuery($sql) |
{ |
if (preg_match('/^\s*SELECT\s+\bDISTINCT\b/is', $sql) || preg_match('/\s+GROUP\s+BY\s+/is', $sql)) { |
return false; |
} |
$open_parenthesis = '(?:\()'; |
$close_parenthesis = '(?:\))'; |
$subquery_in_select = $open_parenthesis.'.*\bFROM\b.*'.$close_parenthesis; |
$pattern = '/(?:.*'.$subquery_in_select.'.*)\bFROM\b\s+/Uims'; |
if (preg_match($pattern, $sql)) { |
return false; |
} |
$subquery_with_limit_order = $open_parenthesis.'.*\b(LIMIT|ORDER)\b.*'.$close_parenthesis; |
$pattern = '/.*\bFROM\b.*(?:.*'.$subquery_with_limit_order.'.*).*/Uims'; |
if (preg_match($pattern, $sql)) { |
return false; |
} |
$queryCount = preg_replace('/(?:.*)\bFROM\b\s+/Uims', 'SELECT COUNT(*) FROM ', $sql, 1); |
list($queryCount, ) = preg_split('/\s+ORDER\s+BY\s+/is', $queryCount); |
list($queryCount, ) = preg_split('/\bLIMIT\b/is', $queryCount); |
return trim($queryCount); |
} |
/** |
* @param object PEAR::DB instance |
* @param string db query |
* @param array PEAR::Pager options |
* @param boolean Disable pagination (get all results) |
* @param integer fetch mode constant |
* @param mixed parameters for query placeholders |
* If you use placeholders for table names or column names, please |
* count the # of items returned by the query and pass it as an option: |
* $pager_options['totalItems'] = count_records('some query'); |
* @return array with links and paged data |
*/ |
function Pager_Wrapper_DB(&$db, $query, $pager_options = array(), $disabled = false, $fetchMode = DB_FETCHMODE_ASSOC, $dbparams = null) |
{ |
if (!array_key_exists('totalItems', $pager_options)) { |
// be smart and try to guess the total number of records |
if ($countQuery = rewriteCountQuery($query)) { |
$totalItems = $db->getOne($countQuery, $dbparams); |
if (PEAR::isError($totalItems)) { |
return $totalItems; |
} |
} else { |
$res =& $db->query($query, $dbparams); |
if (PEAR::isError($res)) { |
return $res; |
} |
$totalItems = (int)$res->numRows(); |
$res->free(); |
} |
$pager_options['totalItems'] = $totalItems; |
} |
require_once 'Pager/Pager.php'; |
$pager = Pager::factory($pager_options); |
$page = array(); |
$page['totalItems'] = $pager_options['totalItems']; |
$page['links'] = $pager->links; |
$page['page_numbers'] = array( |
'current' => $pager->getCurrentPageID(), |
'total' => $pager->numPages() |
); |
list($page['from'], $page['to']) = $pager->getOffsetByPageId(); |
$res = ($disabled) |
? $db->limitQuery($query, 0, $totalItems, $dbparams) |
: $db->limitQuery($query, $page['from']-1, $pager_options['perPage'], $dbparams); |
if (PEAR::isError($res)) { |
return $res; |
} |
$page['data'] = array(); |
while ($res->fetchInto($row, $fetchMode)) { |
$page['data'][] = $row; |
} |
if ($disabled) { |
$page['links'] = ''; |
$page['page_numbers'] = array( |
'current' => 1, |
'total' => 1 |
); |
} |
return $page; |
} |
/** |
* @param object PEAR::MDB instance |
* @param string db query |
* @param array PEAR::Pager options |
* @param boolean Disable pagination (get all results) |
* @param integer fetch mode constant |
* @return array with links and paged data |
*/ |
function Pager_Wrapper_MDB(&$db, $query, $pager_options = array(), $disabled = false, $fetchMode = MDB_FETCHMODE_ASSOC) |
{ |
if (!array_key_exists('totalItems', $pager_options)) { |
//be smart and try to guess the total number of records |
if ($countQuery = rewriteCountQuery($query)) { |
$totalItems = $db->queryOne($countQuery); |
if (PEAR::isError($totalItems)) { |
return $totalItems; |
} |
} else { |
$res = $db->query($query); |
if (PEAR::isError($res)) { |
return $res; |
} |
$totalItems = (int)$db->numRows($res); |
$db->freeResult($res); |
} |
$pager_options['totalItems'] = $totalItems; |
} |
require_once 'Pager/Pager.php'; |
$pager = Pager::factory($pager_options); |
$page = array(); |
$page['totalItems'] = $pager_options['totalItems']; |
$page['links'] = $pager->links; |
$page['page_numbers'] = array( |
'current' => $pager->getCurrentPageID(), |
'total' => $pager->numPages() |
); |
list($page['from'], $page['to']) = $pager->getOffsetByPageId(); |
$res = ($disabled) |
? $db->limitQuery($query, null, 0, $totalItems) |
: $db->limitQuery($query, null, $page['from']-1, $pager_options['perPage']); |
if (PEAR::isError($res)) { |
return $res; |
} |
$page['data'] = array(); |
while ($row = $db->fetchInto($res, $fetchMode)) { |
$page['data'][] = $row; |
} |
if ($disabled) { |
$page['links'] = ''; |
$page['page_numbers'] = array( |
'current' => 1, |
'total' => 1 |
); |
} |
return $page; |
} |
/** |
* @param object PEAR::MDB2 instance |
* @param string db query |
* @param array PEAR::Pager options |
* @param boolean Disable pagination (get all results) |
* @param integer fetch mode constant |
* @return array with links and paged data |
*/ |
function Pager_Wrapper_MDB2(&$db, $query, $pager_options = array(), $disabled = false, $fetchMode = MDB2_FETCHMODE_ASSOC) |
{ |
if (!array_key_exists('totalItems', $pager_options)) { |
//be smart and try to guess the total number of records |
if ($countQuery = rewriteCountQuery($query)) { |
$totalItems = $db->queryOne($countQuery); |
if (PEAR::isError($totalItems)) { |
return $totalItems; |
} |
} else { |
//GROUP BY => fetch the whole resultset and count the rows returned |
$res =& $db->queryCol($query); |
if (PEAR::isError($res)) { |
return $res; |
} |
$totalItems = count($res); |
} |
$pager_options['totalItems'] = $totalItems; |
} |
require_once 'Pager/Pager.php'; |
$pager = Pager::factory($pager_options); |
$page = array(); |
$page['links'] = $pager->links; |
$page['totalItems'] = $pager_options['totalItems']; |
$page['page_numbers'] = array( |
'current' => $pager->getCurrentPageID(), |
'total' => $pager->numPages() |
); |
list($page['from'], $page['to']) = $pager->getOffsetByPageId(); |
$page['limit'] = $page['to'] - $page['from'] +1; |
if (!$disabled) { |
$db->setLimit($pager_options['perPage'], $page['from']-1); |
} |
$page['data'] = $db->queryAll($query, null, $fetchMode); |
if (PEAR::isError($page['data'])) { |
return $page['data']; |
} |
if ($disabled) { |
$page['links'] = ''; |
$page['page_numbers'] = array( |
'current' => 1, |
'total' => 1 |
); |
} |
return $page; |
} |
/** |
* @param object PEAR::DataObject instance |
* @param array PEAR::Pager options |
* @param boolean Disable pagination (get all results) |
* @return array with links and paged data |
* @author Massimiliano Arione <garak@studenti.it> |
*/ |
function Pager_Wrapper_DBDO(&$db, $pager_options = array(), $disabled = false) |
{ |
if (!array_key_exists('totalItems', $pager_options)) { |
$totalItems = $db->count(); |
$pager_options['totalItems'] = $totalItems; |
} |
require_once 'Pager/Pager.php'; |
$pager = Pager::factory($pager_options); |
$page = array(); |
$page['links'] = $pager->links; |
$page['totalItems'] = $pager_options['totalItems']; |
$page['page_numbers'] = array( |
'current' => $pager->getCurrentPageID(), |
'total' => $pager->numPages() |
); |
list($page['from'], $page['to']) = $pager->getOffsetByPageId(); |
$page['limit'] = $page['to'] - $page['from'] + 1; |
if (!$disabled) { |
$db->limit($page['from'] - 1, $pager_options['perPage']); |
} |
$db->find(); |
while ($db->fetch()) { |
$db->getLinks(); |
$page['data'][] = $db->toArray('%s', true); |
} |
return $page; |
} |
/** |
* @param object PHP Eclipse instance |
* @param string db query |
* @param array PEAR::Pager options |
* @param boolean Disable pagination (get all results) |
* @return array with links and paged data |
* @author Matte Edens <matte@arubanetworks.com> |
* @see http://sourceforge.net/projects/eclipselib/ |
*/ |
function Pager_Wrapper_Eclipse(&$db, $query, $pager_options = array(), $disabled = false) |
{ |
if (!$disabled) { |
require_once(ECLIPSE_ROOT . 'PagedQuery.php'); |
$query =& new PagedQuery($db->query($query), $pager_options['perPage']); |
$totalrows = $query->getRowCount(); |
$numpages = $query->getPageCount(); |
$whichpage = isset($_GET[$pager_options['urlVar']]) ? (int)$_GET[$pager_options['urlVar']] - 1 : 0; |
if ($whichpage >= $numpages) { |
$whichpage = $numpages - 1; |
} |
$result = $query->getPage($whichpage); |
} else { |
$result = $db->query($query); |
$totalrows = $result->getRowCount(); |
$numpages = 1; |
} |
if (!$result->isSuccess()) { |
return PEAR::raiseError($result->getErrorMessage()); |
} |
if (!array_key_exists('totalItems', $pager_options)) { |
$pager_options['totalItems'] = $totalrows; |
} |
$page = array(); |
require_once(ECLIPSE_ROOT . 'QueryIterator.php'); |
for ($it =& new QueryIterator($result); $it->isValid(); $it->next()) { |
$page['data'][] =& $it->getCurrent(); |
} |
require_once 'Pager/Pager.php'; |
$pager = Pager::factory($pager_options); |
$page['links'] = $pager->links; |
$page['totalItems'] = $pager_options['totalItems']; |
$page['page_numbers'] = array( |
'current' => $pager->getCurrentPageID(), |
'total' => $numpages |
); |
$page['perPageSelectBox'] = $pager->getperpageselectbox(); |
list($page['from'], $page['to']) = $pager->getOffsetByPageId(); |
$page['limit'] = $page['to'] - $page['from'] +1; |
if ($disabled) { |
$page['links'] = ''; |
$page['page_numbers'] = array( |
'current' => 1, |
'total' => 1 |
); |
} |
return $page; |
} |
?> |
/branches/livraison_menes/api/pear/Pager/Jumping.php |
---|
New file |
0,0 → 1,280 |
<?php |
/* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4: */ |
/** |
* Contains the Pager_Jumping class |
* |
* PHP versions 4 and 5 |
* |
* LICENSE: Redistribution and use in source and binary forms, with or without |
* modification, are permitted provided that the following conditions are met: |
* 1. Redistributions of source code must retain the above copyright |
* notice, this list of conditions and the following disclaimer. |
* 2. Redistributions in binary form must reproduce the above copyright |
* notice, this list of conditions and the following disclaimer in the |
* documentation and/or other materials provided with the distribution. |
* 3. The name of the author may not be used to endorse or promote products |
* derived from this software without specific prior written permission. |
* |
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR "AS IS" AND ANY EXPRESS OR IMPLIED |
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF |
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. |
* IN NO EVENT SHALL THE FREEBSD PROJECT OR CONTRIBUTORS BE LIABLE FOR ANY |
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES |
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; |
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND |
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF |
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
* |
* @category HTML |
* @package Pager |
* @author Lorenzo Alberton <l dot alberton at quipo dot it> |
* @author Richard Heyes <richard@phpguru.org>, |
* @copyright 2003-2006 Lorenzo Alberton, Richard Heyes |
* @license http://www.debian.org/misc/bsd.license BSD License (3 Clause) |
* @version CVS: $Id$ |
* @link http://pear.php.net/package/Pager |
*/ |
/** |
* require PEAR::Pager_Common base class |
*/ |
require_once 'Pager/Common.php'; |
/** |
* Pager_Jumping - Generic data paging class ("jumping window" style) |
* Handles paging a set of data. For usage see the example.php provided. |
* |
* @category HTML |
* @package Pager |
* @author Lorenzo Alberton <l dot alberton at quipo dot it> |
* @author Richard Heyes <richard@phpguru.org>, |
* @copyright 2003-2005 Lorenzo Alberton, Richard Heyes |
* @license http://www.php.net/license/3_0.txt PHP License 3.0 |
* @link http://pear.php.net/package/Pager |
*/ |
class Pager_Jumping extends Pager_Common |
{ |
// {{{ Pager_Jumping() |
/** |
* Constructor |
* |
* @param array $options An associative array of option names |
* and their values |
* @access public |
*/ |
function Pager_Jumping($options = array()) |
{ |
$err = $this->setOptions($options); |
if ($err !== PAGER_OK) { |
return $this->raiseError($this->errorMessage($err), $err); |
} |
$this->build(); |
} |
// }}} |
// {{{ build() |
/** |
* Generate or refresh the links and paged data after a call to setOptions() |
* |
* @access public |
*/ |
function build() |
{ |
//reset |
$this->_pageData = array(); |
$this->links = ''; |
$this->_generatePageData(); |
$this->_setFirstLastText(); |
$this->links .= $this->_getBackLink(); |
$this->links .= $this->_getPageLinks(); |
$this->links .= $this->_getNextLink(); |
$this->linkTags .= $this->_getFirstLinkTag(); |
$this->linkTags .= $this->_getPrevLinkTag(); |
$this->linkTags .= $this->_getNextLinkTag(); |
$this->linkTags .= $this->_getLastLinkTag(); |
} |
// }}} |
// {{{ getPageIdByOffset() |
/** |
* Returns pageID for given offset |
* |
* @param $index Offset to get pageID for |
* @return int PageID for given offset |
*/ |
function getPageIdByOffset($index) |
{ |
if (!isset($this->_pageData)) { |
$this->_generatePageData(); |
} |
if (($index % $this->_perPage) > 0) { |
$pageID = ceil((float)$index / (float)$this->_perPage); |
} else { |
$pageID = $index / $this->_perPage; |
} |
return $pageID; |
} |
// }}} |
// {{{ getPageRangeByPageId() |
/** |
* Given a PageId, it returns the limits of the range of pages displayed. |
* While getOffsetByPageId() returns the offset of the data within the |
* current page, this method returns the offsets of the page numbers interval. |
* E.g., if you have pageId=3 and delta=10, it will return (1, 10). |
* PageID of 8 would give you (1, 10) as well, because 1 <= 8 <= 10. |
* PageID of 11 would give you (11, 20). |
* If the method is called without parameter, pageID is set to currentPage#. |
* |
* @param integer PageID to get offsets for |
* @return array First and last offsets |
* @access public |
*/ |
function getPageRangeByPageId($pageid = null) |
{ |
$pageid = isset($pageid) ? (int)$pageid : $this->_currentPage; |
if (isset($this->_pageData[$pageid]) || is_null($this->_itemData)) { |
// I'm sure I'm missing something here, but this formula works |
// so I'm using it until I find something simpler. |
$start = ((($pageid + (($this->_delta - ($pageid % $this->_delta))) % $this->_delta) / $this->_delta) - 1) * $this->_delta +1; |
return array( |
max($start, 1), |
min($start+$this->_delta-1, $this->_totalPages) |
); |
} else { |
return array(0, 0); |
} |
} |
// }}} |
// {{{ getLinks() |
/** |
* Returns back/next/first/last and page links, |
* both as ordered and associative array. |
* |
* NB: in original PEAR::Pager this method accepted two parameters, |
* $back_html and $next_html. Now the only parameter accepted is |
* an integer ($pageID), since the html text for prev/next links can |
* be set in the constructor. If a second parameter is provided, then |
* the method act as it previously did. This hack's only purpose is to |
* mantain backward compatibility. |
* |
* @param integer $pageID Optional pageID. If specified, links |
* for that page are provided instead of current one. |
* [ADDED IN NEW PAGER VERSION] |
* @param string $next_html HTML to put inside the next link |
* [deprecated: use the constructor instead] |
* @return array Back/pages/next links |
*/ |
function getLinks($pageID=null, $next_html='') |
{ |
//BC hack |
if (!empty($next_html)) { |
$back_html = $pageID; |
$pageID = null; |
} else { |
$back_html = ''; |
} |
if (!is_null($pageID)) { |
$_sav = $this->_currentPage; |
$this->_currentPage = $pageID; |
$this->links = ''; |
if ($this->_totalPages > $this->_delta) { |
$this->links .= $this->_printFirstPage(); |
} |
$this->links .= $this->_getBackLink('', $back_html); |
$this->links .= $this->_getPageLinks(); |
$this->links .= $this->_getNextLink('', $next_html); |
if ($this->_totalPages > $this->_delta) { |
$this->links .= $this->_printLastPage(); |
} |
} |
$back = str_replace(' ', '', $this->_getBackLink()); |
$next = str_replace(' ', '', $this->_getNextLink()); |
$pages = $this->_getPageLinks(); |
$first = $this->_printFirstPage(); |
$last = $this->_printLastPage(); |
$all = $this->links; |
$linkTags = $this->linkTags; |
if (!is_null($pageID)) { |
$this->_currentPage = $_sav; |
} |
return array( |
$back, |
$pages, |
trim($next), |
$first, |
$last, |
$all, |
$linkTags, |
'back' => $back, |
'pages' => $pages, |
'next' => $next, |
'first' => $first, |
'last' => $last, |
'all' => $all, |
'linktags' => $linkTags |
); |
} |
// }}} |
// {{{ _getPageLinks() |
/** |
* Returns pages link |
* |
* @param $url URL to use in the link |
* [deprecated: use the constructor instead] |
* @return string Links |
* @access private |
*/ |
function _getPageLinks($url = '') |
{ |
//legacy setting... the preferred way to set an option now |
//is adding it to the constuctor |
if (!empty($url)) { |
$this->_path = $url; |
} |
//If there's only one page, don't display links |
if ($this->_clearIfVoid && ($this->_totalPages < 2)) { |
return ''; |
} |
$links = ''; |
$limits = $this->getPageRangeByPageId($this->_currentPage); |
for ($i=$limits[0]; $i<=min($limits[1], $this->_totalPages); $i++) { |
if ($i != $this->_currentPage) { |
$this->range[$i] = false; |
$this->_linkData[$this->_urlVar] = $i; |
$links .= $this->_renderLink($this->_altPage.' '.$i, $i); |
} else { |
$this->range[$i] = true; |
$links .= $this->_curPageSpanPre . $i . $this->_curPageSpanPost; |
} |
$links .= $this->_spacesBefore |
. (($i != $this->_totalPages) ? $this->_separator.$this->_spacesAfter : ''); |
} |
return $links; |
} |
// }}} |
} |
?> |
/branches/livraison_menes/api/pear/Pager/Sliding.php |
---|
New file |
0,0 → 1,324 |
<?php |
/* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4: */ |
/** |
* Contains the Pager_Sliding class |
* |
* PHP versions 4 and 5 |
* |
* LICENSE: Redistribution and use in source and binary forms, with or without |
* modification, are permitted provided that the following conditions are met: |
* 1. Redistributions of source code must retain the above copyright |
* notice, this list of conditions and the following disclaimer. |
* 2. Redistributions in binary form must reproduce the above copyright |
* notice, this list of conditions and the following disclaimer in the |
* documentation and/or other materials provided with the distribution. |
* 3. The name of the author may not be used to endorse or promote products |
* derived from this software without specific prior written permission. |
* |
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR "AS IS" AND ANY EXPRESS OR IMPLIED |
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF |
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. |
* IN NO EVENT SHALL THE FREEBSD PROJECT OR CONTRIBUTORS BE LIABLE FOR ANY |
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES |
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; |
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND |
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF |
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
* |
* @category HTML |
* @package Pager |
* @author Lorenzo Alberton <l dot alberton at quipo dot it> |
* @copyright 2003-2006 Lorenzo Alberton |
* @license http://www.debian.org/misc/bsd.license BSD License (3 Clause) |
* @version CVS: $Id$ |
* @link http://pear.php.net/package/Pager |
*/ |
/** |
* require PEAR::Pager_Common base class |
*/ |
require_once 'Pager/Common.php'; |
/** |
* Pager_Sliding - Generic data paging class ("sliding window" style) |
* Usage examples can be found in the PEAR manual |
* |
* @category HTML |
* @package Pager |
* @author Lorenzo Alberton <l dot alberton at quipo dot it> |
* @copyright 2003-2005 Lorenzo Alberton |
* @license http://www.php.net/license/3_0.txt PHP License 3.0 |
* @link http://pear.php.net/package/Pager |
*/ |
class Pager_Sliding extends Pager_Common |
{ |
// {{{ Pager_Sliding() |
/** |
* Constructor |
* |
* @param array $options An associative array of option names |
* and their values |
* @access public |
*/ |
function Pager_Sliding($options = array()) |
{ |
//set default Pager_Sliding options |
$this->_delta = 2; |
$this->_prevImg = '«'; |
$this->_nextImg = '»'; |
$this->_separator = '|'; |
$this->_spacesBeforeSeparator = 3; |
$this->_spacesAfterSeparator = 3; |
$this->_curPageSpanPre = '<b><u>'; |
$this->_curPageSpanPost = '</u></b>'; |
//set custom options |
$err = $this->setOptions($options); |
if ($err !== PAGER_OK) { |
return $this->raiseError($this->errorMessage($err), $err); |
} |
$this->build(); |
} |
// }}} |
// {{{ build() |
/** |
* Generate or refresh the links and paged data after a call to setOptions() |
* |
* @access public |
*/ |
function build() |
{ |
//reset |
$this->_pageData = array(); |
$this->links = ''; |
$this->_generatePageData(); |
$this->_setFirstLastText(); |
if ($this->_totalPages > (2 * $this->_delta + 1)) { |
$this->links .= $this->_printFirstPage(); |
} |
$this->links .= $this->_getBackLink(); |
$this->links .= $this->_getPageLinks(); |
$this->links .= $this->_getNextLink(); |
$this->linkTags .= $this->_getFirstLinkTag(); |
$this->linkTags .= $this->_getPrevLinkTag(); |
$this->linkTags .= $this->_getNextLinkTag(); |
$this->linkTags .= $this->_getLastLinkTag(); |
if ($this->_totalPages > (2 * $this->_delta + 1)) { |
$this->links .= $this->_printLastPage(); |
} |
} |
// }}} |
// {{{ getPageIdByOffset() |
/** |
* "Overload" PEAR::Pager method. VOID. Not needed here... |
* @param integer $index Offset to get pageID for |
* @deprecated |
* @access public |
*/ |
function getPageIdByOffset($index=null) { } |
// }}} |
// {{{ getPageRangeByPageId() |
/** |
* Given a PageId, it returns the limits of the range of pages displayed. |
* While getOffsetByPageId() returns the offset of the data within the |
* current page, this method returns the offsets of the page numbers interval. |
* E.g., if you have pageId=5 and delta=2, it will return (3, 7). |
* PageID of 9 would give you (4, 8). |
* If the method is called without parameter, pageID is set to currentPage#. |
* |
* @param integer PageID to get offsets for |
* @return array First and last offsets |
* @access public |
*/ |
function getPageRangeByPageId($pageid = null) |
{ |
$pageid = isset($pageid) ? (int)$pageid : $this->_currentPage; |
if (!isset($this->_pageData)) { |
$this->_generatePageData(); |
} |
if (isset($this->_pageData[$pageid]) || is_null($this->_itemData)) { |
if ($this->_expanded) { |
$min_surplus = ($pageid <= $this->_delta) ? ($this->_delta - $pageid + 1) : 0; |
$max_surplus = ($pageid >= ($this->_totalPages - $this->_delta)) ? |
($pageid - ($this->_totalPages - $this->_delta)) : 0; |
} else { |
$min_surplus = $max_surplus = 0; |
} |
return array( |
max($pageid - $this->_delta - $max_surplus, 1), |
min($pageid + $this->_delta + $min_surplus, $this->_totalPages) |
); |
} |
return array(0, 0); |
} |
// }}} |
// {{{ getLinks() |
/** |
* Returns back/next/first/last and page links, |
* both as ordered and associative array. |
* |
* @param integer $pageID Optional pageID. If specified, links |
* for that page are provided instead of current one. |
* @return array back/pages/next/first/last/all links |
* @access public |
*/ |
function getLinks($pageID = null) |
{ |
if ($pageID != null) { |
$_sav = $this->_currentPage; |
$this->_currentPage = $pageID; |
$this->links = ''; |
if ($this->_totalPages > (2 * $this->_delta + 1)) { |
$this->links .= $this->_printFirstPage(); |
} |
$this->links .= $this->_getBackLink(); |
$this->links .= $this->_getPageLinks(); |
$this->links .= $this->_getNextLink(); |
if ($this->_totalPages > (2 * $this->_delta + 1)) { |
$this->links .= $this->_printLastPage(); |
} |
} |
$back = str_replace(' ', '', $this->_getBackLink()); |
$next = str_replace(' ', '', $this->_getNextLink()); |
$pages = $this->_getPageLinks(); |
$first = $this->_printFirstPage(); |
$last = $this->_printLastPage(); |
$all = $this->links; |
$linkTags = $this->linkTags; |
if ($pageID != null) { |
$this->_currentPage = $_sav; |
} |
return array( |
$back, |
$pages, |
trim($next), |
$first, |
$last, |
$all, |
$linkTags, |
'back' => $back, |
'pages' => $pages, |
'next' => $next, |
'first' => $first, |
'last' => $last, |
'all' => $all, |
'linktags' => $linkTags |
); |
} |
// }}} |
// {{{ _getPageLinks() |
/** |
* Returns pages link |
* |
* @return string Links |
* @access private |
*/ |
function _getPageLinks($url = '') |
{ |
//legacy setting... the preferred way to set an option now |
//is adding it to the constuctor |
if (!empty($url)) { |
$this->_path = $url; |
} |
//If there's only one page, don't display links |
if ($this->_clearIfVoid && ($this->_totalPages < 2)) { |
return ''; |
} |
$links = ''; |
if ($this->_totalPages > (2 * $this->_delta + 1)) { |
if ($this->_expanded) { |
if (($this->_totalPages - $this->_delta) <= $this->_currentPage) { |
$expansion_before = $this->_currentPage - ($this->_totalPages - $this->_delta); |
} else { |
$expansion_before = 0; |
} |
for ($i = $this->_currentPage - $this->_delta - $expansion_before; $expansion_before; $expansion_before--, $i++) { |
$print_separator_flag = ($i != $this->_currentPage + $this->_delta); // && ($i != $this->_totalPages - 1) |
$this->range[$i] = false; |
$this->_linkData[$this->_urlVar] = $i; |
$links .= $this->_renderLink($this->_altPage.' '.$i, $i) |
. $this->_spacesBefore |
. ($print_separator_flag ? $this->_separator.$this->_spacesAfter : ''); |
} |
} |
$expansion_after = 0; |
for ($i = $this->_currentPage - $this->_delta; ($i <= $this->_currentPage + $this->_delta) && ($i <= $this->_totalPages); $i++) { |
if ($i < 1) { |
++$expansion_after; |
continue; |
} |
// check when to print separator |
$print_separator_flag = (($i != $this->_currentPage + $this->_delta) && ($i != $this->_totalPages)); |
if ($i == $this->_currentPage) { |
$this->range[$i] = true; |
$links .= $this->_curPageSpanPre . $i . $this->_curPageSpanPost; |
} else { |
$this->range[$i] = false; |
$this->_linkData[$this->_urlVar] = $i; |
$links .= $this->_renderLink($this->_altPage.' '.$i, $i); |
} |
$links .= $this->_spacesBefore |
. ($print_separator_flag ? $this->_separator.$this->_spacesAfter : ''); |
} |
if ($this->_expanded && $expansion_after) { |
$links .= $this->_separator . $this->_spacesAfter; |
for ($i = $this->_currentPage + $this->_delta +1; $expansion_after; $expansion_after--, $i++) { |
$print_separator_flag = ($expansion_after != 1); |
$this->range[$i] = false; |
$this->_linkData[$this->_urlVar] = $i; |
$links .= $this->_renderLink($this->_altPage.' '.$i, $i) |
. $this->_spacesBefore |
. ($print_separator_flag ? $this->_separator.$this->_spacesAfter : ''); |
} |
} |
} else { |
//if $this->_totalPages <= (2*Delta+1) show them all |
for ($i=1; $i<=$this->_totalPages; $i++) { |
if ($i != $this->_currentPage) { |
$this->range[$i] = false; |
$this->_linkData[$this->_urlVar] = $i; |
$links .= $this->_renderLink($this->_altPage.' '.$i, $i); |
} else { |
$this->range[$i] = true; |
$links .= $this->_curPageSpanPre . $i . $this->_curPageSpanPost; |
} |
$links .= $this->_spacesBefore |
. (($i != $this->_totalPages) ? $this->_separator.$this->_spacesAfter : ''); |
} |
} |
return $links; |
} |
// }}} |
} |
?> |
/branches/livraison_menes/api/pear/XML/Tree.php |
---|
New file |
0,0 → 1,370 |
<?php |
// |
// +----------------------------------------------------------------------+ |
// | PHP Version 4 | |
// +----------------------------------------------------------------------+ |
// | Copyright (c) 1997-2002 The PHP Group | |
// +----------------------------------------------------------------------+ |
// | This source file is subject to version 2.02 of the PHP license, | |
// | that is bundled with this package in the file LICENSE, and is | |
// | available at through the world-wide-web at | |
// | http://www.php.net/license/2_02.txt. | |
// | If you did not receive a copy of the PHP license and are unable to | |
// | obtain it through the world-wide-web, please send a note to | |
// | license@php.net so we can mail you a copy immediately. | |
// +----------------------------------------------------------------------+ |
// | Authors: Bernd Römer <berndr@bonn.edu> | |
// | Sebastian Bergmann <sb@sebastian-bergmann.de> | |
// | Tomas V.V.Cox <cox@idecnet.com> (tree mapping from xml file)| |
// +----------------------------------------------------------------------+ |
// |
// $Id: Tree.php,v 1.1 2005-04-18 16:13:31 jpm Exp $ |
// |
require_once 'XML/Parser.php'; |
require_once 'XML/Tree/Node.php'; |
/** |
* PEAR::XML_Tree |
* |
* Purpose |
* |
* Allows for the building of XML data structures |
* using a tree representation, without the need |
* for an extension like DOMXML. |
* |
* Example |
* |
* $tree = new XML_Tree; |
* $root =& $tree->addRoot('root'); |
* $foo =& $root->addChild('foo'); |
* |
* header('Content-Type: text/xml'); |
* $tree->dump(); |
* |
* @author Bernd Römer <berndr@bonn.edu> |
* @package XML |
* @version $Version$ - 1.0 |
*/ |
class XML_Tree extends XML_Parser |
{ |
/** |
* File Handle |
* |
* @var ressource |
*/ |
var $file = NULL; |
/** |
* Filename |
* |
* @var string |
*/ |
var $filename = ''; |
/** |
* Namespace |
* |
* @var array |
*/ |
var $namespace = array(); |
/** |
* Root |
* |
* @var object XML_Tree_Node |
*/ |
var $root = NULL; |
/** |
* XML Version |
* |
* @var string |
*/ |
var $version = '1.0'; |
/** |
* Constructor |
* |
* @param string Filename |
* @param string XML Version |
*/ |
function XML_Tree($filename = '', $version = '1.0') { |
$this->filename = $filename; |
$this->version = $version; |
} |
/** |
* Add root node. |
* |
* @param string $name name of root element |
* @return object XML_Tree_Node reference to root node |
* |
* @access public |
*/ |
function &addRoot($name, $content = '', $attributes = array()) { |
$this->root = new XML_Tree_Node($name, $content, $attributes); |
return $this->root; |
} |
/** |
* @deprecated |
*/ |
function &add_root($name, $content = '', $attributes = array()) { |
return $this->addRoot($name, $content, $attributes); |
} |
/** |
* inserts a child/tree (child) into tree ($path,$pos) and |
* maintains namespace integrity |
* |
* @param array $path path to parent of child to remove |
* @param integer $pos position of child to be inserted in its parents children-list |
* @param mixed $child child-node (by XML_Tree,XML_Node or Name) |
* @param string $content content (text) for new node |
* @param array $attributes attribute-hash for new node |
* |
* @return object XML_Tree_Node inserted child (node) |
* @access public |
*/ |
function &insertChild($path,$pos,$child, $content = '', $attributes = array()) { |
// update namespace to maintain namespace integrity |
$count=count($path); |
foreach($this->namespace as $key => $val) { |
if ((array_slice($val,0,$count)==$path) && ($val[$count]>=$pos)) |
$this->namespace[$key][$count]++; |
} |
$parent=&$this->get_node_by_path($path); |
return($parent->insert_child($pos,$child,$content,$attributes)); |
} |
/** |
* @deprecated |
*/ |
function &insert_child($path,$pos,$child, $content = '', $attributes = array()) { |
return $this->insertChild($path, $child, $content, $attributes); |
} |
/* |
* removes a child ($path,$pos) from tree ($path,$pos) and |
* maintains namespace integrity |
* |
* @param array $path path to parent of child to remove |
* @param integer $pos position of child in parents children-list |
* |
* @return object XML_Tree_Node parent whichs child was removed |
* @access public |
*/ |
function &removeChild($path,$pos) { |
// update namespace to maintain namespace integrity |
$count=count($path); |
foreach($this->namespace as $key => $val) { |
if (array_slice($val,0,$count)==$path) { |
if ($val[$count]==$pos) { unset($this->namespace[$key]); break; } |
if ($val[$count]>$pos) |
$this->namespace[$key][$count]--; |
} |
} |
$parent=&$this->get_node_by_path($path); |
return($parent->remove_child($pos)); |
} |
/** |
* @deprecated |
*/ |
function &remove_child($path, $pos) { |
return $this->removeChild($path, $pos); |
} |
/* |
* Maps a xml file to a objects tree |
* |
* @return mixed The objects tree (XML_tree or an Pear error) |
* @access public |
*/ |
function &getTreeFromFile () |
{ |
$this->folding = false; |
$this->XML_Parser(null, 'event'); |
$err = $this->setInputFile($this->filename); |
if (PEAR::isError($err)) { |
return $err; |
} |
$this->cdata = null; |
$err = $this->parse(); |
if (PEAR::isError($err)) { |
return $err; |
} |
return $this->root; |
} |
function getTreeFromString($str) |
{ |
$this->folding = false; |
$this->XML_Parser(null, 'event'); |
$this->cdata = null; |
$err = $this->parseString($str); |
if (PEAR::isError($err)) { |
return $err; |
} |
return $this->root; |
} |
/** |
* Handler for the xml-data |
* |
* @param mixed $xp ignored |
* @param string $elem name of the element |
* @param array $attribs attributes for the generated node |
* |
* @access private |
*/ |
function startHandler($xp, $elem, &$attribs) |
{ |
// root elem |
if (!isset($this->i)) { |
$this->obj1 =& $this->add_root($elem, null, $attribs); |
$this->i = 2; |
} else { |
// mixed contents |
if (!empty($this->cdata)) { |
$parent_id = 'obj' . ($this->i - 1); |
$parent =& $this->$parent_id; |
$parent->children[] = &new XML_Tree_Node(null, $this->cdata); |
} |
$obj_id = 'obj' . $this->i++; |
$this->$obj_id = &new XML_Tree_Node($elem, null, $attribs); |
} |
$this->cdata = null; |
return null; |
} |
/** |
* Handler for the xml-data |
* |
* @param mixed $xp ignored |
* @param string $elem name of the element |
* |
* @access private |
*/ |
function endHandler($xp, $elem) |
{ |
$this->i--; |
if ($this->i > 1) { |
$obj_id = 'obj' . $this->i; |
// recover the node created in StartHandler |
$node =& $this->$obj_id; |
// mixed contents |
if (count($node->children) > 0) { |
if (trim($this->cdata)) { |
$node->children[] = &new XML_Tree_Node(null, $this->cdata); |
} |
} else { |
$node->set_content($this->cdata); |
} |
$parent_id = 'obj' . ($this->i - 1); |
$parent =& $this->$parent_id; |
// attach the node to its parent node children array |
$parent->children[] = $node; |
} |
$this->cdata = null; |
return null; |
} |
/* |
* The xml character data handler |
* |
* @param mixed $xp ignored |
* @param string $data PCDATA between tags |
* |
* @access private |
*/ |
function cdataHandler($xp, $data) |
{ |
if (trim($data)) { |
$this->cdata .= $data; |
} |
} |
/** |
* Get a copy of this tree. |
* |
* @return object XML_Tree |
* @access public |
*/ |
function clone() { |
$clone=new XML_Tree($this->filename,$this->version); |
$clone->root=$this->root->clone(); |
// clone all other vars |
$temp=get_object_vars($this); |
foreach($temp as $varname => $value) |
if (!in_array($varname,array('filename','version','root'))) |
$clone->$varname=$value; |
return($clone); |
} |
/** |
* Print text representation of XML tree. |
* |
* @access public |
*/ |
function dump() { |
echo $this->get(); |
} |
/** |
* Get text representation of XML tree. |
* |
* @return string XML |
* @access public |
*/ |
function &get() { |
$out = '<?xml version="' . $this->version . "\"?>\n"; |
$out .= $this->root->get(); |
return $out; |
} |
/** |
* Get current namespace. |
* |
* @param string $name namespace |
* @return string |
* |
* @access public |
*/ |
function &getName($name) { |
return $this->root->get_element($this->namespace[$name]); |
} |
/** |
* @deprecated |
*/ |
function &get_name($name) { |
return $this->getName($name); |
} |
/** |
* Register a namespace. |
* |
* @param string $name namespace |
* @param string $path path |
* |
* @access public |
*/ |
function registerName($name, $path) { |
$this->namespace[$name] = $path; |
} |
/** |
* @deprecated |
*/ |
function register_name($name, $path) { |
return $this->registerName($name, $path); |
} |
} |
?> |
/branches/livraison_menes/api/pear/XML/Parser/Simple.php |
---|
New file |
0,0 → 1,297 |
<?php |
// |
// +----------------------------------------------------------------------+ |
// | PHP Version 4 | |
// +----------------------------------------------------------------------+ |
// | Copyright (c) 1997-2004 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 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. | |
// +----------------------------------------------------------------------+ |
// | Author: Stephan Schmidt <schst@php-tools.net> | |
// +----------------------------------------------------------------------+ |
// |
// $Id: Simple.php,v 1.1 2005-04-18 16:13:31 jpm Exp $ |
/** |
* Simple XML parser class. |
* |
* This class is a simplified version of XML_Parser. |
* In most XML applications the real action is executed, |
* when a closing tag is found. |
* |
* XML_Parser_Simple allows you to just implement one callback |
* for each tag that will receive the tag with its attributes |
* and CData |
* |
* @category XML |
* @package XML_Parser |
* @author Stephan Schmidt <schst@php-tools.net> |
*/ |
/** |
* built on XML_Parser |
*/ |
require_once 'XML/Parser.php'; |
/** |
* Simple XML parser class. |
* |
* This class is a simplified version of XML_Parser. |
* In most XML applications the real action is executed, |
* when a closing tag is found. |
* |
* XML_Parser_Simple allows you to just implement one callback |
* for each tag that will receive the tag with its attributes |
* and CData. |
* |
* <code> |
* require_once '../Parser/Simple.php'; |
* |
* class myParser extends XML_Parser_Simple |
* { |
* function myParser() |
* { |
* $this->XML_Parser_Simple(); |
* } |
* |
* function handleElement($name, $attribs, $data) |
* { |
* printf('handle %s<br>', $name); |
* } |
* } |
* |
* $p = &new myParser(); |
* |
* $result = $p->setInputFile('myDoc.xml'); |
* $result = $p->parse(); |
* </code> |
* |
* @category XML |
* @package XML_Parser |
* @author Stephan Schmidt <schst@php-tools.net> |
*/ |
class XML_Parser_Simple extends XML_Parser |
{ |
/** |
* element stack |
* |
* @access private |
* @var array |
*/ |
var $_elStack = array(); |
/** |
* all character data |
* |
* @access private |
* @var array |
*/ |
var $_data = array(); |
/** |
* element depth |
* |
* @access private |
* @var integer |
*/ |
var $_depth = 0; |
/** |
* Mapping from expat handler function to class method. |
* |
* @var array |
*/ |
var $handler = array( |
'default_handler' => 'defaultHandler', |
'processing_instruction_handler' => 'piHandler', |
'unparsed_entity_decl_handler' => 'unparsedHandler', |
'notation_decl_handler' => 'notationHandler', |
'external_entity_ref_handler' => 'entityrefHandler' |
); |
/** |
* Creates an XML parser. |
* |
* This is needed for PHP4 compatibility, it will |
* call the constructor, when a new instance is created. |
* |
* @param string $srcenc source charset encoding, use NULL (default) to use |
* whatever the document specifies |
* @param string $mode how this parser object should work, "event" for |
* handleElement(), "func" to have it call functions |
* named after elements (handleElement_$name()) |
* @param string $tgenc a valid target encoding |
*/ |
function XML_Parser_Simple($srcenc = null, $mode = 'event', $tgtenc = null) |
{ |
$this->XML_Parser($srcenc, $mode, $tgtenc); |
} |
/** |
* inits the handlers |
* |
* @access private |
*/ |
function _initHandlers() |
{ |
if (!is_object($this->_handlerObj)) { |
$this->_handlerObj = &$this; |
} |
if ($this->mode != 'func' && $this->mode != 'event') { |
return $this->raiseError('Unsupported mode given', XML_PARSER_ERROR_UNSUPPORTED_MODE); |
} |
xml_set_object($this->parser, $this->_handlerObj); |
xml_set_element_handler($this->parser, array(&$this, 'startHandler'), array(&$this, 'endHandler')); |
xml_set_character_data_handler($this->parser, array(&$this, 'cdataHandler')); |
/** |
* set additional handlers for character data, entities, etc. |
*/ |
foreach ($this->handler as $xml_func => $method) { |
if (method_exists($this->_handlerObj, $method)) { |
$xml_func = 'xml_set_' . $xml_func; |
$xml_func($this->parser, $method); |
} |
} |
} |
/** |
* Reset the parser. |
* |
* This allows you to use one parser instance |
* to parse multiple XML documents. |
* |
* @access public |
* @return boolean|object true on success, PEAR_Error otherwise |
*/ |
function reset() |
{ |
$this->_elStack = array(); |
$this->_data = array(); |
$this->_depth = 0; |
$result = $this->_create(); |
if ($this->isError( $result )) { |
return $result; |
} |
return true; |
} |
/** |
* start handler |
* |
* Pushes attributes and tagname onto a stack |
* |
* @access private |
* @final |
* @param resource xml parser resource |
* @param string element name |
* @param array attributes |
*/ |
function startHandler($xp, $elem, &$attribs) |
{ |
array_push($this->_elStack, array( |
'name' => $elem, |
'attribs' => $attribs |
) |
); |
$this->_depth++; |
$this->_data[$this->_depth] = ''; |
} |
/** |
* end handler |
* |
* Pulls attributes and tagname from a stack |
* |
* @access private |
* @final |
* @param resource xml parser resource |
* @param string element name |
*/ |
function endHandler($xp, $elem) |
{ |
$el = array_pop($this->_elStack); |
$data = $this->_data[$this->_depth]; |
$this->_depth--; |
switch ($this->mode) { |
case 'event': |
$this->_handlerObj->handleElement($el['name'], $el['attribs'], $data); |
break; |
case 'func': |
$func = 'handleElement_' . $elem; |
if (strchr($func, '.')) { |
$func = str_replace('.', '_', $func); |
} |
if (method_exists($this->_handlerObj, $func)) { |
call_user_func(array(&$this->_handlerObj, $func), $el['name'], $el['attribs'], $data); |
} |
break; |
} |
} |
/** |
* handle character data |
* |
* @access private |
* @final |
* @param resource xml parser resource |
* @param string data |
*/ |
function cdataHandler($xp, $data) |
{ |
$this->_data[$this->_depth] .= $data; |
} |
/** |
* handle a tag |
* |
* Implement this in your parser |
* |
* @access public |
* @abstract |
* @param string element name |
* @param array attributes |
* @param string character data |
*/ |
function handleElement($name, $attribs, $data) |
{ |
} |
/** |
* get the current tag depth |
* |
* The root tag is in depth 0. |
* |
* @access public |
* @return integer |
*/ |
function getCurrentDepth() |
{ |
return $this->_depth; |
} |
/** |
* add some string to the current ddata. |
* |
* This is commonly needed, when a document is parsed recursively. |
* |
* @access public |
* @param string data to add |
* @return void |
*/ |
function addToData( $data ) |
{ |
$this->_data[$this->_depth] .= $data; |
} |
} |
?> |
/branches/livraison_menes/api/pear/XML/RSS.php |
---|
New file |
0,0 → 1,359 |
<?php |
// vim: set expandtab tabstop=4 shiftwidth=4 fdm=marker: |
// +----------------------------------------------------------------------+ |
// | PHP Version 4 | |
// +----------------------------------------------------------------------+ |
// | Copyright (c) 1997-2003 The PHP Group | |
// +----------------------------------------------------------------------+ |
// | This source file is subject to version 2.02 of the PHP license, | |
// | that is bundled with this package in the file LICENSE, and is | |
// | available at through the world-wide-web at | |
// | http://www.php.net/license/2_02.txt. | |
// | If you did not receive a copy of the PHP license and are unable to | |
// | obtain it through the world-wide-web, please send a note to | |
// | license@php.net so we can mail you a copy immediately. | |
// +----------------------------------------------------------------------+ |
// | Authors: Martin Jansen <mj@php.net> | |
// | | |
// +----------------------------------------------------------------------+ |
// |
// $Id: RSS.php,v 1.1 2005-04-18 16:13:31 jpm Exp $ |
// |
require_once 'XML/Parser.php'; |
/** |
* RSS parser class. |
* |
* This class is a parser for Resource Description Framework (RDF) Site |
* Summary (RSS) documents. For more information on RSS see the |
* website of the RSS working group (http://www.purl.org/rss/). |
* |
* @author Martin Jansen <mj@php.net> |
* @version $Revision: 1.1 $ |
* @access public |
*/ |
class XML_RSS extends XML_Parser |
{ |
// {{{ properties |
/** |
* @var string |
*/ |
var $insideTag = ''; |
/** |
* @var string |
*/ |
var $activeTag = ''; |
/** |
* @var array |
*/ |
var $channel = array(); |
/** |
* @var array |
*/ |
var $items = array(); |
/** |
* @var array |
*/ |
var $item = array(); |
/** |
* @var array |
*/ |
var $image = array(); |
/** |
* @var array |
*/ |
var $textinput = array(); |
/** |
* @var array |
*/ |
var $textinputs = array(); |
/** |
* @var array |
*/ |
var $parentTags = array('CHANNEL', 'ITEM', 'IMAGE', 'TEXTINPUT'); |
/** |
* @var array |
*/ |
var $channelTags = array('TITLE', 'LINK', 'DESCRIPTION', 'IMAGE', |
'ITEMS', 'TEXTINPUT'); |
/** |
* @var array |
*/ |
var $itemTags = array('TITLE', 'LINK', 'DESCRIPTION', 'PUBDATE'); |
/** |
* @var array |
*/ |
var $imageTags = array('TITLE', 'URL', 'LINK'); |
var $textinputTags = array('TITLE', 'DESCRIPTION', 'NAME', 'LINK'); |
/** |
* List of allowed module tags |
* |
* Currently Dublin Core Metadata and the blogChannel RSS module |
* are supported. |
* |
* @var array |
*/ |
var $moduleTags = array('DC:TITLE', 'DC:CREATOR', 'DC:SUBJECT', 'DC:DESCRIPTION', |
'DC:PUBLISHER', 'DC:CONTRIBUTOR', 'DC:DATE', 'DC:TYPE', |
'DC:FORMAT', 'DC:IDENTIFIER', 'DC:SOURCE', 'DC:LANGUAGE', |
'DC:RELATION', 'DC:COVERAGE', 'DC:RIGHTS', |
'BLOGCHANNEL:BLOGROLL', 'BLOGCHANNEL:MYSUBSCRIPTIONS', |
'BLOGCHANNEL:MYSUBSCRIPTIONS', 'BLOGCHANNEL:CHANGES'); |
// }}} |
// {{{ Constructor |
/** |
* Constructor |
* |
* @access public |
* @param mixed File pointer or name of the RDF file. |
* @return void |
*/ |
function XML_RSS($handle = '') |
{ |
$this->XML_Parser(); |
if (@is_resource($handle)) { |
$this->setInput($handle); |
} elseif ($handle != '') { |
$this->setInputFile($handle); |
} else { |
$this->raiseError('No filename passed.'); |
} |
} |
// }}} |
// {{{ startHandler() |
/** |
* Start element handler for XML parser |
* |
* @access private |
* @param object XML parser object |
* @param string XML element |
* @param array Attributes of XML tag |
* @return void |
*/ |
function startHandler($parser, $element, $attribs) |
{ |
switch ($element) { |
case 'CHANNEL': |
case 'ITEM': |
case 'IMAGE': |
case 'TEXTINPUT': |
$this->insideTag = $element; |
break; |
default: |
$this->activeTag = $element; |
} |
} |
// }}} |
// {{{ endHandler() |
/** |
* End element handler for XML parser |
* |
* If the end of <item>, <channel>, <image> or <textinput> |
* is reached, this function updates the structure array |
* $this->struct[] and adds the field "type" to this array, |
* that defines the type of the current field. |
* |
* @access private |
* @param object XML parser object |
* @param string |
* @return void |
*/ |
function endHandler($parser, $element) |
{ |
if ($element == $this->insideTag) { |
$this->insideTag = ''; |
$this->struct[] = array_merge(array('type' => strtolower($element)), |
$this->last); |
} |
if ($element == 'ITEM') { |
$this->items[] = $this->item; |
$this->item = ''; |
} |
if ($element == 'IMAGE') { |
$this->images[] = $this->image; |
$this->image = ''; |
} |
if ($element == 'TEXTINPUT') { |
$this->textinputs = $this->textinput; |
$this->textinput = ''; |
} |
$this->activeTag = ''; |
} |
// }}} |
// {{{ cdataHandler() |
/** |
* Handler for character data |
* |
* @access private |
* @param object XML parser object |
* @param string CDATA |
* @return void |
*/ |
function cdataHandler($parser, $cdata) |
{ |
if (in_array($this->insideTag, $this->parentTags)) { |
$tagName = strtolower($this->insideTag); |
$var = $this->{$tagName . 'Tags'}; |
if (in_array($this->activeTag, $var) || |
in_array($this->activeTag, $this->moduleTags)) { |
$this->_add($tagName, strtolower($this->activeTag), |
$cdata); |
} |
} |
} |
// }}} |
// {{{ defaultHandler() |
/** |
* Default handler for XML parser |
* |
* @access private |
* @param object XML parser object |
* @param string CDATA |
* @return void |
*/ |
function defaultHandler($parser, $cdata) |
{ |
return; |
} |
// }}} |
// {{{ _add() |
/** |
* Add element to internal result sets |
* |
* @access private |
* @param string Name of the result set |
* @param string Fieldname |
* @param string Value |
* @return void |
* @see cdataHandler |
*/ |
function _add($type, $field, $value) |
{ |
if (empty($this->{$type}) || empty($this->{$type}[$field])) { |
$this->{$type}[$field] = $value; |
} else { |
$this->{$type}[$field] .= $value; |
} |
$this->last = $this->{$type}; |
} |
// }}} |
// {{{ getStructure() |
/** |
* Get complete structure of RSS file |
* |
* @access public |
* @return array |
*/ |
function getStructure() |
{ |
return (array)$this->struct; |
} |
// }}} |
// {{{ getchannelInfo() |
/** |
* Get general information about current channel |
* |
* This function returns an array containing the information |
* that has been extracted from the <channel>-tag while parsing |
* the RSS file. |
* |
* @access public |
* @return array |
*/ |
function getChannelInfo() |
{ |
return (array)$this->channel; |
} |
// }}} |
// {{{ getItems() |
/** |
* Get items from RSS file |
* |
* This function returns an array containing the set of items |
* that are provided by the RSS file. |
* |
* @access public |
* @return array |
*/ |
function getItems() |
{ |
return (array)$this->items; |
} |
// }}} |
// {{{ getImages() |
/** |
* Get images from RSS file |
* |
* This function returns an array containing the set of images |
* that are provided by the RSS file. |
* |
* @access public |
* @return array |
*/ |
function getImages() |
{ |
return (array)$this->images; |
} |
// }}} |
// {{{ getTextinputs() |
/** |
* Get text input fields from RSS file |
* |
* @access public |
* @return array |
*/ |
function getTextinputs() |
{ |
return (array)$this->textinputs; |
} |
// }}} |
} |
?> |
/branches/livraison_menes/api/pear/XML/Tree/Node.php |
---|
New file |
0,0 → 1,354 |
<?php |
// |
// +----------------------------------------------------------------------+ |
// | PHP Version 4 | |
// +----------------------------------------------------------------------+ |
// | Copyright (c) 1997-2002 The PHP Group | |
// +----------------------------------------------------------------------+ |
// | This source file is subject to version 2.02 of the PHP license, | |
// | that is bundled with this package in the file LICENSE, and is | |
// | available at through the world-wide-web at | |
// | http://www.php.net/license/2_02.txt. | |
// | If you did not receive a copy of the PHP license and are unable to | |
// | obtain it through the world-wide-web, please send a note to | |
// | license@php.net so we can mail you a copy immediately. | |
// +----------------------------------------------------------------------+ |
// | Authors: Bernd Römer <berndr@bonn.edu> | |
// | Sebastian Bergmann <sb@sebastian-bergmann.de> | |
// | Christian Kühn <ck@chkuehn.de> (escape xml entities) | |
// +----------------------------------------------------------------------+ |
// |
// $Id: Node.php,v 1.1 2005-04-18 16:13:31 jpm Exp $ |
// |
/** |
* PEAR::XML_Tree_Node |
* |
* @author Bernd Römer <berndr@bonn.edu> |
* @package XML_Tree |
* @version 1.0 16-Aug-2001 |
*/ |
class XML_Tree_Node { |
/** |
* Attributes of this node |
* |
* @var array |
*/ |
var $attributes; |
/** |
* Children of this node |
* |
* @var array |
*/ |
var $children; |
/** |
* Content |
* |
* @var string |
*/ |
var $content; |
/** |
* Name |
* |
* @var string |
*/ |
var $name; |
/** |
* Constructor |
* |
* @param string name |
* @param string content |
* @param array attributes |
*/ |
function XML_Tree_Node($name, $content = '', $attributes = array()) { |
$this->attributes = $attributes; |
$this->children = array(); |
$this->set_content($content); |
$this->name = $name; |
} |
/** |
* Adds a child node to this node. |
* |
* @param mixed child |
* @param string content |
* @param array attributes |
* @return object reference to new child node |
*/ |
function &addChild($child, $content = '', $attributes = array()) { |
$index = sizeof($this->children); |
if (is_object($child)) { |
if (strtolower(get_class($child)) == 'xml_tree_node') { |
$this->children[$index] = $child; |
} |
if (strtolower(get_class($child)) == 'xml_tree' && isset($child->root)) { |
$this->children[$index] = $child->root->get_element(); |
} |
} else { |
$this->children[$index] = new XML_Tree_Node($child, $content, $attributes); |
} |
return $this->children[$index]; |
} |
/** |
* @deprecated |
*/ |
function &add_child($child, $content = '', $attributes = array()) { |
return $this->addChild($child, $content, $attributes); |
} |
/** |
* clone node and all its children (recursive) |
* |
* @return object reference to the clone-node |
*/ |
function &clone() { |
$clone=new XML_Tree_Node($this->name,$this->content,$this->attributes); |
$max_child=count($this->children); |
for($i=0;$i<$max_child;$i++) { |
$clone->children[]=$this->children[$i]->clone(); |
} |
/* for future use.... |
// clone all other vars |
$temp=get_object_vars($this); |
foreach($temp as $varname => $value) |
if (!in_array($varname,array('name','content','attributes','children'))) |
$clone->$varname=$value; |
*/ |
return($clone); |
} |
/** |
* inserts child ($child) to a specified child-position ($pos) |
* |
* @return inserted node |
*/ |
function &insertChild($path,$pos,&$child, $content = '', $attributes = array()) { |
// direct insert of objects useing array_splice() faild :( |
array_splice($this->children,$pos,0,'dummy'); |
if (is_object($child)) { // child offered is not instanziated |
// insert a single node |
if (strtolower(get_class($child)) == 'xml_tree_node') { |
$this->children[$pos]=&$child; |
} |
// insert a tree i.e insert root-element |
if (strtolower(get_class($child)) == 'xml_tree' && isset($child->root)) { |
$this->children[$pos]=$child->root->get_element(); |
} |
} else { // child offered is not instanziated |
$this->children[$pos]=new XML_Tree_Node($child, $content, $attributes); |
} |
return($this); |
} |
/** |
* @deprecated |
*/ |
function &insert_child($path,$pos,&$child, $content = '', $attributes = array()) { |
return $this->insertChild($path,$pos,$child, $content, $attributes); |
} |
/** |
* removes child ($pos) |
* |
* @param integer pos position of child in children-list |
* |
* @return removed node |
*/ |
function &removeChild($pos) { |
// array_splice() instead of a simple unset() to maintain index-integrity |
return(array_splice($this->children,$pos,1)); |
} |
/** |
* @deprecated |
*/ |
function &remove_child($pos) { |
return $this->removeChild($pos); |
} |
/** |
* Returns text representation of this node. |
* |
* @return string xml |
*/ |
function &get() |
{ |
static $deep = -1; |
static $do_ident = true; |
$deep++; |
if ($this->name !== null) { |
$ident = str_repeat(' ', $deep); |
if ($do_ident) { |
$out = $ident . '<' . $this->name; |
} else { |
$out = '<' . $this->name; |
} |
foreach ($this->attributes as $name => $value) { |
$out .= ' ' . $name . '="' . $value . '"'; |
} |
$out .= '>' . $this->content; |
if (sizeof($this->children) > 0) { |
$out .= "\n"; |
foreach ($this->children as $child) { |
$out .= $child->get(); |
} |
} else { |
$ident = ''; |
} |
if ($do_ident) { |
$out .= $ident . '</' . $this->name . ">\n"; |
} else { |
$out .= '</' . $this->name . '>'; |
} |
$do_ident = true; |
} else { |
$out = $this->content; |
$do_ident = false; |
} |
$deep--; |
return $out; |
} |
/** |
* Gets an attribute by its name. |
* |
* @param string name |
* @return string attribute |
*/ |
function getAttribute($name) { |
return $this->attributes[strtolower($name)]; |
} |
/** |
* @deprecated |
*/ |
function get_attribute($name) { |
return $this->getAttribute($name); |
} |
/** |
* Gets an element by its 'path'. |
* |
* @param string path |
* @return object element |
*/ |
function &getElement($path) { |
if (sizeof($path) == 0) { |
return $this; |
} |
$next = array_shift($path); |
return $this->children[$next]->get_element($path); |
} |
/** |
* @deprecated |
*/ |
function &get_element($path) { |
return $this->getElement($path); |
} |
/** |
* Sets an attribute. |
* |
* @param string name |
* @param string value |
*/ |
function setAttribute($name, $value = '') { |
$this->attributes[strtolower($name)] = $value; |
} |
/** |
* @deprecated |
*/ |
function set_attribute($name, $value = '') { |
return $this->setAttribute($name, $value); |
} |
/** |
* Unsets an attribute. |
* |
* @param string name |
*/ |
function unsetAttribute($name) { |
unset($this->attributes[strtolower($name)]); |
} |
/** |
* @deprecated |
*/ |
function unset_attribute($name) { |
return $this->unsetAttribute($name); |
} |
/** |
* |
* |
*/ |
function setContent(&$content) |
{ |
$this->content = $this->_xml_entities($content); |
} |
function set_content(&$content) |
{ |
return $this->setContent($content); |
} |
/** |
* Escape XML entities. |
* |
* @param string xml |
* @return string xml |
* @access private |
*/ |
function _xml_entities($xml) { |
$xml = str_replace(array('ü', 'Ü', 'ö', |
'Ö', 'ä', 'Ä', |
'ß' |
), |
array('ü', 'Ü', 'ö', |
'Ö', 'ä', 'Ä', |
'ß' |
), |
$xml |
); |
$xml = preg_replace(array("/\&([a-z\d\#]+)\;/i", |
"/\&/", |
"/\#\|\|([a-z\d\#]+)\|\|\#/i", |
"/([^a-zA-Z\d\s\<\>\&\;\.\:\=\"\-\/\%\?\!\'\(\)\[\]\{\}\$\#\+\,\@_])/e" |
), |
array("#||\\1||#", |
"&", |
"&\\1;", |
"'&#'.ord('\\1').';'" |
), |
$xml |
); |
return $xml; |
} |
/** |
* Print text representation of XML tree. |
*/ |
function dump() { |
echo $this->get(); |
} |
} |
?> |
/branches/livraison_menes/api/pear/XML/Parser.php |
---|
New file |
0,0 → 1,684 |
<?php |
// |
// +----------------------------------------------------------------------+ |
// | PHP Version 4 | |
// +----------------------------------------------------------------------+ |
// | Copyright (c) 1997-2004 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 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. | |
// +----------------------------------------------------------------------+ |
// | Author: Stig Bakken <ssb@fast.no> | |
// | Tomas V.V.Cox <cox@idecnet.com> | |
// | Stephan Schmidt <schst@php-tools.net> | |
// +----------------------------------------------------------------------+ |
// |
// $Id: Parser.php,v 1.1 2005-04-18 16:13:31 jpm Exp $ |
/** |
* XML Parser class. |
* |
* This is an XML parser based on PHP's "xml" extension, |
* based on the bundled expat library. |
* |
* @category XML |
* @package XML_Parser |
* @author Stig Bakken <ssb@fast.no> |
* @author Tomas V.V.Cox <cox@idecnet.com> |
* @author Stephan Schmidt <schst@php-tools.net> |
*/ |
/** |
* uses PEAR's error handling |
*/ |
require_once 'PEAR.php'; |
/** |
* resource could not be created |
*/ |
define('XML_PARSER_ERROR_NO_RESOURCE', 200); |
/** |
* unsupported mode |
*/ |
define('XML_PARSER_ERROR_UNSUPPORTED_MODE', 201); |
/** |
* invalid encoding was given |
*/ |
define('XML_PARSER_ERROR_INVALID_ENCODING', 202); |
/** |
* specified file could not be read |
*/ |
define('XML_PARSER_ERROR_FILE_NOT_READABLE', 203); |
/** |
* invalid input |
*/ |
define('XML_PARSER_ERROR_INVALID_INPUT', 204); |
/** |
* remote file cannot be retrieved in safe mode |
*/ |
define('XML_PARSER_ERROR_REMOTE', 205); |
/** |
* XML Parser class. |
* |
* This is an XML parser based on PHP's "xml" extension, |
* based on the bundled expat library. |
* |
* Notes: |
* - It requires PHP 4.0.4pl1 or greater |
* - From revision 1.17, the function names used by the 'func' mode |
* are in the format "xmltag_$elem", for example: use "xmltag_name" |
* to handle the <name></name> tags of your xml file. |
* |
* @category XML |
* @package XML_Parser |
* @author Stig Bakken <ssb@fast.no> |
* @author Tomas V.V.Cox <cox@idecnet.com> |
* @author Stephan Schmidt <schst@php-tools.net> |
* @todo create XML_Parser_Namespace to parse documents with namespaces |
* @todo create XML_Parser_Pull |
* @todo Tests that need to be made: |
* - mixing character encodings |
* - a test using all expat handlers |
* - options (folding, output charset) |
* - different parsing modes |
*/ |
class XML_Parser extends PEAR |
{ |
// {{{ properties |
/** |
* XML parser handle |
* |
* @var resource |
* @see xml_parser_create() |
*/ |
var $parser; |
/** |
* File handle if parsing from a file |
* |
* @var resource |
*/ |
var $fp; |
/** |
* Whether to do case folding |
* |
* If set to true, all tag and attribute names will |
* be converted to UPPER CASE. |
* |
* @var boolean |
*/ |
var $folding = true; |
/** |
* Mode of operation, one of "event" or "func" |
* |
* @var string |
*/ |
var $mode; |
/** |
* Mapping from expat handler function to class method. |
* |
* @var array |
*/ |
var $handler = array( |
'character_data_handler' => 'cdataHandler', |
'default_handler' => 'defaultHandler', |
'processing_instruction_handler' => 'piHandler', |
'unparsed_entity_decl_handler' => 'unparsedHandler', |
'notation_decl_handler' => 'notationHandler', |
'external_entity_ref_handler' => 'entityrefHandler' |
); |
/** |
* source encoding |
* |
* @var string |
*/ |
var $srcenc; |
/** |
* target encoding |
* |
* @var string |
*/ |
var $tgtenc; |
/** |
* handler object |
* |
* @var object |
*/ |
var $_handlerObj; |
// }}} |
// {{{ constructor |
/** |
* Creates an XML parser. |
* |
* This is needed for PHP4 compatibility, it will |
* call the constructor, when a new instance is created. |
* |
* @param string $srcenc source charset encoding, use NULL (default) to use |
* whatever the document specifies |
* @param string $mode how this parser object should work, "event" for |
* startelement/endelement-type events, "func" |
* to have it call functions named after elements |
* @param string $tgenc a valid target encoding |
*/ |
function XML_Parser($srcenc = null, $mode = 'event', $tgtenc = null) |
{ |
XML_Parser::__construct($srcenc, $mode, $tgtenc); |
} |
// }}} |
/** |
* PHP5 constructor |
* |
* @param string $srcenc source charset encoding, use NULL (default) to use |
* whatever the document specifies |
* @param string $mode how this parser object should work, "event" for |
* startelement/endelement-type events, "func" |
* to have it call functions named after elements |
* @param string $tgenc a valid target encoding |
*/ |
function __construct($srcenc = null, $mode = 'event', $tgtenc = null) |
{ |
$this->PEAR('XML_Parser_Error'); |
$this->mode = $mode; |
$this->srcenc = $srcenc; |
$this->tgtenc = $tgtenc; |
} |
// }}} |
/** |
* Sets the mode of the parser. |
* |
* Possible modes are: |
* - func |
* - event |
* |
* You can set the mode using the second parameter |
* in the constructor. |
* |
* This method is only needed, when switching to a new |
* mode at a later point. |
* |
* @access public |
* @param string mode, either 'func' or 'event' |
* @return boolean|object true on success, PEAR_Error otherwise |
*/ |
function setMode($mode) |
{ |
if ($mode != 'func' && $mode != 'event') { |
$this->raiseError('Unsupported mode given', XML_PARSER_ERROR_UNSUPPORTED_MODE); |
} |
$this->mode = $mode; |
return true; |
} |
/** |
* Sets the object, that will handle the XML events |
* |
* This allows you to create a handler object independent of the |
* parser object that you are using and easily switch the underlying |
* parser. |
* |
* If no object will be set, XML_Parser assumes that you |
* extend this class and handle the events in $this. |
* |
* @access public |
* @param object object to handle the events |
* @return boolean will always return true |
* @since v1.2.0beta3 |
*/ |
function setHandlerObj(&$obj) |
{ |
$this->_handlerObj = &$obj; |
return true; |
} |
/** |
* Init the element handlers |
* |
* @access private |
*/ |
function _initHandlers() |
{ |
if (!is_resource($this->parser)) { |
return false; |
} |
if (!is_object($this->_handlerObj)) { |
$this->_handlerObj = &$this; |
} |
switch ($this->mode) { |
case 'func': |
xml_set_object($this->parser, $this->_handlerObj); |
xml_set_element_handler($this->parser, array(&$this, 'funcStartHandler'), array(&$this, 'funcEndHandler')); |
break; |
case 'event': |
xml_set_object($this->parser, $this->_handlerObj); |
xml_set_element_handler($this->parser, 'startHandler', 'endHandler'); |
break; |
default: |
return $this->raiseError('Unsupported mode given', XML_PARSER_ERROR_UNSUPPORTED_MODE); |
break; |
} |
/** |
* set additional handlers for character data, entities, etc. |
*/ |
foreach ($this->handler as $xml_func => $method) { |
if (method_exists($this->_handlerObj, $method)) { |
$xml_func = 'xml_set_' . $xml_func; |
$xml_func($this->parser, $method); |
} |
} |
} |
// {{{ _create() |
/** |
* create the XML parser resource |
* |
* Has been moved from the constructor to avoid |
* problems with object references. |
* |
* Furthermore it allows us returning an error |
* if something fails. |
* |
* @access private |
* @return boolean|object true on success, PEAR_Error otherwise |
* |
* @see xml_parser_create |
*/ |
function _create() |
{ |
if ($this->srcenc === null) { |
$xp = @xml_parser_create(); |
} else { |
$xp = @xml_parser_create($this->srcenc); |
} |
if (is_resource($xp)) { |
if ($this->tgtenc !== null) { |
if (!@xml_parser_set_option($xp, XML_OPTION_TARGET_ENCODING, |
$this->tgtenc)) { |
return $this->raiseError('invalid target encoding', XML_PARSER_ERROR_INVALID_ENCODING); |
} |
} |
$this->parser = $xp; |
$result = $this->_initHandlers($this->mode); |
if ($this->isError($result)) { |
return $result; |
} |
xml_parser_set_option($xp, XML_OPTION_CASE_FOLDING, $this->folding); |
return true; |
} |
return $this->raiseError('Unable to create XML parser resource.', XML_PARSER_ERROR_NO_RESOURCE); |
} |
// }}} |
// {{{ reset() |
/** |
* Reset the parser. |
* |
* This allows you to use one parser instance |
* to parse multiple XML documents. |
* |
* @access public |
* @return boolean|object true on success, PEAR_Error otherwise |
*/ |
function reset() |
{ |
$result = $this->_create(); |
if ($this->isError( $result )) { |
return $result; |
} |
return true; |
} |
// }}} |
// {{{ setInputFile() |
/** |
* Sets the input xml file to be parsed |
* |
* @param string Filename (full path) |
* @return resource fopen handle of the given file |
* @throws XML_Parser_Error |
* @see setInput(), setInputString(), parse() |
* @access public |
*/ |
function setInputFile($file) |
{ |
/** |
* check, if file is a remote file |
*/ |
if (eregi('^(http|ftp)://', substr($file, 0, 10))) { |
if (!ini_get('allow_url_fopen')) { |
return $this->raiseError('Remote files cannot be parsed, as safe mode is enabled.', XML_PARSER_ERROR_REMOTE); |
} |
} |
$fp = @fopen($file, 'rb'); |
if (is_resource($fp)) { |
$this->fp = $fp; |
return $fp; |
} |
return $this->raiseError('File could not be opened.', XML_PARSER_ERROR_FILE_NOT_READABLE); |
} |
// }}} |
// {{{ setInputString() |
/** |
* XML_Parser::setInputString() |
* |
* Sets the xml input from a string |
* |
* @param string $data a string containing the XML document |
* @return null |
**/ |
function setInputString($data) |
{ |
$this->fp = $data; |
return null; |
} |
// }}} |
// {{{ setInput() |
/** |
* Sets the file handle to use with parse(). |
* |
* You should use setInputFile() or setInputString() if you |
* pass a string |
* |
* @param mixed $fp Can be either a resource returned from fopen(), |
* a URL, a local filename or a string. |
* @access public |
* @see parse() |
* @uses setInputString(), setInputFile() |
*/ |
function setInput($fp) |
{ |
if (is_resource($fp)) { |
$this->fp = $fp; |
return true; |
} |
// see if it's an absolute URL (has a scheme at the beginning) |
elseif (eregi('^[a-z]+://', substr($fp, 0, 10))) { |
return $this->setInputFile($fp); |
} |
// see if it's a local file |
elseif (file_exists($fp)) { |
return $this->setInputFile($fp); |
} |
// it must be a string |
else { |
$this->fp = $fp; |
return true; |
} |
return $this->raiseError('Illegal input format', XML_PARSER_ERROR_INVALID_INPUT); |
} |
// }}} |
// {{{ parse() |
/** |
* Central parsing function. |
* |
* @return true|object PEAR error returns true on success, or a PEAR_Error otherwise |
* @access public |
*/ |
function parse() |
{ |
/** |
* reset the parser |
*/ |
$result = $this->reset(); |
if ($this->isError($result)) { |
return $result; |
} |
// if $this->fp was fopened previously |
if (is_resource($this->fp)) { |
while ($data = fread($this->fp, 4096)) { |
if (!$this->_parseString($data, feof($this->fp))) { |
$error = &$this->raiseError(); |
$this->free(); |
return $error; |
} |
} |
// otherwise, $this->fp must be a string |
} else { |
if (!$this->_parseString($this->fp, true)) { |
$error = &$this->raiseError(); |
$this->free(); |
return $error; |
} |
} |
$this->free(); |
return true; |
} |
/** |
* XML_Parser::_parseString() |
* |
* @param string $data |
* @param boolean $eof |
* @return bool |
* @access private |
* @see parseString() |
**/ |
function _parseString($data, $eof = false) |
{ |
return xml_parse($this->parser, $data, $eof); |
} |
// }}} |
// {{{ parseString() |
/** |
* XML_Parser::parseString() |
* |
* Parses a string. |
* |
* @param string $data XML data |
* @param boolean $eof If set and TRUE, data is the last piece of data sent in this parser |
* @throws XML_Parser_Error |
* @return Pear Error|true true on success or a PEAR Error |
* @see _parseString() |
*/ |
function parseString($data, $eof = false) |
{ |
if (!isset($this->parser) || !is_resource($this->parser)) { |
$this->reset(); |
} |
if (!$this->_parseString($data, $eof)) { |
$error = &$this->raiseError(); |
$this->free(); |
return $error; |
} |
if ($eof === true) { |
$this->free(); |
} |
return true; |
} |
/** |
* XML_Parser::free() |
* |
* Free the internal resources associated with the parser |
* |
* @return null |
**/ |
function free() |
{ |
if (isset($this->parser) && is_resource($this->parser)) { |
xml_parser_free($this->parser); |
unset( $this->parser ); |
} |
if (isset($this->fp) && is_resource($this->fp)) { |
fclose($this->fp); |
} |
unset($this->fp); |
return null; |
} |
/** |
* XML_Parser::raiseError() |
* |
* Throws a XML_Parser_Error |
* |
* @param string $msg the error message |
* @param integer $ecode the error message code |
* @return XML_Parser_Error |
**/ |
function raiseError($msg = null, $ecode = 0) |
{ |
$msg = !is_null($msg) ? $msg : $this->parser; |
$err = &new XML_Parser_Error($msg, $ecode); |
return parent::raiseError($err); |
} |
// }}} |
// {{{ funcStartHandler() |
function funcStartHandler($xp, $elem, $attribs) |
{ |
$func = 'xmltag_' . $elem; |
if (strchr($func, '.')) { |
$func = str_replace('.', '_', $func); |
} |
if (method_exists($this->_handlerObj, $func)) { |
call_user_func(array(&$this->_handlerObj, $func), $xp, $elem, $attribs); |
} elseif (method_exists($this->_handlerObj, 'xmltag')) { |
call_user_func(array(&$this->_handlerObj, 'xmltag'), $xp, $elem, $attribs); |
} |
} |
// }}} |
// {{{ funcEndHandler() |
function funcEndHandler($xp, $elem) |
{ |
$func = 'xmltag_' . $elem . '_'; |
if (strchr($func, '.')) { |
$func = str_replace('.', '_', $func); |
} |
if (method_exists($this->_handlerObj, $func)) { |
call_user_func(array(&$this->_handlerObj, $func), $xp, $elem); |
} elseif (method_exists($this->_handlerObj, 'xmltag_')) { |
call_user_func(array(&$this->_handlerObj, 'xmltag_'), $xp, $elem); |
} |
} |
// }}} |
// {{{ startHandler() |
/** |
* |
* @abstract |
*/ |
function startHandler($xp, $elem, &$attribs) |
{ |
return NULL; |
} |
// }}} |
// {{{ endHandler() |
/** |
* |
* @abstract |
*/ |
function endHandler($xp, $elem) |
{ |
return NULL; |
} |
// }}}me |
} |
/** |
* error class, replaces PEAR_Error |
* |
* An instance of this class will be returned |
* if an error occurs inside XML_Parser. |
* |
* There are three advantages over using the standard PEAR_Error: |
* - All messages will be prefixed |
* - check for XML_Parser error, using is_a( $error, 'XML_Parser_Error' ) |
* - messages can be generated from the xml_parser resource |
* |
* @package XML_Parser |
* @access public |
* @see PEAR_Error |
*/ |
class XML_Parser_Error extends PEAR_Error |
{ |
// {{{ properties |
/** |
* prefix for all messages |
* |
* @var string |
*/ |
var $error_message_prefix = 'XML_Parser: '; |
// }}} |
// {{{ constructor() |
/** |
* construct a new error instance |
* |
* You may either pass a message or an xml_parser resource as first |
* parameter. If a resource has been passed, the last error that |
* happened will be retrieved and returned. |
* |
* @access public |
* @param string|resource message or parser resource |
* @param integer error code |
* @param integer error handling |
* @param integer error level |
*/ |
function XML_Parser_Error($msgorparser = 'unknown error', $code = 0, $mode = PEAR_ERROR_RETURN, $level = E_USER_NOTICE) |
{ |
if (is_resource($msgorparser)) { |
$code = xml_get_error_code($msgorparser); |
$msgorparser = sprintf('%s at XML input line %d', |
xml_error_string($code), |
xml_get_current_line_number($msgorparser)); |
} |
$this->PEAR_Error($msgorparser, $code, $mode, $level); |
} |
// }}} |
} |
?> |
/branches/livraison_menes/api/pear/Auth/Container/DB.php |
---|
New file |
0,0 → 1,409 |
<?php |
// |
// +----------------------------------------------------------------------+ |
// | PHP Version 4 | |
// +----------------------------------------------------------------------+ |
// | | |
// +----------------------------------------------------------------------+ |
// | This source file is subject to version 2.02 of the PHP license, | |
// | that is bundled with this package in the file LICENSE, and is | |
// | available at through the world-wide-web at | |
// | http://www.php.net/license/2_02.txt. | |
// | If you did not receive a copy of the PHP license and are unable to | |
// | obtain it through the world-wide-web, please send a note to | |
// | license@php.net so we can mail you a copy immediately. | |
// +----------------------------------------------------------------------+ |
// | Authors: Martin Jansen <mj@php.net> | |
// +----------------------------------------------------------------------+ |
// |
// $Id: DB.php,v 1.1 2005-03-30 08:50:33 jpm Exp $ |
// |
require_once 'Auth/Container.php'; |
require_once 'DB.php'; |
/** |
* Storage driver for fetching login data from a database |
* |
* This storage driver can use all databases which are supported |
* by the PEAR DB abstraction layer to fetch login data. |
* |
* @author Martin Jansen <mj@php.net> |
* @package Auth |
* @version $Revision: 1.1 $ |
*/ |
class Auth_Container_DB extends Auth_Container |
{ |
/** |
* Additional options for the storage container |
* @var array |
*/ |
var $options = array(); |
/** |
* DB object |
* @var object |
*/ |
var $db = null; |
var $dsn = ''; |
/** |
* User that is currently selected from the DB. |
* @var string |
*/ |
var $activeUser = ''; |
// {{{ Constructor |
/** |
* Constructor of the container class |
* |
* Initate connection to the database via PEAR::DB |
* |
* @param string Connection data or DB object |
* @return object Returns an error object if something went wrong |
*/ |
function Auth_Container_DB($dsn) |
{ |
$this->_setDefaults(); |
if (is_array($dsn)) { |
$this->_parseOptions($dsn); |
if (empty($this->options['dsn'])) { |
PEAR::raiseError('No connection parameters specified!'); |
} |
} else { |
$this->options['dsn'] = $dsn; |
} |
} |
// }}} |
// {{{ _connect() |
/** |
* Connect to database by using the given DSN string |
* |
* @access private |
* @param string DSN string |
* @return mixed Object on error, otherwise bool |
*/ |
function _connect($dsn) |
{ |
if (is_string($dsn) || is_array($dsn)) { |
$this->db = DB::Connect($dsn); |
} elseif (get_parent_class($dsn) == "db_common") { |
$this->db = $dsn; |
} elseif (DB::isError($dsn)) { |
return PEAR::raiseError($dsn->getMessage(), $dsn->getCode()); |
} else { |
return PEAR::raiseError('The given dsn was not valid in file ' . __FILE__ . ' at line ' . __LINE__, |
41, |
PEAR_ERROR_RETURN, |
null, |
null |
); |
} |
if (DB::isError($this->db) || PEAR::isError($this->db)) { |
return PEAR::raiseError($this->db->getMessage(), $this->db->getCode()); |
} else { |
return true; |
} |
} |
// }}} |
// {{{ _prepare() |
/** |
* Prepare database connection |
* |
* This function checks if we have already opened a connection to |
* the database. If that's not the case, a new connection is opened. |
* |
* @access private |
* @return mixed True or a DB error object. |
*/ |
function _prepare() |
{ |
if (!DB::isConnection($this->db)) { |
$res = $this->_connect($this->options['dsn']); |
if(DB::isError($res) || PEAR::isError($res)){ |
return $res; |
} |
} |
return true; |
} |
// }}} |
// {{{ query() |
/** |
* Prepare query to the database |
* |
* This function checks if we have already opened a connection to |
* the database. If that's not the case, a new connection is opened. |
* After that the query is passed to the database. |
* |
* @access public |
* @param string Query string |
* @return mixed a DB_result object or DB_OK on success, a DB |
* or PEAR error on failure |
*/ |
function query($query) |
{ |
$err = $this->_prepare(); |
if ($err !== true) { |
return $err; |
} |
return $this->db->query($query); |
} |
// }}} |
// {{{ _setDefaults() |
/** |
* Set some default options |
* |
* @access private |
* @return void |
*/ |
function _setDefaults() |
{ |
$this->options['table'] = 'auth'; |
$this->options['usernamecol'] = 'username'; |
$this->options['passwordcol'] = 'password'; |
$this->options['dsn'] = ''; |
$this->options['db_fields'] = ''; |
$this->options['cryptType'] = 'md5'; |
} |
// }}} |
// {{{ _parseOptions() |
/** |
* Parse options passed to the container class |
* |
* @access private |
* @param array |
*/ |
function _parseOptions($array) |
{ |
foreach ($array as $key => $value) { |
if (isset($this->options[$key])) { |
$this->options[$key] = $value; |
} |
} |
/* Include additional fields if they exist */ |
if(!empty($this->options['db_fields'])){ |
if(is_array($this->options['db_fields'])){ |
$this->options['db_fields'] = join($this->options['db_fields'], ', '); |
} |
$this->options['db_fields'] = ', '.$this->options['db_fields']; |
} |
} |
// }}} |
// {{{ fetchData() |
/** |
* Get user information from database |
* |
* This function uses the given username to fetch |
* the corresponding login data from the database |
* table. If an account that matches the passed username |
* and password is found, the function returns true. |
* Otherwise it returns false. |
* |
* @param string Username |
* @param string Password |
* @return mixed Error object or boolean |
*/ |
function fetchData($username, $password) |
{ |
// Prepare for a database query |
$err = $this->_prepare(); |
if ($err !== true) { |
return PEAR::raiseError($err->getMessage(), $err->getCode()); |
} |
// Find if db_fileds contains a *, i so assume all col are selected |
if(strstr($this->options['db_fields'], '*')){ |
$sql_from = "*"; |
} |
else{ |
$sql_from = $this->options['usernamecol'] . ", ".$this->options['passwordcol'].$this->options['db_fields']; |
} |
/** |
Old Style, removed to go around the oci8 |
problem |
See bug 206 |
http://pear.php.net/bugs/bug.php?id=206 |
$query = "SELECT ! FROM ! WHERE ! = ?"; |
$query_params = array( |
$sql_from, |
$this->options['table'], |
$this->options['usernamecol'], |
$username |
); |
*/ |
$query = "SELECT ".$sql_from. |
" FROM ".$this->options['table']. |
" WHERE ".$this->options['usernamecol']." = '".$this->db->quoteString($username)."'"; |
$res = $this->db->getRow($query, null, DB_FETCHMODE_ASSOC); |
if (DB::isError($res)) { |
return PEAR::raiseError($res->getMessage(), $res->getCode()); |
} |
if (!is_array($res)) { |
$this->activeUser = ''; |
return false; |
} |
if ($this->verifyPassword(trim($password, "\r\n"), |
trim($res[$this->options['passwordcol']], "\r\n"), |
$this->options['cryptType'])) { |
// Store additional field values in the session |
foreach ($res as $key => $value) { |
if ($key == $this->options['passwordcol'] || |
$key == $this->options['usernamecol']) { |
continue; |
} |
// Use reference to the auth object if exists |
// This is because the auth session variable can change so a static call to setAuthData does not make sence |
if(is_object($this->_auth_obj)){ |
$this->_auth_obj->setAuthData($key, $value); |
} else { |
Auth::setAuthData($key, $value); |
} |
} |
return true; |
} |
$this->activeUser = $res[$this->options['usernamecol']]; |
return false; |
} |
// }}} |
// {{{ listUsers() |
function listUsers() |
{ |
$err = $this->_prepare(); |
if ($err !== true) { |
return PEAR::raiseError($err->getMessage(), $err->getCode()); |
} |
$retVal = array(); |
// Find if db_fileds contains a *, i so assume all col are selected |
if(strstr($this->options['db_fields'], '*')){ |
$sql_from = "*"; |
} |
else{ |
$sql_from = $this->options['usernamecol'] . ", ".$this->options['passwordcol'].$this->options['db_fields']; |
} |
$query = sprintf("SELECT %s FROM %s", |
$sql_from, |
$this->options['table'] |
); |
$res = $this->db->getAll($query, null, DB_FETCHMODE_ASSOC); |
if (DB::isError($res)) { |
return PEAR::raiseError($res->getMessage(), $res->getCode()); |
} else { |
foreach ($res as $user) { |
$user['username'] = $user[$this->options['usernamecol']]; |
$retVal[] = $user; |
} |
} |
return $retVal; |
} |
// }}} |
// {{{ addUser() |
/** |
* Add user to the storage container |
* |
* @access public |
* @param string Username |
* @param string Password |
* @param mixed Additional information that are stored in the DB |
* |
* @return mixed True on success, otherwise error object |
*/ |
function addUser($username, $password, $additional = "") |
{ |
if (function_exists($this->options['cryptType'])) { |
$cryptFunction = $this->options['cryptType']; |
} else { |
$cryptFunction = 'md5'; |
} |
$additional_key = ''; |
$additional_value = ''; |
if (is_array($additional)) { |
foreach ($additional as $key => $value) { |
$additional_key .= ', ' . $key; |
$additional_value .= ", '" . $value . "'"; |
} |
} |
$query = sprintf("INSERT INTO %s (%s, %s%s) VALUES ('%s', '%s'%s)", |
$this->options['table'], |
$this->options['usernamecol'], |
$this->options['passwordcol'], |
$additional_key, |
$username, |
$cryptFunction($password), |
$additional_value |
); |
$res = $this->query($query); |
if (DB::isError($res)) { |
return PEAR::raiseError($res->getMessage(), $res->getCode()); |
} else { |
return true; |
} |
} |
// }}} |
// {{{ removeUser() |
/** |
* Remove user from the storage container |
* |
* @access public |
* @param string Username |
* |
* @return mixed True on success, otherwise error object |
*/ |
function removeUser($username) |
{ |
$query = sprintf("DELETE FROM %s WHERE %s = '%s'", |
$this->options['table'], |
$this->options['usernamecol'], |
$username |
); |
$res = $this->query($query); |
if (DB::isError($res)) { |
return PEAR::raiseError($res->getMessage(), $res->getCode()); |
} else { |
return true; |
} |
} |
// }}} |
} |
?> |
/branches/livraison_menes/api/pear/Auth/Container/IMAP.php |
---|
New file |
0,0 → 1,170 |
<?php |
// |
// +----------------------------------------------------------------------+ |
// | PHP Version 4 | |
// +----------------------------------------------------------------------+ |
// | Copyright (c) 1997-2003 The PHP Group | |
// +----------------------------------------------------------------------+ |
// | This source file is subject to version 2.02 of the PHP license, | |
// | that is bundled with this package in the file LICENSE, and is | |
// | available at through the world-wide-web at | |
// | http://www.php.net/license/2_02.txt. | |
// | If you did not receive a copy of the PHP license and are unable to | |
// | obtain it through the world-wide-web, please send a note to | |
// | license@php.net so we can mail you a copy immediately. | |
// +----------------------------------------------------------------------+ |
// | Authors: Jeroen Houben <jeroen@terena.nl> | |
// +----------------------------------------------------------------------+ |
// |
// $Id: IMAP.php,v 1.1 2005-03-30 08:50:33 jpm Exp $ |
// |
require_once "Auth/Container.php"; |
require_once "PEAR.php"; |
/** |
* Storage driver for fetching login data from an IMAP server |
* |
* This class is based on LDAP containers, but it very simple. |
* By default it connects to localhost:143 |
* The constructor will first check if the host:port combination is |
* actually reachable. This behaviour can be disabled. |
* It then tries to create an IMAP stream (without opening a mailbox) |
* If you wish to pass extended options to the connections, you may |
* do so by specifying protocol options. |
* |
* To use this storage containers, you have to use the |
* following syntax: |
* |
* <?php |
* ... |
* $params = array( |
* 'host' => 'mail.example.com', |
* 'port' => 143, |
* ); |
* $myAuth = new Auth('IMAP', $params); |
* .... |
* |
* By default we connect without any protocol options set. However, some |
* servers require you to connect with the notls or norsh options set. |
* To do this you need to add the following value to the params array: |
* 'baseDSN' => '/imap/notls/norsh' |
* |
* To connect to an SSL IMAP server: |
* 'baseDSN' => '/imap/ssl' |
* |
* To connect to an SSL IMAP server with a self-signed certificate: |
* 'baseDSN' => '/imap/ssl/novalidate-cert' |
* |
* Further options may be available and can be found on the php site at |
* http://www.php.net/manual/function.imap-open.php |
* |
*/ |
/* |
* |
* @author Jeroen Houben <jeroen@terena.nl>, Cipriano Groenendal <cipri@campai.nl> |
* @package Auth |
* @version $Revision: 1.1 $ |
*/ |
class Auth_Container_IMAP extends Auth_Container |
{ |
/** |
* Options for the class |
* @var array |
*/ |
var $options = array(); |
/** |
* Constructor of the container class |
* |
* @param $params, associative hash with host,port,basedn and userattr key |
* @param $params, associative array with host, port, baseDSN, checkServer key. |
* @return object Returns an error object if something went wrong |
*/ |
function Auth_Container_IMAP($params) |
{ |
if (!extension_loaded('imap')) { |
return PEAR::raiseError("Cannot use IMAP authentication, IMAP extension not loaded!", |
41, PEAR_ERROR_DIE); |
} |
$this->_setDefaults(); |
// set parameters (if any) |
if (is_array($params)) { |
$this->_parseOptions($params); |
} |
if ($this->options['checkServer']) { |
$this->_checkServer($this->options['timeout']); |
} |
return true; |
} |
/** |
* Set some default options |
* |
* @access private |
*/ |
function _setDefaults() |
{ |
$this->options['host'] = 'localhost'; |
$this->options['port'] = 143; |
$this->options['baseDSN'] = ''; |
$this->options['checkServer'] = true; |
$this->options['timeout'] = 20; |
} |
/** |
* Check if the given server and port are reachable |
* |
* @access private |
*/ |
function _checkServer() { |
$fp = @fsockopen ($this->options['host'], $this->options['port'], |
$errno, $errstr, $timeout); |
if (is_resource($fp)) { |
@fclose($fp); |
} else { |
$message = "Error connecting to IMAP server " |
. $this->options['host'] |
. ":" . $this->options['port']; |
return PEAR::raiseError($message, 41, PEAR_ERROR_DIE); |
} |
} |
/** |
* Parse options passed to the container class |
* |
* @access private |
* @param array |
*/ |
function _parseOptions($array) |
{ |
foreach ($array as $key => $value) { |
$this->options[$key] = $value; |
} |
} |
/** |
* Try to open a IMAP stream using $username / $password |
* |
* @param string Username |
* @param string Password |
* @return boolean |
*/ |
function fetchData($username, $password) |
{ |
$dsn = '{'.$this->options['host'].':'.$this->options['port'].$this->options['baseDSN'].'}'; |
$conn = @imap_open ($dsn, $username, $password, OP_HALFOPEN); |
if (is_resource($conn)){ |
$this->activeUser = $username; |
@imap_close($conn); |
return true; |
} else { |
$this->activeUser = ''; |
return false; |
} |
} |
} |
?> |
/branches/livraison_menes/api/pear/Auth/Container/RADIUS.php |
---|
New file |
0,0 → 1,154 |
<?php |
// |
// +----------------------------------------------------------------------+ |
// | PHP Version 4 | |
// +----------------------------------------------------------------------+ |
// | Copyright (c) 1997-2003 The PHP Group | |
// +----------------------------------------------------------------------+ |
// | This source file is subject to version 2.02 of the PHP license, | |
// | that is bundled with this package in the file LICENSE, and is | |
// | available at through the world-wide-web at | |
// | http://www.php.net/license/2_02.txt. | |
// | If you did not receive a copy of the PHP license and are unable to | |
// | obtain it through the world-wide-web, please send a note to | |
// | license@php.net so we can mail you a copy immediately. | |
// +----------------------------------------------------------------------+ |
// | Authors: Michael Bretterklieber <michael@bretterklieber.com> | |
// +----------------------------------------------------------------------+ |
// |
// $Id: RADIUS.php,v 1.1 2005-03-30 08:50:33 jpm Exp $ |
// |
require_once "Auth/Container.php"; |
require_once "Auth/RADIUS.php"; |
/** |
* Storage driver for authenticating users against RADIUS servers. |
* |
* @author Michael Bretterklieber <michael@bretterklieber.com> |
* @access public |
* @version $Revision: 1.1 $ |
*/ |
class Auth_Container_RADIUS extends Auth_Container |
{ |
/** |
* Contains a RADIUS object |
* @var object |
*/ |
var $radius; |
/** |
* Contains the authentication type |
* @var string |
*/ |
var $authtype; |
/** |
* Constructor of the container class. |
* |
* $options can have these keys: |
* 'servers' an array containing an array: servername, port, |
* sharedsecret, timeout, maxtries |
* 'configfile' The filename of the configuration file |
* 'authtype' The type of authentication, one of: PAP, CHAP_MD5, |
* MSCHAPv1, MSCHAPv2, default is PAP |
* |
* @param $options associative array |
* @return object Returns an error object if something went wrong |
*/ |
function Auth_Container_RADIUS($options) |
{ |
$this->authtype = 'PAP'; |
if (isset($options['authtype'])) { |
$this->authtype = $options['authtype']; |
} |
$classname = 'Auth_RADIUS_' . $this->authtype; |
if (!class_exists($classname)) { |
PEAR::raiseError("Unknown Authtype, please use on of: PAP, CHAP_MD5, MSCHAPv1, MSCHAPv2!", |
41, PEAR_ERROR_DIE); |
} |
$this->radius = new $classname; |
if (isset($options['configfile'])) { |
$this->radius->setConfigfile($options['configfile']); |
} |
$servers = $options['servers']; |
if (is_array($servers)) { |
foreach ($servers as $server) { |
$servername = $server[0]; |
$port = isset($server[1]) ? $server[1] : 0; |
$sharedsecret = isset($server[2]) ? $server[2] : 'testing123'; |
$timeout = isset($server[3]) ? $server[3] : 3; |
$maxtries = isset($server[4]) ? $server[4] : 3; |
$this->radius->addServer($servername, $port, $sharedsecret, $timeout, $maxtries); |
} |
} |
if (!$this->radius->start()) { |
PEAR::raiseError($this->radius->getError(), 41, PEAR_ERROR_DIE); |
} |
} |
/** |
* Authenticate |
* |
* @param string Username |
* @param string Password |
* @return bool true on success, false on reject |
*/ |
function fetchData($username, $password, $challenge = null) |
{ |
switch($this->authtype) { |
case 'CHAP_MD5': |
case 'MSCHAPv1': |
if (isset($challenge)) { |
echo $password; |
$this->radius->challenge = $challenge; |
$this->radius->chapid = 1; |
$this->radius->response = pack('H*', $password); |
} else { |
require_once 'Crypt_CHAP/CHAP.php'; |
$classname = 'Crypt_' . $this->authtype; |
$crpt = new $classname; |
$crpt->password = $password; |
$this->radius->challenge = $crpt->challenge; |
$this->radius->chapid = $crpt->chapid; |
$this->radius->response = $crpt->challengeResponse(); |
break; |
} |
case 'MSCHAPv2': |
require_once 'Crypt_CHAP/CHAP.php'; |
$crpt = new Crypt_MSCHAPv2; |
$crpt->username = $username; |
$crpt->password = $password; |
$this->radius->challenge = $crpt->authChallenge; |
$this->radius->peerChallenge = $crpt->peerChallenge; |
$this->radius->chapid = $crpt->chapid; |
$this->radius->response = $crpt->challengeResponse(); |
break; |
default: |
$this->radius->password = $password; |
break; |
} |
$this->radius->username = $username; |
$this->radius->putAuthAttributes(); |
$result = $this->radius->send(); |
if (PEAR::isError($result)) { |
return false; |
} |
$this->radius->getAttributes(); |
// just for debugging |
// $this->radius->dumpAttributes(); |
return $result; |
} |
} |
?> |
/branches/livraison_menes/api/pear/Auth/Container/vpopmail.php |
---|
New file |
0,0 → 1,66 |
<?PHP |
/* vim: set expandtab tabstop=4 shiftwidth=4: */ |
// +----------------------------------------------------------------------+ |
// | PHP Version 4 | |
// +----------------------------------------------------------------------+ |
// | Copyright (c) 1997-2003 The PHP Group | |
// +----------------------------------------------------------------------+ |
// | This source file is subject to version 2.02 of the PHP license, | |
// | that is bundled with this package in the file LICENSE, and is | |
// | available at through the world-wide-web at | |
// | http://www.php.net/license/2_02.txt. | |
// | If you did not receive a copy of the PHP license and are unable to | |
// | obtain it through the world-wide-web, please send a note to | |
// | license@php.net so we can mail you a copy immediately. | |
// +----------------------------------------------------------------------+ |
// | Author: Stanislav Grozev <tacho@orbitel.bg> | |
// +----------------------------------------------------------------------+ |
// |
// $Id: vpopmail.php,v 1.1 2005-03-30 08:50:33 jpm Exp $ |
// |
require_once "Auth/Container.php"; |
/** |
* Storage driver for fetching login data from vpopmail |
* |
* @author Stanislav Grozev <tacho@orbitel.bg> |
* @package Auth |
* @version $Revision: 1.1 $ |
*/ |
class Auth_Container_vpopmail extends Auth_Container { |
// {{{ Constructor |
/** |
* Constructor of the container class |
* |
* @return integer Always returns 1. |
*/ |
function Auth_Container_vpopmail() |
{ |
return 1; |
} |
// }}} |
// {{{ fetchData() |
/** |
* Get user information from vpopmail |
* |
* @param string Username - has to be valid email address |
* @param string Password |
* @return boolean |
*/ |
function fetchData($username, $password) |
{ |
$userdata = array(); |
$userdata = preg_split("/@/", $username, 2); |
$result = @vpopmail_auth_user($userdata[0], $userdata[1], $password); |
return $result; |
} |
// }}} |
} |
?> |
/branches/livraison_menes/api/pear/Auth/Container/File.php |
---|
New file |
0,0 → 1,200 |
<?php |
/* vim: set expandtab tabstop=4 shiftwidth=4: */ |
// +----------------------------------------------------------------------+ |
// | PHP Version 4 | |
// +----------------------------------------------------------------------+ |
// | Copyright (c) 1997-2003 The PHP Group | |
// +----------------------------------------------------------------------+ |
// | This source file is subject to version 2.02 of the PHP license, | |
// | that is bundled with this package in the file LICENSE, and is | |
// | available at through the world-wide-web at | |
// | http://www.php.net/license/2_02.txt. | |
// | If you did not receive a copy of the PHP license and are unable to | |
// | obtain it through the world-wide-web, please send a note to | |
// | license@php.net so we can mail you a copy immediately. | |
// +----------------------------------------------------------------------+ |
// | Authors: Stefan Ekman <stekman@sedata.org> | |
// | Martin Jansen <mj@php.net> | |
// | Mika Tuupola <tuupola@appelsiini.net> | |
// +----------------------------------------------------------------------+ |
// |
// $Id: File.php,v 1.1 2005-03-30 08:50:33 jpm Exp $ |
// |
require_once "File/Passwd.php"; |
require_once "Auth/Container.php"; |
require_once "PEAR.php"; |
/** |
* Storage driver for fetching login data from an encrypted password file. |
* |
* This storage container can handle CVS pserver style passwd files. |
* |
* @author Stefan Ekman <stekman@sedata.org> |
* @author Michael Wallner <mike@php.net> |
* @package Auth |
* @version $Revision: 1.1 $ |
*/ |
class Auth_Container_File extends Auth_Container |
{ |
/** |
* Path to passwd file |
* |
* @var string |
*/ |
var $pwfile = ''; |
// {{{ Constructor |
/** |
* Constructor of the container class |
* |
* @param string $filename path to passwd file |
* @return object Auth_Container_File new Auth_Container_File object |
*/ |
function Auth_Container_File($filename) |
{ |
$this->pwfile = $filename; |
} |
// }}} |
// {{{ fetchData() |
/** |
* Authenticate an user |
* |
* @param string username |
* @param string password |
* @return mixed boolean|PEAR_Error |
*/ |
function fetchData($user, $pass) |
{ |
return File_Passwd::staticAuth('Cvs', $this->pwfile, $user, $pass); |
} |
// }}} |
// {{{ listUsers() |
/** |
* List all available users |
* |
* @return array |
*/ |
function listUsers() |
{ |
$pw_obj = &$this->_load(); |
if (PEAR::isError($pw_obj)) { |
return array(); |
} |
$users = $pw_obj->listUser(); |
if (!is_array($users)) { |
return array(); |
} |
foreach ($users as $key => $value) { |
$retVal[] = array("username" => $key, |
"password" => $value['passwd'], |
"cvsuser" => $value['system']); |
} |
return $retVal; |
} |
// }}} |
// {{{ addUser() |
/** |
* Add a new user to the storage container |
* |
* @param string username |
* @param string password |
* @param mixed CVS username |
* |
* @return boolean |
*/ |
function addUser($user, $pass, $additional='') |
{ |
$cvs = (string) (is_array($additional) && isset($additional['cvsuser'])) ? |
$additional['cvsuser'] : $additional; |
$pw_obj = &$this->_load(); |
if (PEAR::isError($pw_obj)) { |
return false; |
} |
$res = $pw_obj->addUser($user, $pass, $cvs); |
if(PEAR::isError($res)){ |
return false; |
} |
$res = $pw_obj->save(); |
if (PEAR::isError($res)) { |
return false; |
} |
return true; |
} |
// }}} |
// {{{ removeUser() |
/** |
* Remove user from the storage container |
* |
* @param string Username |
* @return boolean |
*/ |
function removeUser($user) |
{ |
$pw_obj = &$this->_load(); |
if (PEAR::isError($pw_obj)) { |
return false; |
} |
$res = $pw_obj->delUser($user); |
if(PEAR::isError($res)){ |
return false; |
} |
$res = $pw_obj->save(); |
if (PEAR::isError($res)) { |
return false; |
} |
return true; |
} |
// }}} |
// {{{ _load() |
/** |
* Load and initialize the File_Passwd object |
* |
* @return object File_Passwd_Cvs|PEAR_Error |
*/ |
function &_load() |
{ |
static $pw_obj; |
if (!isset($pw_obj)) { |
$pw_obj = File_Passwd::factory('Cvs'); |
if (PEAR::isError($pw_obj)) { |
return $pw_obj; |
} |
$pw_obj->setFile($this->pwfile); |
$res = $pw_obj->load(); |
if (PEAR::isError($res)) { |
return $res; |
} |
} |
return $pw_obj; |
} |
// }}} |
} |
?> |
/branches/livraison_menes/api/pear/Auth/Container/LDAP.php |
---|
New file |
0,0 → 1,472 |
<?php |
// |
// +----------------------------------------------------------------------+ |
// | PHP Version 4 | |
// +----------------------------------------------------------------------+ |
// | Copyright (c) 1997-2003 The PHP Group | |
// +----------------------------------------------------------------------+ |
// | This source file is subject to version 2.02 of the PHP license, | |
// | that is bundled with this package in the file LICENSE, and is | |
// | available at through the world-wide-web at | |
// | http://www.php.net/license/2_02.txt. | |
// | If you did not receive a copy of the PHP license and are unable to | |
// | obtain it through the world-wide-web, please send a note to | |
// | license@php.net so we can mail you a copy immediately. | |
// +----------------------------------------------------------------------+ |
// | Authors: Jan Wagner <wagner@netsols.de> | |
// +----------------------------------------------------------------------+ |
// |
// $Id: LDAP.php,v 1.1 2005-03-30 08:50:33 jpm Exp $ |
// |
require_once "Auth/Container.php"; |
require_once "PEAR.php"; |
/** |
* Storage driver for fetching login data from LDAP |
* |
* This class is heavily based on the DB and File containers. By default it |
* connects to localhost:389 and searches for uid=$username with the scope |
* "sub". If no search base is specified, it will try to determine it via |
* the namingContexts attribute. It takes its parameters in a hash, connects |
* to the ldap server, binds anonymously, searches for the user, and tries |
* to bind as the user with the supplied password. When a group was set, it |
* will look for group membership of the authenticated user. If all goes |
* well the authentication was successful. |
* |
* Parameters: |
* |
* host: localhost (default), ldap.netsols.de or 127.0.0.1 |
* port: 389 (default) or 636 or whereever your server runs |
* url: ldap://localhost:389/ |
* useful for ldaps://, works only with openldap2 ? |
* it will be preferred over host and port |
* binddn: If set, searching for user will be done after binding |
* as this user, if not set the bind will be anonymous. |
* This is reported to make the container work with MS |
* Active Directory, but should work with any server that |
* is configured this way. |
* This has to be a complete dn for now (basedn and |
* userdn will not be appended). |
* bindpw: The password to use for binding with binddn |
* scope: one, sub (default), or base |
* basedn: the base dn of your server |
* userdn: gets prepended to basedn when searching for user |
* userattr: the user attribute to search for (default: uid) |
* useroc: objectclass of user (for the search filter) |
* (default: posixAccount) |
* groupdn: gets prepended to basedn when searching for group |
* groupattr : the group attribute to search for (default: cn) |
* groupoc : objectclass of group (for the search filter) |
* (default: groupOfUniqueNames) |
* memberattr : the attribute of the group object where the user dn |
* may be found (default: uniqueMember) |
* memberisdn: whether the memberattr is the dn of the user (default) |
* or the value of userattr (usually uid) |
* group: the name of group to search for |
* debug: Enable/Disable debugging output (default: false) |
* |
* To use this storage container, you have to use the following syntax: |
* |
* <?php |
* ... |
* |
* $a = new Auth("LDAP", array( |
* 'host' => 'localhost', |
* 'port' => '389', |
* 'basedn' => 'o=netsols,c=de', |
* 'userattr' => 'uid' |
* 'binddn' => 'cn=admin,o=netsols,c=de', |
* 'bindpw' => 'password')); |
* |
* $a2 = new Auth('LDAP', array( |
* 'url' => 'ldaps://ldap.netsols.de', |
* 'basedn' => 'o=netsols,c=de', |
* 'scope' => 'one', |
* 'userdn' => 'ou=People', |
* 'groupdn' => 'ou=Groups', |
* 'groupoc' => 'posixGroup', |
* 'memberattr' => 'memberUid', |
* 'memberisdn' => false, |
* 'group' => 'admin' |
* )); |
* |
* $a3 = new Auth('LDAP', array( |
* 'host' => 'ad.netsols.de', |
* 'basedn' => 'dc=netsols,dc=de', |
* 'userdn' => 'ou=Users', |
* 'binddn' => 'cn=Jan Wagner,ou=Users,dc=netsols,dc=de', |
* 'bindpw' => '*******', |
* 'userattr' => 'samAccountName', |
* 'useroc' => 'user', |
* 'debug' => true |
* )); |
* |
* The parameter values have to correspond |
* to the ones for your LDAP server of course. |
* |
* When talking to a Microsoft ActiveDirectory server you have to |
* use 'samaccountname' as the 'userattr' and follow special rules |
* to translate the ActiveDirectory directory names into 'basedn'. |
* The 'basedn' for the default 'Users' folder on an ActiveDirectory |
* server for the ActiveDirectory Domain (which is not related to |
* its DNS name) "win2000.example.org" would be: |
* "CN=Users, DC=win2000, DC=example, DC=org' |
* where every component of the domain name becomes a DC attribute |
* of its own. If you want to use a custom users folder you have to |
* replace "CN=Users" with a sequence of "OU" attributes that specify |
* the path to your custom folder in reverse order. |
* So the ActiveDirectory folder |
* "win2000.example.org\Custom\Accounts" |
* would become |
* "OU=Accounts, OU=Custom, DC=win2000, DC=example, DC=org' |
* |
* It seems that binding anonymously to an Active Directory |
* is not allowed, so you have to set binddn and bindpw for |
* user searching, |
* |
* Example a3 shows a tested example for connenction to Windows 2000 |
* Active Directory |
* |
* @author Jan Wagner <wagner@netsols.de> |
* @package Auth |
* @version $Revision: 1.1 $ |
*/ |
class Auth_Container_LDAP extends Auth_Container |
{ |
/** |
* Options for the class |
* @var array |
*/ |
var $options = array(); |
/** |
* Connection ID of LDAP Link |
* @var string |
*/ |
var $conn_id = false; |
/** |
* LDAP search function to use |
* @var string |
*/ |
var $ldap_search_func; |
/** |
* Constructor of the container class |
* |
* @param $params, associative hash with host,port,basedn and userattr key |
* @return object Returns an error object if something went wrong |
*/ |
function Auth_Container_LDAP($params) |
{ |
$this->_setDefaults(); |
if (is_array($params)) { |
$this->_parseOptions($params); |
} |
} |
// }}} |
// {{{ _connect() |
/** |
* Connect to the LDAP server using the global options |
* |
* @access private |
* @return object Returns a PEAR error object if an error occurs. |
*/ |
function _connect() |
{ |
// connect |
if (isset($this->options['url']) && $this->options['url'] != '') { |
$this->_debug('Connecting with URL', __LINE__); |
$conn_params = array($this->options['url']); |
} else { |
$this->_debug('Connecting with host:port', __LINE__); |
$conn_params = array($this->options['host'], $this->options['port']); |
} |
if(($this->conn_id = @call_user_func_array('ldap_connect', $conn_params)) === false) { |
return PEAR::raiseError('Auth_Container_LDAP: Could not connect to server.', 41, PEAR_ERROR_DIE); |
} |
$this->_debug('Successfully connected to server', __LINE__); |
// try switchig to LDAPv3 |
$ver = 0; |
if(@ldap_get_option($this->conn_id, LDAP_OPT_PROTOCOL_VERSION, $ver) && $ver >= 2) { |
$this->_debug('Switching to LDAPv3', __LINE__); |
@ldap_set_option($this->conn_id, LDAP_OPT_PROTOCOL_VERSION, 3); |
} |
// bind with credentials or anonymously |
if($this->options['binddn'] && $this->options['bindpw']) { |
$this->_debug('Binding with credentials', __LINE__); |
$bind_params = array($this->conn_id, $this->options['binddn'], $this->options['bindpw']); |
} else { |
$this->_debug('Binding anonymously', __LINE__); |
$bind_params = array($this->conn_id); |
} |
// bind for searching |
if ((@call_user_func_array('ldap_bind', $bind_params)) == false) { |
$this->_debug(); |
$this->_disconnect(); |
return PEAR::raiseError("Auth_Container_LDAP: Could not bind to LDAP server.", 41, PEAR_ERROR_DIE); |
} |
$this->_debug('Binding was successful', __LINE__); |
} |
/** |
* Disconnects (unbinds) from ldap server |
* |
* @access private |
*/ |
function _disconnect() |
{ |
if($this->_isValidLink()) { |
$this->_debug('disconnecting from server'); |
@ldap_unbind($this->conn_id); |
} |
} |
/** |
* Tries to find Basedn via namingContext Attribute |
* |
* @access private |
*/ |
function _getBaseDN() |
{ |
if ($this->options['basedn'] == "" && $this->_isValidLink()) { |
$this->_debug("basedn not set, searching via namingContexts.", __LINE__); |
$result_id = @ldap_read($this->conn_id, "", "(objectclass=*)", array("namingContexts")); |
if (ldap_count_entries($this->conn_id, $result_id) == 1) { |
$this->_debug("got result for namingContexts", __LINE__); |
$entry_id = ldap_first_entry($this->conn_id, $result_id); |
$attrs = ldap_get_attributes($this->conn_id, $entry_id); |
$basedn = $attrs['namingContexts'][0]; |
if ($basedn != "") { |
$this->_debug("result for namingContexts was $basedn", __LINE__); |
$this->options['basedn'] = $basedn; |
} |
} |
ldap_free_result($result_id); |
} |
// if base ist still not set, raise error |
if ($this->options['basedn'] == "") { |
return PEAR::raiseError("Auth_Container_LDAP: LDAP search base not specified!", 41, PEAR_ERROR_DIE); |
} |
return true; |
} |
/** |
* determines whether there is a valid ldap conenction or not |
* |
* @accessd private |
* @return boolean |
*/ |
function _isValidLink() |
{ |
if(is_resource($this->conn_id)) { |
if(get_resource_type($this->conn_id) == 'ldap link') { |
return true; |
} |
} |
return false; |
} |
/** |
* Set some default options |
* |
* @access private |
*/ |
function _setDefaults() |
{ |
$this->options['host'] = 'localhost'; |
$this->options['port'] = '389'; |
$this->options['binddn'] = ''; |
$this->options['bindpw'] = ''; |
$this->options['scope'] = 'sub'; |
$this->options['basedn'] = ''; |
$this->options['userdn'] = ''; |
$this->options['userattr'] = "uid"; |
$this->options['useroc'] = 'posixAccount'; |
$this->options['groupdn'] = ''; |
$this->options['groupattr'] = 'cn'; |
$this->options['groupoc'] = 'groupOfUniqueNames'; |
$this->options['memberattr'] = 'uniqueMember'; |
$this->options['memberisdn'] = true; |
$this->options['debug'] = false; |
} |
/** |
* Parse options passed to the container class |
* |
* @access private |
* @param array |
*/ |
function _parseOptions($array) |
{ |
foreach ($array as $key => $value) { |
$this->options[$key] = $value; |
} |
// get the according search function for selected scope |
switch($this->options['scope']) { |
case 'one': |
$this->ldap_search_func = 'ldap_list'; |
break; |
case 'base': |
$this->ldap_search_func = 'ldap_read'; |
break; |
default: |
$this->ldap_search_func = 'ldap_search'; |
break; |
} |
$this->_debug("LDAP search function will be: {$this->ldap_search_func}", __LINE__); |
} |
/** |
* Fetch data from LDAP server |
* |
* Searches the LDAP server for the given username/password |
* combination. |
* |
* @param string Username |
* @param string Password |
* @return boolean |
*/ |
function fetchData($username, $password) |
{ |
$this->_connect(); |
$this->_getBaseDN(); |
// make search filter |
$filter = sprintf('(&(objectClass=%s)(%s=%s))', $this->options['useroc'], $this->options['userattr'], $username); |
// make search base dn |
$search_basedn = $this->options['userdn']; |
if ($search_basedn != '' && substr($search_basedn, -1) != ',') { |
$search_basedn .= ','; |
} |
$search_basedn .= $this->options['basedn']; |
// make functions params array |
$func_params = array($this->conn_id, $search_basedn, $filter, array($this->options['userattr'])); |
$this->_debug("Searching with $filter in $search_basedn", __LINE__); |
// search |
if (($result_id = @call_user_func_array($this->ldap_search_func, $func_params)) == false) { |
$this->_debug('User not found', __LINE__); |
} elseif (ldap_count_entries($this->conn_id, $result_id) == 1) { // did we get just one entry? |
$this->_debug('User was found', __LINE__); |
// then get the user dn |
$entry_id = ldap_first_entry($this->conn_id, $result_id); |
$user_dn = ldap_get_dn($this->conn_id, $entry_id); |
ldap_free_result($result_id); |
// need to catch an empty password as openldap seems to return TRUE |
// if anonymous binding is allowed |
if ($password != "") { |
$this->_debug("Bind as $user_dn", __LINE__); |
// try binding as this user with the supplied password |
if (@ldap_bind($this->conn_id, $user_dn, $password)) { |
$this->_debug('Bind successful', __LINE__); |
// check group if appropiate |
if(isset($this->options['group'])) { |
// decide whether memberattr value is a dn or the username |
$this->_debug('Checking group membership', __LINE__); |
return $this->checkGroup(($this->options['memberisdn']) ? $user_dn : $username); |
} else { |
$this->_debug('Authenticated', __LINE__); |
$this->_disconnect(); |
return true; // user authenticated |
} // checkGroup |
} // bind |
} // non-empty password |
} // one entry |
// default |
$this->_debug('NOT authenticated!', __LINE__); |
$this->_disconnect(); |
return false; |
} |
/** |
* Validate group membership |
* |
* Searches the LDAP server for group membership of the |
* authenticated user |
* |
* @param string Distinguished Name of the authenticated User |
* @return boolean |
*/ |
function checkGroup($user) |
{ |
// make filter |
$filter = sprintf('(&(%s=%s)(objectClass=%s)(%s=%s))', |
$this->options['groupattr'], |
$this->options['group'], |
$this->options['groupoc'], |
$this->options['memberattr'], |
$user |
); |
// make search base dn |
$search_basedn = $this->options['groupdn']; |
if($search_basedn != '' && substr($search_basedn, -1) != ',') { |
$search_basedn .= ','; |
} |
$search_basedn .= $this->options['basedn']; |
$func_params = array($this->conn_id, $search_basedn, $filter, array($this->options['memberattr'])); |
$this->_debug("Searching with $filter in $search_basedn", __LINE__); |
// search |
if(($result_id = @call_user_func_array($this->ldap_search_func, $func_params)) != false) { |
if(ldap_count_entries($this->conn_id, $result_id) == 1) { |
ldap_free_result($result_id); |
$this->_debug('User is member of group', __LINE__); |
$this->_disconnect(); |
return true; |
} |
} |
// default |
$this->_debug('User is NOT member of group', __LINE__); |
$this->_disconnect(); |
return false; |
} |
/** |
* Outputs debugging messages |
* |
* @access private |
* @param string Debugging Message |
* @param integer Line number |
*/ |
function _debug($msg = '', $line = 0) |
{ |
if($this->options['debug'] === true) { |
if($msg == '' && $this->_isValidLink()) { |
$msg = 'LDAP_Error: ' . @ldap_err2str(@ldap_errno($this->_conn_id)); |
} |
print("$line: $msg <br />"); |
} |
} |
} |
?> |
/branches/livraison_menes/api/pear/Auth/Container/POP3.php |
---|
New file |
0,0 → 1,107 |
<?php |
/* vim: set expandtab tabstop=4 shiftwidth=4: */ |
// +----------------------------------------------------------------------+ |
// | PHP Version 4 | |
// +----------------------------------------------------------------------+ |
// | Copyright (c) 1997-2002 The PHP Group | |
// +----------------------------------------------------------------------+ |
// | This source file is subject to version 2.02 of the PHP license, | |
// | that is bundled with this package in the file LICENSE, and is | |
// | available at through the world-wide-web at | |
// | http://www.php.net/license/2_02.txt. | |
// | If you did not receive a copy of the PHP license and are unable to | |
// | obtain it through the world-wide-web, please send a note to | |
// | license@php.net so we can mail you a copy immediately. | |
// +----------------------------------------------------------------------+ |
// | Authors: Stefan Ekman <stekman@sedata.org> | |
// | Martin Jansen <mj@php.net> | |
// | Mika Tuupola <tuupola@appelsiini.net> | |
// +----------------------------------------------------------------------+ |
// |
// $Id: POP3.php,v 1.1 2005-03-30 08:50:33 jpm Exp $ |
// |
require_once('Auth/Container.php'); |
require_once('PEAR.php'); |
require_once('Net/POP3.php'); |
/** |
* Storage driver for Authentication on a POP3 server. |
* |
* @author Yavor Shahpasov <yavo@netsmart.com.cy> |
* @package Auth |
* @version $Revision: 1.1 $ |
*/ |
class Auth_Container_POP3 extends Auth_Container |
{ |
/** |
* POP3 Server |
* @var string |
*/ |
var $server='localhost'; |
/** |
* POP3 Server port |
* @var string |
*/ |
var $port='110'; |
// {{{ Constructor |
/** |
* Constructor of the container class |
* |
* @param $server string server or server:port combination |
* @return object Returns an error object if something went wrong |
*/ |
function Auth_Container_POP3($server=null) |
{ |
if(isset($server)){ |
if(is_array($server)){ |
if(isset($server['host'])){ |
$this->server = $server['host']; |
} |
if(isset($server['port'])){ |
$this->port = $server['port']; |
} |
} |
else{ |
if(strstr($server, ':')){ |
$serverparts = explode(':', trim($server)); |
$this->server = $serverparts[0]; |
$this->port = $serverparts[1]; |
} |
else |
{ |
$this->server = $server; |
} |
} |
} |
} |
// }}} |
// {{{ fetchData() |
/** |
* Try to login to the POP3 server |
* |
* @param string Username |
* @param string Password |
* @return boolean |
*/ |
function fetchData($username, $password) |
{ |
$pop3 =& new Net_POP3(); |
$res = $pop3->connect($this->server, $this->port); |
if(!$res){ |
return($res); |
} |
$result = $pop3->login($username, $password); |
$pop3->disconnect(); |
return $result; |
} |
// }}} |
} |
?> |
/branches/livraison_menes/api/pear/Auth/Container/MDB.php |
---|
New file |
0,0 → 1,392 |
<?php |
// |
// +----------------------------------------------------------------------+ |
// | PHP Version 4 | |
// +----------------------------------------------------------------------+ |
// | | |
// +----------------------------------------------------------------------+ |
// | This source file is subject to version 2.02 of the PHP license, | |
// | that is bundled with this package in the file LICENSE, and is | |
// | available at through the world-wide-web at | |
// | http://www.php.net/license/2_02.txt. | |
// | If you did not receive a copy of the PHP license and are unable to | |
// | obtain it through the world-wide-web, please send a note to | |
// | license@php.net so we can mail you a copy immediately. | |
// +----------------------------------------------------------------------+ |
// | Author: Lorenzo Alberton <l.alberton@quipo.it> | |
// +----------------------------------------------------------------------+ |
// |
// $Id: MDB.php,v 1.1 2005-03-30 08:50:33 jpm Exp $ |
// |
require_once 'Auth/Container.php'; |
require_once 'MDB.php'; |
/** |
* Storage driver for fetching login data from a database |
* |
* This storage driver can use all databases which are supported |
* by the PEAR MDB abstraction layer to fetch login data. |
* |
* @author Lorenzo Alberton <l.alberton@quipo.it> |
* @package Auth |
* @version $Revision: 1.1 $ |
*/ |
class Auth_Container_MDB extends Auth_Container |
{ |
/** |
* Additional options for the storage container |
* @var array |
*/ |
var $options = array(); |
/** |
* DB object |
* @var object |
*/ |
var $db = null; |
var $dsn = ''; |
/** |
* User that is currently selected from the DB. |
* @var string |
*/ |
var $activeUser = ''; |
// {{{ Constructor |
/** |
* Constructor of the container class |
* |
* Initate connection to the database via PEAR::DB |
* |
* @param string Connection data or DB object |
* @return object Returns an error object if something went wrong |
*/ |
function Auth_Container_MDB($dsn) |
{ |
$this->_setDefaults(); |
if (is_array($dsn)) { |
$this->_parseOptions($dsn); |
if (empty($this->options['dsn'])) { |
PEAR::raiseError('No connection parameters specified!'); |
} |
} else { |
$this->options['dsn'] = $dsn; |
} |
} |
// }}} |
// {{{ _connect() |
/** |
* Connect to database by using the given DSN string |
* |
* @access private |
* @param string DSN string |
* @return mixed Object on error, otherwise bool |
*/ |
function _connect($dsn) |
{ |
if (is_string($dsn) || is_array($dsn)) { |
$this->db =& MDB::Connect($dsn); |
} elseif (get_parent_class($dsn) == "mdb_common") { |
$this->db = $dsn; |
} elseif (is_object($dsn) && MDB::isError($dsn)) { |
return PEAR::raiseError($dsn->getMessage(), $dsn->code); |
} else { |
return PEAR::raiseError('The given dsn was not valid in file ' . __FILE__ . ' at line ' . __LINE__, |
41, |
PEAR_ERROR_RETURN, |
null, |
null |
); |
} |
if (MDB::isError($this->db) || PEAR::isError($this->db)) { |
return PEAR::raiseError($this->db->getMessage(), $this->db->code); |
} else { |
return true; |
} |
} |
// }}} |
// {{{ _prepare() |
/** |
* Prepare database connection |
* |
* This function checks if we have already opened a connection to |
* the database. If that's not the case, a new connection is opened. |
* |
* @access private |
* @return mixed True or a DB error object. |
*/ |
function _prepare() |
{ |
return $this->_connect($this->options['dsn']); |
} |
// }}} |
// {{{ query() |
/** |
* Prepare query to the database |
* |
* This function checks if we have already opened a connection to |
* the database. If that's not the case, a new connection is opened. |
* After that the query is passed to the database. |
* |
* @access public |
* @param string Query string |
* @return mixed a MDB_result object or MDB_OK on success, a MDB |
* or PEAR error on failure |
*/ |
function query($query) |
{ |
$err = $this->_prepare(); |
if ($err !== true) { |
return $err; |
} |
return $this->db->query($query); |
} |
// }}} |
// {{{ _setDefaults() |
/** |
* Set some default options |
* |
* @access private |
* @return void |
*/ |
function _setDefaults() |
{ |
$this->options['table'] = 'auth'; |
$this->options['usernamecol'] = 'username'; |
$this->options['passwordcol'] = 'password'; |
$this->options['dsn'] = ''; |
$this->options['db_fields'] = ''; |
$this->options['cryptType'] = 'md5'; |
} |
// }}} |
// {{{ _parseOptions() |
/** |
* Parse options passed to the container class |
* |
* @access private |
* @param array |
*/ |
function _parseOptions($array) |
{ |
foreach ($array as $key => $value) { |
if (isset($this->options[$key])) { |
$this->options[$key] = $value; |
} |
} |
// Include additional fields if they exist |
if (!empty($this->options['db_fields'])) { |
if (is_array($this->options['db_fields'])) { |
$this->options['db_fields'] = join($this->options['db_fields'], ', '); |
} |
$this->options['db_fields'] = ', ' . $this->options['db_fields']; |
} |
} |
// }}} |
// {{{ fetchData() |
/** |
* Get user information from database |
* |
* This function uses the given username to fetch |
* the corresponding login data from the database |
* table. If an account that matches the passed username |
* and password is found, the function returns true. |
* Otherwise it returns false. |
* |
* @param string Username |
* @param string Password |
* @return mixed Error object or boolean |
*/ |
function fetchData($username, $password) |
{ |
// Prepare for a database query |
$err = $this->_prepare(); |
if ($err !== true) { |
return PEAR::raiseError($err->getMessage(), $err->getCode()); |
} |
// Find if db_fileds contains a *, i so assume all col are selected |
if (strstr($this->options['db_fields'], '*')) { |
$sql_from = '*'; |
} else{ |
$sql_from = $this->options['usernamecol'] . ', '. $this->options['passwordcol'] . $this->options['db_fields']; |
} |
$query = sprintf("SELECT %s FROM %s WHERE %s = %s", |
$sql_from, |
$this->options['table'], |
$this->options['usernamecol'], |
$this->db->getTextValue($username) |
); |
$res = $this->db->getRow($query, null, null, null, MDB_FETCHMODE_ASSOC); |
if (MDB::isError($res) || PEAR::isError($res)) { |
return PEAR::raiseError($res->getMessage(), $res->getCode()); |
} |
if (!is_array($res)) { |
$this->activeUser = ''; |
return false; |
} |
if ($this->verifyPassword(trim($password, "\r\n"), |
trim($res[$this->options['passwordcol']], "\r\n"), |
$this->options['cryptType'])) { |
// Store additional field values in the session |
foreach ($res as $key => $value) { |
if ($key == $this->options['passwordcol'] || |
$key == $this->options['usernamecol']) { |
continue; |
} |
// Use reference to the auth object if exists |
// This is because the auth session variable can change so a static call to setAuthData does not make sence |
if(is_object($this->_auth_obj)){ |
$this->_auth_obj->setAuthData($key, $value); |
} else { |
Auth::setAuthData($key, $value); |
} |
} |
return true; |
} |
$this->activeUser = $res[$this->options['usernamecol']]; |
return false; |
} |
// }}} |
// {{{ listUsers() |
function listUsers() |
{ |
$err = $this->_prepare(); |
if ($err !== true) { |
return PEAR::raiseError($err->getMessage(), $err->getCode()); |
} |
$retVal = array(); |
// Find if db_fileds contains a *, i so assume all col are selected |
if (strstr($this->options['db_fields'], '*')) { |
$sql_from = '*'; |
} else{ |
$sql_from = $this->options['db_fields']; |
} |
$query = sprintf('SELECT %s FROM %s', |
$sql_from, |
$this->options['table'] |
); |
$res = $this->db->getAll($query, null, null, null, MDB_FETCHMODE_ASSOC); |
if (MDB::isError($res)) { |
return PEAR::raiseError($res->getMessage(), $res->getCode()); |
} else { |
foreach ($res as $user) { |
$user['username'] = $user[$this->options['usernamecol']]; |
$retVal[] = $user; |
} |
} |
return $retVal; |
} |
// }}} |
// {{{ addUser() |
/** |
* Add user to the storage container |
* |
* @access public |
* @param string Username |
* @param string Password |
* @param mixed Additional information that are stored in the DB |
* |
* @return mixed True on success, otherwise error object |
*/ |
function addUser($username, $password, $additional = "") |
{ |
if (function_exists($this->options['cryptType'])) { |
$cryptFunction = $this->options['cryptType']; |
} else { |
$cryptFunction = 'md5'; |
} |
$additional_key = ''; |
$additional_value = ''; |
if (is_array($additional)) { |
foreach ($additional as $key => $value) { |
$additional_key .= ', ' . $key; |
$additional_value .= ', ' . $this->db->getTextValue($value); |
} |
} |
$query = sprintf("INSERT INTO %s (%s, %s%s) VALUES (%s, %s%s)", |
$this->options['table'], |
$this->options['usernamecol'], |
$this->options['passwordcol'], |
$additional_key, |
$this->db->getTextValue($username), |
$this->db->getTextValue($cryptFunction($password)), |
$additional_value |
); |
$res = $this->query($query); |
if (MDB::isError($res)) { |
return PEAR::raiseError($res->getMessage(), $res->code); |
} else { |
return true; |
} |
} |
// }}} |
// {{{ removeUser() |
/** |
* Remove user from the storage container |
* |
* @access public |
* @param string Username |
* |
* @return mixed True on success, otherwise error object |
*/ |
function removeUser($username) |
{ |
$query = sprintf("DELETE FROM %s WHERE %s = %s", |
$this->options['table'], |
$this->options['usernamecol'], |
$this->db->getTextValue($username) |
); |
$res = $this->query($query); |
if (MDB::isError($res)) { |
return PEAR::raiseError($res->getMessage(), $res->code); |
} else { |
return true; |
} |
} |
// }}} |
} |
?> |
/branches/livraison_menes/api/pear/Auth/Container/SOAP.php |
---|
New file |
0,0 → 1,170 |
<?php |
// |
// +----------------------------------------------------------------------+ |
// | PHP Version 4 | |
// +----------------------------------------------------------------------+ |
// | Copyright (c) 1997-2002 The PHP Group | |
// +----------------------------------------------------------------------+ |
// | This source file is subject to version 2.02 of the PHP license, | |
// | that is bundled with this package in the file LICENSE, and is | |
// | available at through the world-wide-web at | |
// | http://www.php.net/license/2_02.txt. | |
// | If you did not receive a copy of the PHP license and are unable to | |
// | obtain it through the world-wide-web, please send a note to | |
// | license@php.net so we can mail you a copy immediately. | |
// +----------------------------------------------------------------------+ |
// | Authors: Bruno Pedro <bpedro@co.sapo.pt> | |
// +----------------------------------------------------------------------+ |
// |
// $Id: SOAP.php,v 1.1 2005-03-30 08:50:33 jpm Exp $ |
// |
require_once "Auth/Container.php"; |
require_once "PEAR.php"; |
require_once 'SOAP/Client.php'; |
/** |
* Storage driver for fetching login data from SOAP |
* |
* This class takes one parameter (options), where |
* you specify the following fields: endpoint, namespace, |
* method, encoding, usernamefield and passwordfield. |
* |
* You can use specify features of your SOAP service |
* by providing its parameters in an associative manner by |
* using the '_features' array through the options parameter. |
* |
* The 'matchpassword' option should be set to false if your |
* webservice doesn't return (username,password) pairs, but |
* instead returns error when the login is invalid. |
* |
* Example usage: |
* |
* <?php |
* |
* ... |
* |
* $options = array ( |
* 'endpoint' => 'http://your.soap.service/endpoint', |
* 'namespace' => 'urn:/Your/Namespace', |
* 'method' => 'get', |
* 'encoding' => 'UTF-8', |
* 'usernamefield' => 'login', |
* 'passwordfield' => 'password', |
* 'matchpasswords' => false, |
* '_features' => array ( |
* 'example_feature' => 'example_value', |
* 'another_example' => '' |
* ) |
* ); |
* $auth = new Auth('SOAP', $options, 'loginFunction'); |
* $auth->start(); |
* |
* ... |
* |
* ?> |
* |
* @author Bruno Pedro <bpedro@co.sapo.pt> |
* @package Auth |
* @version $Revision: 1.1 $ |
*/ |
class Auth_Container_SOAP extends Auth_Container |
{ |
/** |
* Required options for the class |
* @var array |
* @access private |
*/ |
var $_requiredOptions = array('endpoint', 'namespace', 'method', 'encoding', 'usernamefield', 'passwordfield'); |
/** |
* Options for the class |
* @var array |
* @access private |
*/ |
var $_options = array(); |
/** |
* Optional SOAP features |
* @var array |
* @access private |
*/ |
var $_features = array(); |
/** |
* The SOAP response |
* @var array |
* @access public |
*/ |
var $soapResponse = array(); |
/** |
* Constructor of the container class |
* |
* @param $options, associative array with endpoint, namespace, method, |
* usernamefield, passwordfield and optional features |
*/ |
function Auth_Container_SOAP($options) |
{ |
$this->_options = $options; |
if (!isset($this->_options['matchpasswords'])) { |
$this->_options['matchpasswords'] = true; |
} |
if (!empty($this->_options['_features'])) { |
$this->_features = $this->_options['_features']; |
unset($this->_options['_features']); |
} |
} |
/** |
* Fetch data from SOAP service |
* |
* Requests the SOAP service for the given username/password |
* combination. |
* |
* @param string Username |
* @param string Password |
* @return mixed Returns the SOAP response or false if something went wrong |
*/ |
function fetchData($username, $password) |
{ |
// check if all required options are set |
if (array_intersect($this->_requiredOptions, array_keys($this->_options)) != $this->_requiredOptions) { |
return false; |
} else { |
// create a SOAP client and set encoding |
$soapClient = new SOAP_Client($this->_options['endpoint']); |
$soapClient->setEncoding($this->_options['encoding']); |
} |
// assign username and password fields |
$usernameField = new SOAP_Value($this->_options['usernamefield'],'string', $username); |
$passwordField = new SOAP_Value($this->_options['passwordfield'],'string', $password); |
$SOAPParams = array($usernameField, $passwordField); |
// assign optional features |
foreach ($this->_features as $fieldName => $fieldValue) { |
$SOAPParams[] = new SOAP_Value($fieldName, 'string', $fieldValue); |
} |
// make SOAP call |
$this->soapResponse = $soapClient->call( |
$this->_options['method'], |
$SOAPParams, |
array('namespace' => $this->_options['namespace']) |
); |
if (!PEAR::isError($this->soapResponse)) { |
if ($this->_options['matchpasswords']) { |
// check if passwords match |
if ($password == $this->soapResponse->{$this->_options['passwordfield']}) { |
return true; |
} else { |
return false; |
} |
} else { |
return true; |
} |
} else { |
return false; |
} |
} |
} |
?> |
/branches/livraison_menes/api/pear/Auth/Container/SMBPasswd.php |
---|
New file |
0,0 → 1,134 |
<?php |
/* vim: set expandtab tabstop=4 shiftwidth=4: */ |
// +----------------------------------------------------------------------+ |
// | PHP Version 4 | |
// +----------------------------------------------------------------------+ |
// | Copyright (c) 1997-2003 The PHP Group | |
// +----------------------------------------------------------------------+ |
// | This source file is subject to version 2.02 of the PHP license, | |
// | that is bundled with this package in the file LICENSE, and is | |
// | available at through the world-wide-web at | |
// | http://www.php.net/license/2_02.txt. | |
// | If you did not receive a copy of the PHP license and are unable to | |
// | obtain it through the world-wide-web, please send a note to | |
// | license@php.net so we can mail you a copy immediately. | |
// +----------------------------------------------------------------------+ |
// | Authors: Michael Bretterklieber <michael@bretterklieber.com> | |
// +----------------------------------------------------------------------+ |
// |
// $Id: SMBPasswd.php,v 1.1 2005-03-30 08:50:33 jpm Exp $ |
// |
require_once "File/SMBPasswd.php"; |
require_once "Auth/Container.php"; |
require_once "PEAR.php"; |
/** |
* Storage driver for fetching login data from an SAMBA smbpasswd file. |
* |
* This storage container can handle SAMBA smbpasswd files. |
* |
* Example: |
* $a = new Auth("SMBPasswd", '/usr/local/private/smbpasswd'); |
* $a->start(); |
* if ($a->getAuth()) { |
* printf ("AUTH OK<br>\n"); |
* $a->logout(); |
* } |
* |
* @author Michael Bretterklieber <michael@bretterklieber.com> |
* @package Auth |
* @version $Revision: 1.1 $ |
*/ |
class Auth_Container_SMBPasswd extends Auth_Container |
{ |
/** |
* File_SMBPasswd object |
* @var object |
*/ |
var $pwfile; |
// {{{ Constructor |
/** |
* Constructor of the container class |
* |
* @param $filename string filename for a passwd type file |
* @return object Returns an error object if something went wrong |
*/ |
function Auth_Container_SMBPasswd($filename) |
{ |
$this->pwfile = new File_SMBPasswd($filename,0); |
if (!$this->pwfile->load()) { |
PEAR::raiseError("Error while reading file contents.", 41, PEAR_ERROR_DIE); |
return; |
} |
} |
// }}} |
// {{{ fetchData() |
/** |
* Get user information from pwfile |
* |
* @param string Username |
* @param string Password |
* @return boolean |
*/ |
function fetchData($username, $password) |
{ |
return $this->pwfile->verifyAccount($username, $password); |
} |
// }}} |
// {{{ listUsers() |
function listUsers() |
{ |
return $this->pwfile->getAccounts(); |
} |
// }}} |
// {{{ addUser() |
/** |
* Add a new user to the storage container |
* |
* @param string Username |
* @param string Password |
* @param array Additional information |
* |
* @return boolean |
*/ |
function addUser($username, $password, $additional = '') |
{ |
$res = $this->pwfile->addUser($user, $additional['userid'], $pass); |
if ($res === true) { |
return $this->pwfile->save(); |
} |
return $res; |
} |
// }}} |
// {{{ removeUser() |
/** |
* Remove user from the storage container |
* |
* @param string Username |
*/ |
function removeUser($username) |
{ |
$res = $this->pwfile->delUser($username); |
if ($res === true) { |
return $this->pwfile->save(); |
} |
return $res; |
} |
// }}} |
} |
?> |
/branches/livraison_menes/api/pear/Auth/Auth.php |
---|
New file |
0,0 → 1,5 |
<?php |
include_once('Auth.php'); |
?> |
/branches/livraison_menes/api/pear/Auth/Container.php |
---|
New file |
0,0 → 1,177 |
<?php |
// |
// +----------------------------------------------------------------------+ |
// | PHP Version 4 | |
// +----------------------------------------------------------------------+ |
// | Copyright (c) 1997-2003 The PHP Group | |
// +----------------------------------------------------------------------+ |
// | This source file is subject to version 2.02 of the PHP license, | |
// | that is bundled with this package in the file LICENSE, and is | |
// | available at through the world-wide-web at | |
// | http://www.php.net/license/2_02.txt. | |
// | If you did not receive a copy of the PHP license and are unable to | |
// | obtain it through the world-wide-web, please send a note to | |
// | license@php.net so we can mail you a copy immediately. | |
// +----------------------------------------------------------------------+ |
// | Authors: Martin Jansen <mj@php.net> | |
// +----------------------------------------------------------------------+ |
// |
// $Id: Container.php,v 1.1 2005-03-30 08:50:33 jpm Exp $ |
// |
define("AUTH_METHOD_NOT_SUPPORTED", -4); |
/** |
* Storage class for fetching login data |
* |
* @author Martin Jansen <mj@php.net> |
* @package Auth |
*/ |
class Auth_Container |
{ |
/** |
* User that is currently selected from the storage container. |
* |
* @access public |
*/ |
var $activeUser = ""; |
// {{{ Constructor |
/** |
* Constructor |
* |
* Has to be overwritten by each storage class |
* |
* @access public |
*/ |
function Auth_Container() |
{ |
} |
// }}} |
// {{{ fetchData() |
/** |
* Fetch data from storage container |
* |
* Has to be overwritten by each storage class |
* |
* @access public |
*/ |
function fetchData() |
{ |
} |
// }}} |
// {{{ verifyPassword() |
/** |
* Crypt and verfiy the entered password |
* |
* @param string Entered password |
* @param string Password from the data container (usually this password |
* is already encrypted. |
* @param string Type of algorithm with which the password from |
* the container has been crypted. (md5, crypt etc.) |
* Defaults to "md5". |
* @return bool True, if the passwords match |
*/ |
function verifyPassword($password1, $password2, $cryptType = "md5") |
{ |
switch ($cryptType) { |
case "crypt" : |
return (($password2 == "**" . $password1) || |
(crypt($password1, $password2) == $password2) |
); |
break; |
case "none" : |
return ($password1 == $password2); |
break; |
case "md5" : |
return (md5($password1) == $password2); |
break; |
default : |
if (function_exists($cryptType)) { |
return ($cryptType($password1) == $password2); |
} |
else if (method_exists($this,$cryptType)) { |
return ($this->$cryptType($password1) == $password2); |
} else { |
return false; |
} |
break; |
} |
} |
// }}} |
// {{{ listUsers() |
/** |
* List all users that are available from the storage container |
*/ |
function listUsers() |
{ |
return AUTH_METHOD_NOT_SUPPORTED; |
} |
/** |
* Returns a user assoc array |
* |
* Containers which want should overide this |
* |
* @param string The username |
*/ |
function getUser($username) |
{ |
$users = $this->listUsers(); |
if($users === AUTH_METHOD_NOT_SUPPORTED){ |
return(AUTH_METHOD_NOT_SUPPORTED); |
} |
for($i=0;$c = count($users),$i<$c;$i++){ |
if($users[$i]['username'] == $username){ |
return($users[$i]); |
} |
} |
return(false); |
} |
// }}} |
// {{{ addUser() |
/** |
* Add a new user to the storage container |
* |
* @param string Username |
* @param string Password |
* @param array Additional information |
* |
* @return boolean |
*/ |
function addUser($username, $password, $additional=null) |
{ |
return AUTH_METHOD_NOT_SUPPORTED; |
} |
// }}} |
// {{{ removeUser() |
/** |
* Remove user from the storage container |
* |
* @param string Username |
*/ |
function removeUser($username) |
{ |
return AUTH_METHOD_NOT_SUPPORTED; |
} |
// }}} |
} |
?> |
/branches/livraison_menes/api/pear/Mail/null.php |
---|
New file |
0,0 → 1,60 |
<?php |
// |
// +----------------------------------------------------------------------+ |
// | PHP Version 4 | |
// +----------------------------------------------------------------------+ |
// | Copyright (c) 1997-2003 The PHP Group | |
// +----------------------------------------------------------------------+ |
// | This source file is subject to version 2.02 of the PHP license, | |
// | that is bundled with this package in the file LICENSE, and is | |
// | available at through the world-wide-web at | |
// | http://www.php.net/license/2_02.txt. | |
// | If you did not receive a copy of the PHP license and are unable to | |
// | obtain it through the world-wide-web, please send a note to | |
// | license@php.net so we can mail you a copy immediately. | |
// +----------------------------------------------------------------------+ |
// | Author: Phil Kernick <philk@rotfl.com.au> | |
// +----------------------------------------------------------------------+ |
// |
// $Id: null.php,v 1.1 2005-11-24 16:15:46 florian Exp $ |
// |
/** |
* Null implementation of the PEAR Mail:: interface. |
* @access public |
* @package Mail |
* @version $Revision: 1.1 $ |
*/ |
class Mail_null extends Mail { |
/** |
* Implements Mail_null::send() function. Silently discards all |
* mail. |
* |
* @param mixed $recipients Either a comma-seperated list of recipients |
* (RFC822 compliant), or an array of recipients, |
* each RFC822 valid. This may contain recipients not |
* specified in the headers, for Bcc:, resending |
* messages, etc. |
* |
* @param array $headers The array of headers to send with the mail, in an |
* associative array, where the array key is the |
* header name (ie, 'Subject'), and the array value |
* is the header value (ie, 'test'). The header |
* produced from those values would be 'Subject: |
* test'. |
* |
* @param string $body The full text of the message body, including any |
* Mime parts, etc. |
* |
* @return mixed Returns true on success, or a PEAR_Error |
* containing a descriptive error message on |
* failure. |
* @access public |
*/ |
function send($recipients, $headers, $body) |
{ |
return true; |
} |
} |
/branches/livraison_menes/api/pear/Mail/mimeDecode.php |
---|
New file |
0,0 → 1,837 |
<?php |
/* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4: */ |
// +-----------------------------------------------------------------------+ |
// | Copyright (c) 2002-2003 Richard Heyes | |
// | Copyright (c) 2003-2005 The PHP Group | |
// | All rights reserved. | |
// | | |
// | Redistribution and use in source and binary forms, with or without | |
// | modification, are permitted provided that the following conditions | |
// | are met: | |
// | | |
// | o Redistributions of source code must retain the above copyright | |
// | notice, this list of conditions and the following disclaimer. | |
// | o 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.| |
// | o The names of the authors may not be used to endorse or promote | |
// | products derived from this software without specific prior written | |
// | permission. | |
// | | |
// | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS | |
// | "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT | |
// | LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR | |
// | A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT | |
// | OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, | |
// | SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT | |
// | LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, | |
// | DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY | |
// | THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | |
// | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE | |
// | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | |
// | | |
// +-----------------------------------------------------------------------+ |
// | Author: Richard Heyes <richard@phpguru.org> | |
// +-----------------------------------------------------------------------+ |
require_once 'PEAR.php'; |
/** |
* +----------------------------- IMPORTANT ------------------------------+ |
* | Usage of this class compared to native php extensions such as | |
* | mailparse or imap, is slow and may be feature deficient. If available| |
* | you are STRONGLY recommended to use the php extensions. | |
* +----------------------------------------------------------------------+ |
* |
* Mime Decoding class |
* |
* This class will parse a raw mime email and return |
* the structure. Returned structure is similar to |
* that returned by imap_fetchstructure(). |
* |
* USAGE: (assume $input is your raw email) |
* |
* $decode = new Mail_mimeDecode($input, "\r\n"); |
* $structure = $decode->decode(); |
* print_r($structure); |
* |
* Or statically: |
* |
* $params['input'] = $input; |
* $structure = Mail_mimeDecode::decode($params); |
* print_r($structure); |
* |
* TODO: |
* o Implement multipart/appledouble |
* o UTF8: ??? |
> 4. We have also found a solution for decoding the UTF-8 |
> headers. Therefore I made the following function: |
> |
> function decode_utf8($txt) { |
> $trans=array("Å‘"=>"õ","ű"=>"û","Å"=>"Õ","Å°" |
=>"Û"); |
> $txt=strtr($txt,$trans); |
> return(utf8_decode($txt)); |
> } |
> |
> And I have inserted the following line to the class: |
> |
> if (strtolower($charset)=="utf-8") $text=decode_utf8($text); |
> |
> ... before the following one in the "_decodeHeader" function: |
> |
> $input = str_replace($encoded, $text, $input); |
> |
> This way from now on it can easily decode the UTF-8 headers too. |
* |
* @author Richard Heyes <richard@phpguru.org> |
* @version $Revision: 1.1 $ |
* @package Mail |
*/ |
class Mail_mimeDecode extends PEAR |
{ |
/** |
* The raw email to decode |
* @var string |
*/ |
var $_input; |
/** |
* The header part of the input |
* @var string |
*/ |
var $_header; |
/** |
* The body part of the input |
* @var string |
*/ |
var $_body; |
/** |
* If an error occurs, this is used to store the message |
* @var string |
*/ |
var $_error; |
/** |
* Flag to determine whether to include bodies in the |
* returned object. |
* @var boolean |
*/ |
var $_include_bodies; |
/** |
* Flag to determine whether to decode bodies |
* @var boolean |
*/ |
var $_decode_bodies; |
/** |
* Flag to determine whether to decode headers |
* @var boolean |
*/ |
var $_decode_headers; |
/** |
* Constructor. |
* |
* Sets up the object, initialise the variables, and splits and |
* stores the header and body of the input. |
* |
* @param string The input to decode |
* @access public |
*/ |
function Mail_mimeDecode($input) |
{ |
list($header, $body) = $this->_splitBodyHeader($input); |
$this->_input = $input; |
$this->_header = $header; |
$this->_body = $body; |
$this->_decode_bodies = false; |
$this->_include_bodies = true; |
} |
/** |
* Begins the decoding process. If called statically |
* it will create an object and call the decode() method |
* of it. |
* |
* @param array An array of various parameters that determine |
* various things: |
* include_bodies - Whether to include the body in the returned |
* object. |
* decode_bodies - Whether to decode the bodies |
* of the parts. (Transfer encoding) |
* decode_headers - Whether to decode headers |
* input - If called statically, this will be treated |
* as the input |
* @return object Decoded results |
* @access public |
*/ |
function decode($params = null) |
{ |
// determine if this method has been called statically |
$isStatic = !(isset($this) && get_class($this) == __CLASS__); |
// Have we been called statically? |
// If so, create an object and pass details to that. |
if ($isStatic AND isset($params['input'])) { |
$obj = new Mail_mimeDecode($params['input']); |
$structure = $obj->decode($params); |
// Called statically but no input |
} elseif ($isStatic) { |
return PEAR::raiseError('Called statically and no input given'); |
// Called via an object |
} else { |
$this->_include_bodies = isset($params['include_bodies']) ? |
$params['include_bodies'] : false; |
$this->_decode_bodies = isset($params['decode_bodies']) ? |
$params['decode_bodies'] : false; |
$this->_decode_headers = isset($params['decode_headers']) ? |
$params['decode_headers'] : false; |
$structure = $this->_decode($this->_header, $this->_body); |
if ($structure === false) { |
$structure = $this->raiseError($this->_error); |
} |
} |
return $structure; |
} |
/** |
* Performs the decoding. Decodes the body string passed to it |
* If it finds certain content-types it will call itself in a |
* recursive fashion |
* |
* @param string Header section |
* @param string Body section |
* @return object Results of decoding process |
* @access private |
*/ |
function _decode($headers, $body, $default_ctype = 'text/plain') |
{ |
$return = new stdClass; |
$return->headers = array(); |
$headers = $this->_parseHeaders($headers); |
foreach ($headers as $value) { |
if (isset($return->headers[strtolower($value['name'])]) AND !is_array($return->headers[strtolower($value['name'])])) { |
$return->headers[strtolower($value['name'])] = array($return->headers[strtolower($value['name'])]); |
$return->headers[strtolower($value['name'])][] = $value['value']; |
} elseif (isset($return->headers[strtolower($value['name'])])) { |
$return->headers[strtolower($value['name'])][] = $value['value']; |
} else { |
$return->headers[strtolower($value['name'])] = $value['value']; |
} |
} |
reset($headers); |
while (list($key, $value) = each($headers)) { |
$headers[$key]['name'] = strtolower($headers[$key]['name']); |
switch ($headers[$key]['name']) { |
case 'content-type': |
$content_type = $this->_parseHeaderValue($headers[$key]['value']); |
if (preg_match('/([0-9a-z+.-]+)\/([0-9a-z+.-]+)/i', $content_type['value'], $regs)) { |
$return->ctype_primary = $regs[1]; |
$return->ctype_secondary = $regs[2]; |
} |
if (isset($content_type['other'])) { |
while (list($p_name, $p_value) = each($content_type['other'])) { |
$return->ctype_parameters[$p_name] = $p_value; |
} |
} |
break; |
case 'content-disposition': |
$content_disposition = $this->_parseHeaderValue($headers[$key]['value']); |
$return->disposition = $content_disposition['value']; |
if (isset($content_disposition['other'])) { |
while (list($p_name, $p_value) = each($content_disposition['other'])) { |
$return->d_parameters[$p_name] = $p_value; |
} |
} |
break; |
case 'content-transfer-encoding': |
$content_transfer_encoding = $this->_parseHeaderValue($headers[$key]['value']); |
break; |
} |
} |
if (isset($content_type)) { |
switch (strtolower($content_type['value'])) { |
case 'text/plain': |
$encoding = isset($content_transfer_encoding) ? $content_transfer_encoding['value'] : '7bit'; |
$this->_include_bodies ? $return->body = ($this->_decode_bodies ? $this->_decodeBody($body, $encoding) : $body) : null; |
break; |
case 'text/html': |
$encoding = isset($content_transfer_encoding) ? $content_transfer_encoding['value'] : '7bit'; |
$this->_include_bodies ? $return->body = ($this->_decode_bodies ? $this->_decodeBody($body, $encoding) : $body) : null; |
break; |
case 'multipart/parallel': |
case 'multipart/report': // RFC1892 |
case 'multipart/signed': // PGP |
case 'multipart/digest': |
case 'multipart/alternative': |
case 'multipart/related': |
case 'multipart/mixed': |
if(!isset($content_type['other']['boundary'])){ |
$this->_error = 'No boundary found for ' . $content_type['value'] . ' part'; |
return false; |
} |
$default_ctype = (strtolower($content_type['value']) === 'multipart/digest') ? 'message/rfc822' : 'text/plain'; |
$parts = $this->_boundarySplit($body, $content_type['other']['boundary']); |
for ($i = 0; $i < count($parts); $i++) { |
list($part_header, $part_body) = $this->_splitBodyHeader($parts[$i]); |
$part = $this->_decode($part_header, $part_body, $default_ctype); |
if($part === false) |
$part = $this->raiseError($this->_error); |
$return->parts[] = $part; |
} |
break; |
case 'message/rfc822': |
$obj = &new Mail_mimeDecode($body); |
$return->parts[] = $obj->decode(array('include_bodies' => $this->_include_bodies, |
'decode_bodies' => $this->_decode_bodies, |
'decode_headers' => $this->_decode_headers)); |
unset($obj); |
break; |
default: |
if(!isset($content_transfer_encoding['value'])) |
$content_transfer_encoding['value'] = '7bit'; |
$this->_include_bodies ? $return->body = ($this->_decode_bodies ? $this->_decodeBody($body, $content_transfer_encoding['value']) : $body) : null; |
break; |
} |
} else { |
$ctype = explode('/', $default_ctype); |
$return->ctype_primary = $ctype[0]; |
$return->ctype_secondary = $ctype[1]; |
$this->_include_bodies ? $return->body = ($this->_decode_bodies ? $this->_decodeBody($body) : $body) : null; |
} |
return $return; |
} |
/** |
* Given the output of the above function, this will return an |
* array of references to the parts, indexed by mime number. |
* |
* @param object $structure The structure to go through |
* @param string $mime_number Internal use only. |
* @return array Mime numbers |
*/ |
function &getMimeNumbers(&$structure, $no_refs = false, $mime_number = '', $prepend = '') |
{ |
$return = array(); |
if (!empty($structure->parts)) { |
if ($mime_number != '') { |
$structure->mime_id = $prepend . $mime_number; |
$return[$prepend . $mime_number] = &$structure; |
} |
for ($i = 0; $i < count($structure->parts); $i++) { |
if (!empty($structure->headers['content-type']) AND substr(strtolower($structure->headers['content-type']), 0, 8) == 'message/') { |
$prepend = $prepend . $mime_number . '.'; |
$_mime_number = ''; |
} else { |
$_mime_number = ($mime_number == '' ? $i + 1 : sprintf('%s.%s', $mime_number, $i + 1)); |
} |
$arr = &Mail_mimeDecode::getMimeNumbers($structure->parts[$i], $no_refs, $_mime_number, $prepend); |
foreach ($arr as $key => $val) { |
$no_refs ? $return[$key] = '' : $return[$key] = &$arr[$key]; |
} |
} |
} else { |
if ($mime_number == '') { |
$mime_number = '1'; |
} |
$structure->mime_id = $prepend . $mime_number; |
$no_refs ? $return[$prepend . $mime_number] = '' : $return[$prepend . $mime_number] = &$structure; |
} |
return $return; |
} |
/** |
* Given a string containing a header and body |
* section, this function will split them (at the first |
* blank line) and return them. |
* |
* @param string Input to split apart |
* @return array Contains header and body section |
* @access private |
*/ |
function _splitBodyHeader($input) |
{ |
if (preg_match("/^(.*?)\r?\n\r?\n(.*)/s", $input, $match)) { |
return array($match[1], $match[2]); |
} |
$this->_error = 'Could not split header and body'; |
return false; |
} |
/** |
* Parse headers given in $input and return |
* as assoc array. |
* |
* @param string Headers to parse |
* @return array Contains parsed headers |
* @access private |
*/ |
function _parseHeaders($input) |
{ |
if ($input !== '') { |
// Unfold the input |
$input = preg_replace("/\r?\n/", "\r\n", $input); |
$input = preg_replace("/\r\n(\t| )+/", ' ', $input); |
$headers = explode("\r\n", trim($input)); |
foreach ($headers as $value) { |
$hdr_name = substr($value, 0, $pos = strpos($value, ':')); |
$hdr_value = substr($value, $pos+1); |
if($hdr_value[0] == ' ') |
$hdr_value = substr($hdr_value, 1); |
$return[] = array( |
'name' => $hdr_name, |
'value' => $this->_decode_headers ? $this->_decodeHeader($hdr_value) : $hdr_value |
); |
} |
} else { |
$return = array(); |
} |
return $return; |
} |
/** |
* Function to parse a header value, |
* extract first part, and any secondary |
* parts (after ;) This function is not as |
* robust as it could be. Eg. header comments |
* in the wrong place will probably break it. |
* |
* @param string Header value to parse |
* @return array Contains parsed result |
* @access private |
*/ |
function _parseHeaderValue($input) |
{ |
if (($pos = strpos($input, ';')) !== false) { |
$return['value'] = trim(substr($input, 0, $pos)); |
$input = trim(substr($input, $pos+1)); |
if (strlen($input) > 0) { |
// This splits on a semi-colon, if there's no preceeding backslash |
// Now works with quoted values; had to glue the \; breaks in PHP |
// the regex is already bordering on incomprehensible |
$splitRegex = '/([^;\'"]*[\'"]([^\'"]*([^\'"]*)*)[\'"][^;\'"]*|([^;]+))(;|$)/'; |
preg_match_all($splitRegex, $input, $matches); |
$parameters = array(); |
for ($i=0; $i<count($matches[0]); $i++) { |
$param = $matches[0][$i]; |
while (substr($param, -2) == '\;') { |
$param .= $matches[0][++$i]; |
} |
$parameters[] = $param; |
} |
for ($i = 0; $i < count($parameters); $i++) { |
$param_name = trim(substr($parameters[$i], 0, $pos = strpos($parameters[$i], '=')), "'\";\t\\ "); |
$param_value = trim(str_replace('\;', ';', substr($parameters[$i], $pos + 1)), "'\";\t\\ "); |
if ($param_value[0] == '"') { |
$param_value = substr($param_value, 1, -1); |
} |
$return['other'][$param_name] = $param_value; |
$return['other'][strtolower($param_name)] = $param_value; |
} |
} |
} else { |
$return['value'] = trim($input); |
} |
return $return; |
} |
/** |
* This function splits the input based |
* on the given boundary |
* |
* @param string Input to parse |
* @return array Contains array of resulting mime parts |
* @access private |
*/ |
function _boundarySplit($input, $boundary) |
{ |
$parts = array(); |
$bs_possible = substr($boundary, 2, -2); |
$bs_check = '\"' . $bs_possible . '\"'; |
if ($boundary == $bs_check) { |
$boundary = $bs_possible; |
} |
$tmp = explode('--' . $boundary, $input); |
for ($i = 1; $i < count($tmp) - 1; $i++) { |
$parts[] = $tmp[$i]; |
} |
return $parts; |
} |
/** |
* Given a header, this function will decode it |
* according to RFC2047. Probably not *exactly* |
* conformant, but it does pass all the given |
* examples (in RFC2047). |
* |
* @param string Input header value to decode |
* @return string Decoded header value |
* @access private |
*/ |
function _decodeHeader($input) |
{ |
// Remove white space between encoded-words |
$input = preg_replace('/(=\?[^?]+\?(q|b)\?[^?]*\?=)(\s)+=\?/i', '\1=?', $input); |
// For each encoded-word... |
while (preg_match('/(=\?([^?]+)\?(q|b)\?([^?]*)\?=)/i', $input, $matches)) { |
$encoded = $matches[1]; |
$charset = $matches[2]; |
$encoding = $matches[3]; |
$text = $matches[4]; |
switch (strtolower($encoding)) { |
case 'b': |
$text = base64_decode($text); |
break; |
case 'q': |
$text = str_replace('_', ' ', $text); |
preg_match_all('/=([a-f0-9]{2})/i', $text, $matches); |
foreach($matches[1] as $value) |
$text = str_replace('='.$value, chr(hexdec($value)), $text); |
break; |
} |
$input = str_replace($encoded, $text, $input); |
} |
return $input; |
} |
/** |
* Given a body string and an encoding type, |
* this function will decode and return it. |
* |
* @param string Input body to decode |
* @param string Encoding type to use. |
* @return string Decoded body |
* @access private |
*/ |
function _decodeBody($input, $encoding = '7bit') |
{ |
switch (strtolower($encoding)) { |
case '7bit': |
return $input; |
break; |
case 'quoted-printable': |
return $this->_quotedPrintableDecode($input); |
break; |
case 'base64': |
return base64_decode($input); |
break; |
default: |
return $input; |
} |
} |
/** |
* Given a quoted-printable string, this |
* function will decode and return it. |
* |
* @param string Input body to decode |
* @return string Decoded body |
* @access private |
*/ |
function _quotedPrintableDecode($input) |
{ |
// Remove soft line breaks |
$input = preg_replace("/=\r?\n/", '', $input); |
// Replace encoded characters |
$input = preg_replace('/=([a-f0-9]{2})/ie', "chr(hexdec('\\1'))", $input); |
return $input; |
} |
/** |
* Checks the input for uuencoded files and returns |
* an array of them. Can be called statically, eg: |
* |
* $files =& Mail_mimeDecode::uudecode($some_text); |
* |
* It will check for the begin 666 ... end syntax |
* however and won't just blindly decode whatever you |
* pass it. |
* |
* @param string Input body to look for attahcments in |
* @return array Decoded bodies, filenames and permissions |
* @access public |
* @author Unknown |
*/ |
function &uudecode($input) |
{ |
// Find all uuencoded sections |
preg_match_all("/begin ([0-7]{3}) (.+)\r?\n(.+)\r?\nend/Us", $input, $matches); |
for ($j = 0; $j < count($matches[3]); $j++) { |
$str = $matches[3][$j]; |
$filename = $matches[2][$j]; |
$fileperm = $matches[1][$j]; |
$file = ''; |
$str = preg_split("/\r?\n/", trim($str)); |
$strlen = count($str); |
for ($i = 0; $i < $strlen; $i++) { |
$pos = 1; |
$d = 0; |
$len=(int)(((ord(substr($str[$i],0,1)) -32) - ' ') & 077); |
while (($d + 3 <= $len) AND ($pos + 4 <= strlen($str[$i]))) { |
$c0 = (ord(substr($str[$i],$pos,1)) ^ 0x20); |
$c1 = (ord(substr($str[$i],$pos+1,1)) ^ 0x20); |
$c2 = (ord(substr($str[$i],$pos+2,1)) ^ 0x20); |
$c3 = (ord(substr($str[$i],$pos+3,1)) ^ 0x20); |
$file .= chr(((($c0 - ' ') & 077) << 2) | ((($c1 - ' ') & 077) >> 4)); |
$file .= chr(((($c1 - ' ') & 077) << 4) | ((($c2 - ' ') & 077) >> 2)); |
$file .= chr(((($c2 - ' ') & 077) << 6) | (($c3 - ' ') & 077)); |
$pos += 4; |
$d += 3; |
} |
if (($d + 2 <= $len) && ($pos + 3 <= strlen($str[$i]))) { |
$c0 = (ord(substr($str[$i],$pos,1)) ^ 0x20); |
$c1 = (ord(substr($str[$i],$pos+1,1)) ^ 0x20); |
$c2 = (ord(substr($str[$i],$pos+2,1)) ^ 0x20); |
$file .= chr(((($c0 - ' ') & 077) << 2) | ((($c1 - ' ') & 077) >> 4)); |
$file .= chr(((($c1 - ' ') & 077) << 4) | ((($c2 - ' ') & 077) >> 2)); |
$pos += 3; |
$d += 2; |
} |
if (($d + 1 <= $len) && ($pos + 2 <= strlen($str[$i]))) { |
$c0 = (ord(substr($str[$i],$pos,1)) ^ 0x20); |
$c1 = (ord(substr($str[$i],$pos+1,1)) ^ 0x20); |
$file .= chr(((($c0 - ' ') & 077) << 2) | ((($c1 - ' ') & 077) >> 4)); |
} |
} |
$files[] = array('filename' => $filename, 'fileperm' => $fileperm, 'filedata' => $file); |
} |
return $files; |
} |
/** |
* getSendArray() returns the arguments required for Mail::send() |
* used to build the arguments for a mail::send() call |
* |
* Usage: |
* $mailtext = Full email (for example generated by a template) |
* $decoder = new Mail_mimeDecode($mailtext); |
* $parts = $decoder->getSendArray(); |
* if (!PEAR::isError($parts) { |
* list($recipents,$headers,$body) = $parts; |
* $mail = Mail::factory('smtp'); |
* $mail->send($recipents,$headers,$body); |
* } else { |
* echo $parts->message; |
* } |
* @return mixed array of recipeint, headers,body or Pear_Error |
* @access public |
* @author Alan Knowles <alan@akbkhome.com> |
*/ |
function getSendArray() |
{ |
// prevent warning if this is not set |
$this->_decode_headers = FALSE; |
$headerlist =$this->_parseHeaders($this->_header); |
$to = ""; |
if (!$headerlist) { |
return $this->raiseError("Message did not contain headers"); |
} |
foreach($headerlist as $item) { |
$header[$item['name']] = $item['value']; |
switch (strtolower($item['name'])) { |
case "to": |
case "cc": |
case "bcc": |
$to = ",".$item['value']; |
default: |
break; |
} |
} |
if ($to == "") { |
return $this->raiseError("Message did not contain any recipents"); |
} |
$to = substr($to,1); |
return array($to,$header,$this->_body); |
} |
/** |
* Returns a xml copy of the output of |
* Mail_mimeDecode::decode. Pass the output in as the |
* argument. This function can be called statically. Eg: |
* |
* $output = $obj->decode(); |
* $xml = Mail_mimeDecode::getXML($output); |
* |
* The DTD used for this should have been in the package. Or |
* alternatively you can get it from cvs, or here: |
* http://www.phpguru.org/xmail/xmail.dtd. |
* |
* @param object Input to convert to xml. This should be the |
* output of the Mail_mimeDecode::decode function |
* @return string XML version of input |
* @access public |
*/ |
function getXML($input) |
{ |
$crlf = "\r\n"; |
$output = '<?xml version=\'1.0\'?>' . $crlf . |
'<!DOCTYPE email SYSTEM "http://www.phpguru.org/xmail/xmail.dtd">' . $crlf . |
'<email>' . $crlf . |
Mail_mimeDecode::_getXML($input) . |
'</email>'; |
return $output; |
} |
/** |
* Function that does the actual conversion to xml. Does a single |
* mimepart at a time. |
* |
* @param object Input to convert to xml. This is a mimepart object. |
* It may or may not contain subparts. |
* @param integer Number of tabs to indent |
* @return string XML version of input |
* @access private |
*/ |
function _getXML($input, $indent = 1) |
{ |
$htab = "\t"; |
$crlf = "\r\n"; |
$output = ''; |
$headers = @(array)$input->headers; |
foreach ($headers as $hdr_name => $hdr_value) { |
// Multiple headers with this name |
if (is_array($headers[$hdr_name])) { |
for ($i = 0; $i < count($hdr_value); $i++) { |
$output .= Mail_mimeDecode::_getXML_helper($hdr_name, $hdr_value[$i], $indent); |
} |
// Only one header of this sort |
} else { |
$output .= Mail_mimeDecode::_getXML_helper($hdr_name, $hdr_value, $indent); |
} |
} |
if (!empty($input->parts)) { |
for ($i = 0; $i < count($input->parts); $i++) { |
$output .= $crlf . str_repeat($htab, $indent) . '<mimepart>' . $crlf . |
Mail_mimeDecode::_getXML($input->parts[$i], $indent+1) . |
str_repeat($htab, $indent) . '</mimepart>' . $crlf; |
} |
} elseif (isset($input->body)) { |
$output .= $crlf . str_repeat($htab, $indent) . '<body><![CDATA[' . |
$input->body . ']]></body>' . $crlf; |
} |
return $output; |
} |
/** |
* Helper function to _getXML(). Returns xml of a header. |
* |
* @param string Name of header |
* @param string Value of header |
* @param integer Number of tabs to indent |
* @return string XML version of input |
* @access private |
*/ |
function _getXML_helper($hdr_name, $hdr_value, $indent) |
{ |
$htab = "\t"; |
$crlf = "\r\n"; |
$return = ''; |
$new_hdr_value = ($hdr_name != 'received') ? Mail_mimeDecode::_parseHeaderValue($hdr_value) : array('value' => $hdr_value); |
$new_hdr_name = str_replace(' ', '-', ucwords(str_replace('-', ' ', $hdr_name))); |
// Sort out any parameters |
if (!empty($new_hdr_value['other'])) { |
foreach ($new_hdr_value['other'] as $paramname => $paramvalue) { |
$params[] = str_repeat($htab, $indent) . $htab . '<parameter>' . $crlf . |
str_repeat($htab, $indent) . $htab . $htab . '<paramname>' . htmlspecialchars($paramname) . '</paramname>' . $crlf . |
str_repeat($htab, $indent) . $htab . $htab . '<paramvalue>' . htmlspecialchars($paramvalue) . '</paramvalue>' . $crlf . |
str_repeat($htab, $indent) . $htab . '</parameter>' . $crlf; |
} |
$params = implode('', $params); |
} else { |
$params = ''; |
} |
$return = str_repeat($htab, $indent) . '<header>' . $crlf . |
str_repeat($htab, $indent) . $htab . '<headername>' . htmlspecialchars($new_hdr_name) . '</headername>' . $crlf . |
str_repeat($htab, $indent) . $htab . '<headervalue>' . htmlspecialchars($new_hdr_value['value']) . '</headervalue>' . $crlf . |
$params . |
str_repeat($htab, $indent) . '</header>' . $crlf; |
return $return; |
} |
} // End of class |
?> |
/branches/livraison_menes/api/pear/Mail/sendmail.php |
---|
New file |
0,0 → 1,145 |
<?php |
// |
// +----------------------------------------------------------------------+ |
// | PHP Version 4 | |
// +----------------------------------------------------------------------+ |
// | Copyright (c) 1997-2003 The PHP Group | |
// +----------------------------------------------------------------------+ |
// | This source file is subject to version 2.02 of the PHP license, | |
// | that is bundled with this package in the file LICENSE, and is | |
// | available at through the world-wide-web at | |
// | http://www.php.net/license/2_02.txt. | |
// | If you did not receive a copy of the PHP license and are unable to | |
// | obtain it through the world-wide-web, please send a note to | |
// | license@php.net so we can mail you a copy immediately. | |
// +----------------------------------------------------------------------+ |
// | Author: Chuck Hagenbuch <chuck@horde.org> | |
// +----------------------------------------------------------------------+ |
/** |
* Sendmail implementation of the PEAR Mail:: interface. |
* @access public |
* @package Mail |
* @version $Revision: 1.1 $ |
*/ |
class Mail_sendmail extends Mail { |
/** |
* The location of the sendmail or sendmail wrapper binary on the |
* filesystem. |
* @var string |
*/ |
var $sendmail_path = '/usr/sbin/sendmail'; |
/** |
* Any extra command-line parameters to pass to the sendmail or |
* sendmail wrapper binary. |
* @var string |
*/ |
var $sendmail_args = ''; |
/** |
* Constructor. |
* |
* Instantiates a new Mail_sendmail:: object based on the parameters |
* passed in. It looks for the following parameters: |
* sendmail_path The location of the sendmail binary on the |
* filesystem. Defaults to '/usr/sbin/sendmail'. |
* |
* sendmail_args Any extra parameters to pass to the sendmail |
* or sendmail wrapper binary. |
* |
* If a parameter is present in the $params array, it replaces the |
* default. |
* |
* @param array $params Hash containing any parameters different from the |
* defaults. |
* @access public |
*/ |
function Mail_sendmail($params) |
{ |
if (isset($params['sendmail_path'])) $this->sendmail_path = $params['sendmail_path']; |
if (isset($params['sendmail_args'])) $this->sendmail_args = $params['sendmail_args']; |
/* |
* Because we need to pass message headers to the sendmail program on |
* the commandline, we can't guarantee the use of the standard "\r\n" |
* separator. Instead, we use the system's native line separator. |
*/ |
$this->sep = (strpos(PHP_OS, 'WIN') === false) ? "\n" : "\r\n"; |
} |
/** |
* Implements Mail::send() function using the sendmail |
* command-line binary. |
* |
* @param mixed $recipients Either a comma-seperated list of recipients |
* (RFC822 compliant), or an array of recipients, |
* each RFC822 valid. This may contain recipients not |
* specified in the headers, for Bcc:, resending |
* messages, etc. |
* |
* @param array $headers The array of headers to send with the mail, in an |
* associative array, where the array key is the |
* header name (ie, 'Subject'), and the array value |
* is the header value (ie, 'test'). The header |
* produced from those values would be 'Subject: |
* test'. |
* |
* @param string $body The full text of the message body, including any |
* Mime parts, etc. |
* |
* @return mixed Returns true on success, or a PEAR_Error |
* containing a descriptive error message on |
* failure. |
* @access public |
*/ |
function send($recipients, $headers, $body) |
{ |
$recipients = $this->parseRecipients($recipients); |
if (PEAR::isError($recipients)) { |
return $recipients; |
} |
$recipients = escapeShellCmd(implode(' ', $recipients)); |
$headerElements = $this->prepareHeaders($headers); |
if (PEAR::isError($headerElements)) { |
return $headerElements; |
} |
list($from, $text_headers) = $headerElements; |
if (!isset($from)) { |
return PEAR::raiseError('No from address given.'); |
} elseif (strpos($from, ' ') !== false || |
strpos($from, ';') !== false || |
strpos($from, '&') !== false || |
strpos($from, '`') !== false) { |
return PEAR::raiseError('From address specified with dangerous characters.'); |
} |
$result = 0; |
if (@is_file($this->sendmail_path)) { |
$from = escapeShellCmd($from); |
$mail = popen($this->sendmail_path . (!empty($this->sendmail_args) ? ' ' . $this->sendmail_args : '') . " -f$from -- $recipients", 'w'); |
fputs($mail, $text_headers); |
fputs($mail, $this->sep); // newline to end the headers section |
fputs($mail, $body); |
$result = pclose($mail); |
if (version_compare(phpversion(), '4.2.3') == -1) { |
// With older php versions, we need to shift the |
// pclose result to get the exit code. |
$result = $result >> 8 & 0xFF; |
} |
} else { |
return PEAR::raiseError('sendmail [' . $this->sendmail_path . '] is not a valid file'); |
} |
if ($result != 0) { |
return PEAR::raiseError('sendmail returned error code ' . $result, |
$result); |
} |
return true; |
} |
} |
/branches/livraison_menes/api/pear/Mail/mimePart.php |
---|
New file |
0,0 → 1,351 |
<?php |
// +-----------------------------------------------------------------------+ |
// | Copyright (c) 2002-2003 Richard Heyes | |
// | All rights reserved. | |
// | | |
// | Redistribution and use in source and binary forms, with or without | |
// | modification, are permitted provided that the following conditions | |
// | are met: | |
// | | |
// | o Redistributions of source code must retain the above copyright | |
// | notice, this list of conditions and the following disclaimer. | |
// | o 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.| |
// | o The names of the authors may not be used to endorse or promote | |
// | products derived from this software without specific prior written | |
// | permission. | |
// | | |
// | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS | |
// | "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT | |
// | LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR | |
// | A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT | |
// | OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, | |
// | SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT | |
// | LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, | |
// | DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY | |
// | THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | |
// | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE | |
// | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | |
// | | |
// +-----------------------------------------------------------------------+ |
// | Author: Richard Heyes <richard@phpguru.org> | |
// +-----------------------------------------------------------------------+ |
/** |
* |
* Raw mime encoding class |
* |
* What is it? |
* This class enables you to manipulate and build |
* a mime email from the ground up. |
* |
* Why use this instead of mime.php? |
* mime.php is a userfriendly api to this class for |
* people who aren't interested in the internals of |
* mime mail. This class however allows full control |
* over the email. |
* |
* Eg. |
* |
* // Since multipart/mixed has no real body, (the body is |
* // the subpart), we set the body argument to blank. |
* |
* $params['content_type'] = 'multipart/mixed'; |
* $email = new Mail_mimePart('', $params); |
* |
* // Here we add a text part to the multipart we have |
* // already. Assume $body contains plain text. |
* |
* $params['content_type'] = 'text/plain'; |
* $params['encoding'] = '7bit'; |
* $text = $email->addSubPart($body, $params); |
* |
* // Now add an attachment. Assume $attach is |
* the contents of the attachment |
* |
* $params['content_type'] = 'application/zip'; |
* $params['encoding'] = 'base64'; |
* $params['disposition'] = 'attachment'; |
* $params['dfilename'] = 'example.zip'; |
* $attach =& $email->addSubPart($body, $params); |
* |
* // Now build the email. Note that the encode |
* // function returns an associative array containing two |
* // elements, body and headers. You will need to add extra |
* // headers, (eg. Mime-Version) before sending. |
* |
* $email = $message->encode(); |
* $email['headers'][] = 'Mime-Version: 1.0'; |
* |
* |
* Further examples are available at http://www.phpguru.org |
* |
* TODO: |
* - Set encode() to return the $obj->encoded if encode() |
* has already been run. Unless a flag is passed to specifically |
* re-build the message. |
* |
* @author Richard Heyes <richard@phpguru.org> |
* @version $Revision: 1.1 $ |
* @package Mail |
*/ |
class Mail_mimePart { |
/** |
* The encoding type of this part |
* @var string |
*/ |
var $_encoding; |
/** |
* An array of subparts |
* @var array |
*/ |
var $_subparts; |
/** |
* The output of this part after being built |
* @var string |
*/ |
var $_encoded; |
/** |
* Headers for this part |
* @var array |
*/ |
var $_headers; |
/** |
* The body of this part (not encoded) |
* @var string |
*/ |
var $_body; |
/** |
* Constructor. |
* |
* Sets up the object. |
* |
* @param $body - The body of the mime part if any. |
* @param $params - An associative array of parameters: |
* content_type - The content type for this part eg multipart/mixed |
* encoding - The encoding to use, 7bit, 8bit, base64, or quoted-printable |
* cid - Content ID to apply |
* disposition - Content disposition, inline or attachment |
* dfilename - Optional filename parameter for content disposition |
* description - Content description |
* charset - Character set to use |
* @access public |
*/ |
function Mail_mimePart($body = '', $params = array()) |
{ |
if (!defined('MAIL_MIMEPART_CRLF')) { |
define('MAIL_MIMEPART_CRLF', defined('MAIL_MIME_CRLF') ? MAIL_MIME_CRLF : "\r\n", TRUE); |
} |
foreach ($params as $key => $value) { |
switch ($key) { |
case 'content_type': |
$headers['Content-Type'] = $value . (isset($charset) ? '; charset="' . $charset . '"' : ''); |
break; |
case 'encoding': |
$this->_encoding = $value; |
$headers['Content-Transfer-Encoding'] = $value; |
break; |
case 'cid': |
$headers['Content-ID'] = '<' . $value . '>'; |
break; |
case 'disposition': |
$headers['Content-Disposition'] = $value . (isset($dfilename) ? '; filename="' . $dfilename . '"' : ''); |
break; |
case 'dfilename': |
if (isset($headers['Content-Disposition'])) { |
$headers['Content-Disposition'] .= '; filename="' . $value . '"'; |
} else { |
$dfilename = $value; |
} |
break; |
case 'description': |
$headers['Content-Description'] = $value; |
break; |
case 'charset': |
if (isset($headers['Content-Type'])) { |
$headers['Content-Type'] .= '; charset="' . $value . '"'; |
} else { |
$charset = $value; |
} |
break; |
} |
} |
// Default content-type |
if (!isset($headers['Content-Type'])) { |
$headers['Content-Type'] = 'text/plain'; |
} |
//Default encoding |
if (!isset($this->_encoding)) { |
$this->_encoding = '7bit'; |
} |
// Assign stuff to member variables |
$this->_encoded = array(); |
$this->_headers = $headers; |
$this->_body = $body; |
} |
/** |
* encode() |
* |
* Encodes and returns the email. Also stores |
* it in the encoded member variable |
* |
* @return An associative array containing two elements, |
* body and headers. The headers element is itself |
* an indexed array. |
* @access public |
*/ |
function encode() |
{ |
$encoded =& $this->_encoded; |
if (!empty($this->_subparts)) { |
srand((double)microtime()*1000000); |
$boundary = '=_' . md5(rand() . microtime()); |
$this->_headers['Content-Type'] .= ';' . MAIL_MIMEPART_CRLF . "\t" . 'boundary="' . $boundary . '"'; |
// Add body parts to $subparts |
for ($i = 0; $i < count($this->_subparts); $i++) { |
$headers = array(); |
$tmp = $this->_subparts[$i]->encode(); |
foreach ($tmp['headers'] as $key => $value) { |
$headers[] = $key . ': ' . $value; |
} |
$subparts[] = implode(MAIL_MIMEPART_CRLF, $headers) . MAIL_MIMEPART_CRLF . MAIL_MIMEPART_CRLF . $tmp['body']; |
} |
$encoded['body'] = '--' . $boundary . MAIL_MIMEPART_CRLF . |
implode('--' . $boundary . MAIL_MIMEPART_CRLF, $subparts) . |
'--' . $boundary.'--' . MAIL_MIMEPART_CRLF; |
} else { |
$encoded['body'] = $this->_getEncodedData($this->_body, $this->_encoding) . MAIL_MIMEPART_CRLF; |
} |
// Add headers to $encoded |
$encoded['headers'] =& $this->_headers; |
return $encoded; |
} |
/** |
* &addSubPart() |
* |
* Adds a subpart to current mime part and returns |
* a reference to it |
* |
* @param $body The body of the subpart, if any. |
* @param $params The parameters for the subpart, same |
* as the $params argument for constructor. |
* @return A reference to the part you just added. It is |
* crucial if using multipart/* in your subparts that |
* you use =& in your script when calling this function, |
* otherwise you will not be able to add further subparts. |
* @access public |
*/ |
function &addSubPart($body, $params) |
{ |
$this->_subparts[] = new Mail_mimePart($body, $params); |
return $this->_subparts[count($this->_subparts) - 1]; |
} |
/** |
* _getEncodedData() |
* |
* Returns encoded data based upon encoding passed to it |
* |
* @param $data The data to encode. |
* @param $encoding The encoding type to use, 7bit, base64, |
* or quoted-printable. |
* @access private |
*/ |
function _getEncodedData($data, $encoding) |
{ |
switch ($encoding) { |
case '8bit': |
case '7bit': |
return $data; |
break; |
case 'quoted-printable': |
return $this->_quotedPrintableEncode($data); |
break; |
case 'base64': |
return rtrim(chunk_split(base64_encode($data), 76, MAIL_MIMEPART_CRLF)); |
break; |
default: |
return $data; |
} |
} |
/** |
* quoteadPrintableEncode() |
* |
* Encodes data to quoted-printable standard. |
* |
* @param $input The data to encode |
* @param $line_max Optional max line length. Should |
* not be more than 76 chars |
* |
* @access private |
*/ |
function _quotedPrintableEncode($input , $line_max = 76) |
{ |
$lines = preg_split("/\r?\n/", $input); |
$eol = MAIL_MIMEPART_CRLF; |
$escape = '='; |
$output = ''; |
while(list(, $line) = each($lines)){ |
$linlen = strlen($line); |
$newline = ''; |
for ($i = 0; $i < $linlen; $i++) { |
$char = substr($line, $i, 1); |
$dec = ord($char); |
if (($dec == 32) AND ($i == ($linlen - 1))){ // convert space at eol only |
$char = '=20'; |
} elseif(($dec == 9) AND ($i == ($linlen - 1))) { // convert tab at eol only |
$char = '=09'; |
} elseif($dec == 9) { |
; // Do nothing if a tab. |
} elseif(($dec == 61) OR ($dec < 32 ) OR ($dec > 126)) { |
$char = $escape . strtoupper(sprintf('%02s', dechex($dec))); |
} |
if ((strlen($newline) + strlen($char)) >= $line_max) { // MAIL_MIMEPART_CRLF is not counted |
$output .= $newline . $escape . $eol; // soft line break; " =\r\n" is okay |
$newline = ''; |
} |
$newline .= $char; |
} // end of for |
$output .= $newline . $eol; |
} |
$output = substr($output, 0, -1 * strlen($eol)); // Don't want last crlf |
return $output; |
} |
} // End of class |
?> |
/branches/livraison_menes/api/pear/Mail/mail.php |
---|
New file |
0,0 → 1,130 |
<?php |
// |
// +----------------------------------------------------------------------+ |
// | PHP Version 4 | |
// +----------------------------------------------------------------------+ |
// | Copyright (c) 1997-2003 The PHP Group | |
// +----------------------------------------------------------------------+ |
// | This source file is subject to version 2.02 of the PHP license, | |
// | that is bundled with this package in the file LICENSE, and is | |
// | available at through the world-wide-web at | |
// | http://www.php.net/license/2_02.txt. | |
// | If you did not receive a copy of the PHP license and are unable to | |
// | obtain it through the world-wide-web, please send a note to | |
// | license@php.net so we can mail you a copy immediately. | |
// +----------------------------------------------------------------------+ |
// | Author: Chuck Hagenbuch <chuck@horde.org> | |
// +----------------------------------------------------------------------+ |
// |
// $Id: mail.php,v 1.1 2005-11-24 16:15:46 florian Exp $ |
/** |
* internal PHP-mail() implementation of the PEAR Mail:: interface. |
* @package Mail |
* @version $Revision: 1.1 $ |
*/ |
class Mail_mail extends Mail { |
/** |
* Any arguments to pass to the mail() function. |
* @var string |
*/ |
var $_params = ''; |
/** |
* Constructor. |
* |
* Instantiates a new Mail_mail:: object based on the parameters |
* passed in. |
* |
* @param array $params Extra arguments for the mail() function. |
*/ |
function Mail_mail($params = null) |
{ |
/* The other mail implementations accept parameters as arrays. |
* In the interest of being consistent, explode an array into |
* a string of parameter arguments. */ |
if (is_array($params)) { |
$this->_params = join(' ', $params); |
} else { |
$this->_params = $params; |
} |
/* Because the mail() function may pass headers as command |
* line arguments, we can't guarantee the use of the standard |
* "\r\n" separator. Instead, we use the system's native line |
* separator. */ |
$this->sep = (strpos(PHP_OS, 'WIN') === false) ? "\n" : "\r\n"; |
} |
/** |
* Implements Mail_mail::send() function using php's built-in mail() |
* command. |
* |
* @param mixed $recipients Either a comma-seperated list of recipients |
* (RFC822 compliant), or an array of recipients, |
* each RFC822 valid. This may contain recipients not |
* specified in the headers, for Bcc:, resending |
* messages, etc. |
* |
* @param array $headers The array of headers to send with the mail, in an |
* associative array, where the array key is the |
* header name (ie, 'Subject'), and the array value |
* is the header value (ie, 'test'). The header |
* produced from those values would be 'Subject: |
* test'. |
* |
* @param string $body The full text of the message body, including any |
* Mime parts, etc. |
* |
* @return mixed Returns true on success, or a PEAR_Error |
* containing a descriptive error message on |
* failure. |
* |
* @access public |
*/ |
function send($recipients, $headers, $body) |
{ |
// If we're passed an array of recipients, implode it. |
if (is_array($recipients)) { |
$recipients = implode(', ', $recipients); |
} |
// Get the Subject out of the headers array so that we can |
// pass it as a seperate argument to mail(). |
$subject = ''; |
if (isset($headers['Subject'])) { |
$subject = $headers['Subject']; |
unset($headers['Subject']); |
} |
// Flatten the headers out. |
$headerElements = $this->prepareHeaders($headers); |
if (PEAR::isError($headerElements)) { |
return $headerElements; |
} |
list(, $text_headers) = $headerElements; |
/* |
* We only use mail()'s optional fifth parameter if the additional |
* parameters have been provided and we're not running in safe mode. |
*/ |
if (empty($this->_params) || ini_get('safe_mode')) { |
$result = mail($recipients, $subject, $body, $text_headers); |
} else { |
$result = mail($recipients, $subject, $body, $text_headers, |
$this->_params); |
} |
/* |
* If the mail() function returned failure, we need to create a |
* PEAR_Error object and return it instead of the boolean result. |
*/ |
if ($result === false) { |
$result = PEAR::raiseError('mail() returned failure'); |
} |
return $result; |
} |
} |
/branches/livraison_menes/api/pear/Mail/smtp.php |
---|
New file |
0,0 → 1,323 |
<?php |
// |
// +----------------------------------------------------------------------+ |
// | PHP Version 4 | |
// +----------------------------------------------------------------------+ |
// | Copyright (c) 1997-2003 The PHP Group | |
// +----------------------------------------------------------------------+ |
// | This source file is subject to version 2.02 of the PHP license, | |
// | that is bundled with this package in the file LICENSE, and is | |
// | available at through the world-wide-web at | |
// | http://www.php.net/license/2_02.txt. | |
// | If you did not receive a copy of the PHP license and are unable to | |
// | obtain it through the world-wide-web, please send a note to | |
// | license@php.net so we can mail you a copy immediately. | |
// +----------------------------------------------------------------------+ |
// | Authors: Chuck Hagenbuch <chuck@horde.org> | |
// | Jon Parise <jon@php.net> | |
// +----------------------------------------------------------------------+ |
/** |
* SMTP implementation of the PEAR Mail interface. Requires the Net_SMTP class. |
* @access public |
* @package Mail |
* @version $Revision: 1.1 $ |
*/ |
class Mail_smtp extends Mail { |
/** |
* SMTP connection object. |
* |
* @var object |
* @access private |
*/ |
var $_smtp = null; |
/** |
* The SMTP host to connect to. |
* @var string |
*/ |
var $host = 'localhost'; |
/** |
* The port the SMTP server is on. |
* @var integer |
*/ |
var $port = 25; |
/** |
* Should SMTP authentication be used? |
* |
* This value may be set to true, false or the name of a specific |
* authentication method. |
* |
* If the value is set to true, the Net_SMTP package will attempt to use |
* the best authentication method advertised by the remote SMTP server. |
* |
* @var mixed |
*/ |
var $auth = false; |
/** |
* The username to use if the SMTP server requires authentication. |
* @var string |
*/ |
var $username = ''; |
/** |
* The password to use if the SMTP server requires authentication. |
* @var string |
*/ |
var $password = ''; |
/** |
* Hostname or domain that will be sent to the remote SMTP server in the |
* HELO / EHLO message. |
* |
* @var string |
*/ |
var $localhost = 'localhost'; |
/** |
* SMTP connection timeout value. NULL indicates no timeout. |
* |
* @var integer |
*/ |
var $timeout = null; |
/** |
* Whether to use VERP or not. If not a boolean, the string value |
* will be used as the VERP separators. |
* |
* @var mixed boolean or string |
*/ |
var $verp = false; |
/** |
* Turn on Net_SMTP debugging? |
* |
* @var boolean $debug |
*/ |
var $debug = false; |
/** |
* Indicates whether or not the SMTP connection should persist over |
* multiple calls to the send() method. |
* |
* @var boolean |
*/ |
var $persist = false; |
/** |
* Constructor. |
* |
* Instantiates a new Mail_smtp:: object based on the parameters |
* passed in. It looks for the following parameters: |
* host The server to connect to. Defaults to localhost. |
* port The port to connect to. Defaults to 25. |
* auth SMTP authentication. Defaults to none. |
* username The username to use for SMTP auth. No default. |
* password The password to use for SMTP auth. No default. |
* localhost The local hostname / domain. Defaults to localhost. |
* timeout The SMTP connection timeout. Defaults to none. |
* verp Whether to use VERP or not. Defaults to false. |
* debug Activate SMTP debug mode? Defaults to false. |
* persist Should the SMTP connection persist? |
* |
* If a parameter is present in the $params array, it replaces the |
* default. |
* |
* @param array Hash containing any parameters different from the |
* defaults. |
* @access public |
*/ |
function Mail_smtp($params) |
{ |
if (isset($params['host'])) $this->host = $params['host']; |
if (isset($params['port'])) $this->port = $params['port']; |
if (isset($params['auth'])) $this->auth = $params['auth']; |
if (isset($params['username'])) $this->username = $params['username']; |
if (isset($params['password'])) $this->password = $params['password']; |
if (isset($params['localhost'])) $this->localhost = $params['localhost']; |
if (isset($params['timeout'])) $this->timeout = $params['timeout']; |
if (isset($params['verp'])) $this->verp = $params['verp']; |
if (isset($params['debug'])) $this->debug = (boolean)$params['debug']; |
if (isset($params['persist'])) $this->persist = (boolean)$params['persist']; |
register_shutdown_function(array(&$this, '_Mail_smtp')); |
} |
/** |
* Destructor implementation to ensure that we disconnect from any |
* potentially-alive persistent SMTP connections. |
*/ |
function _Mail_smtp() |
{ |
$this->disconnect(); |
} |
/** |
* Implements Mail::send() function using SMTP. |
* |
* @param mixed $recipients Either a comma-seperated list of recipients |
* (RFC822 compliant), or an array of recipients, |
* each RFC822 valid. This may contain recipients not |
* specified in the headers, for Bcc:, resending |
* messages, etc. |
* |
* @param array $headers The array of headers to send with the mail, in an |
* associative array, where the array key is the |
* header name (e.g., 'Subject'), and the array value |
* is the header value (e.g., 'test'). The header |
* produced from those values would be 'Subject: |
* test'. |
* |
* @param string $body The full text of the message body, including any |
* Mime parts, etc. |
* |
* @return mixed Returns true on success, or a PEAR_Error |
* containing a descriptive error message on |
* failure. |
* @access public |
*/ |
function send($recipients, $headers, $body) |
{ |
include_once 'Net/SMTP.php'; |
/* If we don't already have an SMTP object, create one. */ |
if (is_object($this->_smtp) === false) { |
$this->_smtp =& new Net_SMTP($this->host, $this->port, |
$this->localhost); |
/* If we still don't have an SMTP object at this point, fail. */ |
if (is_object($this->_smtp) === false) { |
return PEAR::raiseError('Failed to create a Net_SMTP object'); |
} |
/* Configure the SMTP connection. */ |
if ($this->debug) { |
$this->_smtp->setDebug(true); |
} |
/* Attempt to connect to the configured SMTP server. */ |
if (PEAR::isError($res = $this->_smtp->connect($this->timeout))) { |
$error = $this->_error('Failed to connect to ' . |
$this->host . ':' . $this->port, |
$res); |
return PEAR::raiseError($error); |
} |
/* Attempt to authenticate if authentication has been enabled. */ |
if ($this->auth) { |
$method = is_string($this->auth) ? $this->auth : ''; |
if (PEAR::isError($res = $this->_smtp->auth($this->username, |
$this->password, |
$method))) { |
$error = $this->_error("$method authentication failure", |
$res); |
$this->_smtp->rset(); |
return PEAR::raiseError($error); |
} |
} |
} |
$headerElements = $this->prepareHeaders($headers); |
if (PEAR::isError($headerElements)) { |
$this->_smtp->rset(); |
return $headerElements; |
} |
list($from, $textHeaders) = $headerElements; |
/* Since few MTAs are going to allow this header to be forged |
* unless it's in the MAIL FROM: exchange, we'll use |
* Return-Path instead of From: if it's set. */ |
if (!empty($headers['Return-Path'])) { |
$from = $headers['Return-Path']; |
} |
if (!isset($from)) { |
$this->_smtp->rset(); |
return PEAR::raiseError('No From: address has been provided'); |
} |
$args['verp'] = $this->verp; |
if (PEAR::isError($res = $this->_smtp->mailFrom($from, $args))) { |
$error = $this->_error("Failed to set sender: $from", $res); |
$this->_smtp->rset(); |
return PEAR::raiseError($error); |
} |
$recipients = $this->parseRecipients($recipients); |
if (PEAR::isError($recipients)) { |
$this->_smtp->rset(); |
return $recipients; |
} |
foreach ($recipients as $recipient) { |
if (PEAR::isError($res = $this->_smtp->rcptTo($recipient))) { |
$error = $this->_error("Failed to add recipient: $recipient", |
$res); |
$this->_smtp->rset(); |
return PEAR::raiseError($error); |
} |
} |
/* Send the message's headers and the body as SMTP data. */ |
if (PEAR::isError($res = $this->_smtp->data("$textHeaders\r\n$body"))) { |
$error = $this->_error('Failed to send data', $res); |
$this->_smtp->rset(); |
return PEAR::raiseError($error); |
} |
/* If persistent connections are disabled, destroy our SMTP object. */ |
if ($this->persist === false) { |
$this->disconnect(); |
} |
return true; |
} |
/** |
* Disconnect and destroy the current SMTP connection. |
* |
* @return boolean True if the SMTP connection no longer exists. |
* |
* @since 1.1.9 |
* @access public |
*/ |
function disconnect() |
{ |
/* If we have an SMTP object, disconnect and destroy it. */ |
if (is_object($this->_smtp) && $this->_smtp->disconnect()) { |
$this->_smtp = null; |
} |
/* We are disconnected if we no longer have an SMTP object. */ |
return ($this->_smtp === null); |
} |
/** |
* Build a standardized string describing the current SMTP error. |
* |
* @param string $text Custom string describing the error context. |
* @param object $error Reference to the current PEAR_Error object. |
* |
* @return string A string describing the current SMTP error. |
* |
* @since 1.1.7 |
* @access private |
*/ |
function _error($text, &$error) |
{ |
/* Split the SMTP response into a code and a response string. */ |
list($code, $response) = $this->_smtp->getResponse(); |
/* Build our standardized error string. */ |
$msg = $text; |
$msg .= ' [SMTP: ' . $error->getMessage(); |
$msg .= " (code: $code, response: $response)]"; |
return $msg; |
} |
} |
/branches/livraison_menes/api/pear/Mail/RFC822.php |
---|
New file |
0,0 → 1,923 |
<?php |
// +-----------------------------------------------------------------------+ |
// | Copyright (c) 2001-2002, Richard Heyes | |
// | All rights reserved. | |
// | | |
// | Redistribution and use in source and binary forms, with or without | |
// | modification, are permitted provided that the following conditions | |
// | are met: | |
// | | |
// | o Redistributions of source code must retain the above copyright | |
// | notice, this list of conditions and the following disclaimer. | |
// | o 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.| |
// | o The names of the authors may not be used to endorse or promote | |
// | products derived from this software without specific prior written | |
// | permission. | |
// | | |
// | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS | |
// | "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT | |
// | LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR | |
// | A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT | |
// | OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, | |
// | SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT | |
// | LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, | |
// | DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY | |
// | THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | |
// | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE | |
// | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | |
// | | |
// +-----------------------------------------------------------------------+ |
// | Authors: Richard Heyes <richard@phpguru.org> | |
// | Chuck Hagenbuch <chuck@horde.org> | |
// +-----------------------------------------------------------------------+ |
/** |
* RFC 822 Email address list validation Utility |
* |
* What is it? |
* |
* This class will take an address string, and parse it into it's consituent |
* parts, be that either addresses, groups, or combinations. Nested groups |
* are not supported. The structure it returns is pretty straight forward, |
* and is similar to that provided by the imap_rfc822_parse_adrlist(). Use |
* print_r() to view the structure. |
* |
* How do I use it? |
* |
* $address_string = 'My Group: "Richard" <richard@localhost> (A comment), ted@example.com (Ted Bloggs), Barney;'; |
* $structure = Mail_RFC822::parseAddressList($address_string, 'example.com', true) |
* print_r($structure); |
* |
* @author Richard Heyes <richard@phpguru.org> |
* @author Chuck Hagenbuch <chuck@horde.org> |
* @version $Revision: 1.1 $ |
* @license BSD |
* @package Mail |
*/ |
class Mail_RFC822 { |
/** |
* The address being parsed by the RFC822 object. |
* @var string $address |
*/ |
var $address = ''; |
/** |
* The default domain to use for unqualified addresses. |
* @var string $default_domain |
*/ |
var $default_domain = 'localhost'; |
/** |
* Should we return a nested array showing groups, or flatten everything? |
* @var boolean $nestGroups |
*/ |
var $nestGroups = true; |
/** |
* Whether or not to validate atoms for non-ascii characters. |
* @var boolean $validate |
*/ |
var $validate = true; |
/** |
* The array of raw addresses built up as we parse. |
* @var array $addresses |
*/ |
var $addresses = array(); |
/** |
* The final array of parsed address information that we build up. |
* @var array $structure |
*/ |
var $structure = array(); |
/** |
* The current error message, if any. |
* @var string $error |
*/ |
var $error = null; |
/** |
* An internal counter/pointer. |
* @var integer $index |
*/ |
var $index = null; |
/** |
* The number of groups that have been found in the address list. |
* @var integer $num_groups |
* @access public |
*/ |
var $num_groups = 0; |
/** |
* A variable so that we can tell whether or not we're inside a |
* Mail_RFC822 object. |
* @var boolean $mailRFC822 |
*/ |
var $mailRFC822 = true; |
/** |
* A limit after which processing stops |
* @var int $limit |
*/ |
var $limit = null; |
/** |
* Sets up the object. The address must either be set here or when |
* calling parseAddressList(). One or the other. |
* |
* @access public |
* @param string $address The address(es) to validate. |
* @param string $default_domain Default domain/host etc. If not supplied, will be set to localhost. |
* @param boolean $nest_groups Whether to return the structure with groups nested for easier viewing. |
* @param boolean $validate Whether to validate atoms. Turn this off if you need to run addresses through before encoding the personal names, for instance. |
* |
* @return object Mail_RFC822 A new Mail_RFC822 object. |
*/ |
function Mail_RFC822($address = null, $default_domain = null, $nest_groups = null, $validate = null, $limit = null) |
{ |
if (isset($address)) $this->address = $address; |
if (isset($default_domain)) $this->default_domain = $default_domain; |
if (isset($nest_groups)) $this->nestGroups = $nest_groups; |
if (isset($validate)) $this->validate = $validate; |
if (isset($limit)) $this->limit = $limit; |
} |
/** |
* Starts the whole process. The address must either be set here |
* or when creating the object. One or the other. |
* |
* @access public |
* @param string $address The address(es) to validate. |
* @param string $default_domain Default domain/host etc. |
* @param boolean $nest_groups Whether to return the structure with groups nested for easier viewing. |
* @param boolean $validate Whether to validate atoms. Turn this off if you need to run addresses through before encoding the personal names, for instance. |
* |
* @return array A structured array of addresses. |
*/ |
function parseAddressList($address = null, $default_domain = null, $nest_groups = null, $validate = null, $limit = null) |
{ |
if (!isset($this) || !isset($this->mailRFC822)) { |
$obj = new Mail_RFC822($address, $default_domain, $nest_groups, $validate, $limit); |
return $obj->parseAddressList(); |
} |
if (isset($address)) $this->address = $address; |
if (isset($default_domain)) $this->default_domain = $default_domain; |
if (isset($nest_groups)) $this->nestGroups = $nest_groups; |
if (isset($validate)) $this->validate = $validate; |
if (isset($limit)) $this->limit = $limit; |
$this->structure = array(); |
$this->addresses = array(); |
$this->error = null; |
$this->index = null; |
// Unfold any long lines in $this->address. |
$this->address = preg_replace('/\r?\n/', "\r\n", $this->address); |
$this->address = preg_replace('/\r\n(\t| )+/', ' ', $this->address); |
while ($this->address = $this->_splitAddresses($this->address)); |
if ($this->address === false || isset($this->error)) { |
require_once 'PEAR.php'; |
return PEAR::raiseError($this->error); |
} |
// Validate each address individually. If we encounter an invalid |
// address, stop iterating and return an error immediately. |
foreach ($this->addresses as $address) { |
$valid = $this->_validateAddress($address); |
if ($valid === false || isset($this->error)) { |
require_once 'PEAR.php'; |
return PEAR::raiseError($this->error); |
} |
if (!$this->nestGroups) { |
$this->structure = array_merge($this->structure, $valid); |
} else { |
$this->structure[] = $valid; |
} |
} |
return $this->structure; |
} |
/** |
* Splits an address into separate addresses. |
* |
* @access private |
* @param string $address The addresses to split. |
* @return boolean Success or failure. |
*/ |
function _splitAddresses($address) |
{ |
if (!empty($this->limit) && count($this->addresses) == $this->limit) { |
return ''; |
} |
if ($this->_isGroup($address) && !isset($this->error)) { |
$split_char = ';'; |
$is_group = true; |
} elseif (!isset($this->error)) { |
$split_char = ','; |
$is_group = false; |
} elseif (isset($this->error)) { |
return false; |
} |
// Split the string based on the above ten or so lines. |
$parts = explode($split_char, $address); |
$string = $this->_splitCheck($parts, $split_char); |
// If a group... |
if ($is_group) { |
// If $string does not contain a colon outside of |
// brackets/quotes etc then something's fubar. |
// First check there's a colon at all: |
if (strpos($string, ':') === false) { |
$this->error = 'Invalid address: ' . $string; |
return false; |
} |
// Now check it's outside of brackets/quotes: |
if (!$this->_splitCheck(explode(':', $string), ':')) { |
return false; |
} |
// We must have a group at this point, so increase the counter: |
$this->num_groups++; |
} |
// $string now contains the first full address/group. |
// Add to the addresses array. |
$this->addresses[] = array( |
'address' => trim($string), |
'group' => $is_group |
); |
// Remove the now stored address from the initial line, the +1 |
// is to account for the explode character. |
$address = trim(substr($address, strlen($string) + 1)); |
// If the next char is a comma and this was a group, then |
// there are more addresses, otherwise, if there are any more |
// chars, then there is another address. |
if ($is_group && substr($address, 0, 1) == ','){ |
$address = trim(substr($address, 1)); |
return $address; |
} elseif (strlen($address) > 0) { |
return $address; |
} else { |
return ''; |
} |
// If you got here then something's off |
return false; |
} |
/** |
* Checks for a group at the start of the string. |
* |
* @access private |
* @param string $address The address to check. |
* @return boolean Whether or not there is a group at the start of the string. |
*/ |
function _isGroup($address) |
{ |
// First comma not in quotes, angles or escaped: |
$parts = explode(',', $address); |
$string = $this->_splitCheck($parts, ','); |
// Now we have the first address, we can reliably check for a |
// group by searching for a colon that's not escaped or in |
// quotes or angle brackets. |
if (count($parts = explode(':', $string)) > 1) { |
$string2 = $this->_splitCheck($parts, ':'); |
return ($string2 !== $string); |
} else { |
return false; |
} |
} |
/** |
* A common function that will check an exploded string. |
* |
* @access private |
* @param array $parts The exloded string. |
* @param string $char The char that was exploded on. |
* @return mixed False if the string contains unclosed quotes/brackets, or the string on success. |
*/ |
function _splitCheck($parts, $char) |
{ |
$string = $parts[0]; |
for ($i = 0; $i < count($parts); $i++) { |
if ($this->_hasUnclosedQuotes($string) |
|| $this->_hasUnclosedBrackets($string, '<>') |
|| $this->_hasUnclosedBrackets($string, '[]') |
|| $this->_hasUnclosedBrackets($string, '()') |
|| substr($string, -1) == '\\') { |
if (isset($parts[$i + 1])) { |
$string = $string . $char . $parts[$i + 1]; |
} else { |
$this->error = 'Invalid address spec. Unclosed bracket or quotes'; |
return false; |
} |
} else { |
$this->index = $i; |
break; |
} |
} |
return $string; |
} |
/** |
* Checks if a string has an unclosed quotes or not. |
* |
* @access private |
* @param string $string The string to check. |
* @return boolean True if there are unclosed quotes inside the string, false otherwise. |
*/ |
function _hasUnclosedQuotes($string) |
{ |
$string = explode('"', $string); |
$string_cnt = count($string); |
for ($i = 0; $i < (count($string) - 1); $i++) |
if (substr($string[$i], -1) == '\\') |
$string_cnt--; |
return ($string_cnt % 2 === 0); |
} |
/** |
* Checks if a string has an unclosed brackets or not. IMPORTANT: |
* This function handles both angle brackets and square brackets; |
* |
* @access private |
* @param string $string The string to check. |
* @param string $chars The characters to check for. |
* @return boolean True if there are unclosed brackets inside the string, false otherwise. |
*/ |
function _hasUnclosedBrackets($string, $chars) |
{ |
$num_angle_start = substr_count($string, $chars[0]); |
$num_angle_end = substr_count($string, $chars[1]); |
$this->_hasUnclosedBracketsSub($string, $num_angle_start, $chars[0]); |
$this->_hasUnclosedBracketsSub($string, $num_angle_end, $chars[1]); |
if ($num_angle_start < $num_angle_end) { |
$this->error = 'Invalid address spec. Unmatched quote or bracket (' . $chars . ')'; |
return false; |
} else { |
return ($num_angle_start > $num_angle_end); |
} |
} |
/** |
* Sub function that is used only by hasUnclosedBrackets(). |
* |
* @access private |
* @param string $string The string to check. |
* @param integer &$num The number of occurences. |
* @param string $char The character to count. |
* @return integer The number of occurences of $char in $string, adjusted for backslashes. |
*/ |
function _hasUnclosedBracketsSub($string, &$num, $char) |
{ |
$parts = explode($char, $string); |
for ($i = 0; $i < count($parts); $i++){ |
if (substr($parts[$i], -1) == '\\' || $this->_hasUnclosedQuotes($parts[$i])) |
$num--; |
if (isset($parts[$i + 1])) |
$parts[$i + 1] = $parts[$i] . $char . $parts[$i + 1]; |
} |
return $num; |
} |
/** |
* Function to begin checking the address. |
* |
* @access private |
* @param string $address The address to validate. |
* @return mixed False on failure, or a structured array of address information on success. |
*/ |
function _validateAddress($address) |
{ |
$is_group = false; |
$addresses = array(); |
if ($address['group']) { |
$is_group = true; |
// Get the group part of the name |
$parts = explode(':', $address['address']); |
$groupname = $this->_splitCheck($parts, ':'); |
$structure = array(); |
// And validate the group part of the name. |
if (!$this->_validatePhrase($groupname)){ |
$this->error = 'Group name did not validate.'; |
return false; |
} else { |
// Don't include groups if we are not nesting |
// them. This avoids returning invalid addresses. |
if ($this->nestGroups) { |
$structure = new stdClass; |
$structure->groupname = $groupname; |
} |
} |
$address['address'] = ltrim(substr($address['address'], strlen($groupname . ':'))); |
} |
// If a group then split on comma and put into an array. |
// Otherwise, Just put the whole address in an array. |
if ($is_group) { |
while (strlen($address['address']) > 0) { |
$parts = explode(',', $address['address']); |
$addresses[] = $this->_splitCheck($parts, ','); |
$address['address'] = trim(substr($address['address'], strlen(end($addresses) . ','))); |
} |
} else { |
$addresses[] = $address['address']; |
} |
// Check that $addresses is set, if address like this: |
// Groupname:; |
// Then errors were appearing. |
if (!count($addresses)){ |
$this->error = 'Empty group.'; |
return false; |
} |
// Trim the whitespace from all of the address strings. |
array_map('trim', $addresses); |
// Validate each mailbox. |
// Format could be one of: name <geezer@domain.com> |
// geezer@domain.com |
// geezer |
// ... or any other format valid by RFC 822. |
for ($i = 0; $i < count($addresses); $i++) { |
if (!$this->validateMailbox($addresses[$i])) { |
if (empty($this->error)) { |
$this->error = 'Validation failed for: ' . $addresses[$i]; |
} |
return false; |
} |
} |
// Nested format |
if ($this->nestGroups) { |
if ($is_group) { |
$structure->addresses = $addresses; |
} else { |
$structure = $addresses[0]; |
} |
// Flat format |
} else { |
if ($is_group) { |
$structure = array_merge($structure, $addresses); |
} else { |
$structure = $addresses; |
} |
} |
return $structure; |
} |
/** |
* Function to validate a phrase. |
* |
* @access private |
* @param string $phrase The phrase to check. |
* @return boolean Success or failure. |
*/ |
function _validatePhrase($phrase) |
{ |
// Splits on one or more Tab or space. |
$parts = preg_split('/[ \\x09]+/', $phrase, -1, PREG_SPLIT_NO_EMPTY); |
$phrase_parts = array(); |
while (count($parts) > 0){ |
$phrase_parts[] = $this->_splitCheck($parts, ' '); |
for ($i = 0; $i < $this->index + 1; $i++) |
array_shift($parts); |
} |
foreach ($phrase_parts as $part) { |
// If quoted string: |
if (substr($part, 0, 1) == '"') { |
if (!$this->_validateQuotedString($part)) { |
return false; |
} |
continue; |
} |
// Otherwise it's an atom: |
if (!$this->_validateAtom($part)) return false; |
} |
return true; |
} |
/** |
* Function to validate an atom which from rfc822 is: |
* atom = 1*<any CHAR except specials, SPACE and CTLs> |
* |
* If validation ($this->validate) has been turned off, then |
* validateAtom() doesn't actually check anything. This is so that you |
* can split a list of addresses up before encoding personal names |
* (umlauts, etc.), for example. |
* |
* @access private |
* @param string $atom The string to check. |
* @return boolean Success or failure. |
*/ |
function _validateAtom($atom) |
{ |
if (!$this->validate) { |
// Validation has been turned off; assume the atom is okay. |
return true; |
} |
// Check for any char from ASCII 0 - ASCII 127 |
if (!preg_match('/^[\\x00-\\x7E]+$/i', $atom, $matches)) { |
return false; |
} |
// Check for specials: |
if (preg_match('/[][()<>@,;\\:". ]/', $atom)) { |
return false; |
} |
// Check for control characters (ASCII 0-31): |
if (preg_match('/[\\x00-\\x1F]+/', $atom)) { |
return false; |
} |
return true; |
} |
/** |
* Function to validate quoted string, which is: |
* quoted-string = <"> *(qtext/quoted-pair) <"> |
* |
* @access private |
* @param string $qstring The string to check |
* @return boolean Success or failure. |
*/ |
function _validateQuotedString($qstring) |
{ |
// Leading and trailing " |
$qstring = substr($qstring, 1, -1); |
// Perform check, removing quoted characters first. |
return !preg_match('/[\x0D\\\\"]/', preg_replace('/\\\\./', '', $qstring)); |
} |
/** |
* Function to validate a mailbox, which is: |
* mailbox = addr-spec ; simple address |
* / phrase route-addr ; name and route-addr |
* |
* @access public |
* @param string &$mailbox The string to check. |
* @return boolean Success or failure. |
*/ |
function validateMailbox(&$mailbox) |
{ |
// A couple of defaults. |
$phrase = ''; |
$comment = ''; |
$comments = array(); |
// Catch any RFC822 comments and store them separately. |
$_mailbox = $mailbox; |
while (strlen(trim($_mailbox)) > 0) { |
$parts = explode('(', $_mailbox); |
$before_comment = $this->_splitCheck($parts, '('); |
if ($before_comment != $_mailbox) { |
// First char should be a (. |
$comment = substr(str_replace($before_comment, '', $_mailbox), 1); |
$parts = explode(')', $comment); |
$comment = $this->_splitCheck($parts, ')'); |
$comments[] = $comment; |
// +1 is for the trailing ) |
$_mailbox = substr($_mailbox, strpos($_mailbox, $comment)+strlen($comment)+1); |
} else { |
break; |
} |
} |
foreach ($comments as $comment) { |
$mailbox = str_replace("($comment)", '', $mailbox); |
} |
$mailbox = trim($mailbox); |
// Check for name + route-addr |
if (substr($mailbox, -1) == '>' && substr($mailbox, 0, 1) != '<') { |
$parts = explode('<', $mailbox); |
$name = $this->_splitCheck($parts, '<'); |
$phrase = trim($name); |
$route_addr = trim(substr($mailbox, strlen($name.'<'), -1)); |
if ($this->_validatePhrase($phrase) === false || ($route_addr = $this->_validateRouteAddr($route_addr)) === false) { |
return false; |
} |
// Only got addr-spec |
} else { |
// First snip angle brackets if present. |
if (substr($mailbox, 0, 1) == '<' && substr($mailbox, -1) == '>') { |
$addr_spec = substr($mailbox, 1, -1); |
} else { |
$addr_spec = $mailbox; |
} |
if (($addr_spec = $this->_validateAddrSpec($addr_spec)) === false) { |
return false; |
} |
} |
// Construct the object that will be returned. |
$mbox = new stdClass(); |
// Add the phrase (even if empty) and comments |
$mbox->personal = $phrase; |
$mbox->comment = isset($comments) ? $comments : array(); |
if (isset($route_addr)) { |
$mbox->mailbox = $route_addr['local_part']; |
$mbox->host = $route_addr['domain']; |
$route_addr['adl'] !== '' ? $mbox->adl = $route_addr['adl'] : ''; |
} else { |
$mbox->mailbox = $addr_spec['local_part']; |
$mbox->host = $addr_spec['domain']; |
} |
$mailbox = $mbox; |
return true; |
} |
/** |
* This function validates a route-addr which is: |
* route-addr = "<" [route] addr-spec ">" |
* |
* Angle brackets have already been removed at the point of |
* getting to this function. |
* |
* @access private |
* @param string $route_addr The string to check. |
* @return mixed False on failure, or an array containing validated address/route information on success. |
*/ |
function _validateRouteAddr($route_addr) |
{ |
// Check for colon. |
if (strpos($route_addr, ':') !== false) { |
$parts = explode(':', $route_addr); |
$route = $this->_splitCheck($parts, ':'); |
} else { |
$route = $route_addr; |
} |
// If $route is same as $route_addr then the colon was in |
// quotes or brackets or, of course, non existent. |
if ($route === $route_addr){ |
unset($route); |
$addr_spec = $route_addr; |
if (($addr_spec = $this->_validateAddrSpec($addr_spec)) === false) { |
return false; |
} |
} else { |
// Validate route part. |
if (($route = $this->_validateRoute($route)) === false) { |
return false; |
} |
$addr_spec = substr($route_addr, strlen($route . ':')); |
// Validate addr-spec part. |
if (($addr_spec = $this->_validateAddrSpec($addr_spec)) === false) { |
return false; |
} |
} |
if (isset($route)) { |
$return['adl'] = $route; |
} else { |
$return['adl'] = ''; |
} |
$return = array_merge($return, $addr_spec); |
return $return; |
} |
/** |
* Function to validate a route, which is: |
* route = 1#("@" domain) ":" |
* |
* @access private |
* @param string $route The string to check. |
* @return mixed False on failure, or the validated $route on success. |
*/ |
function _validateRoute($route) |
{ |
// Split on comma. |
$domains = explode(',', trim($route)); |
foreach ($domains as $domain) { |
$domain = str_replace('@', '', trim($domain)); |
if (!$this->_validateDomain($domain)) return false; |
} |
return $route; |
} |
/** |
* Function to validate a domain, though this is not quite what |
* you expect of a strict internet domain. |
* |
* domain = sub-domain *("." sub-domain) |
* |
* @access private |
* @param string $domain The string to check. |
* @return mixed False on failure, or the validated domain on success. |
*/ |
function _validateDomain($domain) |
{ |
// Note the different use of $subdomains and $sub_domains |
$subdomains = explode('.', $domain); |
while (count($subdomains) > 0) { |
$sub_domains[] = $this->_splitCheck($subdomains, '.'); |
for ($i = 0; $i < $this->index + 1; $i++) |
array_shift($subdomains); |
} |
foreach ($sub_domains as $sub_domain) { |
if (!$this->_validateSubdomain(trim($sub_domain))) |
return false; |
} |
// Managed to get here, so return input. |
return $domain; |
} |
/** |
* Function to validate a subdomain: |
* subdomain = domain-ref / domain-literal |
* |
* @access private |
* @param string $subdomain The string to check. |
* @return boolean Success or failure. |
*/ |
function _validateSubdomain($subdomain) |
{ |
if (preg_match('|^\[(.*)]$|', $subdomain, $arr)){ |
if (!$this->_validateDliteral($arr[1])) return false; |
} else { |
if (!$this->_validateAtom($subdomain)) return false; |
} |
// Got here, so return successful. |
return true; |
} |
/** |
* Function to validate a domain literal: |
* domain-literal = "[" *(dtext / quoted-pair) "]" |
* |
* @access private |
* @param string $dliteral The string to check. |
* @return boolean Success or failure. |
*/ |
function _validateDliteral($dliteral) |
{ |
return !preg_match('/(.)[][\x0D\\\\]/', $dliteral, $matches) && $matches[1] != '\\'; |
} |
/** |
* Function to validate an addr-spec. |
* |
* addr-spec = local-part "@" domain |
* |
* @access private |
* @param string $addr_spec The string to check. |
* @return mixed False on failure, or the validated addr-spec on success. |
*/ |
function _validateAddrSpec($addr_spec) |
{ |
$addr_spec = trim($addr_spec); |
// Split on @ sign if there is one. |
if (strpos($addr_spec, '@') !== false) { |
$parts = explode('@', $addr_spec); |
$local_part = $this->_splitCheck($parts, '@'); |
$domain = substr($addr_spec, strlen($local_part . '@')); |
// No @ sign so assume the default domain. |
} else { |
$local_part = $addr_spec; |
$domain = $this->default_domain; |
} |
if (($local_part = $this->_validateLocalPart($local_part)) === false) return false; |
if (($domain = $this->_validateDomain($domain)) === false) return false; |
// Got here so return successful. |
return array('local_part' => $local_part, 'domain' => $domain); |
} |
/** |
* Function to validate the local part of an address: |
* local-part = word *("." word) |
* |
* @access private |
* @param string $local_part |
* @return mixed False on failure, or the validated local part on success. |
*/ |
function _validateLocalPart($local_part) |
{ |
$parts = explode('.', $local_part); |
$words = array(); |
// Split the local_part into words. |
while (count($parts) > 0){ |
$words[] = $this->_splitCheck($parts, '.'); |
for ($i = 0; $i < $this->index + 1; $i++) { |
array_shift($parts); |
} |
} |
// Validate each word. |
foreach ($words as $word) { |
// If this word contains an unquoted space, it is invalid. (6.2.4) |
if (strpos($word, ' ') && $word[0] !== '"') |
{ |
return false; |
} |
if ($this->_validatePhrase(trim($word)) === false) return false; |
} |
// Managed to get here, so return the input. |
return $local_part; |
} |
/** |
* Returns an approximate count of how many addresses are in the |
* given string. This is APPROXIMATE as it only splits based on a |
* comma which has no preceding backslash. Could be useful as |
* large amounts of addresses will end up producing *large* |
* structures when used with parseAddressList(). |
* |
* @param string $data Addresses to count |
* @return int Approximate count |
*/ |
function approximateCount($data) |
{ |
return count(preg_split('/(?<!\\\\),/', $data)); |
} |
/** |
* This is a email validating function separate to the rest of the |
* class. It simply validates whether an email is of the common |
* internet form: <user>@<domain>. This can be sufficient for most |
* people. Optional stricter mode can be utilised which restricts |
* mailbox characters allowed to alphanumeric, full stop, hyphen |
* and underscore. |
* |
* @param string $data Address to check |
* @param boolean $strict Optional stricter mode |
* @return mixed False if it fails, an indexed array |
* username/domain if it matches |
*/ |
function isValidInetAddress($data, $strict = false) |
{ |
$regex = $strict ? '/^([.0-9a-z_+-]+)@(([0-9a-z-]+\.)+[0-9a-z]{2,4})$/i' : '/^([*+!.&#$|\'\\%\/0-9a-z^_`{}=?~:-]+)@(([0-9a-z-]+\.)+[0-9a-z]{2,4})$/i'; |
if (preg_match($regex, trim($data), $matches)) { |
return array($matches[1], $matches[2]); |
} else { |
return false; |
} |
} |
} |
/branches/livraison_menes/api/pear/Mail/mime.php |
---|
New file |
0,0 → 1,713 |
<?php |
/* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4: */ |
// +-----------------------------------------------------------------------+ |
// | Copyright (c) 2002-2003 Richard Heyes | |
// | Copyright (c) 2003-2005 The PHP Group | |
// | All rights reserved. | |
// | | |
// | Redistribution and use in source and binary forms, with or without | |
// | modification, are permitted provided that the following conditions | |
// | are met: | |
// | | |
// | o Redistributions of source code must retain the above copyright | |
// | notice, this list of conditions and the following disclaimer. | |
// | o 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.| |
// | o The names of the authors may not be used to endorse or promote | |
// | products derived from this software without specific prior written | |
// | permission. | |
// | | |
// | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS | |
// | "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT | |
// | LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR | |
// | A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT | |
// | OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, | |
// | SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT | |
// | LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, | |
// | DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY | |
// | THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | |
// | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE | |
// | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | |
// | | |
// +-----------------------------------------------------------------------+ |
// | Author: Richard Heyes <richard@phpguru.org> | |
// | Tomas V.V.Cox <cox@idecnet.com> (port to PEAR) | |
// +-----------------------------------------------------------------------+ |
// |
// $Id: mime.php,v 1.1 2006-09-13 08:49:41 alexandre_tb Exp $ |
require_once('PEAR.php'); |
require_once('Mail/mimePart.php'); |
/** |
* Mime mail composer class. Can handle: text and html bodies, embedded html |
* images and attachments. |
* Documentation and examples of this class are avaible here: |
* http://pear.php.net/manual/ |
* |
* @notes This class is based on HTML Mime Mail class from |
* Richard Heyes <richard@phpguru.org> which was based also |
* in the mime_mail.class by Tobias Ratschiller <tobias@dnet.it> and |
* Sascha Schumann <sascha@schumann.cx> |
* |
* @author Richard Heyes <richard.heyes@heyes-computing.net> |
* @author Tomas V.V.Cox <cox@idecnet.com> |
* @package Mail |
* @access public |
*/ |
class Mail_mime |
{ |
/** |
* Contains the plain text part of the email |
* @var string |
*/ |
var $_txtbody; |
/** |
* Contains the html part of the email |
* @var string |
*/ |
var $_htmlbody; |
/** |
* contains the mime encoded text |
* @var string |
*/ |
var $_mime; |
/** |
* contains the multipart content |
* @var string |
*/ |
var $_multipart; |
/** |
* list of the attached images |
* @var array |
*/ |
var $_html_images = array(); |
/** |
* list of the attachements |
* @var array |
*/ |
var $_parts = array(); |
/** |
* Build parameters |
* @var array |
*/ |
var $_build_params = array(); |
/** |
* Headers for the mail |
* @var array |
*/ |
var $_headers = array(); |
/** |
* End Of Line sequence (for serialize) |
* @var string |
*/ |
var $_eol; |
/** |
* Constructor function |
* |
* @access public |
*/ |
function Mail_mime($crlf = "\r\n") |
{ |
$this->_setEOL($crlf); |
$this->_build_params = array( |
'text_encoding' => '7bit', |
'html_encoding' => 'quoted-printable', |
'7bit_wrap' => 998, |
'html_charset' => 'ISO-8859-1', |
'text_charset' => 'ISO-8859-1', |
'head_charset' => 'ISO-8859-1' |
); |
} |
/** |
* Wakeup (unserialize) - re-sets EOL constant |
* |
* @access private |
*/ |
function __wakeup() |
{ |
$this->_setEOL($this->_eol); |
} |
/** |
* Accessor function to set the body text. Body text is used if |
* it's not an html mail being sent or else is used to fill the |
* text/plain part that emails clients who don't support |
* html should show. |
* |
* @param string $data Either a string or |
* the file name with the contents |
* @param bool $isfile If true the first param should be treated |
* as a file name, else as a string (default) |
* @param bool $append If true the text or file is appended to |
* the existing body, else the old body is |
* overwritten |
* @return mixed true on success or PEAR_Error object |
* @access public |
*/ |
function setTXTBody($data, $isfile = false, $append = false) |
{ |
if (!$isfile) { |
if (!$append) { |
$this->_txtbody = $data; |
} else { |
$this->_txtbody .= $data; |
} |
} else { |
$cont = $this->_file2str($data); |
if (PEAR::isError($cont)) { |
return $cont; |
} |
if (!$append) { |
$this->_txtbody = $cont; |
} else { |
$this->_txtbody .= $cont; |
} |
} |
return true; |
} |
/** |
* Adds a html part to the mail |
* |
* @param string $data Either a string or the file name with the |
* contents |
* @param bool $isfile If true the first param should be treated |
* as a file name, else as a string (default) |
* @return mixed true on success or PEAR_Error object |
* @access public |
*/ |
function setHTMLBody($data, $isfile = false) |
{ |
if (!$isfile) { |
$this->_htmlbody = $data; |
} else { |
$cont = $this->_file2str($data); |
if (PEAR::isError($cont)) { |
return $cont; |
} |
$this->_htmlbody = $cont; |
} |
return true; |
} |
/** |
* Adds an image to the list of embedded images. |
* |
* @param string $file The image file name OR image data itself |
* @param string $c_type The content type |
* @param string $name The filename of the image. |
* Only use if $file is the image data |
* @param bool $isfilename Whether $file is a filename or not |
* Defaults to true |
* @return mixed true on success or PEAR_Error object |
* @access public |
*/ |
function addHTMLImage($file, $c_type='application/octet-stream', |
$name = '', $isfilename = true) |
{ |
$filedata = ($isfilename === true) ? $this->_file2str($file) |
: $file; |
if ($isfilename === true) { |
$filename = ($name == '' ? basename($file) : basename($name)); |
} else { |
$filename = basename($name); |
} |
if (PEAR::isError($filedata)) { |
return $filedata; |
} |
$this->_html_images[] = array( |
'body' => $filedata, |
'name' => $filename, |
'c_type' => $c_type, |
'cid' => md5(uniqid(time())) |
); |
return true; |
} |
/** |
* Adds a file to the list of attachments. |
* |
* @param string $file The file name of the file to attach |
* OR the file data itself |
* @param string $c_type The content type |
* @param string $name The filename of the attachment |
* Only use if $file is the file data |
* @param bool $isFilename Whether $file is a filename or not |
* Defaults to true |
* @return mixed true on success or PEAR_Error object |
* @access public |
*/ |
function addAttachment($file, $c_type = 'application/octet-stream', |
$name = '', $isfilename = true, |
$encoding = 'base64') |
{ |
$filedata = ($isfilename === true) ? $this->_file2str($file) |
: $file; |
if ($isfilename === true) { |
// Force the name the user supplied, otherwise use $file |
$filename = (!empty($name)) ? $name : $file; |
} else { |
$filename = $name; |
} |
if (empty($filename)) { |
return PEAR::raiseError( |
'The supplied filename for the attachment can\'t be empty' |
); |
} |
$filename = basename($filename); |
if (PEAR::isError($filedata)) { |
return $filedata; |
} |
$this->_parts[] = array( |
'body' => $filedata, |
'name' => $filename, |
'c_type' => $c_type, |
'encoding' => $encoding |
); |
return true; |
} |
/** |
* Get the contents of the given file name as string |
* |
* @param string $file_name path of file to process |
* @return string contents of $file_name |
* @access private |
*/ |
function &_file2str($file_name) |
{ |
if (!is_readable($file_name)) { |
return PEAR::raiseError('File is not readable ' . $file_name); |
} |
if (!$fd = fopen($file_name, 'rb')) { |
return PEAR::raiseError('Could not open ' . $file_name); |
} |
$filesize = filesize($file_name); |
if ($filesize == 0){ |
$cont = ""; |
}else{ |
$cont = fread($fd, $filesize); |
} |
fclose($fd); |
return $cont; |
} |
/** |
* Adds a text subpart to the mimePart object and |
* returns it during the build process. |
* |
* @param mixed The object to add the part to, or |
* null if a new object is to be created. |
* @param string The text to add. |
* @return object The text mimePart object |
* @access private |
*/ |
function &_addTextPart(&$obj, $text) |
{ |
$params['content_type'] = 'text/plain'; |
$params['encoding'] = $this->_build_params['text_encoding']; |
$params['charset'] = $this->_build_params['text_charset']; |
if (is_object($obj)) { |
return $obj->addSubpart($text, $params); |
} else { |
return new Mail_mimePart($text, $params); |
} |
} |
/** |
* Adds a html subpart to the mimePart object and |
* returns it during the build process. |
* |
* @param mixed The object to add the part to, or |
* null if a new object is to be created. |
* @return object The html mimePart object |
* @access private |
*/ |
function &_addHtmlPart(&$obj) |
{ |
$params['content_type'] = 'text/html'; |
$params['encoding'] = $this->_build_params['html_encoding']; |
$params['charset'] = $this->_build_params['html_charset']; |
if (is_object($obj)) { |
return $obj->addSubpart($this->_htmlbody, $params); |
} else { |
return new Mail_mimePart($this->_htmlbody, $params); |
} |
} |
/** |
* Creates a new mimePart object, using multipart/mixed as |
* the initial content-type and returns it during the |
* build process. |
* |
* @return object The multipart/mixed mimePart object |
* @access private |
*/ |
function &_addMixedPart() |
{ |
$params['content_type'] = 'multipart/mixed'; |
return new Mail_mimePart('', $params); |
} |
/** |
* Adds a multipart/alternative part to a mimePart |
* object (or creates one), and returns it during |
* the build process. |
* |
* @param mixed The object to add the part to, or |
* null if a new object is to be created. |
* @return object The multipart/mixed mimePart object |
* @access private |
*/ |
function &_addAlternativePart(&$obj) |
{ |
$params['content_type'] = 'multipart/alternative'; |
if (is_object($obj)) { |
return $obj->addSubpart('', $params); |
} else { |
return new Mail_mimePart('', $params); |
} |
} |
/** |
* Adds a multipart/related part to a mimePart |
* object (or creates one), and returns it during |
* the build process. |
* |
* @param mixed The object to add the part to, or |
* null if a new object is to be created |
* @return object The multipart/mixed mimePart object |
* @access private |
*/ |
function &_addRelatedPart(&$obj) |
{ |
$params['content_type'] = 'multipart/related'; |
if (is_object($obj)) { |
return $obj->addSubpart('', $params); |
} else { |
return new Mail_mimePart('', $params); |
} |
} |
/** |
* Adds an html image subpart to a mimePart object |
* and returns it during the build process. |
* |
* @param object The mimePart to add the image to |
* @param array The image information |
* @return object The image mimePart object |
* @access private |
*/ |
function &_addHtmlImagePart(&$obj, $value) |
{ |
$params['content_type'] = $value['c_type']; |
$params['encoding'] = 'base64'; |
$params['disposition'] = 'inline'; |
$params['dfilename'] = $value['name']; |
$params['cid'] = $value['cid']; |
$obj->addSubpart($value['body'], $params); |
} |
/** |
* Adds an attachment subpart to a mimePart object |
* and returns it during the build process. |
* |
* @param object The mimePart to add the image to |
* @param array The attachment information |
* @return object The image mimePart object |
* @access private |
*/ |
function &_addAttachmentPart(&$obj, $value) |
{ |
$params['content_type'] = $value['c_type']; |
$params['encoding'] = $value['encoding']; |
$params['disposition'] = 'attachment'; |
$params['dfilename'] = $value['name']; |
$obj->addSubpart($value['body'], $params); |
} |
/** |
* Builds the multipart message from the list ($this->_parts) and |
* returns the mime content. |
* |
* @param array Build parameters that change the way the email |
* is built. Should be associative. Can contain: |
* text_encoding - What encoding to use for plain text |
* Default is 7bit |
* html_encoding - What encoding to use for html |
* Default is quoted-printable |
* 7bit_wrap - Number of characters before text is |
* wrapped in 7bit encoding |
* Default is 998 |
* html_charset - The character set to use for html. |
* Default is iso-8859-1 |
* text_charset - The character set to use for text. |
* Default is iso-8859-1 |
* head_charset - The character set to use for headers. |
* Default is iso-8859-1 |
* @return string The mime content |
* @access public |
*/ |
function &get($build_params = null) |
{ |
if (isset($build_params)) { |
while (list($key, $value) = each($build_params)) { |
$this->_build_params[$key] = $value; |
} |
} |
if (!empty($this->_html_images) AND isset($this->_htmlbody)) { |
foreach ($this->_html_images as $value) { |
$regex = '#(\s)((?i)src|background|href(?-i))\s*=\s*(["\']?)' . preg_quote($value['name'], '#') . |
'\3#'; |
$rep = '\1\2=\3cid:' . $value['cid'] .'\3'; |
$this->_htmlbody = preg_replace($regex, $rep, |
$this->_htmlbody |
); |
} |
} |
$null = null; |
$attachments = !empty($this->_parts) ? true : false; |
$html_images = !empty($this->_html_images) ? true : false; |
$html = !empty($this->_htmlbody) ? true : false; |
$text = (!$html AND !empty($this->_txtbody)) ? true : false; |
switch (true) { |
case $text AND !$attachments: |
$message =& $this->_addTextPart($null, $this->_txtbody); |
break; |
case !$text AND !$html AND $attachments: |
$message =& $this->_addMixedPart(); |
for ($i = 0; $i < count($this->_parts); $i++) { |
$this->_addAttachmentPart($message, $this->_parts[$i]); |
} |
break; |
case $text AND $attachments: |
$message =& $this->_addMixedPart(); |
$this->_addTextPart($message, $this->_txtbody); |
for ($i = 0; $i < count($this->_parts); $i++) { |
$this->_addAttachmentPart($message, $this->_parts[$i]); |
} |
break; |
case $html AND !$attachments AND !$html_images: |
if (isset($this->_txtbody)) { |
$message =& $this->_addAlternativePart($null); |
$this->_addTextPart($message, $this->_txtbody); |
$this->_addHtmlPart($message); |
} else { |
$message =& $this->_addHtmlPart($null); |
} |
break; |
case $html AND !$attachments AND $html_images: |
if (isset($this->_txtbody)) { |
$message =& $this->_addAlternativePart($null); |
$this->_addTextPart($message, $this->_txtbody); |
$related =& $this->_addRelatedPart($message); |
} else { |
$message =& $this->_addRelatedPart($null); |
$related =& $message; |
} |
$this->_addHtmlPart($related); |
for ($i = 0; $i < count($this->_html_images); $i++) { |
$this->_addHtmlImagePart($related, $this->_html_images[$i]); |
} |
break; |
case $html AND $attachments AND !$html_images: |
$message =& $this->_addMixedPart(); |
if (isset($this->_txtbody)) { |
$alt =& $this->_addAlternativePart($message); |
$this->_addTextPart($alt, $this->_txtbody); |
$this->_addHtmlPart($alt); |
} else { |
$this->_addHtmlPart($message); |
} |
for ($i = 0; $i < count($this->_parts); $i++) { |
$this->_addAttachmentPart($message, $this->_parts[$i]); |
} |
break; |
case $html AND $attachments AND $html_images: |
$message =& $this->_addMixedPart(); |
if (isset($this->_txtbody)) { |
$alt =& $this->_addAlternativePart($message); |
$this->_addTextPart($alt, $this->_txtbody); |
$rel =& $this->_addRelatedPart($alt); |
} else { |
$rel =& $this->_addRelatedPart($message); |
} |
$this->_addHtmlPart($rel); |
for ($i = 0; $i < count($this->_html_images); $i++) { |
$this->_addHtmlImagePart($rel, $this->_html_images[$i]); |
} |
for ($i = 0; $i < count($this->_parts); $i++) { |
$this->_addAttachmentPart($message, $this->_parts[$i]); |
} |
break; |
} |
if (isset($message)) { |
$output = $message->encode(); |
$this->_headers = array_merge($this->_headers, |
$output['headers']); |
return $output['body']; |
} else { |
return false; |
} |
} |
/** |
* Returns an array with the headers needed to prepend to the email |
* (MIME-Version and Content-Type). Format of argument is: |
* $array['header-name'] = 'header-value'; |
* |
* @param array $xtra_headers Assoc array with any extra headers. |
* Optional. |
* @return array Assoc array with the mime headers |
* @access public |
*/ |
function &headers($xtra_headers = null) |
{ |
// Content-Type header should already be present, |
// So just add mime version header |
$headers['MIME-Version'] = '1.0'; |
if (isset($xtra_headers)) { |
$headers = array_merge($headers, $xtra_headers); |
} |
$this->_headers = array_merge($headers, $this->_headers); |
return $this->_encodeHeaders($this->_headers); |
} |
/** |
* Get the text version of the headers |
* (usefull if you want to use the PHP mail() function) |
* |
* @param array $xtra_headers Assoc array with any extra headers. |
* Optional. |
* @return string Plain text headers |
* @access public |
*/ |
function txtHeaders($xtra_headers = null) |
{ |
$headers = $this->headers($xtra_headers); |
$ret = ''; |
foreach ($headers as $key => $val) { |
$ret .= "$key: $val" . MAIL_MIME_CRLF; |
} |
return $ret; |
} |
/** |
* Sets the Subject header |
* |
* @param string $subject String to set the subject to |
* access public |
*/ |
function setSubject($subject) |
{ |
$this->_headers['Subject'] = $subject; |
} |
/** |
* Set an email to the From (the sender) header |
* |
* @param string $email The email direction to add |
* @access public |
*/ |
function setFrom($email) |
{ |
$this->_headers['From'] = $email; |
} |
/** |
* Add an email to the Cc (carbon copy) header |
* (multiple calls to this method are allowed) |
* |
* @param string $email The email direction to add |
* @access public |
*/ |
function addCc($email) |
{ |
if (isset($this->_headers['Cc'])) { |
$this->_headers['Cc'] .= ", $email"; |
} else { |
$this->_headers['Cc'] = $email; |
} |
} |
/** |
* Add an email to the Bcc (blank carbon copy) header |
* (multiple calls to this method are allowed) |
* |
* @param string $email The email direction to add |
* @access public |
*/ |
function addBcc($email) |
{ |
if (isset($this->_headers['Bcc'])) { |
$this->_headers['Bcc'] .= ", $email"; |
} else { |
$this->_headers['Bcc'] = $email; |
} |
} |
/** |
* Encodes a header as per RFC2047 |
* |
* @param string $input The header data to encode |
* @return string Encoded data |
* @access private |
*/ |
function _encodeHeaders($input) |
{ |
foreach ($input as $hdr_name => $hdr_value) { |
preg_match_all('/(\w*[\x80-\xFF]+\w*)/', $hdr_value, $matches); |
foreach ($matches[1] as $value) { |
$replacement = preg_replace('/([\x80-\xFF])/e', |
'"=" . |
strtoupper(dechex(ord("\1")))', |
$value); |
$hdr_value = str_replace($value, '=?' . |
$this->_build_params['head_charset'] . |
'?Q?' . $replacement . '?=', |
$hdr_value); |
} |
$input[$hdr_name] = $hdr_value; |
} |
return $input; |
} |
/** |
* Set the object's end-of-line and define the constant if applicable |
* |
* @param string $eol End Of Line sequence |
* @access private |
*/ |
function _setEOL($eol) |
{ |
$this->_eol = $eol; |
if (!defined('MAIL_MIME_CRLF')) { |
define('MAIL_MIME_CRLF', $this->_eol, true); |
} |
} |
} // End of class |
?> |
/branches/livraison_menes/api/pear/HTML/Common.php |
---|
Cannot display: file marked as a binary type. |
svn:mime-type = application/octet-stream |
/branches/livraison_menes/api/pear/HTML/Common.php |
---|
New file |
Property changes: |
Added: svn:mime-type |
+application/octet-stream |
\ No newline at end of property |
/branches/livraison_menes/api/pear/HTML/QuickForm/Renderer.php |
---|
New file |
0,0 → 1,150 |
<?php |
/* vim: set expandtab tabstop=4 shiftwidth=4: */ |
// +----------------------------------------------------------------------+ |
// | PHP version 4.0 | |
// +----------------------------------------------------------------------+ |
// | Copyright (c) 1997-2003 The PHP Group | |
// +----------------------------------------------------------------------+ |
// | This source file is subject to version 2.0 of the PHP license, | |
// | that is bundled with this package in the file LICENSE, and is | |
// | available at through the world-wide-web at | |
// | http://www.php.net/license/2_02.txt. | |
// | If you did not receive a copy of the PHP license and are unable to | |
// | obtain it through the world-wide-web, please send a note to | |
// | license@php.net so we can mail you a copy immediately. | |
// +----------------------------------------------------------------------+ |
// | Author: Alexey Borzov <borz_off@cs.msu.su> | |
// +----------------------------------------------------------------------+ |
// |
// $Id: Renderer.php,v 1.2 2005-09-20 17:01:22 ddelon Exp $ |
/** |
* An abstract base class for QuickForm renderers |
* |
* The class implements a Visitor design pattern |
* |
* @abstract |
* @author Alexey Borzov <borz_off@cs.msu.su> |
*/ |
class HTML_QuickForm_Renderer |
{ |
/** |
* Constructor |
* |
* @access public |
*/ |
function HTML_QuickForm_Renderer() |
{ |
} // end constructor |
/** |
* Called when visiting a form, before processing any form elements |
* |
* @param object An HTML_QuickForm object 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 object An HTML_QuickForm object being visited |
* @access public |
* @return void |
* @abstract |
*/ |
function finishForm(&$form) |
{ |
return; |
} // end func finishForm |
/** |
* Called when visiting a header element |
* |
* @param object An HTML_QuickForm_header element being visited |
* @access public |
* @return void |
* @abstract |
*/ |
function renderHeader(&$header) |
{ |
return; |
} // end func renderHeader |
/** |
* Called when visiting an element |
* |
* @param object An HTML_QuickForm_element object 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 object An HTML_QuickForm_hidden object being visited |
* @access public |
* @return void |
* @abstract |
*/ |
function renderHidden(&$element) |
{ |
return; |
} // end func renderHidden |
/** |
* Called when visiting a raw HTML/text pseudo-element |
* |
* Seems that this should not be used when using a template-based renderer |
* |
* @param object An HTML_QuickForm_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 object An HTML_QuickForm_group object 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 object An HTML_QuickForm_group object being visited |
* @access public |
* @return void |
* @abstract |
*/ |
function finishGroup(&$group) |
{ |
return; |
} // end func finishGroup |
} // end class HTML_QuickForm_Renderer |
?> |
/branches/livraison_menes/api/pear/HTML/QuickForm/Rule.php |
---|
New file |
0,0 → 1,67 |
<?php |
/* vim: set expandtab tabstop=4 shiftwidth=4: */ |
// +----------------------------------------------------------------------+ |
// | PHP version 4.0 | |
// +----------------------------------------------------------------------+ |
// | Copyright (c) 1997-2003 The PHP Group | |
// +----------------------------------------------------------------------+ |
// | This source file is subject to version 2.0 of the PHP license, | |
// | that is bundled with this package in the file LICENSE, and is | |
// | available at through the world-wide-web at | |
// | http://www.php.net/license/2_02.txt. | |
// | If you did not receive a copy of the PHP license and are unable to | |
// | obtain it through the world-wide-web, please send a note to | |
// | license@php.net so we can mail you a copy immediately. | |
// +----------------------------------------------------------------------+ |
// | Authors: Bertrand Mansion <bmansion@mamasam.com> | |
// +----------------------------------------------------------------------+ |
// |
// $Id: Rule.php,v 1.2 2005-09-20 17:01:22 ddelon Exp $ |
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 |
* |
* @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 |
*/ |
function getValidationScript($options = null) |
{ |
return array('', ''); |
} |
} |
?> |
/branches/livraison_menes/api/pear/HTML/QuickForm/button.php |
---|
New file |
0,0 → 1,73 |
<?php |
/* vim: set expandtab tabstop=4 shiftwidth=4: */ |
// +----------------------------------------------------------------------+ |
// | PHP version 4.0 | |
// +----------------------------------------------------------------------+ |
// | Copyright (c) 1997, 1998, 1999, 2000, 2001 The PHP Group | |
// +----------------------------------------------------------------------+ |
// | This source file is subject to version 2.0 of the PHP license, | |
// | that is bundled with this package in the file LICENSE, and is | |
// | available at through the world-wide-web at | |
// | http://www.php.net/license/2_02.txt. | |
// | If you did not receive a copy of the PHP license and are unable to | |
// | obtain it through the world-wide-web, please send a note to | |
// | license@php.net so we can mail you a copy immediately. | |
// +----------------------------------------------------------------------+ |
// | Authors: Adam Daniel <adaniel1@eesus.jnj.com> | |
// | Bertrand Mansion <bmansion@mamasam.com> | |
// +----------------------------------------------------------------------+ |
// |
// $Id: button.php,v 1.2 2005-09-20 17:01:22 ddelon Exp $ |
require_once("HTML/QuickForm/input.php"); |
/** |
* HTML class for a button type element |
* |
* @author Adam Daniel <adaniel1@eesus.jnj.com> |
* @author Bertrand Mansion <bmansion@mamasam.com> |
* @version 1.1 |
* @since PHP4.04pl1 |
* @access public |
*/ |
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 |
?> |
/branches/livraison_menes/api/pear/HTML/QuickForm/date.php |
---|
New file |
0,0 → 1,484 |
<?php |
/* vim: set expandtab tabstop=4 shiftwidth=4: */ |
// +----------------------------------------------------------------------+ |
// | PHP Version 4 | |
// +----------------------------------------------------------------------+ |
// | Copyright (c) 1997-2003 The PHP Group | |
// +----------------------------------------------------------------------+ |
// | This source file is subject to version 2.0 of the PHP license, | |
// | that is bundled with this package in the file LICENSE, and is | |
// | available at through the world-wide-web at | |
// | http://www.php.net/license/2_02.txt. | |
// | If you did not receive a copy of the PHP license and are unable to | |
// | obtain it through the world-wide-web, please send a note to | |
// | license@php.net so we can mail you a copy immediately. | |
// +----------------------------------------------------------------------+ |
// | Authors: Alexey Borzov <avb@php.net> | |
// | Adam Daniel <adaniel1@eesus.jnj.com> | |
// | Bertrand Mansion <bmansion@mamasam.com> | |
// +----------------------------------------------------------------------+ |
// |
// $Id: date.php,v 1.2 2005-09-20 17:01:22 ddelon Exp $ |
require_once 'HTML/QuickForm/group.php'; |
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 |
* |
* @author Alexey Borzov <avb@php.net> |
* @access public |
*/ |
class HTML_QuickForm_date extends HTML_QuickForm_group |
{ |
// {{{ properties |
/** |
* Various options to control the element's display. |
* |
* Currently known options are |
* 'language': date language |
* 'format': Format of the date, based on PHP's date() function. |
* The following characters are recognised in format string: |
* 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 |
* '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 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') |
) |
); |
// }}} |
// {{{ constructor |
/** |
* Class constructor |
* |
* @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)) { |
$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; |
} |
// }}} |
// {{{ 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-d-n-Y-h-H-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' => $arr[6], |
's' => $arr[7], |
'a' => $arr[8], |
'A' => $arr[9], |
'W' => $arr[10] |
); |
} |
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); |
} |
} |
// }}} |
} |
?> |
/branches/livraison_menes/api/pear/HTML/QuickForm/textarea.php |
---|
New file |
0,0 → 1,222 |
<?php |
/* vim: set expandtab tabstop=4 shiftwidth=4: */ |
// +----------------------------------------------------------------------+ |
// | PHP version 4.0 | |
// +----------------------------------------------------------------------+ |
// | Copyright (c) 1997, 1998, 1999, 2000, 2001 The PHP Group | |
// +----------------------------------------------------------------------+ |
// | This source file is subject to version 2.0 of the PHP license, | |
// | that is bundled with this package in the file LICENSE, and is | |
// | available at through the world-wide-web at | |
// | http://www.php.net/license/2_02.txt. | |
// | If you did not receive a copy of the PHP license and are unable to | |
// | obtain it through the world-wide-web, please send a note to | |
// | license@php.net so we can mail you a copy immediately. | |
// +----------------------------------------------------------------------+ |
// | Authors: Adam Daniel <adaniel1@eesus.jnj.com> | |
// | Bertrand Mansion <bmansion@mamasam.com> | |
// +----------------------------------------------------------------------+ |
// |
// $Id: textarea.php,v 1.2 2005-09-20 17:01:22 ddelon Exp $ |
require_once("HTML/QuickForm/element.php"); |
/** |
* HTML class for a textarea type field |
* |
* @author Adam Daniel <adaniel1@eesus.jnj.com> |
* @author Bertrand Mansion <bmansion@mamasam.com> |
* @version 1.0 |
* @since PHP4.04pl1 |
* @access public |
*/ |
class HTML_QuickForm_textarea extends HTML_QuickForm_element |
{ |
// {{{ properties |
/** |
* Field value |
* @var string |
* @since 1.0 |
* @access private |
*/ |
var $_value = null; |
// }}} |
// {{{ constructor |
/** |
* Class constructor |
* |
* @param string Input field name attribute |
* @param mixed Label(s) for a field |
* @param mixed Either a typical HTML attribute string or an associative array |
* @since 1.0 |
* @access public |
* @return void |
*/ |
function HTML_QuickForm_textarea($elementName=null, $elementLabel=null, $attributes=null) |
{ |
HTML_QuickForm_element::HTML_QuickForm_element($elementName, $elementLabel, $attributes); |
$this->_persistantFreeze = true; |
$this->_type = 'textarea'; |
} //end constructor |
// }}} |
// {{{ 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 value for textarea element |
* |
* @param string $value Value for textarea element |
* @since 1.0 |
* @access public |
* @return void |
*/ |
function setValue($value) |
{ |
$this->_value = $value; |
} //end func setValue |
// }}} |
// {{{ getValue() |
/** |
* Returns the value of the form element |
* |
* @since 1.0 |
* @access public |
* @return string |
*/ |
function getValue() |
{ |
return $this->_value; |
} // end func getValue |
// }}} |
// {{{ setWrap() |
/** |
* Sets wrap type for textarea element |
* |
* @param string $wrap Wrap type |
* @since 1.0 |
* @access public |
* @return void |
*/ |
function setWrap($wrap) |
{ |
$this->updateAttributes(array('wrap' => $wrap)); |
} //end func setWrap |
// }}} |
// {{{ setRows() |
/** |
* Sets height in rows for textarea element |
* |
* @param string $rows Height expressed in rows |
* @since 1.0 |
* @access public |
* @return void |
*/ |
function setRows($rows) |
{ |
$this->updateAttributes(array('rows' => $rows)); |
} //end func setRows |
// }}} |
// {{{ setCols() |
/** |
* Sets width in cols for textarea element |
* |
* @param string $cols Width expressed in cols |
* @since 1.0 |
* @access public |
* @return void |
*/ |
function setCols($cols) |
{ |
$this->updateAttributes(array('cols' => $cols)); |
} //end func setCols |
// }}} |
// {{{ toHtml() |
/** |
* Returns the textarea element in HTML |
* |
* @since 1.0 |
* @access public |
* @return string |
*/ |
function toHtml() |
{ |
if ($this->_flagFrozen) { |
return $this->getFrozenHtml(); |
} else { |
return $this->_getTabs() . |
'<textarea' . $this->_getAttrString($this->_attributes) . '>' . |
// because we wrap the form later we don't want the text indented |
preg_replace("/(\r\n|\n|\r)/", '
', htmlspecialchars($this->_value)) . |
'</textarea>'; |
} |
} //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 |
*/ |
function getFrozenHtml() |
{ |
$value = htmlspecialchars($this->getValue()); |
if ($this->getAttribute('wrap') == 'off') { |
$html = $this->_getTabs() . '<pre>' . $value."</pre>\n"; |
} else { |
$html = nl2br($value)."\n"; |
} |
return $html . $this->_getPersistantData(); |
} //end func getFrozenHtml |
// }}} |
} //end class HTML_QuickForm_textarea |
?> |
/branches/livraison_menes/api/pear/HTML/QuickForm/file.php |
---|
New file |
0,0 → 1,346 |
<?php |
/* vim: set expandtab tabstop=4 shiftwidth=4: */ |
// +----------------------------------------------------------------------+ |
// | PHP version 4.0 | |
// +----------------------------------------------------------------------+ |
// | Copyright (c) 1997, 1998, 1999, 2000, 2001 The PHP Group | |
// +----------------------------------------------------------------------+ |
// | This source file is subject to version 2.0 of the PHP license, | |
// | that is bundled with this package in the file LICENSE, and is | |
// | available at through the world-wide-web at | |
// | http://www.php.net/license/2_02.txt. | |
// | If you did not receive a copy of the PHP license and are unable to | |
// | obtain it through the world-wide-web, please send a note to | |
// | license@php.net so we can mail you a copy immediately. | |
// +----------------------------------------------------------------------+ |
// | Authors: Adam Daniel <adaniel1@eesus.jnj.com> | |
// | Bertrand Mansion <bmansion@mamasam.com> | |
// +----------------------------------------------------------------------+ |
// |
// $Id: file.php,v 1.2 2005-09-20 17:01:22 ddelon Exp $ |
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 type element |
* |
* @author Adam Daniel <adaniel1@eesus.jnj.com> |
* @author Bertrand Mansion <bmansion@mamasam.com> |
* @version 1.0 |
* @since PHP4.04pl1 |
* @access public |
*/ |
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 |
*/ |
function moveUploadedFile($dest, $fileName = '') |
{ |
if ($dest != '' && substr($dest, -1) != '/') { |
$dest .= '/'; |
} |
$fileName = ($fileName != '') ? $fileName : basename($this->_value['name']); |
if (move_uploaded_file($this->_value['tmp_name'], $dest . $fileName)) { |
return true; |
} else { |
return false; |
} |
} // 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 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 = 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 |
?> |
/branches/livraison_menes/api/pear/HTML/QuickForm/select.php |
---|
New file |
0,0 → 1,604 |
<?php |
/* vim: set expandtab tabstop=4 shiftwidth=4: */ |
// +----------------------------------------------------------------------+ |
// | PHP version 4.0 | |
// +----------------------------------------------------------------------+ |
// | Copyright (c) 1997-2003 The PHP Group | |
// +----------------------------------------------------------------------+ |
// | This source file is subject to version 2.0 of the PHP license, | |
// | that is bundled with this package in the file LICENSE, and is | |
// | available at through the world-wide-web at | |
// | http://www.php.net/license/2_02.txt. | |
// | If you did not receive a copy of the PHP license and are unable to | |
// | obtain it through the world-wide-web, please send a note to | |
// | license@php.net so we can mail you a copy immediately. | |
// +----------------------------------------------------------------------+ |
// | Authors: Adam Daniel <adaniel1@eesus.jnj.com> | |
// | Bertrand Mansion <bmansion@mamasam.com> | |
// +----------------------------------------------------------------------+ |
// |
// $Id: select.php,v 1.2 2005-09-20 17:01:22 ddelon Exp $ |
require_once('HTML/QuickForm/element.php'); |
/** |
* Class to dynamically create an HTML SELECT |
* |
* @author Adam Daniel <adaniel1@eesus.jnj.com> |
* @author Bertrand Mansion <bmansion@mamasam.com> |
* @version 1.0 |
* @since PHP4.04pl1 |
* @access public |
*/ |
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' => $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' => $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_DEFAULT; |
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) ): |
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"; |
foreach ($this->_options as $option) { |
if (is_array($this->_values) && in_array((string)$option['attr']['value'], $this->_values)) { |
$this->_updateAttrArray($option['attr'], array('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 ((string)$val == (string)$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 ($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 |
// XXX: should we push this to element::onQuickFormEvent()? |
if (null === $value && !$caller->isSubmitted()) { |
$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 |
?> |
/branches/livraison_menes/api/pear/HTML/QuickForm/Renderer/Array.php |
---|
New file |
0,0 → 1,319 |
<?php |
/* vim: set expandtab tabstop=4 shiftwidth=4: */ |
// +----------------------------------------------------------------------+ |
// | PHP version 4.0 | |
// +----------------------------------------------------------------------+ |
// | Copyright (c) 1997-2003 The PHP Group | |
// +----------------------------------------------------------------------+ |
// | This source file is subject to version 2.0 of the PHP license, | |
// | that is bundled with this package in the file LICENSE, and is | |
// | available at through the world-wide-web at | |
// | http://www.php.net/license/2_02.txt. | |
// | If you did not receive a copy of the PHP license and are unable to | |
// | obtain it through the world-wide-web, please send a note to | |
// | license@php.net so we can mail you a copy immediately. | |
// +----------------------------------------------------------------------+ |
// | Authors: Alexey Borzov <borz_off@cs.msu.su> | |
// | Adam Daniel <adaniel1@eesus.jnj.com> | |
// | Bertrand Mansion <bmansion@mamasam.com> | |
// | Thomas Schulz <ths@4bconsult.de> | |
// +----------------------------------------------------------------------+ |
// |
// $Id: Array.php,v 1.2 2005-09-20 17:01:22 ddelon Exp $ |
require_once 'HTML/QuickForm/Renderer.php'; |
/** |
* A concrete renderer for HTML_QuickForm, makes an array of form contents |
* |
* Based on old toArray() code. |
* |
* The form array structure is the following: |
* 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 |
* ) |
* ) |
* ) |
* ); |
* |
* where element_i is an array of the form: |
* 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 |
* ) |
* ); |
* |
* @access public |
*/ |
class HTML_QuickForm_Renderer_Array extends HTML_QuickForm_Renderer |
{ |
/** |
* 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 object An HTML_QuickForm_element object |
* @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; |
} |
} |
} |
?> |
/branches/livraison_menes/api/pear/HTML/QuickForm/Renderer/ArraySmarty.php |
---|
New file |
0,0 → 1,376 |
<?php |
/* vim: set expandtab tabstop=4 shiftwidth=4: */ |
// +----------------------------------------------------------------------+ |
// | PHP version 4.0 | |
// +----------------------------------------------------------------------+ |
// | Copyright (c) 1997-2003 The PHP Group | |
// +----------------------------------------------------------------------+ |
// | This source file is subject to version 2.0 of the PHP license, | |
// | that is bundled with this package in the file LICENSE, and is | |
// | available at through the world-wide-web at | |
// | http://www.php.net/license/2_02.txt. | |
// | If you did not receive a copy of the PHP license and are unable to | |
// | obtain it through the world-wide-web, please send a note to | |
// | license@php.net so we can mail you a copy immediately. | |
// +----------------------------------------------------------------------+ |
// | Authors: Alexey Borzov <borz_off@cs.msu.su> | |
// | Bertrand Mansion <bmansion@mamasam.com> | |
// | Thomas Schulz <ths@4bconsult.de> | |
// +----------------------------------------------------------------------+ |
// |
// $Id: ArraySmarty.php,v 1.2 2005-09-20 17:01:22 ddelon Exp $ |
require_once 'HTML/QuickForm/Renderer/Array.php'; |
/** |
* A static renderer for HTML_QuickForm, makes an array of form content |
* useful for an Smarty template |
* |
* Based on old toArray() code and ITStatic renderer. |
* |
* The form array structure is the following: |
* 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 |
* |
* // where an element array has the form: |
* ( |
* [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 |
* ) |
* ) |
* |
* @access public |
*/ |
class HTML_QuickForm_Renderer_ArraySmarty extends HTML_QuickForm_Renderer_Array |
{ |
/** |
* 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 object 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 object An HTML_QuickForm_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 object An HTML_QuickForm_group object 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 object An HTML_QuickForm_element object |
* @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) { |
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 = '[\'' . $matches[1] . '\']' . $sKeysSub; |
} else { |
$sKeys = '[\'' . $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 = '[\'' . $ret['name'] . '\']'; |
} |
// for radios: add extra key from value |
if ('radio' == $ret['type'] and substr($sKeys, -2) != '[]') { |
$sKeys .= '[\'' . $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 |
} |
?> |
/branches/livraison_menes/api/pear/HTML/QuickForm/Renderer/ObjectFlexy.php |
---|
New file |
0,0 → 1,261 |
<?php |
/* vim: set expandtab tabstop=4 shiftwidth=4: */ |
// +----------------------------------------------------------------------+ |
// | PHP version 4.0 | |
// +----------------------------------------------------------------------+ |
// | Copyright (c) 1997-2003 The PHP Group | |
// +----------------------------------------------------------------------+ |
// | This source file is subject to version 2.0 of the PHP license, | |
// | that is bundled with this package in the file LICENSE, and is | |
// | available at through the world-wide-web at | |
// | http://www.php.net/license/2_02.txt. | |
// | If you did not receive a copy of the PHP license and are unable to | |
// | obtain it through the world-wide-web, please send a note to | |
// | license@php.net so we can mail you a copy immediately. | |
// +----------------------------------------------------------------------+ |
// | Author: Ron McClain <ron@humaniq.com> | |
// +----------------------------------------------------------------------+ |
// |
// $Id: ObjectFlexy.php,v 1.2 2005-09-20 17:01:22 ddelon Exp $ |
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: |
* $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"); |
* |
* Based on the code for HTML_QuickForm_Renderer_ArraySmarty |
* |
* @see QuickFormFlexyObject |
* @access public |
*/ |
class HTML_QuickForm_Renderer_ObjectFlexy extends HTML_QuickForm_Renderer_Object |
{ |
/** |
* 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 $flexy object HTML_Template_Flexy instance |
* @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 element object An HTML_QuickForm_element object |
* @param required bool Whether an element is required |
* @param error 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 = '->{\'' . $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 = '->{\'' . $ret->name . '\'}'; |
} |
// for radios: add extra key from value |
if ('radio' == $ret->type && '[]' != substr($keys, -2)) { |
$keys .= '->{\'' . $ret->value . '\'}'; |
} |
$ret->keys = $keys; |
$this->_elementIdx++; |
return $ret; |
} |
/** |
* Stores an object representation of an element in the |
* QuickformFormObject instance |
* |
* @access private |
* @param elObj object 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. |
* {if:error} |
* <font color="red" size="1">{error:h}</font><br /> |
* {end:} |
* {html:h} |
* |
* @access public |
* @param template 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. |
* {if:required} |
* <font color="orange" size="1">*</font> |
* {end:} |
* {label:h} |
* |
* @access public |
* @param template 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 |
*/ |
class QuickformFlexyForm extends QuickformForm |
{ |
} |
/** |
* Adds nothing to QuickformElement, left for backwards compatibility |
*/ |
class QuickformFlexyElement extends QuickformElement |
{ |
} |
?> |
/branches/livraison_menes/api/pear/HTML/QuickForm/Renderer/ITDynamic.php |
---|
New file |
0,0 → 1,287 |
<?php |
/* vim: set expandtab tabstop=4 shiftwidth=4: */ |
// +----------------------------------------------------------------------+ |
// | PHP version 4.0 | |
// +----------------------------------------------------------------------+ |
// | Copyright (c) 1997-2003 The PHP Group | |
// +----------------------------------------------------------------------+ |
// | This source file is subject to version 2.0 of the PHP license, | |
// | that is bundled with this package in the file LICENSE, and is | |
// | available at through the world-wide-web at | |
// | http://www.php.net/license/2_02.txt. | |
// | If you did not receive a copy of the PHP license and are unable to | |
// | obtain it through the world-wide-web, please send a note to | |
// | license@php.net so we can mail you a copy immediately. | |
// +----------------------------------------------------------------------+ |
// | Author: Alexey Borzov <borz_off@cs.msu.su> | |
// +----------------------------------------------------------------------+ |
// |
// $Id: ITDynamic.php,v 1.2 2005-09-20 17:01:22 ddelon Exp $ |
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. |
* |
* @author Alexey Borzov <borz_off@cs.msu.su> |
* @access public |
*/ |
class HTML_QuickForm_Renderer_ITDynamic extends HTML_QuickForm_Renderer |
{ |
/** |
* A template class (HTML_Template_ITX or HTML_Template_Sigma) instance |
* @var object |
*/ |
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 object An HTML_Template_ITX/HTML_Template_Sigma 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 object An HTML_QuickForm_element object |
* @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; |
} |
} |
?> |
/branches/livraison_menes/api/pear/HTML/QuickForm/Renderer/QuickHtml.php |
---|
New file |
0,0 → 1,203 |
<?php |
/* vim: set expandtab tabstop=4 shiftwidth=4: */ |
// +----------------------------------------------------------------------+ |
// | PHP version 4.0 | |
// +----------------------------------------------------------------------+ |
// | Copyright (c) 1997-2003 The PHP Group | |
// +----------------------------------------------------------------------+ |
// | This source file is subject to version 2.0 of the PHP license, | |
// | that is bundled with this package in the file LICENSE, and is | |
// | available at through the world-wide-web at | |
// | http://www.php.net/license/2_02.txt. | |
// | If you did not receive a copy of the PHP license and are unable to | |
// | obtain it through the world-wide-web, please send a note to | |
// | license@php.net so we can mail you a copy immediately. | |
// +----------------------------------------------------------------------+ |
// | Authors: Jason Rust <jrust@rustyparts.com> | |
// +----------------------------------------------------------------------+ |
// |
// $Id: QuickHtml.php,v 1.2 2005-09-20 17:01:22 ddelon Exp $ |
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 |
* |
* @access public |
* @package QuickForm |
*/ |
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 |
*/ |
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 object An HTML_QuickForm_element object |
* @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 object An HTML_QuickForm_hidden object 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 object An HTML_QuickForm_group object 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 |
?> |
/branches/livraison_menes/api/pear/HTML/QuickForm/Renderer/Default.php |
---|
New file |
0,0 → 1,474 |
<?php |
/* vim: set expandtab tabstop=4 shiftwidth=4: */ |
// +----------------------------------------------------------------------+ |
// | PHP version 4.0 | |
// +----------------------------------------------------------------------+ |
// | Copyright (c) 1997-2003 The PHP Group | |
// +----------------------------------------------------------------------+ |
// | This source file is subject to version 2.0 of the PHP license, | |
// | that is bundled with this package in the file LICENSE, and is | |
// | available at through the world-wide-web at | |
// | http://www.php.net/license/2_02.txt. | |
// | If you did not receive a copy of the PHP license and are unable to | |
// | obtain it through the world-wide-web, please send a note to | |
// | license@php.net so we can mail you a copy immediately. | |
// +----------------------------------------------------------------------+ |
// | Authors: Alexey Borzov <borz_off@cs.msu.su> | |
// | Adam Daniel <adaniel1@eesus.jnj.com> | |
// | Bertrand Mansion <bmansion@mamasam.com> | |
// +----------------------------------------------------------------------+ |
// |
// $Id: Default.php,v 1.2 2005-09-20 17:01:22 ddelon Exp $ |
require_once('HTML/QuickForm/Renderer.php'); |
/** |
* A concrete renderer for HTML_QuickForm, |
* based on QuickForm 2.x built-in one |
* |
* @access public |
*/ |
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 object An HTML_QuickForm 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 object An HTML_QuickForm 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 object An HTML_QuickForm_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 -->(\s|\S)*<!-- END required -->([ \t\n\r]*)?/i", '', $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 -->(\s|\S)*<!-- END error -->([ \t\n\r]*)?/i", '', $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*/i', '', $html); |
} |
return $html; |
} // end func _prepareTemplate |
/** |
* Renders an element Html |
* Called when visiting an element |
* |
* @param object An HTML_QuickForm_element object 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 -->(\s|\S)*<!-- END required -->([ \t\n\r]*)?/i", '', $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 object An HTML_QuickForm_hidden object 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 object An 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 object An HTML_QuickForm_group object 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 object An HTML_QuickForm_group object 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 |
?> |
/branches/livraison_menes/api/pear/HTML/QuickForm/Renderer/ITStatic.php |
---|
New file |
0,0 → 1,490 |
<?php |
/* vim: set expandtab tabstop=4 shiftwidth=4: */ |
// +----------------------------------------------------------------------+ |
// | PHP version 4.0 | |
// +----------------------------------------------------------------------+ |
// | Copyright (c) 1997-2003 The PHP Group | |
// +----------------------------------------------------------------------+ |
// | This source file is subject to version 2.0 of the PHP license, | |
// | that is bundled with this package in the file LICENSE, and is | |
// | available at through the world-wide-web at | |
// | http://www.php.net/license/2_02.txt. | |
// | If you did not receive a copy of the PHP license and are unable to | |
// | obtain it through the world-wide-web, please send a note to | |
// | license@php.net so we can mail you a copy immediately. | |
// +----------------------------------------------------------------------+ |
// | Author: Bertrand Mansion <bmansion@mamasam.com> | |
// +----------------------------------------------------------------------+ |
// |
// $Id: ITStatic.php,v 1.2 2005-09-20 17:01:22 ddelon Exp $ |
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. |
* |
* @author Bertrand Mansion <bmansion@mamasam.com> |
* @access public |
*/ |
class HTML_QuickForm_Renderer_ITStatic extends HTML_QuickForm_Renderer |
{ |
/** |
* 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 object An HTML_Template_IT or other compatible 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 object An HTML_QuickForm 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 object An HTML_QuickForm 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 object An HTML_QuickForm_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 object An HTML_QuickForm_element object 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 object An HTML_QuickForm_hidden object 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 object An HTML_QuickForm_group object 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 object An HTML_QuickForm_group object 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 |
?> |
/branches/livraison_menes/api/pear/HTML/QuickForm/Renderer/Object.php |
---|
New file |
0,0 → 1,432 |
<?php |
/* vim: set expandtab tabstop=4 shiftwidth=4: */ |
// +----------------------------------------------------------------------+ |
// | PHP version 4.0 | |
// +----------------------------------------------------------------------+ |
// | Copyright (c) 1997-2003 The PHP Group | |
// +----------------------------------------------------------------------+ |
// | This source file is subject to version 2.0 of the PHP license, | |
// | that is bundled with this package in the file LICENSE, and is | |
// | available at through the world-wide-web at | |
// | http://www.php.net/license/2_02.txt. | |
// | If you did not receive a copy of the PHP license and are unable to | |
// | obtain it through the world-wide-web, please send a note to | |
// | license@php.net so we can mail you a copy immediately. | |
// +----------------------------------------------------------------------+ |
// | Author: Ron McClain <ron@humaniq.com> | |
// +----------------------------------------------------------------------+ |
// |
// $Id: Object.php,v 1.2 2005-09-20 17:01:22 ddelon Exp $ |
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 |
* |
* @access public |
*/ |
class HTML_QuickForm_Renderer_Object extends HTML_QuickForm_Renderer |
{ |
/** |
* The object being generated |
* @var object $_obj |
*/ |
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 collecthidden 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 type 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 element object An HTML_QuickForm_element object |
* @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 elObj object 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. |
* {form.outputJavaScript():h} |
* {form.outputHeader():h} |
* <table> |
* <tr> |
* <td>{form.name.label:h}</td><td>{form.name.html:h}</td> |
* </tr> |
* </table> |
* </form> |
*/ |
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. |
*/ |
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 |
?> |
/branches/livraison_menes/api/pear/HTML/QuickForm/advcheckbox.php |
---|
New file |
0,0 → 1,283 |
<?php |
/* vim: set expandtab tabstop=4 shiftwidth=4: */ |
// +----------------------------------------------------------------------+ |
// | PHP version 4.0 | |
// +----------------------------------------------------------------------+ |
// | Copyright (c) 1997, 1998, 1999, 2000, 2001 The PHP Group | |
// +----------------------------------------------------------------------+ |
// | This source file is subject to version 2.0 of the PHP license, | |
// | that is bundled with this package in the file LICENSE, and is | |
// | available at through the world-wide-web at | |
// | http://www.php.net/license/2_02.txt. | |
// | If you did not receive a copy of the PHP license and are unable to | |
// | obtain it through the world-wide-web, please send a note to | |
// | license@php.net so we can mail you a copy immediately. | |
// +----------------------------------------------------------------------+ |
// | Authors: Adam Daniel <adaniel1@eesus.jnj.com> | |
// | Bertrand Mansion <bmansion@mamasam.com> | |
// +----------------------------------------------------------------------+ |
// |
// $Id: advcheckbox.php,v 1.2 2005-09-20 17:01:22 ddelon Exp $ |
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 creating a hidden field with the passed-in name |
* and creating the checkbox with no name, but with a javascript |
* onclick which sets the value of the hidden field. |
* |
* @author Jason Rust <jrust@php.net> |
* @since 2.0 |
* @access public |
*/ |
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 pribate name for the element |
* |
* @param string $elementName The element name to make private |
* |
* @access public |
* @return string |
*/ |
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 |
*/ |
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->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 { |
$oldName = $this->getName(); |
$oldJs = $this->getAttribute('onclick'); |
$this->updateAttributes(array( |
'name' => $this->getPrivateName($oldName), |
'onclick' => $this->getOnclickJs($oldName) . ' ' . $oldJs |
)); |
$html = parent::toHtml() . '<input' . |
$this->_getAttrString(array( |
'type' => 'hidden', |
'name' => $oldName, |
'value' => $this->getValue() |
)) . ' />'; |
// revert the name and JS, in case this method will be called once more |
$this->updateAttributes(array( |
'name' => $oldName, |
'onclick' => $oldJs |
)); |
return $html; |
} |
} //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 |
?> |
/branches/livraison_menes/api/pear/HTML/QuickForm/Rule/Required.php |
---|
New file |
0,0 → 1,52 |
<?php |
/* vim: set expandtab tabstop=4 shiftwidth=4: */ |
// +----------------------------------------------------------------------+ |
// | PHP version 4.0 | |
// +----------------------------------------------------------------------+ |
// | Copyright (c) 1997-2003 The PHP Group | |
// +----------------------------------------------------------------------+ |
// | This source file is subject to version 2.0 of the PHP license, | |
// | that is bundled with this package in the file LICENSE, and is | |
// | available at through the world-wide-web at | |
// | http://www.php.net/license/2_02.txt. | |
// | If you did not receive a copy of the PHP license and are unable to | |
// | obtain it through the world-wide-web, please send a note to | |
// | license@php.net so we can mail you a copy immediately. | |
// +----------------------------------------------------------------------+ |
// | Authors: Bertrand Mansion <bmansion@mamasam.com> | |
// +----------------------------------------------------------------------+ |
// |
// $Id: Required.php,v 1.2 2005-09-20 17:01:22 ddelon Exp $ |
require_once('HTML/QuickForm/Rule.php'); |
/** |
* Required elements validation |
* @version 1.0 |
*/ |
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 |
?> |
/branches/livraison_menes/api/pear/HTML/QuickForm/Rule/Compare.php |
---|
New file |
0,0 → 1,95 |
<?php |
/* vim: set expandtab tabstop=4 shiftwidth=4: */ |
// +----------------------------------------------------------------------+ |
// | PHP version 4.0 | |
// +----------------------------------------------------------------------+ |
// | Copyright (c) 1997-2003 The PHP Group | |
// +----------------------------------------------------------------------+ |
// | This source file is subject to version 2.0 of the PHP license, | |
// | that is bundled with this package in the file LICENSE, and is | |
// | available at through the world-wide-web at | |
// | http://www.php.net/license/2_02.txt. | |
// | If you did not receive a copy of the PHP license and are unable to | |
// | obtain it through the world-wide-web, please send a note to | |
// | license@php.net so we can mail you a copy immediately. | |
// +----------------------------------------------------------------------+ |
// | Author: Alexey Borzov <avb@php.net> | |
// +----------------------------------------------------------------------+ |
// |
// $Id: Compare.php,v 1.2 2005-09-20 17:01:22 ddelon Exp $ |
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 |
* |
* @access public |
* @package HTML_QuickForm |
* @version $Revision: 1.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 $a ' . $operator . ' $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 = "!({jsVar}[0] {$operator} {jsVar}[1])"; |
} |
return array('', "'' != {jsVar}[0] && {$check}"); |
} |
} |
?> |
/branches/livraison_menes/api/pear/HTML/QuickForm/Rule/Email.php |
---|
New file |
0,0 → 1,61 |
<?php |
/* vim: set expandtab tabstop=4 shiftwidth=4: */ |
// +----------------------------------------------------------------------+ |
// | PHP version 4.0 | |
// +----------------------------------------------------------------------+ |
// | Copyright (c) 1997-2003 The PHP Group | |
// +----------------------------------------------------------------------+ |
// | This source file is subject to version 2.0 of the PHP license, | |
// | that is bundled with this package in the file LICENSE, and is | |
// | available at through the world-wide-web at | |
// | http://www.php.net/license/2_02.txt. | |
// | If you did not receive a copy of the PHP license and are unable to | |
// | obtain it through the world-wide-web, please send a note to | |
// | license@php.net so we can mail you a copy immediately. | |
// +----------------------------------------------------------------------+ |
// | Authors: Bertrand Mansion <bmansion@mamasam.com> | |
// +----------------------------------------------------------------------+ |
// |
// $Id: Email.php,v 1.2 2005-09-20 17:01:22 ddelon Exp $ |
require_once('HTML/QuickForm/Rule.php'); |
/** |
* Email validation rule |
* @version 1.0 |
*/ |
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) |
{ |
if (preg_match($this->regex, $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 |
?> |
/branches/livraison_menes/api/pear/HTML/QuickForm/Rule/Regex.php |
---|
New file |
0,0 → 1,89 |
<?php |
/* vim: set expandtab tabstop=4 shiftwidth=4: */ |
// +----------------------------------------------------------------------+ |
// | PHP version 4.0 | |
// +----------------------------------------------------------------------+ |
// | Copyright (c) 1997-2003 The PHP Group | |
// +----------------------------------------------------------------------+ |
// | This source file is subject to version 2.0 of the PHP license, | |
// | that is bundled with this package in the file LICENSE, and is | |
// | available at through the world-wide-web at | |
// | http://www.php.net/license/2_02.txt. | |
// | If you did not receive a copy of the PHP license and are unable to | |
// | obtain it through the world-wide-web, please send a note to | |
// | license@php.net so we can mail you a copy immediately. | |
// +----------------------------------------------------------------------+ |
// | Authors: Bertrand Mansion <bmansion@mamasam.com> | |
// +----------------------------------------------------------------------+ |
// |
// $Id: Regex.php,v 1.2 2005-09-20 17:01:22 ddelon Exp $ |
require_once('HTML/QuickForm/Rule.php'); |
/** |
* Validates values using regular expressions |
* @version 1.0 |
*/ |
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) |
{ |
if (isset($this->_data[$this->name])) { |
if (!preg_match($this->_data[$this->name], $value)) { |
return false; |
} |
} else { |
if (!preg_match($regex, $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 |
?> |
/branches/livraison_menes/api/pear/HTML/QuickForm/Rule/Callback.php |
---|
New file |
0,0 → 1,113 |
<?php |
/* vim: set expandtab tabstop=4 shiftwidth=4: */ |
// +----------------------------------------------------------------------+ |
// | PHP version 4.0 | |
// +----------------------------------------------------------------------+ |
// | Copyright (c) 1997-2003 The PHP Group | |
// +----------------------------------------------------------------------+ |
// | This source file is subject to version 2.0 of the PHP license, | |
// | that is bundled with this package in the file LICENSE, and is | |
// | available at through the world-wide-web at | |
// | http://www.php.net/license/2_02.txt. | |
// | If you did not receive a copy of the PHP license and are unable to | |
// | obtain it through the world-wide-web, please send a note to | |
// | license@php.net so we can mail you a copy immediately. | |
// +----------------------------------------------------------------------+ |
// | Authors: Bertrand Mansion <bmansion@mamasam.com> | |
// +----------------------------------------------------------------------+ |
// |
// $Id: Callback.php,v 1.2 2005-09-20 17:01:22 ddelon Exp $ |
require_once('HTML/QuickForm/Rule.php'); |
/** |
* Validates values using callback functions or methods |
* @version 1.0 |
*/ |
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 |
?> |
/branches/livraison_menes/api/pear/HTML/QuickForm/Rule/Range.php |
---|
New file |
0,0 → 1,64 |
<?php |
/* vim: set expandtab tabstop=4 shiftwidth=4: */ |
// +----------------------------------------------------------------------+ |
// | PHP version 4.0 | |
// +----------------------------------------------------------------------+ |
// | Copyright (c) 1997-2003 The PHP Group | |
// +----------------------------------------------------------------------+ |
// | This source file is subject to version 2.0 of the PHP license, | |
// | that is bundled with this package in the file LICENSE, and is | |
// | available at through the world-wide-web at | |
// | http://www.php.net/license/2_02.txt. | |
// | If you did not receive a copy of the PHP license and are unable to | |
// | obtain it through the world-wide-web, please send a note to | |
// | license@php.net so we can mail you a copy immediately. | |
// +----------------------------------------------------------------------+ |
// | Authors: Bertrand Mansion <bmansion@mamasam.com> | |
// +----------------------------------------------------------------------+ |
// |
// $Id: Range.php,v 1.2 2005-09-20 17:01:22 ddelon Exp $ |
require_once('HTML/QuickForm/Rule.php'); |
/** |
* Validates values using range comparison |
* @version 1.0 |
*/ |
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 |
?> |
/branches/livraison_menes/api/pear/HTML/QuickForm/image.php |
---|
New file |
0,0 → 1,119 |
<?php |
/* vim: set expandtab tabstop=4 shiftwidth=4: */ |
// +----------------------------------------------------------------------+ |
// | PHP version 4.0 | |
// +----------------------------------------------------------------------+ |
// | Copyright (c) 1997, 1998, 1999, 2000, 2001 The PHP Group | |
// +----------------------------------------------------------------------+ |
// | This source file is subject to version 2.0 of the PHP license, | |
// | that is bundled with this package in the file LICENSE, and is | |
// | available at through the world-wide-web at | |
// | http://www.php.net/license/2_02.txt. | |
// | If you did not receive a copy of the PHP license and are unable to | |
// | obtain it through the world-wide-web, please send a note to | |
// | license@php.net so we can mail you a copy immediately. | |
// +----------------------------------------------------------------------+ |
// | Authors: Adam Daniel <adaniel1@eesus.jnj.com> | |
// | Bertrand Mansion <bmansion@mamasam.com> | |
// +----------------------------------------------------------------------+ |
// |
// $Id: image.php,v 1.2 2005-09-20 17:01:22 ddelon Exp $ |
require_once("HTML/QuickForm/input.php"); |
/** |
* HTML class for a image type element |
* |
* @author Adam Daniel <adaniel1@eesus.jnj.com> |
* @author Bertrand Mansion <bmansion@mamasam.com> |
* @version 1.0 |
* @since PHP4.04pl1 |
* @access public |
*/ |
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 |
?> |
/branches/livraison_menes/api/pear/HTML/QuickForm/reset.php |
---|
New file |
0,0 → 1,72 |
<?php |
/* vim: set expandtab tabstop=4 shiftwidth=4: */ |
// +----------------------------------------------------------------------+ |
// | PHP version 4.0 | |
// +----------------------------------------------------------------------+ |
// | Copyright (c) 1997, 1998, 1999, 2000, 2001 The PHP Group | |
// +----------------------------------------------------------------------+ |
// | This source file is subject to version 2.0 of the PHP license, | |
// | that is bundled with this package in the file LICENSE, and is | |
// | available at through the world-wide-web at | |
// | http://www.php.net/license/2_02.txt. | |
// | If you did not receive a copy of the PHP license and are unable to | |
// | obtain it through the world-wide-web, please send a note to | |
// | license@php.net so we can mail you a copy immediately. | |
// +----------------------------------------------------------------------+ |
// | Authors: Adam Daniel <adaniel1@eesus.jnj.com> | |
// | Bertrand Mansion <bmansion@mamasam.com> | |
// +----------------------------------------------------------------------+ |
// |
// $Id: reset.php,v 1.2 2005-09-20 17:01:22 ddelon Exp $ |
require_once("HTML/QuickForm/input.php"); |
/** |
* HTML class for a reset type element |
* |
* @author Adam Daniel <adaniel1@eesus.jnj.com> |
* @author Bertrand Mansion <bmansion@mamasam.com> |
* @version 1.1 |
* @since PHP4.04pl1 |
* @access public |
*/ |
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 |
?> |
/branches/livraison_menes/api/pear/HTML/QuickForm/text.php |
---|
New file |
0,0 → 1,91 |
<?php |
/* vim: set expandtab tabstop=4 shiftwidth=4: */ |
// +----------------------------------------------------------------------+ |
// | PHP version 4.0 | |
// +----------------------------------------------------------------------+ |
// | Copyright (c) 1997, 1998, 1999, 2000, 2001 The PHP Group | |
// +----------------------------------------------------------------------+ |
// | This source file is subject to version 2.0 of the PHP license, | |
// | that is bundled with this package in the file LICENSE, and is | |
// | available at through the world-wide-web at | |
// | http://www.php.net/license/2_02.txt. | |
// | If you did not receive a copy of the PHP license and are unable to | |
// | obtain it through the world-wide-web, please send a note to | |
// | license@php.net so we can mail you a copy immediately. | |
// +----------------------------------------------------------------------+ |
// | Authors: Adam Daniel <adaniel1@eesus.jnj.com> | |
// | Bertrand Mansion <bmansion@mamasam.com> | |
// +----------------------------------------------------------------------+ |
// |
// $Id: text.php,v 1.2 2005-09-20 17:01:22 ddelon Exp $ |
require_once("HTML/QuickForm/input.php"); |
/** |
* HTML class for a text field |
* |
* @author Adam Daniel <adaniel1@eesus.jnj.com> |
* @author Bertrand Mansion <bmansion@mamasam.com> |
* @version 1.0 |
* @since PHP4.04pl1 |
* @access public |
*/ |
class HTML_QuickForm_text 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 |
*/ |
function HTML_QuickForm_text($elementName=null, $elementLabel=null, $attributes=null) |
{ |
HTML_QuickForm_input::HTML_QuickForm_input($elementName, $elementLabel, $attributes); |
$this->_persistantFreeze = true; |
$this->setType('text'); |
} //end constructor |
// }}} |
// {{{ setSize() |
/** |
* Sets size of text field |
* |
* @param string $size Size of text field |
* @since 1.3 |
* @access public |
* @return void |
*/ |
function setSize($size) |
{ |
$this->updateAttributes(array('size'=>$size)); |
} //end func setSize |
// }}} |
// {{{ setMaxlength() |
/** |
* Sets maxlength of text field |
* |
* @param string $maxlength Maximum length of text field |
* @since 1.3 |
* @access public |
* @return void |
*/ |
function setMaxlength($maxlength) |
{ |
$this->updateAttributes(array('maxlength'=>$maxlength)); |
} //end func setMaxlength |
// }}} |
} //end class HTML_QuickForm_text |
?> |
/branches/livraison_menes/api/pear/HTML/QuickForm/checkbox.php |
---|
New file |
0,0 → 1,268 |
<?php |
/* vim: set expandtab tabstop=4 shiftwidth=4: */ |
// +----------------------------------------------------------------------+ |
// | PHP version 4.0 | |
// +----------------------------------------------------------------------+ |
// | Copyright (c) 1997, 1998, 1999, 2000, 2001 The PHP Group | |
// +----------------------------------------------------------------------+ |
// | This source file is subject to version 2.0 of the PHP license, | |
// | that is bundled with this package in the file LICENSE, and is | |
// | available at through the world-wide-web at | |
// | http://www.php.net/license/2_02.txt. | |
// | If you did not receive a copy of the PHP license and are unable to | |
// | obtain it through the world-wide-web, please send a note to | |
// | license@php.net so we can mail you a copy immediately. | |
// +----------------------------------------------------------------------+ |
// | Authors: Adam Daniel <adaniel1@eesus.jnj.com> | |
// | Bertrand Mansion <bmansion@mamasam.com> | |
// +----------------------------------------------------------------------+ |
// |
// $Id: checkbox.php,v 1.2 2005-09-20 17:01:22 ddelon Exp $ |
require_once("HTML/QuickForm/input.php"); |
/** |
* HTML class for a checkbox type field |
* |
* @author Adam Daniel <adaniel1@eesus.jnj.com> |
* @author Bertrand Mansion <bmansion@mamasam.com> |
* @version 1.1 |
* @since PHP4.04pl1 |
* @access public |
*/ |
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) { |
$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 |
?> |
/branches/livraison_menes/api/pear/HTML/QuickForm/static.php |
---|
New file |
0,0 → 1,193 |
<?php |
/* vim: set expandtab tabstop=4 shiftwidth=4: */ |
// +----------------------------------------------------------------------+ |
// | PHP version 4.0 | |
// +----------------------------------------------------------------------+ |
// | Copyright (c) 1997-2003 The PHP Group | |
// +----------------------------------------------------------------------+ |
// | This source file is subject to version 2.0 of the PHP license, | |
// | that is bundled with this package in the file LICENSE, and is | |
// | available at through the world-wide-web at | |
// | http://www.php.net/license/2_02.txt. | |
// | If you did not receive a copy of the PHP license and are unable to | |
// | obtain it through the world-wide-web, please send a note to | |
// | license@php.net so we can mail you a copy immediately. | |
// +----------------------------------------------------------------------+ |
// | Authors: Adam Daniel <adaniel1@eesus.jnj.com> | |
// | Bertrand Mansion <bmansion@mamasam.com> | |
// +----------------------------------------------------------------------+ |
// |
// $Id: static.php,v 1.2 2005-09-20 17:01:22 ddelon Exp $ |
require_once("HTML/QuickForm/element.php"); |
/** |
* HTML class for static data |
* |
* @author Wojciech Gdela <eltehaem@poczta.onet.pl> |
* @access public |
*/ |
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 |
?> |
/branches/livraison_menes/api/pear/HTML/QuickForm/hierselect.php |
---|
New file |
0,0 → 1,565 |
<?php |
/* vim: set expandtab tabstop=4 shiftwidth=4: */ |
// +----------------------------------------------------------------------+ |
// | PHP version 4.0 | |
// +----------------------------------------------------------------------+ |
// | Copyright (c) 1997-2004 The PHP Group | |
// +----------------------------------------------------------------------+ |
// | This source file is subject to version 2.0 of the PHP license, | |
// | that is bundled with this package in the file LICENSE, and is | |
// | available at through the world-wide-web at | |
// | http://www.php.net/license/2_02.txt. | |
// | If you did not receive a copy of the PHP license and are unable to | |
// | obtain it through the world-wide-web, please send a note to | |
// | license@php.net so we can mail you a copy immediately. | |
// +----------------------------------------------------------------------+ |
// | Authors: Herim Vasquez <vasquezh@iro.umontreal.ca> | |
// | Bertrand Mansion <bmansion@mamasam.com> | |
// | Alexey Borzov <avb@php.net> |
// +----------------------------------------------------------------------+ |
// |
// $Id: hierselect.php,v 1.2 2005-09-20 17:01:22 ddelon Exp $ |
require_once('HTML/QuickForm/group.php'); |
require_once('HTML/QuickForm/select.php'); |
/** |
* 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]... |
* |
* @author Herim Vasquez <vasquezh@iro.umontreal.ca> |
* @author Bertrand Mansion <bmansion@mamasam.com> |
* @version 1.0 |
* @since PHP4.04pl1 |
* @access public |
*/ |
class HTML_QuickForm_hierselect extends HTML_QuickForm_group |
{ |
// {{{ properties |
/** |
* Options for all the select elements |
* |
* Format is a bit more complex as we need to know which options |
* are related to the ones in the previous select: |
* |
* Ex: |
* // 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 depracated 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)); |
* |
* @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. |
* |
* @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 |
* @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 |
* @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) |
{ |
$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_replaceOptions(ctl, optionList) |
{ |
var j = 0; |
ctl.options.length = 0; |
for (i in optionList) { |
ctl.options[j++] = new Option(optionList[i], 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 |
?> |
/branches/livraison_menes/api/pear/HTML/QuickForm/header.php |
---|
New file |
0,0 → 1,65 |
<?php |
/* vim: set expandtab tabstop=4 shiftwidth=4: */ |
// +----------------------------------------------------------------------+ |
// | PHP version 4.0 | |
// +----------------------------------------------------------------------+ |
// | Copyright (c) 1997-2003 The PHP Group | |
// +----------------------------------------------------------------------+ |
// | This source file is subject to version 2.0 of the PHP license, | |
// | that is bundled with this package in the file LICENSE, and is | |
// | available at through the world-wide-web at | |
// | http://www.php.net/license/2_02.txt. | |
// | If you did not receive a copy of the PHP license and are unable to | |
// | obtain it through the world-wide-web, please send a note to | |
// | license@php.net so we can mail you a copy immediately. | |
// +----------------------------------------------------------------------+ |
// | Author: Alexey Borzov <borz_off@cs.msu.su> | |
// +----------------------------------------------------------------------+ |
// |
// $Id: header.php,v 1.2 2005-09-20 17:01:22 ddelon Exp $ |
require_once 'HTML/QuickForm/static.php'; |
/** |
* A pseudo-element used for adding headers to form |
* |
* @author Alexey Borzov <borz_off@cs.msu.su> |
* @access public |
*/ |
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 object An HTML_QuickForm_Renderer object |
* @access public |
* @return void |
*/ |
function accept(&$renderer) |
{ |
$renderer->renderHeader($this); |
} // end func accept |
// }}} |
} //end class HTML_QuickForm_header |
?> |
/branches/livraison_menes/api/pear/HTML/QuickForm/element.php |
---|
New file |
0,0 → 1,479 |
<?php |
/* vim: set expandtab tabstop=4 shiftwidth=4: */ |
// +----------------------------------------------------------------------+ |
// | PHP version 4.0 | |
// +----------------------------------------------------------------------+ |
// | Copyright (c) 1997, 1998, 1999, 2000, 2001 The PHP Group | |
// +----------------------------------------------------------------------+ |
// | This source file is subject to version 2.0 of the PHP license, | |
// | that is bundled with this package in the file LICENSE, and is | |
// | available at through the world-wide-web at | |
// | http://www.php.net/license/2_02.txt. | |
// | If you did not receive a copy of the PHP license and are unable to | |
// | obtain it through the world-wide-web, please send a note to | |
// | license@php.net so we can mail you a copy immediately. | |
// +----------------------------------------------------------------------+ |
// | Authors: Adam Daniel <adaniel1@eesus.jnj.com> | |
// | Bertrand Mansion <bmansion@mamasam.com> | |
// +----------------------------------------------------------------------+ |
// |
// $Id: element.php,v 1.2 2005-09-20 17:01:22 ddelon Exp $ |
require_once('HTML/Common.php'); |
/** |
* Base class for form elements |
* |
* @author Adam Daniel <adaniel1@eesus.jnj.com> |
* @author Bertrand Mansion <bmansion@mamasam.com> |
* @version 1.3 |
* @since PHP4.04pl1 |
* @access public |
* @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 2.0; |
} // 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 ('' != $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 object An HTML_QuickForm_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 |
?> |
/branches/livraison_menes/api/pear/HTML/QuickForm/hidden.php |
---|
New file |
0,0 → 1,87 |
<?php |
/* vim: set expandtab tabstop=4 shiftwidth=4: */ |
// +----------------------------------------------------------------------+ |
// | PHP version 4.0 | |
// +----------------------------------------------------------------------+ |
// | Copyright (c) 1997, 1998, 1999, 2000, 2001 The PHP Group | |
// +----------------------------------------------------------------------+ |
// | This source file is subject to version 2.0 of the PHP license, | |
// | that is bundled with this package in the file LICENSE, and is | |
// | available at through the world-wide-web at | |
// | http://www.php.net/license/2_02.txt. | |
// | If you did not receive a copy of the PHP license and are unable to | |
// | obtain it through the world-wide-web, please send a note to | |
// | license@php.net so we can mail you a copy immediately. | |
// +----------------------------------------------------------------------+ |
// | Authors: Adam Daniel <adaniel1@eesus.jnj.com> | |
// | Bertrand Mansion <bmansion@mamasam.com> | |
// +----------------------------------------------------------------------+ |
// |
// $Id: hidden.php,v 1.2 2005-09-20 17:01:22 ddelon Exp $ |
require_once("HTML/QuickForm/input.php"); |
/** |
* HTML class for a hidden type element |
* |
* @author Adam Daniel <adaniel1@eesus.jnj.com> |
* @author Bertrand Mansion <bmansion@mamasam.com> |
* @version 1.0 |
* @since PHP4.04pl1 |
* @access public |
*/ |
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 object An HTML_QuickForm_Renderer object |
* @access public |
* @return void |
*/ |
function accept(&$renderer) |
{ |
$renderer->renderHidden($this); |
} // end func accept |
// }}} |
} //end class HTML_QuickForm_hidden |
?> |
/branches/livraison_menes/api/pear/HTML/QuickForm/hiddenselect.php |
---|
New file |
0,0 → 1,107 |
<?php |
/* vim: set expandtab tabstop=4 shiftwidth=4: */ |
// +----------------------------------------------------------------------+ |
// | PHP version 4.0 | |
// +----------------------------------------------------------------------+ |
// | Copyright (c) 1997, 1998, 1999, 2000, 2001 The PHP Group | |
// +----------------------------------------------------------------------+ |
// | This source file is subject to version 2.0 of the PHP license, | |
// | that is bundled with this package in the file LICENSE, and is | |
// | available at through the world-wide-web at | |
// | http://www.php.net/license/2_02.txt. | |
// | If you did not receive a copy of the PHP license and are unable to | |
// | obtain it through the world-wide-web, please send a note to | |
// | license@php.net so we can mail you a copy immediately. | |
// +----------------------------------------------------------------------+ |
// | Authors: Adam Daniel <adaniel1@eesus.jnj.com> | |
// | Bertrand Mansion <bmansion@mamasam.com> | |
// +----------------------------------------------------------------------+ |
// |
// $Id: hiddenselect.php,v 1.2 2005-09-20 17:01:22 ddelon Exp $ |
require_once('HTML/QuickForm/select.php'); |
/** |
* 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. |
* |
* @author Isaac Shepard <ishepard@bsiweb.com> |
* |
* @version 1.0 |
* @since 2.1 |
* @access public |
*/ |
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() |
{ |
$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 |
?> |
/branches/livraison_menes/api/pear/HTML/QuickForm/group.php |
---|
New file |
0,0 → 1,579 |
<?php |
/* vim: set expandtab tabstop=4 shiftwidth=4: */ |
// +----------------------------------------------------------------------+ |
// | PHP version 4.0 | |
// +----------------------------------------------------------------------+ |
// | Copyright (c) 1997, 1998, 1999, 2000, 2001 The PHP Group | |
// +----------------------------------------------------------------------+ |
// | This source file is subject to version 2.0 of the PHP license, | |
// | that is bundled with this package in the file LICENSE, and is | |
// | available at through the world-wide-web at | |
// | http://www.php.net/license/2_02.txt. | |
// | If you did not receive a copy of the PHP license and are unable to | |
// | obtain it through the world-wide-web, please send a note to | |
// | license@php.net so we can mail you a copy immediately. | |
// +----------------------------------------------------------------------+ |
// | Authors: Adam Daniel <adaniel1@eesus.jnj.com> | |
// | Bertrand Mansion <bmansion@mamasam.com> | |
// +----------------------------------------------------------------------+ |
// |
// $Id: group.php,v 1.2 2005-09-20 17:01:22 ddelon Exp $ |
require_once("HTML/QuickForm/element.php"); |
/** |
* HTML class for a form element group |
* |
* @author Adam Daniel <adaniel1@eesus.jnj.com> |
* @author Bertrand Mansion <bmansion@mamasam.com> |
* @version 1.0 |
* @since PHP4.04pl1 |
* @access public |
*/ |
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 object An HTML_QuickForm_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 |
?> |
/branches/livraison_menes/api/pear/HTML/QuickForm/link.php |
---|
New file |
0,0 → 1,192 |
<?php |
/* vim: set expandtab tabstop=4 shiftwidth=4: */ |
// +----------------------------------------------------------------------+ |
// | PHP version 4.0 | |
// +----------------------------------------------------------------------+ |
// | Copyright (c) 1997, 1998, 1999, 2000, 2001 The PHP Group | |
// +----------------------------------------------------------------------+ |
// | This source file is subject to version 2.0 of the PHP license, | |
// | that is bundled with this package in the file LICENSE, and is | |
// | available at through the world-wide-web at | |
// | http://www.php.net/license/2_02.txt. | |
// | If you did not receive a copy of the PHP license and are unable to | |
// | obtain it through the world-wide-web, please send a note to | |
// | license@php.net so we can mail you a copy immediately. | |
// +----------------------------------------------------------------------+ |
// | Authors: Adam Daniel <adaniel1@eesus.jnj.com> | |
// | Bertrand Mansion <bmansion@mamasam.com> | |
// +----------------------------------------------------------------------+ |
// |
require_once 'HTML/QuickForm/static.php'; |
/** |
* HTML class for a link type field |
* |
* @author Adam Daniel <adaniel1@eesus.jnj.com> |
* @author Bertrand Mansion <bmansion@mamasam.com> |
* @version 1.0 |
* @since PHP4.04pl1 |
* @access public |
*/ |
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 |
?> |
/branches/livraison_menes/api/pear/HTML/QuickForm/radio.php |
---|
New file |
0,0 → 1,244 |
<?php |
/* vim: set expandtab tabstop=4 shiftwidth=4: */ |
// +----------------------------------------------------------------------+ |
// | PHP version 4.0 | |
// +----------------------------------------------------------------------+ |
// | Copyright (c) 1997, 1998, 1999, 2000, 2001 The PHP Group | |
// +----------------------------------------------------------------------+ |
// | This source file is subject to version 2.0 of the PHP license, | |
// | that is bundled with this package in the file LICENSE, and is | |
// | available at through the world-wide-web at | |
// | http://www.php.net/license/2_02.txt. | |
// | If you did not receive a copy of the PHP license and are unable to | |
// | obtain it through the world-wide-web, please send a note to | |
// | license@php.net so we can mail you a copy immediately. | |
// +----------------------------------------------------------------------+ |
// | Authors: Adam Daniel <adaniel1@eesus.jnj.com> | |
// | Bertrand Mansion <bmansion@mamasam.com> | |
// +----------------------------------------------------------------------+ |
// |
// $Id: radio.php,v 1.2 2005-09-20 17:01:22 ddelon Exp $ |
require_once('HTML/QuickForm/input.php'); |
/** |
* HTML class for a radio type element |
* |
* @author Adam Daniel <adaniel1@eesus.jnj.com> |
* @author Bertrand Mansion <bmansion@mamasam.com> |
* @version 1.1 |
* @since PHP4.04pl1 |
* @access public |
*/ |
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 ($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 |
?> |
/branches/livraison_menes/api/pear/HTML/QuickForm/input.php |
---|
New file |
0,0 → 1,202 |
<?php |
/* vim: set expandtab tabstop=4 shiftwidth=4: */ |
// +----------------------------------------------------------------------+ |
// | PHP version 4.0 | |
// +----------------------------------------------------------------------+ |
// | Copyright (c) 1997, 1998, 1999, 2000, 2001 The PHP Group | |
// +----------------------------------------------------------------------+ |
// | This source file is subject to version 2.0 of the PHP license, | |
// | that is bundled with this package in the file LICENSE, and is | |
// | available at through the world-wide-web at | |
// | http://www.php.net/license/2_02.txt. | |
// | If you did not receive a copy of the PHP license and are unable to | |
// | obtain it through the world-wide-web, please send a note to | |
// | license@php.net so we can mail you a copy immediately. | |
// +----------------------------------------------------------------------+ |
// | Authors: Adam Daniel <adaniel1@eesus.jnj.com> | |
// | Bertrand Mansion <bmansion@mamasam.com> | |
// +----------------------------------------------------------------------+ |
// |
// $Id: input.php,v 1.2 2005-09-20 17:01:22 ddelon Exp $ |
require_once("HTML/QuickForm/element.php"); |
/** |
* Base class for input form elements |
* |
* @author Adam Daniel <adaniel1@eesus.jnj.com> |
* @author Bertrand Mansion <bmansion@mamasam.com> |
* @version 1.0 |
* @since PHP4.04pl1 |
* @access public |
* @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 |
?> |
/branches/livraison_menes/api/pear/HTML/QuickForm/RuleRegistry.php |
---|
New file |
0,0 → 1,333 |
<?php |
/* vim: set expandtab tabstop=4 shiftwidth=4: */ |
// +----------------------------------------------------------------------+ |
// | PHP version 4.0 | |
// +----------------------------------------------------------------------+ |
// | Copyright (c) 1997-2003 The PHP Group | |
// +----------------------------------------------------------------------+ |
// | This source file is subject to version 2.0 of the PHP license, | |
// | that is bundled with this package in the file LICENSE, and is | |
// | available at through the world-wide-web at | |
// | http://www.php.net/license/2_02.txt. | |
// | If you did not receive a copy of the PHP license and are unable to | |
// | obtain it through the world-wide-web, please send a note to | |
// | license@php.net so we can mail you a copy immediately. | |
// +----------------------------------------------------------------------+ |
// | Authors: Adam Daniel <adaniel1@eesus.jnj.com> | |
// | Alexey Borzov <borz_off@cs.msu.su> | |
// | Bertrand Mansion <bmansion@mamasam.com> | |
// +----------------------------------------------------------------------+ |
// |
// $Id: RuleRegistry.php,v 1.2 2005-09-20 17:01:22 ddelon Exp $ |
/** |
* Registers rule objects and uses them for validation |
* |
*/ |
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 object Reference to the HTML_QuickForm_RuleRegistry singleton |
*/ |
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 object |
*/ |
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 mixed Element(s) the rule applies to |
* @param string Element name, in case $element is not 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 object 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' && !is_a($element, 'html_quickform_advcheckbox')) { |
$value = " if (frm.elements['$elementName'].checked) {\n" . |
" value{$jsIndex} = '1';\n" . |
" } else {\n" . |
" value{$jsIndex} = '';\n" . |
" }"; |
$tmp_reset .= ($reset) ? " field.checked = field.defaultChecked;\n" : ''; |
} elseif ($element->getType() == 'radio') { |
$value = " value{$jsIndex} = '';\n" . |
" for (var i = 0; i < frm.elements['$elementName'].length; i++) {\n" . |
" if (frm.elements['$elementName'][i].checked) {\n" . |
" value{$jsIndex} = frm.elements['$elementName'][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 |
?> |
/branches/livraison_menes/api/pear/HTML/QuickForm/autocomplete.php |
---|
New file |
0,0 → 1,249 |
<?php |
/* vim: set expandtab tabstop=4 shiftwidth=4: */ |
// +----------------------------------------------------------------------+ |
// | PHP Version 4 | |
// +----------------------------------------------------------------------+ |
// | Copyright (c) 1997-2003 The PHP Group | |
// +----------------------------------------------------------------------+ |
// | This source file is subject to version 2.0 of the PHP license, | |
// | that is bundled with this package in the file LICENSE, and is | |
// | available at through the world-wide-web at | |
// | http://www.php.net/license/2_02.txt. | |
// | If you did not receive a copy of the PHP license and are unable to | |
// | obtain it through the world-wide-web, please send a note to | |
// | license@php.net so we can mail you a copy immediately. | |
// +----------------------------------------------------------------------+ |
// | Author: Matteo Di Giovinazzo <matteodg@infinito.it> | |
// | | |
// | For the JavaScript code thanks to Martin Honnen and | |
// | Nicholas C. Zakas | |
// | See: | |
// | http://www.faqts.com/knowledge_base/view.phtml/aid/13562 | |
// | and | |
// | http://www.sitepoint.com/article/1220 | |
// +----------------------------------------------------------------------+ |
// |
// $Id: autocomplete.php,v 1.2 2005-09-20 17:01:22 ddelon Exp $ |
require_once("HTML/QuickForm/text.php"); |
/** |
* Class to dynamically create an HTML input text element that |
* at every keypressed javascript event, check in an array of options |
* if there's a match and autocomplete the text in case of match. |
* |
* Ex: |
* $autocomplete =& $form->addElement('autocomplete', 'fruit', 'Favourite fruit:'); |
* $options = array("Apple", "Orange", "Pear", "Strawberry"); |
* $autocomplete->setOptions($options); |
* |
* @author Matteo Di Giovinazzo <matteodg@infinito.it> |
*/ |
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 |
?> |
/branches/livraison_menes/api/pear/HTML/QuickForm/password.php |
---|
New file |
0,0 → 1,108 |
<?php |
/* vim: set expandtab tabstop=4 shiftwidth=4: */ |
// +----------------------------------------------------------------------+ |
// | PHP version 4.0 | |
// +----------------------------------------------------------------------+ |
// | Copyright (c) 1997, 1998, 1999, 2000, 2001 The PHP Group | |
// +----------------------------------------------------------------------+ |
// | This source file is subject to version 2.0 of the PHP license, | |
// | that is bundled with this package in the file LICENSE, and is | |
// | available at through the world-wide-web at | |
// | http://www.php.net/license/2_02.txt. | |
// | If you did not receive a copy of the PHP license and are unable to | |
// | obtain it through the world-wide-web, please send a note to | |
// | license@php.net so we can mail you a copy immediately. | |
// +----------------------------------------------------------------------+ |
// | Authors: Adam Daniel <adaniel1@eesus.jnj.com> | |
// | Bertrand Mansion <bmansion@mamasam.com> | |
// +----------------------------------------------------------------------+ |
// |
// $Id: password.php,v 1.2 2005-09-20 17:01:22 ddelon Exp $ |
require_once("HTML/QuickForm/input.php"); |
/** |
* HTML class for a password type field |
* |
* @author Adam Daniel <adaniel1@eesus.jnj.com> |
* @author Bertrand Mansion <bmansion@mamasam.com> |
* @version 1.1 |
* @since PHP4.04pl1 |
* @access public |
*/ |
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 |
?> |
/branches/livraison_menes/api/pear/HTML/QuickForm/submit.php |
---|
New file |
0,0 → 1,82 |
<?php |
/* vim: set expandtab tabstop=4 shiftwidth=4: */ |
// +----------------------------------------------------------------------+ |
// | PHP version 4.0 | |
// +----------------------------------------------------------------------+ |
// | Copyright (c) 1997, 1998, 1999, 2000, 2001 The PHP Group | |
// +----------------------------------------------------------------------+ |
// | This source file is subject to version 2.0 of the PHP license, | |
// | that is bundled with this package in the file LICENSE, and is | |
// | available at through the world-wide-web at | |
// | http://www.php.net/license/2_02.txt. | |
// | If you did not receive a copy of the PHP license and are unable to | |
// | obtain it through the world-wide-web, please send a note to | |
// | license@php.net so we can mail you a copy immediately. | |
// +----------------------------------------------------------------------+ |
// | Authors: Adam Daniel <adaniel1@eesus.jnj.com> | |
// | Bertrand Mansion <bmansion@mamasam.com> | |
// +----------------------------------------------------------------------+ |
// |
// $Id: submit.php,v 1.2 2005-09-20 17:01:22 ddelon Exp $ |
require_once("HTML/QuickForm/input.php"); |
/** |
* HTML class for a submit type element |
* |
* @author Adam Daniel <adaniel1@eesus.jnj.com> |
* @author Bertrand Mansion <bmansion@mamasam.com> |
* @version 1.0 |
* @since PHP4.04pl1 |
* @access public |
*/ |
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 |
?> |
/branches/livraison_menes/api/pear/HTML/QuickForm/xbutton.php |
---|
New file |
0,0 → 1,145 |
<?php |
/* vim: set expandtab tabstop=4 shiftwidth=4: */ |
// +----------------------------------------------------------------------+ |
// | PHP Version 4 | |
// +----------------------------------------------------------------------+ |
// | Copyright (c) 1997-2003 The PHP Group | |
// +----------------------------------------------------------------------+ |
// | This source file is subject to version 2.0 of the PHP license, | |
// | that is bundled with this package in the file LICENSE, and is | |
// | available at through the world-wide-web at | |
// | http://www.php.net/license/2_02.txt. | |
// | If you did not receive a copy of the PHP license and are unable to | |
// | obtain it through the world-wide-web, please send a note to | |
// | license@php.net so we can mail you a copy immediately. | |
// +----------------------------------------------------------------------+ |
// | Authors: Alexey Borzov <avb@php.net> | |
// +----------------------------------------------------------------------+ |
// |
// $Id: xbutton.php,v 1.2 2005-09-20 17:01:22 ddelon Exp $ |
require_once 'HTML/QuickForm/element.php'; |
/** |
* Class for HTML 4.0 <button> element |
* |
* @author Alexey Borzov <avb@php.net> |
* @since 3.2.3 |
* @access public |
*/ |
class HTML_QuickForm_xbutton extends HTML_QuickForm_element |
{ |
/** |
* Contents of the <button> tag |
* @var string |
* @access private |
*/ |
var $_content; |
/** |
* Class constructor |
* |
* @param string Button name |
* @param string Button content (HTML to add between <button></button> tags) |
* @param mixed Either a typical HTML attribute string or an associative array |
* @access public |
*/ |
function HTML_QuickForm_xbutton($elementName = null, $elementContent = null, $attributes = null) |
{ |
$this->HTML_QuickForm_element($elementName, null, $attributes); |
$this->setContent($elementContent); |
$this->setPersistantFreeze(false); |
$this->_type = 'xbutton'; |
} |
function toHtml() |
{ |
return '<button' . $this->getAttributes(true) . '>' . $this->_content . '</button>'; |
} |
function getFrozenHtml() |
{ |
return $this->toHtml(); |
} |
function freeze() |
{ |
return false; |
} |
function setName($name) |
{ |
$this->updateAttributes(array( |
'name' => $name |
)); |
} |
function getName() |
{ |
return $this->getAttribute('name'); |
} |
function setValue($value) |
{ |
$this->updateAttributes(array( |
'value' => $value |
)); |
} |
function getValue() |
{ |
return $this->getAttribute('value'); |
} |
/** |
* Sets the contents of the button element |
* |
* @param string Button content (HTML to add between <button></button> tags) |
*/ |
function setContent($content) |
{ |
$this->_content = $content; |
} |
function onQuickFormEvent($event, $arg, &$caller) |
{ |
if ('updateValue' != $event) { |
return 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; |
} |
/** |
* Returns a 'safe' element's value |
* |
* The value is only returned if the button's type is "submit" and if this |
* particlular button was clicked |
*/ |
function exportValue(&$submitValues, $assoc = false) |
{ |
if ('submit' == $this->getAttribute('type')) { |
return $this->_prepareValue($this->_findValue($submitValues), $assoc); |
} else { |
return null; |
} |
} |
} |
?> |
/branches/livraison_menes/api/pear/HTML/QuickForm/html.php |
---|
New file |
0,0 → 1,67 |
<?php |
/* vim: set expandtab tabstop=4 shiftwidth=4: */ |
// +----------------------------------------------------------------------+ |
// | PHP version 4.0 | |
// +----------------------------------------------------------------------+ |
// | Copyright (c) 1997-2003 The PHP Group | |
// +----------------------------------------------------------------------+ |
// | This source file is subject to version 2.0 of the PHP license, | |
// | that is bundled with this package in the file LICENSE, and is | |
// | available at through the world-wide-web at | |
// | http://www.php.net/license/2_02.txt. | |
// | If you did not receive a copy of the PHP license and are unable to | |
// | obtain it through the world-wide-web, please send a note to | |
// | license@php.net so we can mail you a copy immediately. | |
// +----------------------------------------------------------------------+ |
// | Author: Alexey Borzov <borz_off@cs.msu.su> | |
// +----------------------------------------------------------------------+ |
// |
// $Id: html.php,v 1.2 2005-09-20 17:01:22 ddelon Exp $ |
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 |
* |
* @author Alexey Borzov <borz_off@cs.msu.su> |
* @access public |
*/ |
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 object An HTML_QuickForm_Renderer object |
* @access public |
* @return void |
*/ |
function accept(&$renderer) |
{ |
$renderer->renderHtml($this); |
} // end func accept |
// }}} |
} //end class HTML_QuickForm_header |
?> |
/branches/livraison_menes/api/pear/HTML/QuickForm.php |
---|
Cannot display: file marked as a binary type. |
svn:mime-type = application/octet-stream |
/branches/livraison_menes/api/pear/HTML/QuickForm.php |
---|
New file |
Property changes: |
Added: svn:mime-type |
+application/octet-stream |
\ No newline at end of property |
/branches/livraison_menes/api/pear/HTML/Template/ITX.php |
---|
New file |
0,0 → 1,809 |
<?php |
// |
// +----------------------------------------------------------------------+ |
// | Copyright (c) 1997-2005 Ulf Wendel, Pierre-Alain Joye | |
// +----------------------------------------------------------------------+ |
// | This source file is subject to the New BSD license, That is bundled | |
// | with this package in the file LICENSE, and is available through | |
// | the world-wide-web at | |
// | http://www.opensource.org/licenses/bsd-license.php | |
// | If you did not receive a copy of the new BSD license and are unable | |
// | to obtain it through the world-wide-web, please send a note to | |
// | pajoye@php.net so we can mail you a copy immediately. | |
// +----------------------------------------------------------------------+ |
// | Author: Ulf Wendel <ulf.wendel@phpdoc.de> | |
// | Pierre-Alain Joye <pajoye@php.net> | |
// +----------------------------------------------------------------------+ |
// |
// $Id$ |
// |
require_once 'HTML/Template/IT.php'; |
require_once 'HTML/Template/IT_Error.php'; |
/** |
* Integrated Template Extension - ITX |
* |
* With this class you get the full power of the phplib template class. |
* You may have one file with blocks in it but you have as well one main file |
* and multiple files one for each block. This is quite usefull when you have |
* user configurable websites. Using blocks not in the main template allows |
* you to modify some parts of your layout easily. |
* |
* Note that you can replace an existing block and add new blocks at runtime. |
* Adding new blocks means changing a variable placeholder to a block. |
* |
* @author Ulf Wendel <uw@netuse.de> |
* @access public |
* @version $Id$ |
* @package IT[X] |
*/ |
class HTML_Template_ITX extends HTML_Template_IT |
{ |
/** |
* Array with all warnings. |
* @var array |
* @access public |
* @see $printWarning, $haltOnWarning, warning() |
*/ |
var $warn = array(); |
/** |
* Print warnings? |
* @var array |
* @access public |
* @see $haltOnWarning, $warn, warning() |
*/ |
var $printWarning = false; |
/** |
* Call die() on warning? |
* @var boolean |
* @access public |
* @see $warn, $printWarning, warning() |
*/ |
var $haltOnWarning = false; |
/** |
* RegExp used to test for a valid blockname. |
* @var string |
*/ |
var $checkblocknameRegExp = ''; |
/** |
* Functionnameprefix used when searching function calls in the template. |
* @var string |
*/ |
var $functionPrefix = 'func_'; |
/** |
* Functionname RegExp. |
* @var string |
*/ |
var $functionnameRegExp = '[_a-zA-Z]+[A-Za-z_0-9]*'; |
/** |
* RegExp used to grep function calls in the template. |
* |
* The variable gets set by the constructor. |
* |
* @var string |
* @see HTML_Template_IT() |
*/ |
var $functionRegExp = ''; |
/** |
* List of functions found in the template. |
* |
* @var array |
*/ |
var $functions = array(); |
/** |
* List of callback functions specified by the user. |
* |
* @var array |
*/ |
var $callback = array(); |
/** |
* Builds some complex regexps and calls the constructor |
* of the parent class. |
* |
* Make sure that you call this constructor if you derive your own |
* template class from this one. |
* |
* @see HTML_Template_IT() |
*/ |
function HTML_Template_ITX($root = '') |
{ |
$this->checkblocknameRegExp = '@' . $this->blocknameRegExp . '@'; |
$this->functionRegExp = '@' . $this->functionPrefix . '(' . |
$this->functionnameRegExp . ')\s*\(@sm'; |
$this->HTML_Template_IT($root); |
} // end func constructor |
function init() |
{ |
$this->free(); |
$this->buildFunctionlist(); |
$this->findBlocks($this->template); |
// we don't need it any more |
$this->template = ''; |
$this->buildBlockvariablelist(); |
} // end func init |
/** |
* Replaces an existing block with new content. |
* |
* This function will replace a block of the template and all blocks |
* contained in the replaced block and add a new block insted, means |
* you can dynamically change your template. |
* |
* Note that changing the template structure violates one of the IT[X] |
* development goals. I've tried to write a simple to use template engine |
* supporting blocks. In contrast to other systems IT[X] analyses the way |
* you've nested blocks and knows which block belongs into another block. |
* The nesting information helps to make the API short and simple. Replacing |
* blocks does not only mean that IT[X] has to update the nesting |
* information (relatively time consumpting task) but you have to make sure |
* that you do not get confused due to the template change itself. |
* |
* @param string Blockname |
* @param string Blockcontent |
* @param boolean true if the new block inherits the content |
* of the old block |
* @return boolean |
* @throws IT_Error |
* @see replaceBlockfile(), addBlock(), addBlockfile() |
* @access public |
*/ |
function replaceBlock($block, $template, $keep_content = false) |
{ |
if (!isset($this->blocklist[$block])) { |
return new IT_Error( |
"The block "."'$block'". |
" does not exist in the template and thus it can't be replaced.", |
__FILE__, __LINE__ |
); |
} |
if ($template == '') { |
return new IT_Error('No block content given.', __FILE__, __LINE__); |
} |
if ($keep_content) { |
$blockdata = $this->blockdata[$block]; |
} |
// remove all kinds of links to the block / data of the block |
$this->removeBlockData($block); |
$template = "<!-- BEGIN $block -->" . $template . "<!-- END $block -->"; |
$parents = $this->blockparents[$block]; |
$this->findBlocks($template); |
$this->blockparents[$block] = $parents; |
// KLUDGE: rebuild the list for all block - could be done faster |
$this->buildBlockvariablelist(); |
if ($keep_content) { |
$this->blockdata[$block] = $blockdata; |
} |
// old TODO - I'm not sure if we need this |
// update caches |
return true; |
} // end func replaceBlock |
/** |
* Replaces an existing block with new content from a file. |
* |
* @brother replaceBlock() |
* @param string Blockname |
* @param string Name of the file that contains the blockcontent |
* @param boolean true if the new block inherits the content of the old block |
*/ |
function replaceBlockfile($block, $filename, $keep_content = false) |
{ |
return $this->replaceBlock($block, $this->getFile($filename), $keep_content); |
} // end func replaceBlockfile |
/** |
* Adds a block to the template changing a variable placeholder |
* to a block placeholder. |
* |
* Add means "replace a variable placeholder by a new block". |
* This is different to PHPLibs templates. The function loads a |
* block, creates a handle for it and assigns it to a certain |
* variable placeholder. To to the same with PHPLibs templates you would |
* call set_file() to create the handle and parse() to assign the |
* parsed block to a variable. By this PHPLibs templates assume |
* that you tend to assign a block to more than one one placeholder. |
* To assign a parsed block to more than only the placeholder you specify |
* in this function you have to use a combination of getBlock() |
* and setVariable(). |
* |
* As no updates to cached data is necessary addBlock() and addBlockfile() |
* are rather "cheap" meaning quick operations. |
* |
* The block content must not start with <!-- BEGIN blockname --> |
* and end with <!-- END blockname --> this would cause overhead and |
* produce an error. |
* |
* @param string Name of the variable placeholder, the name must be unique |
* within the template. |
* @param string Name of the block to be added |
* @param string Content of the block |
* @return boolean |
* @throws IT_Error |
* @see addBlockfile() |
* @access public |
*/ |
function addBlock($placeholder, $blockname, $template) |
{ |
// Don't trust any user even if it's a programmer or yourself... |
if ($placeholder == '') { |
return new IT_Error('No variable placeholder given.', |
__FILE__, __LINE__ |
); |
} elseif ($blockname == '' || |
!preg_match($this->checkblocknameRegExp, $blockname) |
) { |
return new IT_Error("No or invalid blockname '$blockname' given.", |
__FILE__, __LINE__ |
); |
} elseif ($template == '') { |
return new IT_Error('No block content given.', __FILE__, __LINE__); |
} elseif (isset($this->blocklist[$blockname])) { |
return new IT_Error('The block already exists.', |
__FILE__, __LINE__ |
); |
} |
// find out where to insert the new block |
$parents = $this->findPlaceholderBlocks($placeholder); |
if (count($parents) == 0) { |
return new IT_Error( |
"The variable placeholder". |
" '$placeholder' was not found in the template.", |
__FILE__, __LINE__ |
); |
} elseif (count($parents) > 1) { |
reset($parents); |
while (list($k, $parent) = each($parents)) { |
$msg .= "$parent, "; |
} |
$msg = substr($parent, -2); |
return new IT_Error("The variable placeholder "."'$placeholder'". |
" must be unique, found in multiple blocks '$msg'.", |
__FILE__, __LINE__ |
); |
} |
$template = "<!-- BEGIN $blockname -->" . $template . "<!-- END $blockname -->"; |
$this->findBlocks($template); |
if ($this->flagBlocktrouble) { |
return false; // findBlocks() already throws an exception |
} |
$this->blockinner[$parents[0]][] = $blockname; |
$this->blocklist[$parents[0]] = preg_replace( |
'@' . $this->openingDelimiter . $placeholder . |
$this->closingDelimiter . '@', |
$this->openingDelimiter . '__' . $blockname . '__' . |
$this->closingDelimiter, |
$this->blocklist[$parents[0]] |
); |
$this->deleteFromBlockvariablelist($parents[0], $placeholder); |
$this->updateBlockvariablelist($blockname); |
/* |
// check if any inner blocks were found |
if(is_array($this->blockinner[$blockname]) and count($this->blockinner[$blockname]) > 0) { |
// loop through inner blocks, registering the variable placeholders in each |
foreach($this->blockinner[$blockname] as $childBlock) { |
$this->updateBlockvariablelist($childBlock); |
} |
} |
*/ |
return true; |
} // end func addBlock |
/** |
* Adds a block taken from a file to the template changing a variable |
* placeholder to a block placeholder. |
* |
* @param string Name of the variable placeholder to be converted |
* @param string Name of the block to be added |
* @param string File that contains the block |
* @brother addBlock() |
*/ |
function addBlockfile($placeholder, $blockname, $filename) |
{ |
return $this->addBlock($placeholder, $blockname, $this->getFile($filename)); |
} // end func addBlockfile |
/** |
* Returns the name of the (first) block that contains |
* the specified placeholder. |
* |
* @param string Name of the placeholder you're searching |
* @param string Name of the block to scan. If left out (default) |
* all blocks are scanned. |
* @return string Name of the (first) block that contains |
* the specified placeholder. |
* If the placeholder was not found or an error occured |
* an empty string is returned. |
* @throws IT_Error |
* @access public |
*/ |
function placeholderExists($placeholder, $block = '') |
{ |
if ($placeholder == '') { |
new IT_Error('No placeholder name given.', __FILE__, __LINE__); |
return ''; |
} |
if ($block != '' && !isset($this->blocklist[$block])) { |
new IT_Error("Unknown block '$block'.", __FILE__, __LINE__); |
return ''; |
} |
// name of the block where the given placeholder was found |
$found = ''; |
if ($block != '') { |
if (is_array($variables = $this->blockvariables[$block])) { |
// search the value in the list of blockvariables |
reset($variables); |
while (list($k, $variable) = each($variables)) { |
if ($k == $placeholder) { |
$found = $block; |
break; |
} |
} |
} |
} else { |
// search all blocks and return the name of the first block that |
// contains the placeholder |
reset($this->blockvariables); |
while (list($blockname, $variables) = each($this->blockvariables)){ |
if (is_array($variables) && isset($variables[$placeholder])) { |
$found = $blockname; |
break; |
} |
} |
} |
return $found; |
} // end func placeholderExists |
/** |
* Checks the list of function calls in the template and |
* calls their callback function. |
* |
* @access public |
*/ |
function performCallback() |
{ |
reset($this->functions); |
while (list($func_id, $function) = each($this->functions)) { |
if (isset($this->callback[$function['name']])) { |
if ($this->callback[$function['name']]['object'] != '') { |
$this->variableCache['__function' . $func_id . '__'] = |
call_user_func( |
array( |
&$GLOBALS[$this->callback[$function['name']]['object']], |
$this->callback[$function['name']]['function']), |
$function['args'] |
); |
} else { |
$this->variableCache['__function' . $func_id . '__'] = |
call_user_func( |
$this->callback[$function['name']]['function'], |
$function['args'] |
); |
} |
} |
} |
} // end func performCallback |
/** |
* Returns a list of all function calls in the current template. |
* |
* @return array |
* @access public |
*/ |
function getFunctioncalls() |
{ |
return $this->functions; |
} // end func getFunctioncalls |
/** |
* Replaces a function call with the given replacement. |
* |
* @param int Function ID |
* @param string Replacement |
* @deprec |
*/ |
function setFunctioncontent($functionID, $replacement) |
{ |
$this->variableCache['__function' . $functionID . '__'] = $replacement; |
} // end func setFunctioncontent |
/** |
* Sets a callback function. |
* |
* IT[X] templates (note the X) can contain simple function calls. |
* "function call" means that the editor of the template can add |
* special placeholder to the template like 'func_h1("embedded in h1")'. |
* IT[X] will grab this function calls and allow you to define a callback |
* function for them. |
* |
* This is an absolutely evil feature. If your application makes heavy |
* use of such callbacks and you're even implementing if-then etc. on |
* the level of a template engine you're reiventing the wheel... - that's |
* actually how PHP came into life. Anyway, sometimes it's handy. |
* |
* Consider also using XML/XSLT or native PHP. And please do not push |
* IT[X] any further into this direction of adding logics to the template |
* engine. |
* |
* For those of you ready for the X in IT[X]: |
* |
* <?php |
* ... |
* function h_one($args) { |
* return sprintf('<h1>%s</h1>', $args[0]); |
* } |
* |
* ... |
* $itx = new HTML_Template_ITX( ... ); |
* ... |
* $itx->setCallbackFunction('h1', 'h_one'); |
* $itx->performCallback(); |
* ?> |
* |
* template: |
* func_h1('H1 Headline'); |
* |
* @param string Function name in the template |
* @param string Name of the callback function |
* @param string Name of the callback object |
* @return boolean False on failure. |
* @throws IT_Error |
* @access public |
*/ |
function |
setCallbackFunction($tplfunction, $callbackfunction, $callbackobject = '') |
{ |
if ($tplfunction == '' || $callbackfunction == '') { |
return new IT_Error( |
"No template function "."('$tplfunction')". |
" and/or no callback function ('$callback') given.", |
__FILE__, __LINE__ |
); |
} |
$this->callback[$tplfunction] = array( |
'function' => $callbackfunction, |
'object' => $callbackobject |
); |
return true; |
} // end func setCallbackFunction |
/** |
* Sets the Callback function lookup table |
* |
* @param array function table |
* array[templatefunction] = |
* array( |
* "function" => userfunction, |
* "object" => userobject |
* ) |
* @access public |
*/ |
function setCallbackFuntiontable($functions) |
{ |
$this->callback = $functions; |
} // end func setCallbackFunctiontable |
/** |
* Recursively removes all data assiciated with a block, including all inner blocks |
* |
* @param string block to be removed |
*/ |
function removeBlockData($block) |
{ |
if (isset($this->blockinner[$block])) { |
foreach ($this->blockinner[$block] as $k => $inner) { |
$this->removeBlockData($inner); |
} |
unset($this->blockinner[$block]); |
} |
unset($this->blocklist[$block]); |
unset($this->blockdata[$block]); |
unset($this->blockvariables[$block]); |
unset($this->touchedBlocks[$block]); |
} // end func removeBlockinner |
/** |
* Returns a list of blocknames in the template. |
* |
* @return array [blockname => blockname] |
* @access public |
* @see blockExists() |
*/ |
function getBlocklist() |
{ |
$blocklist = array(); |
foreach ($this->blocklist as $block => $content) { |
$blocklist[$block] = $block; |
} |
return $blocklist; |
} // end func getBlocklist |
/** |
* Checks wheter a block exists. |
* |
* @param string |
* @return boolean |
* @access public |
* @see getBlocklist() |
*/ |
function blockExists($blockname) |
{ |
return isset($this->blocklist[$blockname]); |
} // end func blockExists |
/** |
* Returns a list of variables of a block. |
* |
* @param string Blockname |
* @return array [varname => varname] |
* @access public |
* @see BlockvariableExists() |
*/ |
function getBlockvariables($block) |
{ |
if (!isset($this->blockvariables[$block])) { |
return array(); |
} |
$variables = array(); |
foreach ($this->blockvariables[$block] as $variable => $v) { |
$variables[$variable] = $variable; |
} |
return $variables; |
} // end func getBlockvariables |
/** |
* Checks wheter a block variable exists. |
* |
* @param string Blockname |
* @param string Variablename |
* @return boolean |
* @access public |
* @see getBlockvariables() |
*/ |
function BlockvariableExists($block, $variable) |
{ |
return isset($this->blockvariables[$block][$variable]); |
} // end func BlockvariableExists |
/** |
* Builds a functionlist from the template. |
*/ |
function buildFunctionlist() |
{ |
$this->functions = array(); |
$template = $this->template; |
$num = 0; |
while (preg_match($this->functionRegExp, $template, $regs)) { |
$pos = strpos($template, $regs[0]); |
$template = substr($template, $pos + strlen($regs[0])); |
$head = $this->getValue($template, ')'); |
$args = array(); |
$search = $regs[0] . $head . ')'; |
$replace = $this->openingDelimiter . |
'__function' . $num . '__' . |
$this->closingDelimiter; |
$this->template = str_replace($search, $replace, $this->template); |
$template = str_replace($search, $replace, $template); |
while ($head != '' && $args2 = $this->getValue($head, ',')) { |
$arg2 = trim($args2); |
$args[] = ('"' == $arg2{0} || "'" == $arg2{0}) ? |
substr($arg2, 1, -1) : $arg2; |
if ($arg2 == $head) { |
break; |
} |
$head = substr($head, strlen($arg2) + 1); |
} |
$this->functions[$num++] = array( |
'name' => $regs[1], |
'args' => $args |
); |
} |
} // end func buildFunctionlist |
function getValue($code, $delimiter) { |
if ($code == '') { |
return ''; |
} |
if (!is_array($delimiter)) { |
$delimiter = array( $delimiter => true ); |
} |
$len = strlen($code); |
$enclosed = false; |
$enclosed_by = ''; |
if (isset($delimiter[$code[0]])) { |
$i = 1; |
} else { |
for ($i = 0; $i < $len; ++$i) { |
$char = $code[$i]; |
if ( |
($char == '"' || $char = "'") && |
($char == $enclosed_by || '' == $enclosed_by) && |
(0 == $i || ($i > 0 && '\\' != $code[$i - 1])) |
) { |
if (!$enclosed) { |
$enclosed_by = $char; |
} else { |
$enclosed_by = ""; |
} |
$enclosed = !$enclosed; |
} |
if (!$enclosed && isset($delimiter[$char])) { |
break; |
} |
} |
} |
return substr($code, 0, $i); |
} // end func getValue |
/** |
* Deletes one or many variables from the block variable list. |
* |
* @param string Blockname |
* @param mixed Name of one variable or array of variables |
* ( array ( name => true ) ) to be stripped. |
*/ |
function deleteFromBlockvariablelist($block, $variables) |
{ |
if (!is_array($variables)) { |
$variables = array($variables => true); |
} |
reset($this->blockvariables[$block]); |
while (list($varname, $val) = each($this->blockvariables[$block])) { |
if (isset($variables[$varname])) { |
unset($this->blockvariables[$block][$varname]); |
} |
} |
} // end deleteFromBlockvariablelist |
/** |
* Updates the variable list of a block. |
* |
* @param string Blockname |
*/ |
function updateBlockvariablelist($block) |
{ |
preg_match_all( $this->variablesRegExp, |
$this->blocklist[$block], $regs |
); |
if (count($regs[1]) != 0) { |
foreach ($regs[1] as $k => $var) { |
$this->blockvariables[$block][$var] = true; |
} |
} else { |
$this->blockvariables[$block] = array(); |
} |
// check if any inner blocks were found |
if (isset($this->blockinner[$block]) && |
is_array($this->blockinner[$block]) && |
count($this->blockinner[$block]) > 0 |
) { |
/* |
* loop through inner blocks, registering the variable |
* placeholders in each |
*/ |
foreach ($this->blockinner[$block] as $childBlock) { |
$this->updateBlockvariablelist($childBlock); |
} |
} |
} // end func updateBlockvariablelist |
/** |
* Returns an array of blocknames where the given variable |
* placeholder is used. |
* |
* @param string Variable placeholder |
* @return array $parents parents[0..n] = blockname |
*/ |
function findPlaceholderBlocks($variable) |
{ |
$parents = array(); |
reset($this->blocklist); |
while (list($blockname, $content) = each($this->blocklist)) { |
reset($this->blockvariables[$blockname]); |
while ( |
list($varname, $val) = each($this->blockvariables[$blockname])) |
{ |
if ($variable == $varname) { |
$parents[] = $blockname; |
} |
} |
} |
return $parents; |
} // end func findPlaceholderBlocks |
/** |
* Handles warnings, saves them to $warn and prints them or |
* calls die() depending on the flags |
* |
* @param string Warning |
* @param string File where the warning occured |
* @param int Linenumber where the warning occured |
* @see $warn, $printWarning, $haltOnWarning |
*/ |
function warning($message, $file = '', $line = 0) |
{ |
$message = sprintf( |
'HTML_Template_ITX Warning: %s [File: %s, Line: %d]', |
$message, |
$file, |
$line |
); |
$this->warn[] = $message; |
if ($this->printWarning) { |
print $message; |
} |
if ($this->haltOnWarning) { |
die($message); |
} |
} // end func warning |
} // end class HTML_Template_ITX |
?> |
/branches/livraison_menes/api/pear/HTML/Template/IT_Error.php |
---|
New file |
0,0 → 1,51 |
<?php |
// |
// +----------------------------------------------------------------------+ |
// | Copyright (c) 1997-2005 Ulf Wendel, Pierre-Alain Joye | |
// +----------------------------------------------------------------------+ |
// | This source file is subject to the New BSD license, That is bundled | |
// | with this package in the file LICENSE, and is available through | |
// | the world-wide-web at | |
// | http://www.opensource.org/licenses/bsd-license.php | |
// | If you did not receive a copy of the new BSD license and are unable | |
// | to obtain it through the world-wide-web, please send a note to | |
// | pajoye@php.net so we can mail you a copy immediately. | |
// +----------------------------------------------------------------------+ |
// | Author: Ulf Wendel <ulf.wendel@phpdoc.de> | |
// | Pierre-Alain Joye <pajoye@php.net> | |
// +----------------------------------------------------------------------+ |
// |
// $Id$ |
require_once "PEAR.php"; |
/** |
* IT[X] Error class |
* |
* @package IT[X] |
*/ |
class IT_Error extends PEAR_Error { |
/** |
* Prefix of all error messages. |
* |
* @var string |
*/ |
var $error_message_prefix = "IntegratedTemplate Error: "; |
/** |
* Creates an cache error object. |
* |
* @param string error message |
* @param string file where the error occured |
* @param string linenumber where the error occured |
*/ |
function IT_Error($msg, $file = __FILE__, $line = __LINE__) { |
$this->PEAR_Error(sprintf("%s [%s on line %d].", $msg, $file, $line)); |
} // end func IT_Error |
} // end class IT_Error |
?> |
/branches/livraison_menes/api/pear/HTML/Template/IT.php |
---|
New file |
0,0 → 1,990 |
<?php |
// |
// +----------------------------------------------------------------------+ |
// | Copyright (c) 1997-2005 Ulf Wendel, Pierre-Alain Joye | |
// +----------------------------------------------------------------------+ |
// | This source file is subject to the New BSD license, That is bundled | |
// | with this package in the file LICENSE, and is available through | |
// | the world-wide-web at | |
// | http://www.opensource.org/licenses/bsd-license.php | |
// | If you did not receive a copy of the new BSDlicense and are unable | |
// | to obtain it through the world-wide-web, please send a note to | |
// | pajoye@php.net so we can mail you a copy immediately. | |
// +----------------------------------------------------------------------+ |
// | Author: Ulf Wendel <ulf.wendel@phpdoc.de> | |
// | Pierre-Alain Joye <pajoye@php.net> | |
// +----------------------------------------------------------------------+ |
// |
// $Id$ |
// |
require_once 'PEAR.php'; |
define('IT_OK', 1); |
define('IT_ERROR', -1); |
define('IT_TPL_NOT_FOUND', -2); |
define('IT_BLOCK_NOT_FOUND', -3); |
define('IT_BLOCK_DUPLICATE', -4); |
define('IT_UNKNOWN_OPTION', -6); |
/** |
* Integrated Template - IT |
* |
* Well there's not much to say about it. I needed a template class that |
* supports a single template file with multiple (nested) blocks inside and |
* a simple block API. |
* |
* The Isotemplate API is somewhat tricky for a beginner although it is the best |
* one you can build. template::parse() [phplib template = Isotemplate] requests |
* you to name a source and a target where the current block gets parsed into. |
* Source and target can be block names or even handler names. This API gives you |
* a maximum of fexibility but you always have to know what you do which is |
* quite unusual for php skripter like me. |
* |
* I noticed that I do not any control on which block gets parsed into which one. |
* If all blocks are within one file, the script knows how they are nested and in |
* which way you have to parse them. IT knows that inner1 is a child of block2, there's |
* no need to tell him about this. |
* |
* <table border> |
* <tr> |
* <td colspan=2> |
* __global__ |
* <p> |
* (hidden and automatically added) |
* </td> |
* </tr> |
* <tr> |
* <td>block1</td> |
* <td> |
* <table border> |
* <tr> |
* <td colspan=2>block2</td> |
* </tr> |
* <tr> |
* <td>inner1</td> |
* <td>inner2</td> |
* </tr> |
* </table> |
* </td> |
* </tr> |
* </table> |
* |
* To add content to block1 you simply type: |
* <code>$tpl->setCurrentBlock("block1");</code> |
* and repeat this as often as needed: |
* <code> |
* $tpl->setVariable(...); |
* $tpl->parseCurrentBlock(); |
* </code> |
* |
* To add content to block2 you would type something like: |
* <code> |
* $tpl->setCurrentBlock("inner1"); |
* $tpl->setVariable(...); |
* $tpl->parseCurrentBlock(); |
* |
* $tpl->setVariable(...); |
* $tpl->parseCurrentBlock(); |
* |
* $tpl->parse("block1"); |
* </code> |
* |
* This will result in one repition of block1 which contains two repitions |
* of inner1. inner2 will be removed if $removeEmptyBlock is set to true which is the default. |
* |
* Usage: |
* <code> |
* $tpl = new HTML_Template_IT( [string filerootdir] ); |
* |
* // load a template or set it with setTemplate() |
* $tpl->loadTemplatefile( string filename [, boolean removeUnknownVariables, boolean removeEmptyBlocks] ) |
* |
* // set "global" Variables meaning variables not beeing within a (inner) block |
* $tpl->setVariable( string variablename, mixed value ); |
* |
* // like with the Isotemplates there's a second way to use setVariable() |
* $tpl->setVariable( array ( string varname => mixed value ) ); |
* |
* // Let's use any block, even a deeply nested one |
* $tpl->setCurrentBlock( string blockname ); |
* |
* // repeat this as often as you need it. |
* $tpl->setVariable( array ( string varname => mixed value ) ); |
* $tpl->parseCurrentBlock(); |
* |
* // get the parsed template or print it: $tpl->show() |
* $tpl->get(); |
* </code> |
* |
* @author Ulf Wendel <uw@netuse.de> |
* @version $Id$ |
* @access public |
* @package HTML_Template_IT |
*/ |
class HTML_Template_IT |
{ |
/** |
* Contains the error objects |
* @var array |
* @access public |
* @see halt(), $printError, $haltOnError |
*/ |
var $err = array(); |
/** |
* Clear cache on get()? |
* @var boolean |
*/ |
var $clearCache = false; |
/** |
* First character of a variable placeholder ( _{_VARIABLE} ). |
* @var string |
* @access public |
* @see $closingDelimiter, $blocknameRegExp, $variablenameRegExp |
*/ |
var $openingDelimiter = '{'; |
/** |
* Last character of a variable placeholder ( {VARIABLE_}_ ). |
* @var string |
* @access public |
* @see $openingDelimiter, $blocknameRegExp, $variablenameRegExp |
*/ |
var $closingDelimiter = '}'; |
/** |
* RegExp matching a block in the template. |
* Per default "sm" is used as the regexp modifier, "i" is missing. |
* That means a case sensitive search is done. |
* @var string |
* @access public |
* @see $variablenameRegExp, $openingDelimiter, $closingDelimiter |
*/ |
var $blocknameRegExp = '[0-9A-Za-z_-]+'; |
/** |
* RegExp matching a variable placeholder in the template. |
* Per default "sm" is used as the regexp modifier, "i" is missing. |
* That means a case sensitive search is done. |
* @var string |
* @access public |
* @see $blocknameRegExp, $openingDelimiter, $closingDelimiter |
*/ |
var $variablenameRegExp = '[0-9A-Za-z_-]+'; |
/** |
* RegExp used to find variable placeholder, filled by the constructor. |
* @var string Looks somewhat like @(delimiter varname delimiter)@ |
* @access public |
* @see IntegratedTemplate() |
*/ |
var $variablesRegExp = ''; |
/** |
* RegExp used to strip unused variable placeholder. |
* @brother $variablesRegExp |
*/ |
var $removeVariablesRegExp = ''; |
/** |
* Controls the handling of unknown variables, default is remove. |
* @var boolean |
* @access public |
*/ |
var $removeUnknownVariables = true; |
/** |
* Controls the handling of empty blocks, default is remove. |
* @var boolean |
* @access public |
*/ |
var $removeEmptyBlocks = true; |
/** |
* RegExp used to find blocks an their content, filled by the constructor. |
* @var string |
* @see IntegratedTemplate() |
*/ |
var $blockRegExp = ''; |
/** |
* Name of the current block. |
* @var string |
*/ |
var $currentBlock = '__global__'; |
/** |
* Content of the template. |
* @var string |
*/ |
var $template = ''; |
/** |
* Array of all blocks and their content. |
* |
* @var array |
* @see findBlocks() |
*/ |
var $blocklist = array(); |
/** |
* Array with the parsed content of a block. |
* |
* @var array |
*/ |
var $blockdata = array(); |
/** |
* Array of variables in a block. |
* @var array |
*/ |
var $blockvariables = array(); |
/** |
* Array of inner blocks of a block. |
* @var array |
*/ |
var $blockinner = array(); |
/** |
* List of blocks to preverse even if they are "empty". |
* |
* This is something special. Sometimes you have blocks that |
* should be preserved although they are empty (no placeholder replaced). |
* Think of a shopping basket. If it's empty you have to drop a message to |
* the user. If it's filled you have to show the contents of |
* the shopping baseket. Now where do you place the message that the basket |
* is empty? It's no good idea to place it in you applications as customers |
* tend to like unecessary minor text changes. Having another template file |
* for an empty basket means that it's very likely that one fine day |
* the filled and empty basket templates have different layout. I decided |
* to introduce blocks that to not contain any placeholder but only |
* text such as the message "Your shopping basked is empty". |
* |
* Now if there is no replacement done in such a block the block will |
* be recognized as "empty" and by default ($removeEmptyBlocks = true) be |
* stripped off. To avoid thisyou can now call touchBlock() to avoid this. |
* |
* The array $touchedBlocks stores a list of touched block which must not |
* be removed even if they are empty. |
* |
* @var array $touchedBlocks |
* @see touchBlock(), $removeEmptyBlocks |
*/ |
var $touchedBlocks = array(); |
/** |
* List of blocks which should not be shown even if not "empty" |
* @var array $_hiddenBlocks |
* @see hideBlock(), $removeEmptyBlocks |
*/ |
var $_hiddenBlocks = array(); |
/** |
* Variable cache. |
* |
* Variables get cached before any replacement is done. |
* Advantage: empty blocks can be removed automatically. |
* Disadvantage: might take some more memory |
* |
* @var array |
* @see setVariable(), $clearCacheOnParse |
*/ |
var $variableCache = array(); |
/** |
* Clear the variable cache on parse? |
* |
* If you're not an expert just leave the default false. |
* True reduces memory consumption somewhat if you tend to |
* add lots of values for unknown placeholder. |
* |
* @var boolean |
*/ |
var $clearCacheOnParse = false; |
/** |
* Root directory for all file operations. |
* The string gets prefixed to all filenames given. |
* @var string |
* @see HTML_Template_IT(), setRoot() |
*/ |
var $fileRoot = ''; |
/** |
* Internal flag indicating that a blockname was used multiple times. |
* @var boolean |
*/ |
var $flagBlocktrouble = false; |
/** |
* Flag indicating that the global block was parsed. |
* @var boolean |
*/ |
var $flagGlobalParsed = false; |
/** |
* EXPERIMENTAL! FIXME! |
* Flag indication that a template gets cached. |
* |
* Complex templates require some times to be preparsed |
* before the replacement can take place. Often I use |
* one template file over and over again but I don't know |
* before that I will use the same template file again. |
* Now IT could notice this and skip the preparse. |
* |
* @var boolean |
*/ |
var $flagCacheTemplatefile = true; |
/** |
* EXPERIMENTAL! FIXME! |
*/ |
var $lastTemplatefile = ''; |
/** |
* $_options['preserve_data'] Whether to substitute variables and remove |
* empty placeholders in data passed through setVariable |
* (see also bugs #20199, #21951). |
* $_options['use_preg'] Whether to use preg_replace instead of |
* str_replace in parse() |
* (this is a backwards compatibility feature, see also bugs #21951, #20392) |
*/ |
var $_options = array( |
'preserve_data' => false, |
'use_preg' => true |
); |
/** |
* Builds some complex regular expressions and optinally sets the |
* file root directory. |
* |
* Make sure that you call this constructor if you derive your template |
* class from this one. |
* |
* @param string File root directory, prefix for all filenames |
* given to the object. |
* @see setRoot() |
*/ |
function HTML_Template_IT($root = '', $options = null) |
{ |
if (!is_null($options)) { |
$this->setOptions($options); |
} |
$this->variablesRegExp = '@' . $this->openingDelimiter . |
'(' . $this->variablenameRegExp . ')' . |
$this->closingDelimiter . '@sm'; |
$this->removeVariablesRegExp = '@' . $this->openingDelimiter . |
"\s*(" . $this->variablenameRegExp . |
")\s*" . $this->closingDelimiter .'@sm'; |
$this->blockRegExp = '@<!--\s+BEGIN\s+(' . $this->blocknameRegExp . |
')\s+-->(.*)<!--\s+END\s+\1\s+-->@sm'; |
$this->setRoot($root); |
} // end constructor |
/** |
* Sets the option for the template class |
* |
* @access public |
* @param string option name |
* @param mixed option value |
* @return mixed IT_OK on success, error object on failure |
*/ |
function setOption($option, $value) |
{ |
if (array_key_exists($option, $this->_options)) { |
$this->_options[$option] = $value; |
return IT_OK; |
} |
return PEAR::raiseError( |
$this->errorMessage(IT_UNKNOWN_OPTION) . ": '{$option}'", |
IT_UNKNOWN_OPTION |
); |
} |
/** |
* Sets the options for the template class |
* |
* @access public |
* @param string options array of options |
* default value: |
* 'preserve_data' => false, |
* 'use_preg' => true |
* @param mixed option value |
* @return mixed IT_OK on success, error object on failure |
* @see $options |
*/ |
function setOptions($options) |
{ |
if (is_array($options)) { |
foreach ($options as $option => $value) { |
$error = $this->setOption($option, $value); |
if (PEAR::isError($error)) { |
return $error; |
} |
} |
} |
return IT_OK; |
} |
/** |
* Print a certain block with all replacements done. |
* @brother get() |
*/ |
function show($block = '__global__') |
{ |
print $this->get($block); |
} // end func show |
/** |
* Returns a block with all replacements done. |
* |
* @param string name of the block |
* @return string |
* @throws PEAR_Error |
* @access public |
* @see show() |
*/ |
function get($block = '__global__') |
{ |
if ($block == '__global__' && !$this->flagGlobalParsed) { |
$this->parse('__global__'); |
} |
if (!isset($this->blocklist[$block])) { |
$this->err[] = PEAR::raiseError( |
$this->errorMessage(IT_BLOCK_NOT_FOUND) . |
'"' . $block . "'", |
IT_BLOCK_NOT_FOUND |
); |
return ''; |
} |
if (isset($this->blockdata[$block])) { |
$ret = $this->blockdata[$block]; |
if ($this->clearCache) { |
unset($this->blockdata[$block]); |
} |
if ($this->_options['preserve_data']) { |
$ret = str_replace( |
$this->openingDelimiter . |
'%preserved%' . $this->closingDelimiter, |
$this->openingDelimiter, |
$ret |
); |
} |
return $ret; |
} |
return ''; |
} // end func get() |
/** |
* Parses the given block. |
* |
* @param string name of the block to be parsed |
* @access public |
* @see parseCurrentBlock() |
* @throws PEAR_Error |
*/ |
function parse($block = '__global__', $flag_recursion = false) |
{ |
static $regs, $values; |
if (!isset($this->blocklist[$block])) { |
return PEAR::raiseError( |
$this->errorMessage( IT_BLOCK_NOT_FOUND ) . '"' . $block . "'", |
IT_BLOCK_NOT_FOUND |
); |
} |
if ($block == '__global__') { |
$this->flagGlobalParsed = true; |
} |
if (!$flag_recursion) { |
$regs = array(); |
$values = array(); |
} |
$outer = $this->blocklist[$block]; |
$empty = true; |
if ($this->clearCacheOnParse) { |
foreach ($this->variableCache as $name => $value) { |
$regs[] = $this->openingDelimiter . |
$name . $this->closingDelimiter; |
$values[] = $value; |
$empty = false; |
} |
$this->variableCache = array(); |
} else { |
foreach ($this->blockvariables[$block] as $allowedvar => $v) { |
if (isset($this->variableCache[$allowedvar])) { |
$regs[] = $this->openingDelimiter . |
$allowedvar . $this->closingDelimiter; |
$values[] = $this->variableCache[$allowedvar]; |
unset($this->variableCache[$allowedvar]); |
$empty = false; |
} |
} |
} |
if (isset($this->blockinner[$block])) { |
foreach ($this->blockinner[$block] as $k => $innerblock) { |
$this->parse($innerblock, true); |
if ($this->blockdata[$innerblock] != '') { |
$empty = false; |
} |
$placeholder = $this->openingDelimiter . "__" . |
$innerblock . "__" . $this->closingDelimiter; |
$outer = str_replace( |
$placeholder, |
$this->blockdata[$innerblock], $outer |
); |
$this->blockdata[$innerblock] = ""; |
} |
} |
if (!$flag_recursion && 0 != count($values)) { |
if ($this->_options['use_preg']) { |
$regs = array_map(array( |
&$this, '_addPregDelimiters'), |
$regs |
); |
$funcReplace = 'preg_replace'; |
} else { |
$funcReplace = 'str_replace'; |
} |
if ($this->_options['preserve_data']) { |
$values = array_map( |
array(&$this, '_preserveOpeningDelimiter'), $values |
); |
} |
$outer = $funcReplace($regs, $values, $outer); |
if ($this->removeUnknownVariables) { |
$outer = preg_replace($this->removeVariablesRegExp, "", $outer); |
} |
} |
if ($empty) { |
if (!$this->removeEmptyBlocks) { |
$this->blockdata[$block ].= $outer; |
} else { |
if (isset($this->touchedBlocks[$block])) { |
$this->blockdata[$block] .= $outer; |
unset($this->touchedBlocks[$block]); |
} |
} |
} else { |
$this->blockdata[$block] .= $outer; |
} |
return $empty; |
} // end func parse |
/** |
* Parses the current block |
* @see parse(), setCurrentBlock(), $currentBlock |
* @access public |
*/ |
function parseCurrentBlock() |
{ |
return $this->parse($this->currentBlock); |
} // end func parseCurrentBlock |
/** |
* Sets a variable value. |
* |
* The function can be used eighter like setVariable( "varname", "value") |
* or with one array $variables["varname"] = "value" |
* given setVariable($variables) quite like phplib templates set_var(). |
* |
* @param mixed string with the variable name or an array |
* %variables["varname"] = "value" |
* @param string value of the variable or empty if $variable |
* is an array. |
* @param string prefix for variable names |
* @access public |
*/ |
function setVariable($variable, $value = '') |
{ |
if (is_array($variable)) { |
$this->variableCache = array_merge( |
$this->variableCache, $variable |
); |
} else { |
$this->variableCache[$variable] = $value; |
} |
} // end func setVariable |
/** |
* Sets the name of the current block that is the block where variables |
* are added. |
* |
* @param string name of the block |
* @return boolean false on failure, otherwise true |
* @throws PEAR_Error |
* @access public |
*/ |
function setCurrentBlock($block = '__global__') |
{ |
if (!isset($this->blocklist[$block])) { |
return PEAR::raiseError( |
$this->errorMessage( IT_BLOCK_NOT_FOUND ) . |
'"' . $block . "'", IT_BLOCK_NOT_FOUND |
); |
} |
$this->currentBlock = $block; |
return true; |
} // end func setCurrentBlock |
/** |
* Preserves an empty block even if removeEmptyBlocks is true. |
* |
* @param string name of the block |
* @return boolean false on false, otherwise true |
* @throws PEAR_Error |
* @access public |
* @see $removeEmptyBlocks |
*/ |
function touchBlock($block) |
{ |
if (!isset($this->blocklist[$block])) { |
return PEAR::raiseError( |
$this->errorMessage(IT_BLOCK_NOT_FOUND) . |
'"' . $block . "'", IT_BLOCK_NOT_FOUND); |
} |
$this->touchedBlocks[$block] = true; |
return true; |
} // end func touchBlock |
/** |
* Clears all datafields of the object and rebuild the internal blocklist |
* |
* LoadTemplatefile() and setTemplate() automatically call this function |
* when a new template is given. Don't use this function |
* unless you know what you're doing. |
* |
* @access public |
* @see free() |
*/ |
function init() |
{ |
$this->free(); |
$this->findBlocks($this->template); |
// we don't need it any more |
$this->template = ''; |
$this->buildBlockvariablelist(); |
} // end func init |
/** |
* Clears all datafields of the object. |
* |
* Don't use this function unless you know what you're doing. |
* |
* @access public |
* @see init() |
*/ |
function free() |
{ |
$this->err = array(); |
$this->currentBlock = '__global__'; |
$this->variableCache = array(); |
$this->blocklookup = array(); |
$this->touchedBlocks = array(); |
$this->flagBlocktrouble = false; |
$this->flagGlobalParsed = false; |
} // end func free |
/** |
* Sets the template. |
* |
* You can eighter load a template file from disk with |
* LoadTemplatefile() or set the template manually using this function. |
* |
* @param string template content |
* @param boolean remove unknown/unused variables? |
* @param boolean remove empty blocks? |
* @see LoadTemplatefile(), $template |
* @access public |
*/ |
function setTemplate( $template, $removeUnknownVariables = true, |
$removeEmptyBlocks = true) |
{ |
$this->removeUnknownVariables = $removeUnknownVariables; |
$this->removeEmptyBlocks = $removeEmptyBlocks; |
if ($template == '' && $this->flagCacheTemplatefile) { |
$this->variableCache = array(); |
$this->blockdata = array(); |
$this->touchedBlocks = array(); |
$this->currentBlock = '__global__'; |
} else { |
$this->template = '<!-- BEGIN __global__ -->' . $template . |
'<!-- END __global__ -->'; |
$this->init(); |
} |
if ($this->flagBlocktrouble) { |
return false; |
} |
return true; |
} // end func setTemplate |
/** |
* Reads a template file from the disk. |
* |
* @param string name of the template file |
* @param bool how to handle unknown variables. |
* @param bool how to handle empty blocks. |
* @access public |
* @return boolean false on failure, otherwise true |
* @see $template, setTemplate(), $removeUnknownVariables, |
* $removeEmptyBlocks |
*/ |
function loadTemplatefile( $filename, |
$removeUnknownVariables = true, |
$removeEmptyBlocks = true ) |
{ |
$template = ''; |
if (!$this->flagCacheTemplatefile || |
$this->lastTemplatefile != $filename |
) { |
$template = $this->getFile($filename); |
} |
$this->lastTemplatefile = $filename; |
return $template != '' ? |
$this->setTemplate( |
$template,$removeUnknownVariables, $removeEmptyBlocks |
) : false; |
} // end func LoadTemplatefile |
/** |
* Sets the file root. The file root gets prefixed to all filenames passed |
* to the object. |
* |
* Make sure that you override this function when using the class |
* on windows. |
* |
* @param string |
* @see IntegratedTemplate() |
* @access public |
*/ |
function setRoot($root) |
{ |
if ($root != '' && substr($root, -1) != '/') { |
$root .= '/'; |
} |
$this->fileRoot = $root; |
} // end func setRoot |
/** |
* Build a list of all variables within of a block |
*/ |
function buildBlockvariablelist() |
{ |
foreach ($this->blocklist as $name => $content) { |
preg_match_all($this->variablesRegExp, $content, $regs); |
if (count($regs[1]) != 0) { |
foreach ($regs[1] as $k => $var) { |
$this->blockvariables[$name][$var] = true; |
} |
} else { |
$this->blockvariables[$name] = array(); |
} |
} |
} // end func buildBlockvariablelist |
/** |
* Returns a list of all global variables |
*/ |
function getGlobalvariables() |
{ |
$regs = array(); |
$values = array(); |
foreach ($this->blockvariables['__global__'] as $allowedvar => $v) { |
if (isset($this->variableCache[$allowedvar])) { |
$regs[] = '@' . $this->openingDelimiter . |
$allowedvar . $this->closingDelimiter . '@'; |
$values[] = $this->variableCache[$allowedvar]; |
unset($this->variableCache[$allowedvar]); |
} |
} |
return array($regs, $values); |
} // end func getGlobalvariables |
/** |
* Recusively builds a list of all blocks within the template. |
* |
* @param string string that gets scanned |
* @see $blocklist |
*/ |
function findBlocks($string) |
{ |
$blocklist = array(); |
if (preg_match_all($this->blockRegExp, $string, $regs, PREG_SET_ORDER)) { |
foreach ($regs as $k => $match) { |
$blockname = $match[1]; |
$blockcontent = $match[2]; |
if (isset($this->blocklist[$blockname])) { |
$this->err[] = PEAR::raiseError( |
$this->errorMessage( |
IT_BLOCK_DUPLICATE, $blockname), |
IT_BLOCK_DUPLICATE |
); |
$this->flagBlocktrouble = true; |
} |
$this->blocklist[$blockname] = $blockcontent; |
$this->blockdata[$blockname] = ""; |
$blocklist[] = $blockname; |
$inner = $this->findBlocks($blockcontent); |
foreach ($inner as $k => $name) { |
$pattern = sprintf( |
'@<!--\s+BEGIN\s+%s\s+-->(.*)<!--\s+END\s+%s\s+-->@sm', |
$name, |
$name |
); |
$this->blocklist[$blockname] = preg_replace( |
$pattern, |
$this->openingDelimiter . |
'__' . $name . '__' . |
$this->closingDelimiter, |
$this->blocklist[$blockname] |
); |
$this->blockinner[$blockname][] = $name; |
$this->blockparents[$name] = $blockname; |
} |
} |
} |
return $blocklist; |
} // end func findBlocks |
/** |
* Reads a file from disk and returns its content. |
* @param string Filename |
* @return string Filecontent |
*/ |
function getFile($filename) |
{ |
if ($filename{0} == '/' && substr($this->fileRoot, -1) == '/') { |
$filename = substr($filename, 1); |
} |
$filename = $this->fileRoot . $filename; |
if (!($fh = @fopen($filename, 'r'))) { |
$this->err[] = PEAR::raiseError( |
$this->errorMessage(IT_TPL_NOT_FOUND) . |
': "' .$filename .'"', |
IT_TPL_NOT_FOUND |
); |
return ""; |
} |
$content = fread($fh, filesize($filename)); |
fclose($fh); |
return preg_replace( |
"#<!-- INCLUDE (.*) -->#ime", "\$this->getFile('\\1')", $content |
); |
} // end func getFile |
/** |
* Adds delimiters to a string, so it can be used as a pattern |
* in preg_* functions |
* |
* @param string |
* @return string |
*/ |
function _addPregDelimiters($str) |
{ |
return '@' . $str . '@'; |
} |
/** |
* Replaces an opening delimiter by a special string |
* |
* @param string |
* @return string |
*/ |
function _preserveOpeningDelimiter($str) |
{ |
return (false === strpos($str, $this->openingDelimiter))? |
$str: |
str_replace( |
$this->openingDelimiter, |
$this->openingDelimiter . |
'%preserved%' . $this->closingDelimiter, |
$str |
); |
} |
/** |
* Return a textual error message for a IT error code |
* |
* @param integer $value error code |
* |
* @return string error message, or false if the error code was |
* not recognized |
*/ |
function errorMessage($value, $blockname = '') |
{ |
static $errorMessages; |
if (!isset($errorMessages)) { |
$errorMessages = array( |
IT_OK => '', |
IT_ERROR => 'unknown error', |
IT_TPL_NOT_FOUND => 'Cannot read the template file', |
IT_BLOCK_NOT_FOUND => 'Cannot find this block', |
IT_BLOCK_DUPLICATE => 'The name of a block must be'. |
' uniquewithin a template.'. |
' Found "' . $blockname . '" twice.'. |
'Unpredictable results '. |
'may appear.', |
IT_UNKNOWN_OPTION => 'Unknown option' |
); |
} |
if (PEAR::isError($value)) { |
$value = $value->getCode(); |
} |
return isset($errorMessages[$value]) ? |
$errorMessages[$value] : $errorMessages[IT_ERROR]; |
} |
} // end class IntegratedTemplate |
?> |
/branches/livraison_menes/api/pear/HTML/Table.php |
---|
Cannot display: file marked as a binary type. |
svn:mime-type = application/octet-stream |
/branches/livraison_menes/api/pear/HTML/Table.php |
---|
New file |
Property changes: |
Added: svn:mime-type |
+application/octet-stream |
\ No newline at end of property |
/branches/livraison_menes/api/pear/Text/Wiki/Parse/Center.php |
---|
New file |
0,0 → 1,60 |
<?php |
// $Id: Center.php,v 1.1 2005-01-20 19:43:20 jpm Exp $ |
/** |
* |
* This class implements a Text_Wiki_Parse to find lines marked for centering. |
* The line must start with "= " (i.e., an equal-sign followed by a space). |
* |
* @author Paul M. Jones <pmjones@ciaweb.net> |
* |
* @package Text_Wiki |
* |
*/ |
class Text_Wiki_Parse_Center extends Text_Wiki_Parse { |
/** |
* |
* The regular expression used to find source text matching this |
* rule. |
* |
* @access public |
* |
* @var string |
* |
*/ |
var $regex = '/\n\= (.*?)\n/'; |
/** |
* |
* Generates a token entry for the matched text. |
* |
* @access public |
* |
* @param array &$matches The array of matches from parse(). |
* |
* @return A delimited token number to be used as a placeholder in |
* the source text. |
* |
*/ |
function process(&$matches) |
{ |
$start = $this->wiki->addToken( |
$this->rule, |
array('type' => 'start') |
); |
$end = $this->wiki->addToken( |
$this->rule, |
array('type' => 'end') |
); |
return "\n" . $start . $matches[1] . $end . "\n"; |
} |
} |
?> |
/branches/livraison_menes/api/pear/Text/Wiki/Parse/Phplookup.php |
---|
New file |
0,0 → 1,58 |
<?php |
// $Id: Phplookup.php,v 1.1 2005-01-20 19:43:20 jpm Exp $ |
/** |
* |
* Find source text marked for |
* lookup in the PHP online manual. |
* |
* @author Paul M. Jones <pmjones@ciaweb.net> |
* |
* @package Text_Wiki |
* |
*/ |
class Text_Wiki_Parse_Phplookup extends Text_Wiki_Parse { |
/** |
* |
* The regular expression used to parse the source text and find |
* matches conforming to this rule. Used by the parse() method. |
* |
* @access public |
* |
* @var string |
* |
* @see parse() |
* |
*/ |
var $regex = "/\[\[php (.+?)\]\]/"; |
/** |
* |
* Generates a replacement for the matched text. Token options are: |
* |
* 'type' => ['start'|'end'] The starting or ending point of the |
* teletype text. The text itself is left in the source. |
* |
* @access public |
* |
* @param array &$matches The array of matches from parse(). |
* |
* @return string A pair of delimited tokens to be used as a |
* placeholder in the source text surrounding the teletype text. |
* |
*/ |
function process(&$matches) |
{ |
return $this->wiki->addToken( |
$this->rule, array('text' => $matches[1]) |
); |
} |
} |
?> |
/branches/livraison_menes/api/pear/Text/Wiki/Parse/Colortext.php |
---|
New file |
0,0 → 1,74 |
<?php |
// $Id: Colortext.php,v 1.1 2005-01-20 19:43:20 jpm Exp $ |
/** |
* |
* This class implements a Text_Wiki_Parse to find source text marked for |
* coloring. |
* |
* @author Paul M. Jones <pmjones@ciaweb.net> |
* |
* @package Text_Wiki |
* |
*/ |
class Text_Wiki_Parse_Colortext extends Text_Wiki_Parse { |
/** |
* |
* The regular expression used to parse the source text and find |
* matches conforming to this rule. Used by the parse() method. |
* |
* @access public |
* |
* @var string |
* |
* @see parse() |
* |
*/ |
var $regex = "/\#\#(.+?)\|(.+?)\#\#/"; |
/** |
* |
* Generates a replacement for the matched text. Token options are: |
* |
* 'type' => ['start'|'end'] The starting or ending point of the |
* emphasized text. The text itself is left in the source. |
* |
* 'color' => the color indicator |
* |
* @access public |
* |
* @param array &$matches The array of matches from parse(). |
* |
* @return string A pair of delimited tokens to be used as a |
* placeholder in the source text surrounding the text to be |
* emphasized. |
* |
*/ |
function process(&$matches) |
{ |
$start = $this->wiki->addToken( |
$this->rule, |
array( |
'type' => 'start', |
'color' => $matches[1] |
) |
); |
$end = $this->wiki->addToken( |
$this->rule, |
array( |
'type' => 'end', |
'color' => $matches[1] |
) |
); |
return $start . $matches[2] . $end; |
} |
} |
?> |
/branches/livraison_menes/api/pear/Text/Wiki/Parse/Include.php |
---|
New file |
0,0 → 1,84 |
<?php |
// $Id: Include.php,v 1.1 2005-01-20 19:43:20 jpm Exp $ |
/** |
* |
* This class implements a Text_Wiki_Parse to include the results of a |
* script directly into the source at parse-time; thus, the output of the |
* script will be parsed by Text_Wiki. This differs from the 'embed' |
* rule, which incorporates the results at render-time, meaning that the |
* 'embed' content is not parsed by Text_Wiki. |
* |
* DANGER! |
* |
* This rule is inherently not secure; it allows cross-site scripting to |
* occur if the embedded output has <script> or other similar tags. Be |
* careful. |
* |
* @author Paul M. Jones <pmjones@ciaweb.net> |
* |
* @package Text_Wiki |
* |
*/ |
class Text_Wiki_Parse_Include extends Text_Wiki_Parse { |
var $conf = array( |
'base' => '/path/to/scripts/' |
); |
var $file = null; |
var $output = null; |
var $vars = null; |
/** |
* |
* The regular expression used to find source text matching this |
* rule. |
* |
* @access public |
* |
* @var string |
* |
*/ |
var $regex = '/(\[\[include )(.+?)( .+?)?(\]\])/i'; |
/** |
* |
* Includes the results of the script directly into the source; the output |
* will subsequently be parsed by the remaining Text_Wiki rules. |
* |
* @access public |
* |
* @param array &$matches The array of matches from parse(). |
* |
* @return The results of the included script. |
* |
*/ |
function process(&$matches) |
{ |
// save the file location |
$this->file = $this->getConf('base', './') . $matches[2]; |
// extract attribs as variables in the local space |
$this->vars = $this->getAttrs($matches[3]); |
unset($this->vars['this']); |
extract($this->vars); |
// run the script |
ob_start(); |
include($this->file); |
$this->output = ob_get_contents(); |
ob_end_clean(); |
// done, place the script output directly in the source |
return $this->output; |
} |
} |
?> |
/branches/livraison_menes/api/pear/Text/Wiki/Parse/Superscript.php |
---|
New file |
0,0 → 1,67 |
<?php |
// $Id: Superscript.php,v 1.1 2005-01-20 19:43:20 jpm Exp $ |
/** |
* |
* This class implements a Text_Wiki_Parse to find source text marked for |
* strong emphasis (bold) as defined by text surrounded by three |
* single-quotes. On parsing, the text itself is left in place, but the |
* starting and ending instances of three single-quotes are replaced with |
* tokens. |
* |
* @author Paul M. Jones <pmjones@ciaweb.net> |
* |
* @package Text_Wiki |
* |
*/ |
class Text_Wiki_Parse_Superscript extends Text_Wiki_Parse { |
/** |
* |
* The regular expression used to parse the source text and find |
* matches conforming to this rule. Used by the parse() method. |
* |
* @access public |
* |
* @var string |
* |
* @see parse() |
* |
*/ |
var $regex = "/\^\^(()|.*)\^\^/U"; |
/** |
* |
* Generates a replacement for the matched text. Token options are: |
* |
* 'type' => ['start'|'end'] The starting or ending point of the |
* emphasized text. The text itself is left in the source. |
* |
* @access public |
* |
* @param array &$matches The array of matches from parse(). |
* |
* @return A pair of delimited tokens to be used as a placeholder in |
* the source text surrounding the text to be emphasized. |
* |
*/ |
function process(&$matches) |
{ |
$start = $this->wiki->addToken( |
$this->rule, array('type' => 'start') |
); |
$end = $this->wiki->addToken( |
$this->rule, array('type' => 'end') |
); |
return $start . $matches[1] . $end; |
} |
} |
?> |
/branches/livraison_menes/api/pear/Text/Wiki/Parse/Break.php |
---|
New file |
0,0 → 1,54 |
<?php |
// $Id: Break.php,v 1.1 2005-01-20 19:43:20 jpm Exp $ |
/** |
* |
* This class implements a Text_Wiki_Parse to mark forced line breaks in the |
* source text. |
* |
* @author Paul M. Jones <pmjones@ciaweb.net> |
* |
* @package Text_Wiki |
* |
*/ |
class Text_Wiki_Parse_Break extends Text_Wiki_Parse { |
/** |
* |
* The regular expression used to parse the source text and find |
* matches conforming to this rule. Used by the parse() method. |
* |
* @access public |
* |
* @var string |
* |
* @see parse() |
* |
*/ |
var $regex = '/ _\n/'; |
/** |
* |
* Generates a replacement token for the matched text. |
* |
* @access public |
* |
* @param array &$matches The array of matches from parse(). |
* |
* @return string A delimited token to be used as a placeholder in |
* the source text. |
* |
*/ |
function process(&$matches) |
{ |
return $this->wiki->addToken($this->rule); |
} |
} |
?> |
/branches/livraison_menes/api/pear/Text/Wiki/Parse/Function.php |
---|
New file |
0,0 → 1,115 |
<?php |
// $Id: Function.php,v 1.1 2005-01-20 19:43:20 jpm Exp $ |
class Text_Wiki_Parse_Function extends Text_Wiki_Parse { |
var $regex = '/^(\<function\>)\n(.+)\n(\<\/function\>)(\s|$)/Umsi'; |
function process(&$matches) |
{ |
// default options |
$opts = array( |
'name' => null, |
'access' => null, |
'return' => null, |
'params' => array(), |
'throws' => array() |
); |
// split apart the markup lines and loop through them |
$lines = explode("\n", $matches[2]); |
foreach ($lines as $line) { |
// skip blank lines |
if (trim($line) == '') { |
continue; |
} |
// find the first ':' on the line; the left part is the |
// type, the right part is the value. skip lines without |
// a ':' on them. |
$pos = strpos($line, ':'); |
if ($pos === false) { |
continue; |
} |
// $type is the line type: name, access, return, param, throws |
// 012345678901234 |
// name: something |
$type = trim(substr($line, 0, $pos)); |
$val = trim(substr($line, $pos+1)); |
switch($type) { |
case 'a': |
case 'access': |
$opts['access'] = $val; |
break; |
case 'n': |
case 'name': |
$opts['name'] = $val; |
break; |
case 'p': |
case 'param': |
$tmp = explode(',', $val); |
$k = count($tmp); |
if ($k == 1) { |
$opts['params'][] = array( |
'type' => $tmp[0], |
'descr' => null, |
'default' => null |
); |
} elseif ($k == 2) { |
$opts['params'][] = array( |
'type' => $tmp[0], |
'descr' => $tmp[1], |
'default' => null |
); |
} else { |
$opts['params'][] = array( |
'type' => $tmp[0], |
'descr' => $tmp[1], |
'default' => $tmp[2] |
); |
} |
break; |
case 'r': |
case 'return': |
case 'returns': |
$opts['return'] = $val; |
break; |
case 't': |
case 'throws': |
$tmp = explode(',', $val); |
$k = count($tmp); |
if ($k == 1) { |
$opts['throws'][] = array( |
'type' => $tmp[0], |
'descr' => null |
); |
} else { |
$opts['throws'][] = array( |
'type' => $tmp[0], |
'descr' => $tmp[1] |
); |
} |
break; |
default: |
$opts[$type] = $val; |
break; |
} |
} |
// add the token back in place |
return $this->wiki->addToken($this->rule, $opts) . $matches[4]; |
} |
} |
?> |
/branches/livraison_menes/api/pear/Text/Wiki/Parse/Toc.php |
---|
New file |
0,0 → 1,112 |
<?php |
// $Id: Toc.php,v 1.1 2005-01-20 19:43:20 jpm Exp $ |
/** |
* |
* This class implements a Text_Wiki_Parse to find all heading tokens and |
* build a table of contents. The [[toc]] tag gets replaced with a list |
* of all the level-2 through level-6 headings. |
* |
* @author Paul M. Jones <pmjones@ciaweb.net> |
* |
* @package Text_Wiki |
* |
*/ |
class Text_Wiki_Parse_Toc extends Text_Wiki_Parse { |
/** |
* |
* The regular expression used to parse the source text and find |
* matches conforming to this rule. Used by the parse() method. |
* |
* @access public |
* |
* @var string |
* |
* @see parse() |
* |
*/ |
var $regex = "/\n\[\[toc( .*)?\]\]\n/m"; |
/** |
* |
* Generates a replacement for the matched text. |
* |
* Token options are: |
* |
* 'type' => ['list_start'|'list_end'|'item_start'|'item_end'|'target'] |
* |
* 'level' => The heading level (1-6). |
* |
* 'count' => Which entry number this is in the list. |
* |
* @access public |
* |
* @param array &$matches The array of matches from parse(). |
* |
* @return string A token indicating the TOC collection point. |
* |
*/ |
function process(&$matches) |
{ |
$count = 0; |
if (isset($matches[1])) { |
$attr = $this->getAttrs(trim($matches[1])); |
} else { |
$attr = array(); |
} |
$output = $this->wiki->addToken( |
$this->rule, |
array( |
'type' => 'list_start', |
'level' => 0, |
'attr' => $attr |
) |
); |
foreach ($this->wiki->getTokens('Heading') as $key => $val) { |
if ($val[1]['type'] != 'start') { |
continue; |
} |
$options = array( |
'type' => 'item_start', |
'id' => $val[1]['id'], |
'level' => $val[1]['level'], |
'count' => $count ++ |
); |
$output .= $this->wiki->addToken($this->rule, $options); |
$output .= $val[1]['text']; |
$output .= $this->wiki->addToken( |
$this->rule, |
array( |
'type' => 'item_end', |
'level' => $val[1]['level'] |
) |
); |
} |
$output .= $this->wiki->addToken( |
$this->rule, array( |
'type' => 'list_end', |
'level' => 0 |
) |
); |
return $output; |
} |
} |
?> |
/branches/livraison_menes/api/pear/Text/Wiki/Parse/Table.php |
---|
New file |
0,0 → 1,208 |
<?php |
// $Id: Table.php,v 1.1 2005-01-20 19:43:20 jpm Exp $ |
/** |
* |
* This class implements a Text_Wiki_Parse to find source text marked as a |
* set of table rows, where a line start and ends with double-pipes (||) |
* and uses double-pipes to separate table cells. The rows must be on |
* sequential lines (no blank lines between them) -- a blank line |
* indicates the beginning of a new table. |
* |
* @author Paul M. Jones <pmjones@ciaweb.net> |
* |
* @package Text_Wiki |
* |
*/ |
class Text_Wiki_Parse_Table extends Text_Wiki_Parse { |
/** |
* |
* The regular expression used to parse the source text and find |
* matches conforming to this rule. Used by the parse() method. |
* |
* @access public |
* |
* @var string |
* |
* @see parse() |
* |
*/ |
var $regex = '/\n((\|\|).*)(\n)(?!(\|\|))/Us'; |
/** |
* |
* Generates a replacement for the matched text. |
* |
* Token options are: |
* |
* 'type' => |
* 'table_start' : the start of a bullet list |
* 'table_end' : the end of a bullet list |
* 'row_start' : the start of a number list |
* 'row_end' : the end of a number list |
* 'cell_start' : the start of item text (bullet or number) |
* 'cell_end' : the end of item text (bullet or number) |
* |
* 'cols' => the number of columns in the table (for 'table_start') |
* |
* 'rows' => the number of rows in the table (for 'table_start') |
* |
* 'span' => column span (for 'cell_start') |
* |
* 'attr' => column attribute flag (for 'cell_start') |
* |
* @access public |
* |
* @param array &$matches The array of matches from parse(). |
* |
* @return A series of text and delimited tokens marking the different |
* table elements and cell text. |
* |
*/ |
function process(&$matches) |
{ |
// our eventual return value |
$return = ''; |
// the number of columns in the table |
$num_cols = 0; |
// the number of rows in the table |
$num_rows = 0; |
// rows are separated by newlines in the matched text |
$rows = explode("\n", $matches[1]); |
// loop through each row |
foreach ($rows as $row) { |
// increase the row count |
$num_rows ++; |
// start a new row |
$return .= $this->wiki->addToken( |
$this->rule, |
array('type' => 'row_start') |
); |
// cells are separated by double-pipes |
$cell = explode("||", $row); |
// get the number of cells (columns) in this row |
$last = count($cell) - 1; |
// is this more than the current column count? |
// (we decrease by 1 because we never use cell zero) |
if ($last - 1 > $num_cols) { |
// increase the column count |
$num_cols = $last - 1; |
} |
// by default, cells span only one column (their own) |
$span = 1; |
// ignore cell zero, and ignore the "last" cell; cell zero |
// is before the first double-pipe, and the "last" cell is |
// after the last double-pipe. both are always empty. |
for ($i = 1; $i < $last; $i ++) { |
// if there is no content at all, then it's an instance |
// of two sets of || next to each other, indicating a |
// span. |
if ($cell[$i] == '') { |
// add to the span and loop to the next cell |
$span += 1; |
continue; |
} else { |
// this cell has content. |
// find any special "attr"ibute cell markers |
if (substr($cell[$i], 0, 2) == '> ') { |
// right-align |
$attr = 'right'; |
$cell[$i] = substr($cell[$i], 2); |
} elseif (substr($cell[$i], 0, 2) == '= ') { |
// center-align |
$attr = 'center'; |
$cell[$i] = substr($cell[$i], 2); |
} elseif (substr($cell[$i], 0, 2) == '< ') { |
// left-align |
$attr = 'left'; |
$cell[$i] = substr($cell[$i], 2); |
} elseif (substr($cell[$i], 0, 2) == '~ ') { |
$attr = 'header'; |
$cell[$i] = substr($cell[$i], 2); |
} else { |
$attr = null; |
} |
// start a new cell... |
$return .= $this->wiki->addToken( |
$this->rule, |
array ( |
'type' => 'cell_start', |
'attr' => $attr, |
'span' => $span |
) |
); |
// ...add the content... |
$return .= trim($cell[$i]); |
// ...and end the cell. |
$return .= $this->wiki->addToken( |
$this->rule, |
array ( |
'type' => 'cell_end', |
'attr' => $attr, |
'span' => $span |
) |
); |
// reset the span. |
$span = 1; |
} |
} |
// end the row |
$return .= $this->wiki->addToken( |
$this->rule, |
array('type' => 'row_end') |
); |
} |
// wrap the return value in start and end tokens |
$return = |
$this->wiki->addToken( |
$this->rule, |
array( |
'type' => 'table_start', |
'rows' => $num_rows, |
'cols' => $num_cols |
) |
) |
. $return . |
$this->wiki->addToken( |
$this->rule, |
array( |
'type' => 'table_end' |
) |
); |
// we're done! |
return "\n$return\n\n"; |
} |
} |
?> |
/branches/livraison_menes/api/pear/Text/Wiki/Parse/Raw.php |
---|
New file |
0,0 → 1,55 |
<?php |
// $Id: Raw.php,v 1.1 2005-01-20 19:43:20 jpm Exp $ |
/** |
* |
* This class implements a Text_Wiki rule to find sections of the source |
* text that are not to be processed by Text_Wiki. These blocks of "raw" |
* text will be rendered as they were found. |
* |
* @author Paul M. Jones <pmjones@ciaweb.net> |
* |
* @package Text_Wiki |
* |
*/ |
class Text_Wiki_Parse_Raw extends Text_Wiki_Parse { |
/** |
* |
* The regular expression used to find source text matching this |
* rule. |
* |
* @access public |
* |
* @var string |
* |
*/ |
var $regex = "/``(.*)``/U"; |
/** |
* |
* Generates a token entry for the matched text. Token options are: |
* |
* 'text' => The full matched text. |
* |
* @access public |
* |
* @param array &$matches The array of matches from parse(). |
* |
* @return A delimited token number to be used as a placeholder in |
* the source text. |
* |
*/ |
function process(&$matches) |
{ |
$options = array('text' => $matches[1]); |
return $this->wiki->addToken($this->rule, $options); |
} |
} |
?> |
/branches/livraison_menes/api/pear/Text/Wiki/Parse/Deflist.php |
---|
New file |
0,0 → 1,104 |
<?php |
// $Id: Deflist.php,v 1.1 2005-01-20 19:43:20 jpm Exp $ |
/** |
* |
* This class implements a Text_Wiki_Parse to find source text marked as a |
* definition list. In short, if a line starts with ':' then it is a |
* definition list item; another ':' on the same lines indicates the end |
* of the definition term and the beginning of the definition narrative. |
* The list items must be on sequential lines (no blank lines between |
* them) -- a blank line indicates the beginning of a new list. |
* |
* @author Paul M. Jones <pmjones@ciaweb.net> |
* |
* @package Text_Wiki |
* |
*/ |
class Text_Wiki_Parse_Deflist extends Text_Wiki_Parse { |
/** |
* |
* The regular expression used to parse the source text and find |
* matches conforming to this rule. Used by the parse() method. |
* |
* @access public |
* |
* @var string |
* |
* @see parse() |
* |
*/ |
var $regex = '/\n((: ).*\n)(?!(: |\n))/Us'; |
/** |
* |
* Generates a replacement for the matched text. Token options are: |
* |
* 'type' => |
* 'list_start' : the start of a definition list |
* 'list_end' : the end of a definition list |
* 'term_start' : the start of a definition term |
* 'term_end' : the end of a definition term |
* 'narr_start' : the start of definition narrative |
* 'narr_end' : the end of definition narrative |
* 'unknown' : unknown type of definition portion |
* |
* @access public |
* |
* @param array &$matches The array of matches from parse(). |
* |
* @return A series of text and delimited tokens marking the different |
* list text and list elements. |
* |
*/ |
function process(&$matches) |
{ |
// the replacement text we will return to parse() |
$return = ''; |
// the list of post-processing matches |
$list = array(); |
// start the deflist |
$options = array('type' => 'list_start'); |
$return .= $this->wiki->addToken($this->rule, $options); |
// $matches[1] is the text matched as a list set by parse(); |
// create an array called $list that contains a new set of |
// matches for the various definition-list elements. |
preg_match_all( |
'/^(: )(.*)?( : )(.*)?$/Ums', |
$matches[1], |
$list, |
PREG_SET_ORDER |
); |
// add each term and narrative |
foreach ($list as $key => $val) { |
$return .= ( |
$this->wiki->addToken($this->rule, array('type' => 'term_start')) . |
trim($val[2]) . |
$this->wiki->addToken($this->rule, array('type' => 'term_end')) . |
$this->wiki->addToken($this->rule, array('type' => 'narr_start')) . |
trim($val[4]) . |
$this->wiki->addToken($this->rule, array('type' => 'narr_end')) |
); |
} |
// end the deflist |
$options = array('type' => 'list_end'); |
$return .= $this->wiki->addToken($this->rule, $options); |
// done! |
return "\n" . $return . "\n\n"; |
} |
} |
?> |
/branches/livraison_menes/api/pear/Text/Wiki/Parse/Horiz.php |
---|
New file |
0,0 → 1,52 |
<?php |
// $Id: Horiz.php,v 1.1 2005-01-20 19:43:20 jpm Exp $ |
/** |
* |
* This class implements a Text_Wiki_Parse to find source text marked to |
* be a horizontal rule, as defined by four dashed on their own line. |
* |
* @author Paul M. Jones <pmjones@ciaweb.net> |
* |
* @package Text_Wiki |
* |
*/ |
class Text_Wiki_Parse_Horiz extends Text_Wiki_Parse { |
/** |
* |
* The regular expression used to parse the source text and find |
* matches conforming to this rule. Used by the parse() method. |
* |
* @access public |
* |
* @var string |
* |
* @see parse() |
* |
*/ |
var $regex = '/^([-]{4,})$/m'; |
/** |
* |
* Generates a replacement token for the matched text. |
* |
* @access public |
* |
* @param array &$matches The array of matches from parse(). |
* |
* @return string A token marking the horizontal rule. |
* |
*/ |
function process(&$matches) |
{ |
return $this->wiki->addToken($this->rule); |
} |
} |
?> |
/branches/livraison_menes/api/pear/Text/Wiki/Parse/Prefilter.php |
---|
New file |
0,0 → 1,62 |
<?php |
// $Id: Prefilter.php,v 1.1 2005-01-20 19:43:20 jpm Exp $ |
/** |
* |
* "Pre-filter" the source text. |
* |
* Convert DOS and Mac line endings to Unix, concat lines ending in a |
* backslash \ with the next line, convert tabs to 4-spaces, add newlines |
* to the top and end of the source text, compress 3 or more newlines to |
* 2 newlines. |
* |
* @author Paul M. Jones <pmjones@ciaweb.net> |
* |
* @package Text_Wiki |
* |
*/ |
class Text_Wiki_Parse_Prefilter extends Text_Wiki_Parse { |
/** |
* |
* Simple parsing method. |
* |
* @access public |
* |
*/ |
function parse() |
{ |
// convert DOS line endings |
$this->wiki->source = str_replace("\r\n", "\n", |
$this->wiki->source); |
// convert Macintosh line endings |
$this->wiki->source = str_replace("\r", "\n", |
$this->wiki->source); |
// concat lines ending in a backslash |
$this->wiki->source = str_replace("\\\n", "", |
$this->wiki->source); |
// convert tabs to four-spaces |
$this->wiki->source = str_replace("\t", " ", |
$this->wiki->source); |
// add extra newlines at the top and end; this |
// seems to help many rules. |
$this->wiki->source = "\n" . $this->wiki->source . "\n\n"; |
// finally, compress all instances of 3 or more newlines |
// down to two newlines. |
$find = "/\n{3,}/m"; |
$replace = "\n\n"; |
$this->wiki->source = preg_replace($find, $replace, |
$this->wiki->source); |
} |
} |
?> |
/branches/livraison_menes/api/pear/Text/Wiki/Parse/Heading.php |
---|
New file |
0,0 → 1,89 |
<?php |
// $Id: Heading.php,v 1.1 2005-01-20 19:43:20 jpm Exp $ |
/** |
* |
* This class implements a Text_Wiki_Parse to find source text marked to |
* be a heading element, as defined by text on a line by itself prefixed |
* with a number of plus signs (+). The heading text itself is left in |
* the source, but is prefixed and suffixed with delimited tokens marking |
* the start and end of the heading. |
* |
* @author Paul M. Jones <pmjones@ciaweb.net> |
* |
* @package Text_Wiki |
* |
*/ |
class Text_Wiki_Parse_Heading extends Text_Wiki_Parse { |
/** |
* |
* The regular expression used to parse the source text and find |
* matches conforming to this rule. Used by the parse() method. |
* |
* @access public |
* |
* @var string |
* |
* @see parse() |
* |
*/ |
var $regex = '/^(\+{1,6}) (.*)/m'; |
var $conf = array( |
'id_prefix' => 'toc' |
); |
/** |
* |
* Generates a replacement for the matched text. Token options are: |
* |
* 'type' => ['start'|'end'] The starting or ending point of the |
* heading text. The text itself is left in the source. |
* |
* @access public |
* |
* @param array &$matches The array of matches from parse(). |
* |
* @return string A pair of delimited tokens to be used as a |
* placeholder in the source text surrounding the heading text. |
* |
*/ |
function process(&$matches) |
{ |
// keep a running count for header IDs. we use this later |
// when constructing TOC entries, etc. |
static $id; |
if (! isset($id)) { |
$id = 0; |
} |
$prefix = htmlspecialchars($this->getConf('id_prefix')); |
$start = $this->wiki->addToken( |
$this->rule, |
array( |
'type' => 'start', |
'level' => strlen($matches[1]), |
'text' => $matches[2], |
'id' => $prefix . $id ++ |
) |
); |
$end = $this->wiki->addToken( |
$this->rule, |
array( |
'type' => 'end', |
'level' => strlen($matches[1]) |
) |
); |
return $start . $matches[2] . $end . "\n"; |
} |
} |
?> |
/branches/livraison_menes/api/pear/Text/Wiki/Parse/Tighten.php |
---|
New file |
0,0 → 1,32 |
<?php |
// $Id: Tighten.php,v 1.1 2005-01-20 19:43:20 jpm Exp $ |
/** |
* |
* The rule removes all remaining newlines. |
* |
* @author Paul M. Jones <pmjones@ciaweb.net> |
* |
* @package Text_Wiki |
* |
*/ |
class Text_Wiki_Parse_Tighten extends Text_Wiki_Parse { |
/** |
* |
* Apply tightening directly to the source text. |
* |
* @access public |
* |
*/ |
function parse() |
{ |
$this->wiki->source = str_replace("\n", '', |
$this->wiki->source); |
} |
} |
?> |
/branches/livraison_menes/api/pear/Text/Wiki/Parse/Html.php |
---|
New file |
0,0 → 1,57 |
<?php |
// $Id: Html.php,v 1.1 2005-01-20 19:43:20 jpm Exp $ |
/** |
* |
* This class implements a Text_Wiki_Parse to find source text marked as |
* HTML to be redndred as-is. The block start is marked by <html> on its |
* own line, and the block end is marked by </html> on its own line. |
* |
* @author Paul M. Jones <pmjones@ciaweb.net> |
* |
* @package Text_Wiki |
* |
*/ |
class Text_Wiki_Parse_Html extends Text_Wiki_Parse { |
/** |
* |
* The regular expression used to parse the source text and find |
* matches conforming to this rule. Used by the parse() method. |
* |
* @access public |
* |
* @var string |
* |
* @see parse() |
* |
*/ |
var $regex = '/^\<html\>\n(.+)\n\<\/html\>(\s|$)/Umsi'; |
/** |
* |
* Generates a replacement for the matched text. Token options are: |
* |
* 'text' => The text of the HTML to be rendered as-is. |
* |
* @access public |
* |
* @param array &$matches The array of matches from parse(). |
* |
* @return A delimited token to be used as a placeholder in |
* the source text, plus any text following the HTML block. |
* |
*/ |
function process(&$matches) |
{ |
$options = array('text' => $matches[1]); |
return $this->wiki->addToken($this->rule, $options) . $matches[2]; |
} |
} |
?> |
/branches/livraison_menes/api/pear/Text/Wiki/Parse/Paragraph.php |
---|
New file |
0,0 → 1,128 |
<?php |
// $Id: Paragraph.php,v 1.1 2005-01-20 19:43:20 jpm Exp $ |
/** |
* |
* This class implements a Text_Wiki rule to find sections of the source |
* text that are paragraphs. A para is any line not starting with a token |
* delimiter, followed by two newlines. |
* |
* @author Paul M. Jones <pmjones@ciaweb.net> |
* |
* @package Text_Wiki |
* |
*/ |
class Text_Wiki_Parse_Paragraph extends Text_Wiki_Parse { |
/** |
* |
* The regular expression used to find source text matching this |
* rule. |
* |
* @access public |
* |
* @var string |
* |
*/ |
var $regex = "/^.*?\n\n/m"; |
var $conf = array( |
'skip' => array( |
'blockquote', // are we sure about this one? |
'code', |
'heading', |
'horiz', |
'deflist', |
'table', |
'list', |
'toc' |
) |
); |
/** |
* |
* Generates a token entry for the matched text. Token options are: |
* |
* 'start' => The starting point of the paragraph. |
* |
* 'end' => The ending point of the paragraph. |
* |
* @access public |
* |
* @param array &$matches The array of matches from parse(). |
* |
* @return A delimited token number to be used as a placeholder in |
* the source text. |
* |
*/ |
function process(&$matches) |
{ |
$delim = $this->wiki->delim; |
// was anything there? |
if (trim($matches[0]) == '') { |
return ''; |
} |
// does the match start with a delimiter? |
if (substr($matches[0], 0, 1) != $delim) { |
// no. |
$start = $this->wiki->addToken( |
$this->rule, array('type' => 'start') |
); |
$end = $this->wiki->addToken( |
$this->rule, array('type' => 'end') |
); |
return $start . trim($matches[0]) . $end; |
} |
// the line starts with a delimiter. read in the delimited |
// token number, check the token, and see if we should |
// skip it. |
// loop starting at the second character (we already know |
// the first is a delimiter) until we find another |
// delimiter; the text between them is a token key number. |
$key = ''; |
$len = strlen($matches[0]); |
for ($i = 1; $i < $len; $i++) { |
$char = $matches[0]{$i}; |
if ($char == $delim) { |
break; |
} else { |
$key .= $char; |
} |
} |
// look at the token and see if it's skippable (if we skip, |
// it will not be marked as a paragraph) |
$token_type = strtolower($this->wiki->tokens[$key][0]); |
$skip = $this->getConf('skip', array()); |
if (in_array($token_type, $skip)) { |
// this type of token should not have paragraphs applied to it. |
// return the entire matched text. |
return $matches[0]; |
} else { |
$start = $this->wiki->addToken( |
$this->rule, array('type' => 'start') |
); |
$end = $this->wiki->addToken( |
$this->rule, array('type' => 'end') |
); |
return $start . trim($matches[0]) . $end; |
} |
} |
} |
?> |
/branches/livraison_menes/api/pear/Text/Wiki/Parse/Italic.php |
---|
New file |
0,0 → 1,67 |
<?php |
// $Id: Italic.php,v 1.1 2005-01-20 19:43:20 jpm Exp $ |
/** |
* |
* This class implements a Text_Wiki_Parse to find source text marked for |
* emphasis (italics) as defined by text surrounded by two single-quotes. |
* On parsing, the text itself is left in place, but the starting and ending |
* instances of two single-quotes are replaced with tokens. |
* |
* @author Paul M. Jones <pmjones@ciaweb.net> |
* |
* @package Text_Wiki |
* |
*/ |
class Text_Wiki_Parse_Italic extends Text_Wiki_Parse { |
/** |
* |
* The regular expression used to parse the source text and find |
* matches conforming to this rule. Used by the parse() method. |
* |
* @access public |
* |
* @var string |
* |
* @see parse() |
* |
*/ |
var $regex = "/''(()|[^'].*)''/U"; |
/** |
* |
* Generates a replacement for the matched text. Token options are: |
* |
* 'type' => ['start'|'end'] The starting or ending point of the |
* emphasized text. The text itself is left in the source. |
* |
* @access public |
* |
* @param array &$matches The array of matches from parse(). |
* |
* @return string A pair of delimited tokens to be used as a |
* placeholder in the source text surrounding the text to be |
* emphasized. |
* |
*/ |
function process(&$matches) |
{ |
$start = $this->wiki->addToken( |
$this->rule, array('type' => 'start') |
); |
$end = $this->wiki->addToken( |
$this->rule, array('type' => 'end') |
); |
return $start . $matches[1] . $end; |
} |
} |
?> |
/branches/livraison_menes/api/pear/Text/Wiki/Parse/Interwiki.php |
---|
New file |
0,0 → 1,120 |
<?php |
// $Id: Interwiki.php,v 1.1 2005-01-20 19:43:20 jpm Exp $ |
/** |
* |
* This class implements a Text_Wiki_Parse to find source text marked as |
* an Interwiki link. See the regex for a detailed explanation of the |
* text matching procedure; e.g., "InterWikiName:PageName". |
* |
* @author Paul M. Jones <pmjones@ciaweb.net> |
* |
* @package Text_Wiki |
* |
*/ |
class Text_Wiki_Parse_Interwiki extends Text_Wiki_Parse { |
var $regex = '([A-Za-z0-9_]+):([\/=&~#A-Za-z0-9_]+)'; |
/** |
* |
* Parser. We override the standard parser so we can |
* find both described interwiki links and standalone links. |
* |
* @access public |
* |
* @return void |
* |
*/ |
function parse() |
{ |
// described interwiki links |
$tmp_regex = '/\[' . $this->regex . ' (.+?)\]/'; |
$this->wiki->source = preg_replace_callback( |
$tmp_regex, |
array(&$this, 'processDescr'), |
$this->wiki->source |
); |
// standalone interwiki links |
$tmp_regex = '/' . $this->regex . '/'; |
$this->wiki->source = preg_replace_callback( |
$tmp_regex, |
array(&$this, 'process'), |
$this->wiki->source |
); |
} |
/** |
* |
* Generates a replacement for the matched standalone interwiki text. |
* Token options are: |
* |
* 'site' => The key name for the Text_Wiki interwiki array map, |
* usually the name of the interwiki site. |
* |
* 'page' => The page on the target interwiki to link to. |
* |
* 'text' => The text to display as the link. |
* |
* @access public |
* |
* @param array &$matches The array of matches from parse(). |
* |
* @return A delimited token to be used as a placeholder in |
* the source text, plus any text priot to the match. |
* |
*/ |
function process(&$matches) |
{ |
$options = array( |
'site' => $matches[1], |
'page' => $matches[2], |
'text' => $matches[0] |
); |
return $this->wiki->addToken($this->rule, $options); |
} |
/** |
* |
* Generates a replacement for described interwiki links. Token |
* options are: |
* |
* 'site' => The key name for the Text_Wiki interwiki array map, |
* usually the name of the interwiki site. |
* |
* 'page' => The page on the target interwiki to link to. |
* |
* 'text' => The text to display as the link. |
* |
* @access public |
* |
* @param array &$matches The array of matches from parse(). |
* |
* @return A delimited token to be used as a placeholder in |
* the source text, plus any text priot to the match. |
* |
*/ |
function processDescr(&$matches) |
{ |
$options = array( |
'site' => $matches[1], |
'page' => $matches[2], |
'text' => $matches[3] |
); |
return $this->wiki->addToken($this->rule, $options); |
} |
} |
?> |
/branches/livraison_menes/api/pear/Text/Wiki/Parse/Blockquote.php |
---|
New file |
0,0 → 1,163 |
<?php |
/** |
* |
* Parse for block-quoted text. |
* |
* Find source text marked as a blockquote, identified by any number of |
* greater-than signs '>' at the start of the line, followed by a space, |
* and then the quote text; each '>' indicates an additional level of |
* quoting. |
* |
* $Id: Blockquote.php,v 1.1 2005-01-20 19:43:20 jpm Exp $ |
* |
* @author Paul M. Jones <pmjones@ciaweb.net> |
* |
* @package Text_Wiki |
* |
*/ |
class Text_Wiki_Parse_Blockquote extends Text_Wiki_Parse { |
/** |
* |
* Regex for parsing the source text. |
* |
* @access public |
* |
* @var string |
* |
* @see parse() |
* |
*/ |
var $regex = '/\n((\>).*\n)(?!(\>))/Us'; |
/** |
* |
* Generates a replacement for the matched text. |
* |
* Token options are: |
* |
* 'type' => |
* 'start' : the start of a blockquote |
* 'end' : the end of a blockquote |
* |
* 'level' => the indent level (0 for the first level, 1 for the |
* second, etc) |
* |
* @access public |
* |
* @param array &$matches The array of matches from parse(). |
* |
* @return A series of text and delimited tokens marking the different |
* list text and list elements. |
* |
*/ |
function process(&$matches) |
{ |
// the replacement text we will return to parse() |
$return = ''; |
// the list of post-processing matches |
$list = array(); |
// $matches[1] is the text matched as a list set by parse(); |
// create an array called $list that contains a new set of |
// matches for the various list-item elements. |
preg_match_all( |
'=^(\>+) (.*\n)=Ums', |
$matches[1], |
$list, |
PREG_SET_ORDER |
); |
// a stack of starts and ends; we keep this so that we know what |
// indent level we're at. |
$stack = array(); |
// loop through each list-item element. |
foreach ($list as $key => $val) { |
// $val[0] is the full matched list-item line |
// $val[1] is the number of initial '>' chars (indent level) |
// $val[2] is the quote text |
// we number levels starting at 1, not zero |
$level = strlen($val[1]); |
// get the text of the line |
$text = $val[2]; |
// add a level to the list? |
while ($level > count($stack)) { |
// the current indent level is greater than the number |
// of stack elements, so we must be starting a new |
// level. push the new level onto the stack with a |
// dummy value (boolean true)... |
array_push($stack, true); |
$return .= "\n"; |
// ...and add a start token to the return. |
$return .= $this->wiki->addToken( |
$this->rule, |
array( |
'type' => 'start', |
'level' => $level - 1 |
) |
); |
$return .= "\n\n"; |
} |
// remove a level? |
while (count($stack) > $level) { |
// as long as the stack count is greater than the |
// current indent level, we need to end list types. |
// continue adding end-list tokens until the stack count |
// and the indent level are the same. |
array_pop($stack); |
$return .= "\n\n"; |
$return .= $this->wiki->addToken( |
$this->rule, |
array ( |
'type' => 'end', |
'level' => count($stack) |
) |
); |
$return .= "\n"; |
} |
// add the line text. |
$return .= $text; |
} |
// the last line may have been indented. go through the stack |
// and create end-tokens until the stack is empty. |
$return .= "\n"; |
while (count($stack) > 0) { |
array_pop($stack); |
$return .= $this->wiki->addToken( |
$this->rule, |
array ( |
'type' => 'end', |
'level' => count($stack) |
) |
); |
} |
// we're done! send back the replacement text. |
return "\n$return\n\n"; |
} |
} |
?> |
/branches/livraison_menes/api/pear/Text/Wiki/Parse/Anchor.php |
---|
New file |
0,0 → 1,67 |
<?php |
/** |
* |
* This class implements a Text_Wiki_Parse to add an anchor target name |
* in the wiki page. |
* |
* @author Manuel Holtgrewe <purestorm at ggnore dot net> |
* |
* @author Paul M. Jones <pmjones at ciaweb dot net> |
* |
* @package Text_Wiki |
* |
*/ |
class Text_Wiki_Parse_Anchor extends Text_Wiki_Parse { |
/** |
* |
* The regular expression used to find source text matching this |
* rule. |
* |
* @access public |
* |
* @var string |
* |
*/ |
var $regex = '/(\[\[# )([-_A-Za-z0-9.]+?)( .+)?(\]\])/i'; |
/** |
* |
* Generates a token entry for the matched text. Token options are: |
* |
* 'text' => The full matched text, not including the <code></code> tags. |
* |
* @access public |
* |
* @param array &$matches The array of matches from parse(). |
* |
* @return A delimited token number to be used as a placeholder in |
* the source text. |
* |
*/ |
function process(&$matches) { |
$name = $matches[2]; |
$text = $matches[3]; |
$start = $this->wiki->addToken( |
$this->rule, |
array('type' => 'start', 'name' => $name) |
); |
$end = $this->wiki->addToken( |
$this->rule, |
array('type' => 'end', 'name' => $name) |
); |
// done, place the script output directly in the source |
return $start . trim($text) . $end; |
} |
} |
?> |
/branches/livraison_menes/api/pear/Text/Wiki/Parse/List.php |
---|
New file |
0,0 → 1,230 |
<?php |
// $Id: List.php,v 1.1 2005-01-20 19:43:20 jpm Exp $ |
/** |
* |
* This class implements a Text_Wiki_Parse to find source text marked as |
* a bulleted or numbered list. In short, if a line starts with '* ' then |
* it is a bullet list item; if a line starts with '# ' then it is a |
* number list item. Spaces in front of the * or # indicate an indented |
* sub-list. The list items must be on sequential lines, and may be |
* separated by blank lines to improve readability. Using a non-* non-# |
* non-whitespace character at the beginning of a line ends the list. |
* |
* @author Paul M. Jones <pmjones@ciaweb.net> |
* |
* @package Text_Wiki |
* |
*/ |
class Text_Wiki_Parse_List extends Text_Wiki_Parse { |
/** |
* |
* The regular expression used to parse the source text and find |
* matches conforming to this rule. Used by the parse() method. |
* |
* @access public |
* |
* @var string |
* |
* @see parse() |
* |
*/ |
var $regex = '/\n((\*|#) .*\n)(?! {0,}(\* |# |\n))/Us'; |
/** |
* |
* Generates a replacement for the matched text. Token options are: |
* |
* 'type' => |
* 'bullet_start' : the start of a bullet list |
* 'bullet_end' : the end of a bullet list |
* 'number_start' : the start of a number list |
* 'number_end' : the end of a number list |
* 'item_start' : the start of item text (bullet or number) |
* 'item_end' : the end of item text (bullet or number) |
* 'unknown' : unknown type of list or item |
* |
* 'level' => the indent level (0 for the first level, 1 for the |
* second, etc) |
* |
* 'count' => the list item number at this level. not needed for |
* xhtml, but very useful for PDF and RTF. |
* |
* @access public |
* |
* @param array &$matches The array of matches from parse(). |
* |
* @return A series of text and delimited tokens marking the different |
* list text and list elements. |
* |
*/ |
function process(&$matches) |
{ |
// the replacement text we will return |
$return = ''; |
// the list of post-processing matches |
$list = array(); |
// a stack of list-start and list-end types; we keep this |
// so that we know what kind of list we're working with |
// (bullet or number) and what indent level we're at. |
$stack = array(); |
// the item count is the number of list items for any |
// given list-type on the stack |
$itemcount = array(); |
// have we processed the very first list item? |
$pastFirst = false; |
// populate $list with this set of matches. $matches[1] is the |
// text matched as a list set by parse(). |
preg_match_all( |
'=^( {0,})(\*|#) (.*)$=Ums', |
$matches[1], |
$list, |
PREG_SET_ORDER |
); |
// loop through each list-item element. |
foreach ($list as $key => $val) { |
// $val[0] is the full matched list-item line |
// $val[1] is the number of initial spaces (indent level) |
// $val[2] is the list item type (* or #) |
// $val[3] is the list item text |
// how many levels are we indented? (1 means the "root" |
// list level, no indenting.) |
$level = strlen($val[1]) + 1; |
// get the list item type |
if ($val[2] == '*') { |
$type = 'bullet'; |
} elseif ($val[2] == '#') { |
$type = 'number'; |
} else { |
$type = 'unknown'; |
} |
// get the text of the list item |
$text = $val[3]; |
// add a level to the list? |
if ($level > count($stack)) { |
// the current indent level is greater than the |
// number of stack elements, so we must be starting |
// a new list. push the new list type onto the |
// stack... |
array_push($stack, $type); |
// ...and add a list-start token to the return. |
$return .= $this->wiki->addToken( |
$this->rule, |
array( |
'type' => $type . '_list_start', |
'level' => $level - 1 |
) |
); |
} |
// remove a level from the list? |
while (count($stack) > $level) { |
// so we don't keep counting the stack, we set up a temp |
// var for the count. -1 becuase we're going to pop the |
// stack in the next command. $tmp will then equal the |
// current level of indent. |
$tmp = count($stack) - 1; |
// as long as the stack count is greater than the |
// current indent level, we need to end list types. |
// continue adding end-list tokens until the stack count |
// and the indent level are the same. |
$return .= $this->wiki->addToken( |
$this->rule, |
array ( |
'type' => array_pop($stack) . '_list_end', |
'level' => $tmp |
) |
); |
// reset to the current (previous) list type so that |
// the new list item matches the proper list type. |
$type = $stack[$tmp - 1]; |
// reset the item count for the popped indent level |
unset($itemcount[$tmp + 1]); |
} |
// add to the item count for this list (taking into account |
// which level we are at). |
if (! isset($itemcount[$level])) { |
// first count |
$itemcount[$level] = 0; |
} else { |
// increment count |
$itemcount[$level]++; |
} |
// is this the very first item in the list? |
if (! $pastFirst) { |
$first = true; |
$pastFirst = true; |
} else { |
$first = false; |
} |
// create a list-item starting token. |
$start = $this->wiki->addToken( |
$this->rule, |
array( |
'type' => $type . '_item_start', |
'level' => $level, |
'count' => $itemcount[$level], |
'first' => $first |
) |
); |
// create a list-item ending token. |
$end = $this->wiki->addToken( |
$this->rule, |
array( |
'type' => $type . '_item_end', |
'level' => $level, |
'count' => $itemcount[$level] |
) |
); |
// add the starting token, list-item text, and ending token |
// to the return. |
$return .= $start . $val[3] . $end; |
} |
// the last list-item may have been indented. go through the |
// list-type stack and create end-list tokens until the stack |
// is empty. |
while (count($stack) > 0) { |
$return .= $this->wiki->addToken( |
$this->rule, |
array ( |
'type' => array_pop($stack) . '_list_end', |
'level' => count($stack) |
) |
); |
} |
// we're done! send back the replacement text. |
return "\n" . $return . "\n\n"; |
} |
} |
?> |
/branches/livraison_menes/api/pear/Text/Wiki/Parse/Embed.php |
---|
New file |
0,0 → 1,88 |
<?php |
// $Id: Embed.php,v 1.1 2005-01-20 19:43:20 jpm Exp $ |
/** |
* |
* This class implements a Text_Wiki_Parse to embed the contents of a URL |
* inside the page at render-time. Typically used to get script output. |
* This differs from the 'include' rule, which incorporates results at |
* parse-time; 'embed' output does not get parsed by Text_Wiki, while |
* 'include' ouput does. |
* |
* This rule is inherently not secure; it allows cross-site scripting to |
* occur if the embedded output has <script> or other similar tags. Be |
* careful. |
* |
* @author Paul M. Jones <pmjones@ciaweb.net> |
* |
* @package Text_Wiki |
* |
*/ |
class Text_Wiki_Parse_Embed extends Text_Wiki_Parse { |
var $conf = array( |
'base' => '/path/to/scripts/' |
); |
var $file = null; |
var $output = null; |
var $vars = null; |
/** |
* |
* The regular expression used to find source text matching this |
* rule. |
* |
* @access public |
* |
* @var string |
* |
*/ |
var $regex = '/(\[\[embed )(.+?)( .+?)?(\]\])/i'; |
/** |
* |
* Generates a token entry for the matched text. Token options are: |
* |
* 'text' => The full matched text, not including the <code></code> tags. |
* |
* @access public |
* |
* @param array &$matches The array of matches from parse(). |
* |
* @return A delimited token number to be used as a placeholder in |
* the source text. |
* |
*/ |
function process(&$matches) |
{ |
// save the file location |
$this->file = $this->getConf('base', './') . $matches[2]; |
// extract attribs as variables in the local space |
$this->vars = $this->getAttrs($matches[3]); |
unset($this->vars['this']); |
extract($this->vars); |
// run the script |
ob_start(); |
include($this->file); |
$this->output = ob_get_contents(); |
ob_end_clean(); |
// done, place the script output directly in the source |
return $this->wiki->addToken( |
$this->rule, |
array('text' => $this->output) |
); |
} |
} |
?> |
/branches/livraison_menes/api/pear/Text/Wiki/Parse/Delimiter.php |
---|
New file |
0,0 → 1,62 |
<?php |
// $Id: Delimiter.php,v 1.1 2005-01-20 19:43:20 jpm Exp $ |
/** |
* |
* This class implements a Text_Wiki_Parse to find instances of the delimiter |
* character already embedded in the source text; it extracts them and replaces |
* them with a delimited token, then renders them as the delimiter itself |
* when the target format is XHTML. |
* |
* @author Paul M. Jones <pmjones@ciaweb.net> |
* |
* @package Text_Wiki |
* |
*/ |
class Text_Wiki_Parse_Delimiter extends Text_Wiki_Parse { |
/** |
* |
* Constructor. Overrides the Text_Wiki_Parse constructor so that we |
* can set the $regex property dynamically (we need to include the |
* Text_Wiki $delim character. |
* |
* @param object &$obj The calling "parent" Text_Wiki object. |
* |
* @param string $name The token name to use for this rule. |
* |
*/ |
function Text_Wiki_Parse_delimiter(&$obj) |
{ |
parent::Text_Wiki_Parse($obj); |
$this->regex = '/' . $this->wiki->delim . '/'; |
} |
/** |
* |
* Generates a token entry for the matched text. Token options are: |
* |
* 'text' => The full matched text. |
* |
* @access public |
* |
* @param array &$matches The array of matches from parse(). |
* |
* @return A delimited token number to be used as a placeholder in |
* the source text. |
* |
*/ |
function process(&$matches) |
{ |
return $this->wiki->addToken( |
$this->rule, |
array('text' => $this->wiki->delim) |
); |
} |
} |
?> |
/branches/livraison_menes/api/pear/Text/Wiki/Parse/Bold.php |
---|
New file |
0,0 → 1,61 |
<?php |
// $Id: Bold.php,v 1.1 2005-01-20 19:43:20 jpm Exp $ |
/** |
* |
* This class implements a Text_Wiki_Rule to find source text marked for |
* strong emphasis (bold) as defined by text surrounded by three |
* single-quotes. On parsing, the text itself is left in place, but the |
* starting and ending instances of three single-quotes are replaced with |
* tokens. |
* |
* @author Paul M. Jones <pmjones@ciaweb.net> |
* |
* @package Text_Wiki |
* |
*/ |
class Text_Wiki_Parse_Bold extends Text_Wiki_Parse { |
/** |
* |
* The regular expression used to parse the source text and find |
* matches conforming to this rule. Used by the parse() method. |
* |
* @access public |
* |
* @var string |
* |
* @see parse() |
* |
*/ |
var $regex = "/'''(()|[^'].*)'''/U"; |
/** |
* |
* Generates a replacement for the matched text. Token options are: |
* |
* 'type' => ['start'|'end'] The starting or ending point of the |
* emphasized text. The text itself is left in the source. |
* |
* @access public |
* |
* @param array &$matches The array of matches from parse(). |
* |
* @return A pair of delimited tokens to be used as a placeholder in |
* the source text surrounding the text to be emphasized. |
* |
*/ |
function process(&$matches) |
{ |
$start = $this->wiki->addToken($this->rule, array('type' => 'start')); |
$end = $this->wiki->addToken($this->rule, array('type' => 'end')); |
return $start . $matches[1] . $end; |
} |
} |
?> |
/branches/livraison_menes/api/pear/Text/Wiki/Parse/Wikilink.php |
---|
New file |
0,0 → 1,158 |
<?php |
/** |
* |
* Parse for links to wiki pages. |
* |
* Wiki page names are typically in StudlyCapsStyle made of |
* WordsSmashedTogether. |
* |
* You can also create described links to pages in this style: |
* [WikiPageName nice text link to use for display] |
* |
* The token options for this rule are: |
* |
* 'page' => the wiki page name. |
* |
* 'text' => the displayed link text. |
* |
* 'anchor' => a named anchor on the target wiki page. |
* |
* $Id: Wikilink.php,v 1.1 2005-01-20 19:43:20 jpm Exp $ |
* |
* @author Paul M. Jones <pmjones@ciaweb.net> |
* |
* @package Text_Wiki |
* |
*/ |
class Text_Wiki_Parse_Wikilink extends Text_Wiki_Parse { |
/** |
* |
* Constructor. |
* |
* We override the Text_Wiki_Parse constructor so we can |
* explicitly comment each part of the $regex property. |
* |
* @access public |
* |
* @param object &$obj The calling "parent" Text_Wiki object. |
* |
*/ |
function Text_Wiki_Parse_Wikilink(&$obj) |
{ |
parent::Text_Wiki_Parse($obj); |
// allows numbers as "lowercase letters" in the regex |
$this->regex = |
"(!?" . // START WikiPage pattern (1) |
"[A-Z]" . // 1 upper |
"[A-Za-z0-9]*" . // 0+ alpha or digit |
"[a-z0-9]+" . // 1+ lower or digit |
"[A-Z]" . // 1 upper |
"[A-Za-z0-9]*" . // 0+ or more alpha or digit |
")" . // END WikiPage pattern (/1) |
"((\#" . // START Anchor pattern (2)(3) |
"[A-Za-z]" . // 1 alpha |
"(" . // start sub pattern (4) |
"[-A-Za-z0-9_:.]*" . // 0+ dash, alpha, digit, underscore, colon, dot |
"[-A-Za-z0-9_]" . // 1 dash, alpha, digit, or underscore |
")?)?)"; // end subpatterns (/4)(/3)(/2) |
} |
/** |
* |
* First parses for described links, then for standalone links. |
* |
* @access public |
* |
* @return void |
* |
*/ |
function parse() |
{ |
// described wiki links |
$tmp_regex = '/\[' . $this->regex . ' (.+?)\]/'; |
$this->wiki->source = preg_replace_callback( |
$tmp_regex, |
array(&$this, 'processDescr'), |
$this->wiki->source |
); |
// standalone wiki links |
$tmp_regex = '/(^|[^A-Za-z0-9\-_])' . $this->regex . '/'; |
$this->wiki->source = preg_replace_callback( |
$tmp_regex, |
array(&$this, 'process'), |
$this->wiki->source |
); |
} |
/** |
* |
* Generate a replacement for described links. |
* |
* @access public |
* |
* @param array &$matches The array of matches from parse(). |
* |
* @return A delimited token to be used as a placeholder in |
* the source text, plus any text priot to the match. |
* |
*/ |
function processDescr(&$matches) |
{ |
// set the options |
$options = array( |
'page' => $matches[1], |
'text' => $matches[5], |
'anchor' => $matches[3] |
); |
// create and return the replacement token and preceding text |
return $this->wiki->addToken($this->rule, $options); // . $matches[7]; |
} |
/** |
* |
* Generate a replacement for standalone links. |
* |
* |
* @access public |
* |
* @param array &$matches The array of matches from parse(). |
* |
* @return A delimited token to be used as a placeholder in |
* the source text, plus any text prior to the match. |
* |
*/ |
function process(&$matches) |
{ |
// when prefixed with !, it's explicitly not a wiki link. |
// return everything as it was. |
if ($matches[2]{0} == '!') { |
return $matches[1] . substr($matches[2], 1) . $matches[3]; |
} |
// set the options |
$options = array( |
'page' => $matches[2], |
'text' => $matches[2] . $matches[3], |
'anchor' => $matches[3] |
); |
// create and return the replacement token and preceding text |
return $matches[1] . $this->wiki->addToken($this->rule, $options); |
} |
} |
?> |
/branches/livraison_menes/api/pear/Text/Wiki/Parse/Image.php |
---|
New file |
0,0 → 1,76 |
<?php |
// $Id: Image.php,v 1.1 2005-01-20 19:43:20 jpm Exp $ |
/** |
* |
* This class implements a Text_Wiki_Parse to embed the contents of a URL |
* inside the page. Typically used to get script output. |
* |
* This rule is inherently not secure; it allows cross-site scripting to |
* occur if the embedded output has <script> or other similar tags. Be |
* careful. |
* |
* In the future, we'll add a rule config options to set the base embed |
* path so that it is limited to one directory. |
* |
* @author Paul M. Jones <pmjones@ciaweb.net> |
* |
* @package Text_Wiki |
* |
*/ |
class Text_Wiki_Parse_Image extends Text_Wiki_Parse { |
/** |
* |
* The regular expression used to find source text matching this |
* rule. |
* |
* @access public |
* |
* @var string |
* |
*/ |
var $regex = '/(\[\[image )(.+?)(\]\])/i'; |
/** |
* |
* Generates a token entry for the matched text. Token options are: |
* |
* 'src' => The image source, typically a relative path name. |
* |
* 'opts' => Any macro options following the source. |
* |
* @access public |
* |
* @param array &$matches The array of matches from parse(). |
* |
* @return A delimited token number to be used as a placeholder in |
* the source text. |
* |
*/ |
function process(&$matches) |
{ |
$pos = strpos($matches[2], ' '); |
if ($pos === false) { |
$options = array( |
'src' => $matches[2], |
'attr' => array()); |
} else { |
// everything after the space is attribute arguments |
$options = array( |
'src' => substr($matches[2], 0, $pos), |
'attr' => $this->getAttrs(substr($matches[2], $pos+1)) |
); |
} |
return $this->wiki->addToken($this->rule, $options); |
} |
} |
?> |
/branches/livraison_menes/api/pear/Text/Wiki/Parse/Tt.php |
---|
New file |
0,0 → 1,69 |
<?php |
/** |
* |
* Find source text marked for teletype (monospace). |
* |
* Defined by text surrounded by two curly braces. On parsing, the text |
* itself is left in place, but the starting and ending instances of |
* curly braces are replaced with tokens. |
* |
* Token options are: |
* |
* 'type' => ['start'|'end'] The starting or ending point of the |
* teletype text. The text itself is left in the source. |
* |
* |
* $Id: Tt.php,v 1.1 2005-01-20 19:43:20 jpm Exp $ |
* |
* @author Paul M. Jones <pmjones@ciaweb.net> |
* |
* @package Text_Wiki |
* |
*/ |
class Text_Wiki_Parse_Tt extends Text_Wiki_Parse { |
/** |
* |
* The regular expression used to parse the source text. |
* |
* @access public |
* |
* @var string |
* |
* @see parse() |
* |
*/ |
var $regex = "/{{({*?.*}*?)}}/U"; |
/** |
* |
* Generates a replacement for the matched text. |
* |
* @access public |
* |
* @param array &$matches The array of matches from parse(). |
* |
* @return string A pair of delimited tokens to be used as a |
* placeholder in the source text surrounding the teletype text. |
* |
*/ |
function process(&$matches) |
{ |
$start = $this->wiki->addToken( |
$this->rule, array('type' => 'start') |
); |
$end = $this->wiki->addToken( |
$this->rule, array('type' => 'end') |
); |
return $start . $matches[1] . $end; |
} |
} |
?> |
/branches/livraison_menes/api/pear/Text/Wiki/Parse/Revise.php |
---|
New file |
0,0 → 1,130 |
<?php |
// $Id: Revise.php,v 1.1 2005-01-20 19:43:20 jpm Exp $ |
/** |
* |
* This class implements a Text_Wiki_Parse to find source text marked for |
* revision. |
* |
* @author Paul M. Jones <pmjones@ciaweb.net> |
* |
* @package Text_Wiki |
* |
*/ |
class Text_Wiki_Parse_Revise extends Text_Wiki_Parse { |
/** |
* |
* The regular expression used to parse the source text and find |
* matches conforming to this rule. Used by the parse() method. |
* |
* @access public |
* |
* @var string |
* |
* @see parse() |
* |
*/ |
var $regex = "/\@\@({*?.*}*?)\@\@/U"; |
/** |
* |
* Config options. |
* |
* @access public |
* |
* @var array |
* |
*/ |
var $conf = array( |
'delmark' => '---', |
'insmark' => '+++' |
); |
/** |
* |
* Generates a replacement for the matched text. Token options are: |
* |
* 'type' => ['start'|'end'] The starting or ending point of the |
* inserted text. The text itself is left in the source. |
* |
* @access public |
* |
* @param array &$matches The array of matches from parse(). |
* |
* @return string A pair of delimited tokens to be used as a |
* placeholder in the source text surrounding the teletype text. |
* |
*/ |
function process(&$matches) |
{ |
$output = ''; |
$src = $matches[1]; |
$delmark = $this->getConf('delmark'); // --- |
$insmark = $this->getConf('insmark'); // +++ |
// '---' must be before '+++' (if they both appear) |
$del = strpos($src, $delmark); |
$ins = strpos($src, $insmark); |
// if neither is found, return right away |
if ($del === false && $ins === false) { |
return $matches[0]; |
} |
// handle text to be deleted |
if ($del !== false) { |
// move forward to the end of the deletion mark |
$del += strlen($delmark); |
if ($ins === false) { |
// there is no insertion text following |
$text = substr($src, $del); |
} else { |
// there is insertion text following, |
// mitigate the length |
$text = substr($src, $del, $ins - $del); |
} |
$output .= $this->wiki->addToken( |
$this->rule, array('type' => 'del_start') |
); |
$output .= $text; |
$output .= $this->wiki->addToken( |
$this->rule, array('type' => 'del_end') |
); |
} |
// handle text to be inserted |
if ($ins !== false) { |
// move forward to the end of the insert mark |
$ins += strlen($insmark); |
$text = substr($src, $ins); |
$output .= $this->wiki->addToken( |
$this->rule, array('type' => 'ins_start') |
); |
$output .= $text; |
$output .= $this->wiki->addToken( |
$this->rule, array('type' => 'ins_end') |
); |
} |
return $output; |
} |
} |
?> |
/branches/livraison_menes/api/pear/Text/Wiki/Parse/Freelink.php |
---|
New file |
0,0 → 1,111 |
<?php |
// $Id: Freelink.php,v 1.1 2005-01-20 19:43:20 jpm Exp $ |
/** |
* |
* This class implements a Text_Wiki_Parse to find source text marked as a |
* wiki freelink, and automatically create a link to that page. |
* |
* A freelink is any page name not conforming to the standard |
* StudlyCapsStyle for a wiki page name. For example, a page normally |
* named MyHomePage can be renamed and referred to as ((My Home Page)) -- |
* note the spaces in the page name. You can also make a "nice-looking" |
* link without renaming the target page; e.g., ((MyHomePage|My Home |
* Page)). Finally, you can use named anchors on the target page: |
* ((MyHomePage|My Home Page#Section1)). |
* |
* @author Paul M. Jones <pmjones@ciaweb.net> |
* |
* @package Text_Wiki |
* |
*/ |
class Text_Wiki_Parse_Freelink extends Text_Wiki_Parse { |
/** |
* |
* Constructor. We override the Text_Wiki_Parse constructor so we can |
* explicitly comment each part of the $regex property. |
* |
* @access public |
* |
* @param object &$obj The calling "parent" Text_Wiki object. |
* |
*/ |
function Text_Wiki_Parse_Freelink(&$obj) |
{ |
parent::Text_Wiki_Parse($obj); |
$this->regex = |
'/' . // START regex |
"\\(\\(" . // double open-parens |
"(" . // START freelink page patter |
"[-A-Za-z0-9 _+\\/.,;:!?'\"\\[\\]\\{\\}&\xc0-\xff]+" . // 1 or more of just about any character |
")" . // END freelink page pattern |
"(" . // START display-name |
"\|" . // a pipe to start the display name |
"[-A-Za-z0-9 _+\\/.,;:!?'\"\\[\\]\\{\\}&\xc0-\xff]+" . // 1 or more of just about any character |
")?" . // END display-name pattern 0 or 1 |
"(" . // START pattern for named anchors |
"\#" . // a hash mark |
"[A-Za-z]" . // 1 alpha |
"[-A-Za-z0-9_:.]*" . // 0 or more alpha, digit, underscore |
")?" . // END named anchors pattern 0 or 1 |
"()\\)\\)" . // double close-parens |
'/'; // END regex |
} |
/** |
* |
* Generates a replacement for the matched text. Token options are: |
* |
* 'page' => the wiki page name (e.g., HomePage). |
* |
* 'text' => alternative text to be displayed in place of the wiki |
* page name. |
* |
* 'anchor' => a named anchor on the target wiki page |
* |
* @access public |
* |
* @param array &$matches The array of matches from parse(). |
* |
* @return A delimited token to be used as a placeholder in |
* the source text, plus any text priot to the match. |
* |
*/ |
function process(&$matches) |
{ |
// use nice variable names |
$page = $matches[1]; |
$text = $matches[2]; |
// get rid of the leading # from the anchor, if any |
$anchor = substr($matches[3], 1); |
// is the page given a new text appearance? |
if (trim($text) == '') { |
// no |
$text = $page; |
} else { |
// yes, strip the leading | character |
$text = substr($text, 1); |
} |
// set the options |
$options = array( |
'page' => $page, |
'text' => $text, |
'anchor' => $anchor |
); |
// return a token placeholder |
return $this->wiki->addToken($this->rule, $options); |
} |
} |
?> |
/branches/livraison_menes/api/pear/Text/Wiki/Parse/Newline.php |
---|
New file |
0,0 → 1,57 |
<?php |
// $Id: Newline.php,v 1.1 2005-01-20 19:43:20 jpm Exp $ |
/** |
* |
* This class implements a Text_Wiki_Parse to mark implied line breaks in the |
* source text, usually a single carriage return in the middle of a paragraph |
* or block-quoted text. |
* |
* @author Paul M. Jones <pmjones@ciaweb.net> |
* |
* @package Text_Wiki |
* |
*/ |
class Text_Wiki_Parse_Newline extends Text_Wiki_Parse { |
/** |
* |
* The regular expression used to parse the source text and find |
* matches conforming to this rule. Used by the parse() method. |
* |
* @access public |
* |
* @var string |
* |
* @see parse() |
* |
*/ |
var $regex = '/([^\n])\n([^\n])/m'; |
/** |
* |
* Generates a replacement token for the matched text. |
* |
* @access public |
* |
* @param array &$matches The array of matches from parse(). |
* |
* @return string A delimited token to be used as a placeholder in |
* the source text. |
* |
*/ |
function process(&$matches) |
{ |
return $matches[1] . |
$this->wiki->addToken($this->rule) . |
$matches[2]; |
} |
} |
?> |
/branches/livraison_menes/api/pear/Text/Wiki/Parse/Url.php |
---|
New file |
0,0 → 1,265 |
<?php |
/** |
* |
* Parse for URLS in the source text. |
* |
* Various URL markings are supported: inline (the URL by itself), |
* numbered or footnote reference (where the URL is enclosed in square brackets), and |
* named reference (where the URL is enclosed in square brackets and has a |
* name included inside the brackets). E.g.: |
* |
* inline -- http://example.com |
* numbered -- [http://example.com] |
* described -- [http://example.com Example Description] |
* |
* When rendering a URL token, this will convert URLs pointing to a .gif, |
* .jpg, or .png image into an inline <img /> tag (for the 'xhtml' |
* format). |
* |
* Token options are: |
* |
* 'type' => ['inline'|'footnote'|'descr'] the type of URL |
* |
* 'href' => the URL link href portion |
* |
* 'text' => the displayed text of the URL link |
* |
* $Id: Url.php,v 1.1 2005-01-20 19:43:20 jpm Exp $ |
* |
* @author Paul M. Jones <pmjones@ciaweb.net> |
* |
* @package Text_Wiki |
* |
*/ |
class Text_Wiki_Parse_Url extends Text_Wiki_Parse { |
/** |
* |
* Keeps a running count of numbered-reference URLs. |
* |
* @access public |
* |
* @var int |
* |
*/ |
var $footnoteCount = 0; |
/** |
* |
* URL schemes recognized by this rule. |
* |
* @access public |
* |
* @var array |
* |
*/ |
var $conf = array( |
'schemes' => array( |
'http://', |
'https://', |
'ftp://', |
'gopher://', |
'news://', |
'mailto:' |
) |
); |
/** |
* |
* Constructor. |
* |
* We override the constructor so we can comment the regex nicely. |
* |
* @access public |
* |
*/ |
function Text_Wiki_Parse_Url(&$obj) |
{ |
parent::Text_Wiki_Parse($obj); |
// convert the list of recognized schemes to a regex-safe string, |
// where the pattern delim is a slash |
$tmp = array(); |
$list = $this->getConf('schemes', array()); |
foreach ($list as $val) { |
$tmp[] = preg_quote($val, '/'); |
} |
$schemes = implode('|', $tmp); |
// build the regex |
$this->regex = |
"($schemes)" . // allowed schemes |
"(" . // start pattern |
"[^ \\/\"\'{$this->wiki->delim}]*\\/" . // no spaces, backslashes, slashes, double-quotes, single quotes, or delimiters; |
")*" . // end pattern |
"[^ \\t\\n\\/\"\'{$this->wiki->delim}]*" . |
"[A-Za-z0-9\\/?=&~_]"; |
} |
/** |
* |
* Find three different kinds of URLs in the source text. |
* |
* @access public |
* |
*/ |
function parse() |
{ |
// ------------------------------------------------------------- |
// |
// Described-reference (named) URLs. |
// |
// the regular expression for this kind of URL |
$tmp_regex = '/\[(' . $this->regex . ') ([^\]]+)\]/'; |
// use a custom callback processing method to generate |
// the replacement text for matches. |
$this->wiki->source = preg_replace_callback( |
$tmp_regex, |
array(&$this, 'processDescr'), |
$this->wiki->source |
); |
// ------------------------------------------------------------- |
// |
// Numbered-reference (footnote-style) URLs. |
// |
// the regular expression for this kind of URL |
$tmp_regex = '/\[(' . $this->regex . ')\]/U'; |
// use a custom callback processing method to generate |
// the replacement text for matches. |
$this->wiki->source = preg_replace_callback( |
$tmp_regex, |
array(&$this, 'processFootnote'), |
$this->wiki->source |
); |
// ------------------------------------------------------------- |
// |
// Normal inline URLs. |
// |
// the regular expression for this kind of URL |
$tmp_regex = '/(^|[^A-Za-z])(' . $this->regex . ')(.*?)/'; |
// use the standard callback for inline URLs |
$this->wiki->source = preg_replace_callback( |
$tmp_regex, |
array(&$this, 'process'), |
$this->wiki->source |
); |
} |
/** |
* |
* Process inline URLs. |
* |
* @param array &$matches |
* |
* @param array $matches An array of matches from the parse() method |
* as generated by preg_replace_callback. $matches[0] is the full |
* matched string, $matches[1] is the first matched pattern, |
* $matches[2] is the second matched pattern, and so on. |
* |
* @return string The processed text replacement. |
* |
*/ |
function process(&$matches) |
{ |
// set options |
$options = array( |
'type' => 'inline', |
'href' => $matches[2], |
'text' => $matches[2] |
); |
// tokenize |
return $matches[1] . $this->wiki->addToken($this->rule, $options) . $matches[5]; |
} |
/** |
* |
* Process numbered (footnote) URLs. |
* |
* Token options are: |
* @param array &$matches |
* |
* @param array $matches An array of matches from the parse() method |
* as generated by preg_replace_callback. $matches[0] is the full |
* matched string, $matches[1] is the first matched pattern, |
* $matches[2] is the second matched pattern, and so on. |
* |
* @return string The processed text replacement. |
* |
*/ |
function processFootnote(&$matches) |
{ |
// keep a running count for footnotes |
$this->footnoteCount++; |
// set options |
$options = array( |
'type' => 'footnote', |
'href' => $matches[1], |
'text' => $this->footnoteCount |
); |
// tokenize |
return $this->wiki->addToken($this->rule, $options); |
} |
/** |
* |
* Process described-reference (named-reference) URLs. |
* |
* Token options are: |
* 'type' => ['inline'|'footnote'|'descr'] the type of URL |
* 'href' => the URL link href portion |
* 'text' => the displayed text of the URL link |
* |
* @param array &$matches |
* |
* @param array $matches An array of matches from the parse() method |
* as generated by preg_replace_callback. $matches[0] is the full |
* matched string, $matches[1] is the first matched pattern, |
* $matches[2] is the second matched pattern, and so on. |
* |
* @return string The processed text replacement. |
* |
*/ |
function processDescr(&$matches) |
{ |
// set options |
$options = array( |
'type' => 'descr', |
'href' => $matches[1], |
'text' => $matches[4] |
); |
// tokenize |
return $this->wiki->addToken($this->rule, $options); |
} |
} |
?> |
/branches/livraison_menes/api/pear/Text/Wiki/Parse/Emphasis.php |
---|
New file |
0,0 → 1,67 |
<?php |
// $Id: Emphasis.php,v 1.1 2005-01-20 19:43:20 jpm Exp $ |
/** |
* |
* This class implements a Text_Wiki_Parse to find source text marked for |
* emphasis (italics) as defined by text surrounded by two single-quotes. |
* On parsing, the text itself is left in place, but the starting and ending |
* instances of two single-quotes are replaced with tokens. |
* |
* @author Paul M. Jones <pmjones@ciaweb.net> |
* |
* @package Text_Wiki |
* |
*/ |
class Text_Wiki_Parse_emphasis extends Text_Wiki_Parse { |
/** |
* |
* The regular expression used to parse the source text and find |
* matches conforming to this rule. Used by the parse() method. |
* |
* @access public |
* |
* @var string |
* |
* @see parse() |
* |
*/ |
var $regex = "/\/\/(()|.*)\/\//U"; |
/** |
* |
* Generates a replacement for the matched text. Token options are: |
* |
* 'type' => ['start'|'end'] The starting or ending point of the |
* emphasized text. The text itself is left in the source. |
* |
* @access public |
* |
* @param array &$matches The array of matches from parse(). |
* |
* @return string A pair of delimited tokens to be used as a |
* placeholder in the source text surrounding the text to be |
* emphasized. |
* |
*/ |
function process(&$matches) |
{ |
$start = $this->wiki->addToken( |
$this->rule, array('type' => 'start') |
); |
$end = $this->wiki->addToken( |
$this->rule, array('type' => 'end') |
); |
return $start . $matches[1] . $end; |
} |
} |
?> |
/branches/livraison_menes/api/pear/Text/Wiki/Parse/Code.php |
---|
New file |
0,0 → 1,72 |
<?php |
// $Id: Code.php,v 1.1 2005-01-20 19:43:20 jpm Exp $ |
/** |
* |
* This class implements a Text_Wiki_Parse to find sections marked as code |
* examples. Blocks are marked as the string <code> on a line by itself, |
* followed by the inline code example, and terminated with the string |
* </code> on a line by itself. The code example is run through the |
* native PHP highlight_string() function to colorize it, then surrounded |
* with <pre>...</pre> tags when rendered as XHTML. |
* |
* @author Paul M. Jones <pmjones@ciaweb.net> |
* |
* @package Text_Wiki |
* |
*/ |
class Text_Wiki_Parse_Code extends Text_Wiki_Parse { |
/** |
* |
* The regular expression used to find source text matching this |
* rule. |
* |
* @access public |
* |
* @var string |
* |
*/ |
var $regex = '/^(\<code( .+)?\>)\n(.+)\n(\<\/code\>)(\s|$)/Umsi'; |
/** |
* |
* Generates a token entry for the matched text. Token options are: |
* |
* 'text' => The full matched text, not including the <code></code> tags. |
* |
* @access public |
* |
* @param array &$matches The array of matches from parse(). |
* |
* @return A delimited token number to be used as a placeholder in |
* the source text. |
* |
*/ |
function process(&$matches) |
{ |
// are there additional attribute arguments? |
$args = trim($matches[2]); |
if ($args == '') { |
$options = array( |
'text' => $matches[3], |
'attr' => array('type' => '') |
); |
} else { |
$options = array( |
'text' => $matches[3], |
'attr' => $this->getAttrs($args) |
); |
} |
return $this->wiki->addToken($this->rule, $options) . $matches[5]; |
} |
} |
?> |
/branches/livraison_menes/api/pear/Text/Wiki/Parse/Strong.php |
---|
New file |
0,0 → 1,67 |
<?php |
// $Id: Strong.php,v 1.1 2005-01-20 19:43:20 jpm Exp $ |
/** |
* |
* This class implements a Text_Wiki_Parse to find source text marked for |
* strong emphasis (bold) as defined by text surrounded by three |
* single-quotes. On parsing, the text itself is left in place, but the |
* starting and ending instances of three single-quotes are replaced with |
* tokens. |
* |
* @author Paul M. Jones <pmjones@ciaweb.net> |
* |
* @package Text_Wiki |
* |
*/ |
class Text_Wiki_Parse_Strong extends Text_Wiki_Parse { |
/** |
* |
* The regular expression used to parse the source text and find |
* matches conforming to this rule. Used by the parse() method. |
* |
* @access public |
* |
* @var string |
* |
* @see parse() |
* |
*/ |
var $regex = "/\*\*(()|.*)\*\*/U"; |
/** |
* |
* Generates a replacement for the matched text. Token options are: |
* |
* 'type' => ['start'|'end'] The starting or ending point of the |
* emphasized text. The text itself is left in the source. |
* |
* @access public |
* |
* @param array &$matches The array of matches from parse(). |
* |
* @return A pair of delimited tokens to be used as a placeholder in |
* the source text surrounding the text to be emphasized. |
* |
*/ |
function process(&$matches) |
{ |
$start = $this->wiki->addToken( |
$this->rule, array('type' => 'start') |
); |
$end = $this->wiki->addToken( |
$this->rule, array('type' => 'end') |
); |
return $start . $matches[1] . $end; |
} |
} |
?> |
/branches/livraison_menes/api/pear/Text/Wiki/Render/Plain.php |
---|
New file |
0,0 → 1,16 |
<?php |
class Text_Wiki_Render_Plain extends Text_Wiki_Render { |
function pre() |
{ |
return; |
} |
function post() |
{ |
return; |
} |
} |
?> |
/branches/livraison_menes/api/pear/Text/Wiki/Render/Xhtml/Code.php |
---|
New file |
0,0 → 1,102 |
<?php |
class Text_Wiki_Render_Xhtml_Code extends Text_Wiki_Render { |
var $conf = array( |
'css' => null, // class for <pre> |
'css_code' => null, // class for generic <code> |
'css_php' => null, // class for PHP <code> |
'css_html' => null // class for HTML <code> |
); |
/** |
* |
* Renders a token into text matching the requested format. |
* |
* @access public |
* |
* @param array $options The "options" portion of the token (second |
* element). |
* |
* @return string The text rendered from the token options. |
* |
*/ |
function token($options) |
{ |
$text = $options['text']; |
$attr = $options['attr']; |
$type = strtolower($attr['type']); |
$css = $this->formatConf(' class="%s"', 'css'); |
$css_code = $this->formatConf(' class="%s"', 'css_code'); |
$css_php = $this->formatConf(' class="%s"', 'css_php'); |
$css_html = $this->formatConf(' class="%s"', 'css_html'); |
if ($type == 'php') { |
// PHP code example: |
// add the PHP tags |
$text = "<?php\n" . $options['text'] . "\n?>"; // <?php |
// convert tabs to four spaces |
$text = str_replace("\t", " ", $text); |
// colorize the code block (also converts HTML entities and adds |
// <code>...</code> tags) |
ob_start(); |
highlight_string($text); |
$text = ob_get_contents(); |
ob_end_clean(); |
// replace <br /> tags with simple newlines. |
// replace non-breaking space with simple spaces. |
// translate HTML <font> and color to XHTML <span> and style. |
// courtesy of research by A. Kalin :-). |
$map = array( |
'<br />' => "\n", |
' ' => ' ', |
'<font' => '<span', |
'</font>' => '</span>', |
'color="' => 'style="color:' |
); |
$text = strtr($text, $map); |
// get rid of the last newline inside the code block |
// (becuase higlight_string puts one there) |
if (substr($text, -8) == "\n</code>") { |
$text = substr($text, 0, -8) . "</code>"; |
} |
// replace all <code> tags with classed tags |
if ($css_php) { |
$text = str_replace('<code>', "<code$css_php>", $text); |
} |
// done |
$text = "<pre$css>$text</pre>"; |
} elseif ($type == 'html' || $type == 'xhtml') { |
// HTML code example: |
// add <html> opening and closing tags, |
// convert tabs to four spaces, |
// convert entities. |
$text = str_replace("\t", " ", $text); |
$text = "<html>\n$text\n</html>"; |
$text = htmlentities($text); |
$text = "<pre$css><code$css_html>$text</code></pre>"; |
} else { |
// generic code example: |
// convert tabs to four spaces, |
// convert entities. |
$text = str_replace("\t", " ", $text); |
$text = htmlentities($text); |
$text = "<pre$css><code$css_code>$text</code></pre>"; |
} |
return "\n$text\n\n"; |
} |
} |
?> |
/branches/livraison_menes/api/pear/Text/Wiki/Render/Xhtml/Strong.php |
---|
New file |
0,0 → 1,35 |
<?php |
class Text_Wiki_Render_Xhtml_Strong extends Text_Wiki_Render { |
var $conf = array( |
'css' => null |
); |
/** |
* |
* Renders a token into text matching the requested format. |
* |
* @access public |
* |
* @param array $options The "options" portion of the token (second |
* element). |
* |
* @return string The text rendered from the token options. |
* |
*/ |
function token($options) |
{ |
if ($options['type'] == 'start') { |
$css = $this->formatConf(' class="%s"', 'css'); |
return "<strong$css>"; |
} |
if ($options['type'] == 'end') { |
return '</strong>'; |
} |
} |
} |
?> |
/branches/livraison_menes/api/pear/Text/Wiki/Render/Xhtml/Center.php |
---|
New file |
0,0 → 1,29 |
<?php |
class Text_Wiki_Render_Xhtml_Center extends Text_Wiki_Render { |
/** |
* |
* Renders a token into text matching the requested format. |
* |
* @access public |
* |
* @param array $options The "options" portion of the token (second |
* element). |
* |
* @return string The text rendered from the token options. |
* |
*/ |
function token($options) |
{ |
if ($options['type'] == 'start') { |
return '<div style="text-align: center;">'; |
} |
if ($options['type'] == 'end') { |
return '</div>'; |
} |
} |
} |
?> |
/branches/livraison_menes/api/pear/Text/Wiki/Render/Xhtml/Phplookup.php |
---|
New file |
0,0 → 1,59 |
<?php |
// $Id: Phplookup.php,v 1.1 2005-01-20 19:43:21 jpm Exp $ |
class Text_Wiki_Render_Xhtml_Phplookup extends Text_Wiki_Render { |
var $conf = array( |
'target' => '_blank', |
'css' => null |
); |
/** |
* |
* Renders a token into text matching the requested format. |
* |
* @access public |
* |
* @param array $options The "options" portion of the token (second |
* element). |
* |
* @return string The text rendered from the token options. |
* |
*/ |
function token($options) |
{ |
$text = trim($options['text']); |
$css = $this->formatConf(' class="%s"', 'css'); |
// start the html |
$output = "<a$css"; |
// are we targeting another window? |
$target = $this->getConf('target', ''); |
if ($target) { |
// use a "popup" window. this is XHTML compliant, suggested by |
// Aaron Kalin. uses the $target as the new window name. |
$target = htmlspecialchars($target); |
$output .= " onclick=\"window.open(this.href, '$target');"; |
$output .= " return false;\""; |
} |
// take off the final parens for functions |
if (substr($text, -2) == '()') { |
$q = substr($text, 0, -2); |
} else { |
$q = $text; |
} |
$q = htmlspecialchars($q); |
$text = htmlspecialchars($text); |
// finish and return |
$output .= " href=\"http://php.net/$q\">$text</a>"; |
return $output; |
} |
} |
?> |
/branches/livraison_menes/api/pear/Text/Wiki/Render/Xhtml/Superscript.php |
---|
New file |
0,0 → 1,34 |
<?php |
class Text_Wiki_Render_Xhtml_Superscript extends Text_Wiki_Render { |
var $conf = array( |
'css' => null |
); |
/** |
* |
* Renders a token into text matching the requested format. |
* |
* @access public |
* |
* @param array $options The "options" portion of the token (second |
* element). |
* |
* @return string The text rendered from the token options. |
* |
*/ |
function token($options) |
{ |
if ($options['type'] == 'start') { |
$css = $this->formatConf(' class="%s"', 'css'); |
return "<sup$css>"; |
} |
if ($options['type'] == 'end') { |
return '</sup>'; |
} |
} |
} |
?> |
/branches/livraison_menes/api/pear/Text/Wiki/Render/Xhtml/Include.php |
---|
New file |
0,0 → 1,8 |
<?php |
class Text_Wiki_Render_Xhtml_Include extends Text_Wiki_Render { |
function token() |
{ |
return ''; |
} |
} |
?> |
/branches/livraison_menes/api/pear/Text/Wiki/Render/Xhtml/Colortext.php |
---|
New file |
0,0 → 1,56 |
<?php |
class Text_Wiki_Render_Xhtml_Colortext extends Text_Wiki_Render { |
var $colors = array( |
'aqua', |
'black', |
'blue', |
'fuchsia', |
'gray', |
'green', |
'lime', |
'maroon', |
'navy', |
'olive', |
'purple', |
'red', |
'silver', |
'teal', |
'white', |
'yellow' |
); |
/** |
* |
* Renders a token into text matching the requested format. |
* |
* @access public |
* |
* @param array $options The "options" portion of the token (second |
* element). |
* |
* @return string The text rendered from the token options. |
* |
*/ |
function token($options) |
{ |
$type = $options['type']; |
$color = $options['color']; |
if (! in_array($color, $this->colors)) { |
$color = '#' . $color; |
} |
if ($type == 'start') { |
return "<span style=\"color: $color;\">"; |
} |
if ($options['type'] == 'end') { |
return '</span>'; |
} |
} |
} |
?> |
/branches/livraison_menes/api/pear/Text/Wiki/Render/Xhtml/Break.php |
---|
New file |
0,0 → 1,29 |
<?php |
class Text_Wiki_Render_Xhtml_Break extends Text_Wiki_Render { |
var $conf = array( |
'css' => null |
); |
/** |
* |
* Renders a token into text matching the requested format. |
* |
* @access public |
* |
* @param array $options The "options" portion of the token (second |
* element). |
* |
* @return string The text rendered from the token options. |
* |
*/ |
function token($options) |
{ |
$css = $this->formatConf(' class="%s"', 'css'); |
return "<br$css />\n"; |
} |
} |
?> |
/branches/livraison_menes/api/pear/Text/Wiki/Render/Xhtml/Toc.php |
---|
New file |
0,0 → 1,80 |
<?php |
// $Id: Toc.php,v 1.1 2005-01-20 19:43:21 jpm Exp $ |
class Text_Wiki_Render_Xhtml_Toc extends Text_Wiki_Render { |
var $conf = array( |
'css_list' => null, |
'css_item' => null, |
'title' => '<strong>Table of Contents</strong>', |
'div_id' => 'toc' |
); |
var $min = 2; |
/** |
* |
* Renders a token into text matching the requested format. |
* |
* @access public |
* |
* @param array $options The "options" portion of the token (second |
* element). |
* |
* @return string The text rendered from the token options. |
* |
*/ |
function token($options) |
{ |
// type, id, level, count, attr |
extract($options); |
switch ($type) { |
case 'list_start': |
$html = '<div'; |
$css = $this->getConf('css_list'); |
if ($css) { |
$html .= " class=\"$css\""; |
} |
$div_id = $this->getConf('div_id'); |
if ($div_id) { |
$html .= " id=\"$div_id\""; |
} |
$html .= '>'; |
$html .= $this->getConf('title'); |
return $html; |
break; |
case 'list_end': |
return "</div>\n"; |
break; |
case 'item_start': |
$html = '<div'; |
$css = $this->getConf('css_item'); |
if ($css) { |
$html .= " class=\"$css\""; |
} |
$pad = ($level - $this->min); |
$html .= " style=\"margin-left: {$pad}em;\">"; |
$html .= "<a href=\"#$id\">"; |
return $html; |
break; |
case 'item_end': |
return "</a></div>\n"; |
break; |
} |
} |
} |
?> |
/branches/livraison_menes/api/pear/Text/Wiki/Render/Xhtml/Function.php |
---|
New file |
0,0 → 1,87 |
<?php |
// $Id: Function.php,v 1.1 2005-01-20 19:43:21 jpm Exp $ |
class Text_Wiki_Render_Xhtml_Function extends Text_Wiki_Render { |
var $conf = array( |
// list separator for params and throws |
'list_sep' => ', ', |
// the "main" format string |
'format_main' => '%access %return <b>%name</b> ( %params ) %throws', |
// the looped format string for required params |
'format_param' => '%type <i>%descr</i>', |
// the looped format string for params with default values |
'format_paramd' => '[%type <i>%descr</i> default %default]', |
// the looped format string for throws |
'format_throws' => '<b>throws</b> %type <i>%descr</i>' |
); |
/** |
* |
* Renders a token into text matching the requested format. |
* |
* @access public |
* |
* @param array $options The "options" portion of the token (second |
* element). |
* |
* @return string The text rendered from the token options. |
* |
*/ |
function token($options) |
{ |
extract($options); // name, access, return, params, throws |
// build the baseline output |
$output = $this->conf['format_main']; |
$output = str_replace('%access', htmlspecialchars($access), $output); |
$output = str_replace('%return', htmlspecialchars($return), $output); |
$output = str_replace('%name', htmlspecialchars($name), $output); |
// build the set of params |
$list = array(); |
foreach ($params as $key => $val) { |
// is there a default value? |
if ($val['default']) { |
$tmp = $this->conf['format_paramd']; |
} else { |
$tmp = $this->conf['format_param']; |
} |
// add the param elements |
$tmp = str_replace('%type', htmlspecialchars($val['type']), $tmp); |
$tmp = str_replace('%descr', htmlspecialchars($val['descr']), $tmp); |
$tmp = str_replace('%default', htmlspecialchars($val['default']), $tmp); |
$list[] = $tmp; |
} |
// insert params into output |
$tmp = implode($this->conf['list_sep'], $list); |
$output = str_replace('%params', $tmp, $output); |
// build the set of throws |
$list = array(); |
foreach ($throws as $key => $val) { |
$tmp = $this->conf['format_throws']; |
$tmp = str_replace('%type', htmlspecialchars($val['type']), $tmp); |
$tmp = str_replace('%descr', htmlspecialchars($val['descr']), $tmp); |
$list[] = $tmp; |
} |
// insert throws into output |
$tmp = implode($this->conf['list_sep'], $list); |
$output = str_replace('%throws', $tmp, $output); |
// close the div and return the output |
$output .= '</div>'; |
return "\n$output\n\n"; |
} |
} |
?> |
/branches/livraison_menes/api/pear/Text/Wiki/Render/Xhtml/Table.php |
---|
New file |
0,0 → 1,98 |
<?php |
class Text_Wiki_Render_Xhtml_Table extends Text_Wiki_Render { |
var $conf = array( |
'css_table' => null, |
'css_tr' => null, |
'css_th' => null, |
'css_td' => null |
); |
/** |
* |
* Renders a token into text matching the requested format. |
* |
* @access public |
* |
* @param array $options The "options" portion of the token (second |
* element). |
* |
* @return string The text rendered from the token options. |
* |
*/ |
function token($options) |
{ |
// make nice variable names (type, attr, span) |
extract($options); |
$pad = ' '; |
switch ($type) { |
case 'table_start': |
$css = $this->formatConf(' class="%s"', 'css_table'); |
return "\n\n<table$css>\n"; |
break; |
case 'table_end': |
return "</table>\n\n"; |
break; |
case 'row_start': |
$css = $this->formatConf(' class="%s"', 'css_tr'); |
return "$pad<tr$css>\n"; |
break; |
case 'row_end': |
return "$pad</tr>\n"; |
break; |
case 'cell_start': |
// base html |
$html = $pad . $pad; |
// is this a TH or TD cell? |
if ($attr == 'header') { |
// start a header cell |
$css = $this->formatConf(' class="%s"', 'css_th'); |
$html .= "<th$css"; |
} else { |
// start a normal cell |
$css = $this->formatConf(' class="%s"', 'css_td'); |
$html .= "<td$css"; |
} |
// add the column span |
if ($span > 1) { |
$html .= " colspan=\"$span\""; |
} |
// add alignment |
if ($attr != 'header' && $attr != '') { |
$html .= " style=\"text-align: $attr;\""; |
} |
// done! |
$html .= '>'; |
return $html; |
break; |
case 'cell_end': |
if ($attr == 'header') { |
return "</th>\n"; |
} else { |
return "</td>\n"; |
} |
break; |
default: |
return ''; |
} |
} |
} |
?> |
/branches/livraison_menes/api/pear/Text/Wiki/Render/Xhtml/Raw.php |
---|
New file |
0,0 → 1,23 |
<?php |
class Text_Wiki_Render_Xhtml_Raw extends Text_Wiki_Render { |
/** |
* |
* Renders a token into text matching the requested format. |
* |
* @access public |
* |
* @param array $options The "options" portion of the token (second |
* element). |
* |
* @return string The text rendered from the token options. |
* |
*/ |
function token($options) |
{ |
return $options['text']; |
} |
} |
?> |
/branches/livraison_menes/api/pear/Text/Wiki/Render/Xhtml/Deflist.php |
---|
New file |
0,0 → 1,64 |
<?php |
class Text_Wiki_Render_Xhtml_Deflist extends Text_Wiki_Render { |
var $conf = array( |
'css_dl' => null, |
'css_dt' => null, |
'css_dd' => null |
); |
/** |
* |
* Renders a token into text matching the requested format. |
* |
* @access public |
* |
* @param array $options The "options" portion of the token (second |
* element). |
* |
* @return string The text rendered from the token options. |
* |
*/ |
function token($options) |
{ |
$type = $options['type']; |
$pad = " "; |
switch ($type) { |
case 'list_start': |
$css = $this->formatConf(' class="%s"', 'css_dl'); |
return "<dl$css>\n"; |
break; |
case 'list_end': |
return "</dl>\n\n"; |
break; |
case 'term_start': |
$css = $this->formatConf(' class="%s"', 'css_dt'); |
return $pad . "<dt$css>"; |
break; |
case 'term_end': |
return "</dt>\n"; |
break; |
case 'narr_start': |
$css = $this->formatConf(' class="%s"', 'css_dd'); |
return $pad . $pad . "<dd$css>"; |
break; |
case 'narr_end': |
return "</dd>\n"; |
break; |
default: |
return ''; |
} |
} |
} |
?> |
/branches/livraison_menes/api/pear/Text/Wiki/Render/Xhtml/Horiz.php |
---|
New file |
0,0 → 1,28 |
<?php |
class Text_Wiki_Render_Xhtml_Horiz extends Text_Wiki_Render { |
var $conf = array( |
'css' => null |
); |
/** |
* |
* Renders a token into text matching the requested format. |
* |
* @access public |
* |
* @param array $options The "options" portion of the token (second |
* element). |
* |
* @return string The text rendered from the token options. |
* |
*/ |
function token($options) |
{ |
$css = $this->formatConf(' class="%s"', 'css'); |
return "<hr$css />\n"; |
} |
} |
?> |
/branches/livraison_menes/api/pear/Text/Wiki/Render/Xhtml/Prefilter.php |
---|
New file |
0,0 → 1,40 |
<?php |
/* vim: set expandtab tabstop=4 shiftwidth=4: */ |
// +----------------------------------------------------------------------+ |
// | PHP version 4 | |
// +----------------------------------------------------------------------+ |
// | Copyright (c) 1997-2003 The PHP Group | |
// +----------------------------------------------------------------------+ |
// | This source file is subject to version 2.0 of the PHP license, | |
// | that is bundled with this package in the file LICENSE, and is | |
// | available through the world-wide-web at | |
// | http://www.php.net/license/2_02.txt. | |
// | If you did not receive a copy of the PHP license and are unable to | |
// | obtain it through the world-wide-web, please send a note to | |
// | license@php.net so we can mail you a copy immediately. | |
// +----------------------------------------------------------------------+ |
// | Authors: Paul M. Jones <pmjones@ciaweb.net> | |
// +----------------------------------------------------------------------+ |
// |
// $Id: Prefilter.php,v 1.1 2005-01-20 19:43:21 jpm Exp $ |
/** |
* |
* This class implements a Text_Wiki_Render_Xhtml to "pre-filter" source text so |
* that line endings are consistently \n, lines ending in a backslash \ |
* are concatenated with the next line, and tabs are converted to spaces. |
* |
* @author Paul M. Jones <pmjones@ciaweb.net> |
* |
* @package Text_Wiki |
* |
*/ |
class Text_Wiki_Render_Xhtml_Prefilter extends Text_Wiki_Render { |
function token() |
{ |
return ''; |
} |
} |
?> |
/branches/livraison_menes/api/pear/Text/Wiki/Render/Xhtml/Heading.php |
---|
New file |
0,0 → 1,29 |
<?php |
class Text_Wiki_Render_Xhtml_Heading extends Text_Wiki_Render { |
var $conf = array( |
'css_h1' => null, |
'css_h2' => null, |
'css_h3' => null, |
'css_h4' => null, |
'css_h5' => null, |
'css_h6' => null |
); |
function token($options) |
{ |
// get nice variable names (id, type, level) |
extract($options); |
if ($type == 'start') { |
$css = $this->formatConf(' class="%s"', "css_h$level"); |
return "<h$level$css id=\"$id\">"; |
} |
if ($type == 'end') { |
return "</h$level>\n"; |
} |
} |
} |
?> |
/branches/livraison_menes/api/pear/Text/Wiki/Render/Xhtml/Tighten.php |
---|
New file |
0,0 → 1,10 |
<?php |
class Text_Wiki_Render_Xhtml_Tighten extends Text_Wiki_Render { |
function token() |
{ |
return ''; |
} |
} |
?> |
/branches/livraison_menes/api/pear/Text/Wiki/Render/Xhtml/Html.php |
---|
New file |
0,0 → 1,24 |
<?php |
class Text_Wiki_Render_Xhtml_Html extends Text_Wiki_Render { |
/** |
* |
* Renders a token into text matching the requested format. |
* |
* @access public |
* |
* @param array $options The "options" portion of the token (second |
* element). |
* |
* @return string The text rendered from the token options. |
* |
*/ |
function token($options) |
{ |
return $options['text']; |
} |
} |
?> |
/branches/livraison_menes/api/pear/Text/Wiki/Render/Xhtml/Interwiki.php |
---|
New file |
0,0 → 1,74 |
<?php |
class Text_Wiki_Render_Xhtml_Interwiki extends Text_Wiki_Render { |
var $conf = array( |
'sites' => array( |
'MeatBall' => 'http://www.usemod.com/cgi-bin/mb.pl?%s', |
'Advogato' => 'http://advogato.org/%s', |
'Wiki' => 'http://c2.com/cgi/wiki?%s' |
), |
'target' => '_blank', |
'css' => null |
); |
/** |
* |
* Renders a token into text matching the requested format. |
* |
* @access public |
* |
* @param array $options The "options" portion of the token (second |
* element). |
* |
* @return string The text rendered from the token options. |
* |
*/ |
function token($options) |
{ |
$site = $options['site']; |
$page = $options['page']; |
$text = $options['text']; |
$css = $this->formatConf(' class="%s"', 'css'); |
if (isset($this->conf['sites'][$site])) { |
$href = $this->conf['sites'][$site]; |
} else { |
return $text; |
} |
// old form where page is at end, |
// or new form with %s placeholder for sprintf()? |
if (strpos($href, '%s') === false) { |
// use the old form |
$href = $href . $page; |
} else { |
// use the new form |
$href = sprintf($href, $page); |
} |
// allow for alternative targets |
$target = $this->getConf('target'); |
// build base link |
$text = htmlspecialchars($text); |
$output = "<a$css href=\"$href\""; |
// are we targeting a specific window? |
if ($target) { |
// this is XHTML compliant, suggested by Aaron Kalin. |
// code tip is actually from youngpup.net, and it |
// uses the $target as the new window name. |
$target = htmlspecialchars($target); |
$output .= " onClick=\"window.open(this.href, '$target');"; |
$output .= " return false;\""; |
} |
$output .= ">$text</a>"; |
return $output; |
} |
} |
?> |
/branches/livraison_menes/api/pear/Text/Wiki/Render/Xhtml/Italic.php |
---|
New file |
0,0 → 1,34 |
<?php |
class Text_Wiki_Render_Xhtml_Italic extends Text_Wiki_Render { |
var $conf = array( |
'css' => null |
); |
/** |
* |
* Renders a token into text matching the requested format. |
* |
* @access public |
* |
* @param array $options The "options" portion of the token (second |
* element). |
* |
* @return string The text rendered from the token options. |
* |
*/ |
function token($options) |
{ |
if ($options['type'] == 'start') { |
$css = $this->formatConf(' class="%s"', 'css'); |
return "<i$css>"; |
} |
if ($options['type'] == 'end') { |
return '</i>'; |
} |
} |
} |
?> |
/branches/livraison_menes/api/pear/Text/Wiki/Render/Xhtml/Paragraph.php |
---|
New file |
0,0 → 1,36 |
<?php |
class Text_Wiki_Render_Xhtml_Paragraph extends Text_Wiki_Render { |
var $conf = array( |
'css' => null |
); |
/** |
* |
* Renders a token into text matching the requested format. |
* |
* @access public |
* |
* @param array $options The "options" portion of the token (second |
* element). |
* |
* @return string The text rendered from the token options. |
* |
*/ |
function token($options) |
{ |
extract($options); //type |
if ($type == 'start') { |
$css = $this->formatConf(' class="%s"', 'css'); |
return "<p$css>"; |
} |
if ($type == 'end') { |
return "</p>\n\n"; |
} |
} |
} |
?> |
/branches/livraison_menes/api/pear/Text/Wiki/Render/Xhtml/Blockquote.php |
---|
New file |
0,0 → 1,46 |
<?php |
class Text_Wiki_Render_Xhtml_Blockquote extends Text_Wiki_Render { |
var $conf = array( |
'css' => null |
); |
/** |
* |
* Renders a token into text matching the requested format. |
* |
* @access public |
* |
* @param array $options The "options" portion of the token (second |
* element). |
* |
* @return string The text rendered from the token options. |
* |
*/ |
function token($options) |
{ |
$type = $options['type']; |
$level = $options['level']; |
// set up indenting so that the results look nice; we do this |
// in two steps to avoid str_pad mathematics. ;-) |
$pad = str_pad('', $level, "\t"); |
$pad = str_replace("\t", ' ', $pad); |
// pick the css type |
$css = $this->formatConf(' class="%s"', 'css'); |
// starting |
if ($type == 'start') { |
return "$pad<blockquote$css>"; |
} |
// ending |
if ($type == 'end') { |
return $pad . "</blockquote>\n"; |
} |
} |
} |
?> |
/branches/livraison_menes/api/pear/Text/Wiki/Render/Xhtml/Anchor.php |
---|
New file |
0,0 → 1,37 |
<?php |
/** |
* |
* This class renders an anchor target name in XHTML. |
* |
* @author Manuel Holtgrewe <purestorm at ggnore dot net> |
* |
* @author Paul M. Jones <pmjones at ciaweb dot net> |
* |
* @package Text_Wiki |
* |
*/ |
class Text_Wiki_Render_Xhtml_Anchor extends Text_Wiki_Render { |
var $conf = array( |
'css' => null |
); |
function token($options) |
{ |
extract($options); // $type, $name |
if ($type == 'start') { |
$css = $this->formatConf(' class="%s"', 'css'); |
$format = "<a$css id=\"%s\">'"; |
return sprintf($format ,$name); |
} |
if ($type == 'end') { |
return '</a>'; |
} |
} |
} |
?> |
/branches/livraison_menes/api/pear/Text/Wiki/Render/Xhtml/List.php |
---|
New file |
0,0 → 1,142 |
<?php |
class Text_Wiki_Render_Xhtml_List extends Text_Wiki_Render { |
var $conf = array( |
'css_ol' => null, |
'css_ol_li' => null, |
'css_ul' => null, |
'css_ul_li' => null |
); |
/** |
* |
* Renders a token into text matching the requested format. |
* |
* This rendering method is syntactically and semantically compliant |
* with XHTML 1.1 in that sub-lists are part of the previous list item. |
* |
* @access public |
* |
* @param array $options The "options" portion of the token (second |
* element). |
* |
* @return string The text rendered from the token options. |
* |
*/ |
function token($options) |
{ |
// make nice variables (type, level, count) |
extract($options); |
// set up indenting so that the results look nice; we do this |
// in two steps to avoid str_pad mathematics. ;-) |
$pad = str_pad('', $level, "\t"); |
$pad = str_replace("\t", ' ', $pad); |
switch ($type) { |
case 'bullet_list_start': |
// build the base HTML |
$css = $this->formatConf(' class="%s"', 'css_ul'); |
$html = "<ul$css>"; |
// if this is the opening block for the list, |
// put an extra newline in front of it so the |
// output looks nice. |
if ($level == 0) { |
$html = "\n$html"; |
} |
// done! |
return $html; |
break; |
case 'bullet_list_end': |
// build the base HTML |
$html = "</li>\n$pad</ul>"; |
// if this is the closing block for the list, |
// put extra newlines after it so the output |
// looks nice. |
if ($level == 0) { |
$html .= "\n\n"; |
} |
// done! |
return $html; |
break; |
case 'number_list_start': |
// build the base HTML |
$css = $this->formatConf(' class="%s"', 'css_ol'); |
$html = "<ol$css>"; |
// if this is the opening block for the list, |
// put an extra newline in front of it so the |
// output looks nice. |
if ($level == 0) { |
$html = "\n$html"; |
} |
// done! |
return $html; |
break; |
case 'number_list_end': |
// build the base HTML |
$html = "</li>\n$pad</ol>"; |
// if this is the closing block for the list, |
// put extra newlines after it so the output |
// looks nice. |
if ($level == 0) { |
$html .= "\n\n"; |
} |
// done! |
return $html; |
break; |
case 'bullet_item_start': |
case 'number_item_start': |
// pick the proper CSS class |
if ($type == 'bullet_item_start') { |
$css = $this->formatConf(' class="%s"', 'css_ul_li'); |
} else { |
$css = $this->formatConf(' class="%s"', 'css_ol_li'); |
} |
// build the base HTML |
$html = "\n$pad<li$css>"; |
// for the very first item in the list, do nothing. |
// but for additional items, be sure to close the |
// previous item. |
if ($count > 0) { |
$html = "</li>$html"; |
} |
// done! |
return $html; |
break; |
case 'bullet_item_end': |
case 'number_item_end': |
default: |
// ignore item endings and all other types. |
// item endings are taken care of by the other types |
// depending on their place in the list. |
return ''; |
break; |
} |
} |
} |
?> |
/branches/livraison_menes/api/pear/Text/Wiki/Render/Xhtml/Embed.php |
---|
New file |
0,0 → 1,23 |
<?php |
class Text_Wiki_Render_Xhtml_Embed extends Text_Wiki_Render { |
/** |
* |
* Renders a token into text matching the requested format. |
* |
* @access public |
* |
* @param array $options The "options" portion of the token (second |
* element). |
* |
* @return string The text rendered from the token options. |
* |
*/ |
function token($options) |
{ |
return $options['text']; |
} |
} |
?> |
/branches/livraison_menes/api/pear/Text/Wiki/Render/Xhtml/Delimiter.php |
---|
New file |
0,0 → 1,23 |
<?php |
class Text_Wiki_Render_Xhtml_Delimiter extends Text_Wiki_Render { |
/** |
* |
* Renders a token into text matching the requested format. |
* |
* @access public |
* |
* @param array $options The "options" portion of the token (second |
* element). |
* |
* @return string The text rendered from the token options. |
* |
*/ |
function token($options) |
{ |
return $options['text']; |
} |
} |
?> |
/branches/livraison_menes/api/pear/Text/Wiki/Render/Xhtml/Bold.php |
---|
New file |
0,0 → 1,34 |
<?php |
class Text_Wiki_Render_Xhtml_Bold extends Text_Wiki_Render { |
var $conf = array( |
'css' => null |
); |
/** |
* |
* Renders a token into text matching the requested format. |
* |
* @access public |
* |
* @param array $options The "options" portion of the token (second |
* element). |
* |
* @return string The text rendered from the token options. |
* |
*/ |
function token($options) |
{ |
if ($options['type'] == 'start') { |
$css = $this->formatConf(' class="%s"', 'css'); |
return "<b$css>"; |
} |
if ($options['type'] == 'end') { |
return '</b>'; |
} |
} |
} |
?> |
/branches/livraison_menes/api/pear/Text/Wiki/Render/Xhtml/Wikilink.php |
---|
New file |
0,0 → 1,122 |
<?php |
class Text_Wiki_Render_Xhtml_Wikilink extends Text_Wiki_Render { |
var $conf = array( |
'pages' => array(), // set to null or false to turn off page checks |
'view_url' => 'http://example.com/index.php?page=%s', |
'new_url' => 'http://example.com/new.php?page=%s', |
'new_text' => '?', |
'new_text_pos' => 'after', // 'before', 'after', or null/false |
'css' => null, |
'css_new' => null |
); |
/** |
* |
* Renders a token into XHTML. |
* |
* @access public |
* |
* @param array $options The "options" portion of the token (second |
* element). |
* |
* @return string The text rendered from the token options. |
* |
*/ |
function token($options) |
{ |
// make nice variable names (page, anchor, text) |
extract($options); |
// are we checking page existence? |
$list =& $this->getConf('pages'); |
if (is_array($list)) { |
// yes, check against the page list |
$exists = in_array($page, $list); |
} else { |
// no, assume it exists |
$exists = true; |
} |
// convert *after* checking against page names so as not to mess |
// up what the user typed and what we're checking. |
$page = htmlspecialchars($page); |
$anchor = htmlspecialchars($anchor); |
$text = htmlspecialchars($text); |
// does the page exist? |
if ($exists) { |
// PAGE EXISTS. |
// yes, link to the page view, but we have to build |
// the HREF. we support both the old form where |
// the page always comes at the end, and the new |
// form that uses %s for sprintf() |
$href = $this->getConf('view_url'); |
if (strpos($href, '%s') === false) { |
// use the old form (page-at-end) |
$href = $href . $page . $anchor; |
} else { |
// use the new form (sprintf format string) |
$href = sprintf($href, $page . $anchor); |
} |
// get the CSS class and generate output |
$css = $this->formatConf(' class="%s"', 'css'); |
$output = "<a$css href=\"$href\">$text</a>"; |
} else { |
// PAGE DOES NOT EXIST. |
// link to a create-page url, but only if new_url is set |
$href = $this->getConf('new_url', null); |
// set the proper HREF |
if (! $href || trim($href) == '') { |
// no useful href, return the text as it is |
$output = $text; |
} else { |
// yes, link to the new-page href, but we have to build |
// it. we support both the old form where |
// the page always comes at the end, and the new |
// form that uses sprintf() |
if (strpos($href, '%s') === false) { |
// use the old form |
$href = $href . $page; |
} else { |
// use the new form |
$href = sprintf($href, $page); |
} |
} |
// get the appropriate CSS class and new-link text |
$css = $this->formatConf(' class="%s"', 'css'); |
$new = $this->getConf('new_text'); |
// what kind of linking are we doing? |
$pos = $this->getConf('new_text_pos'); |
if (! $pos || ! $new) { |
// no position (or no new_text), use css only on the page name |
$output = "<a$css href=\"$href\">$page</a>"; |
} elseif ($pos == 'before') { |
// use the new_text BEFORE the page name |
$output = "<a$css href=\"$href\">$new</a>$text"; |
} else { |
// default, use the new_text link AFTER the page name |
$output = "$text<a$css href=\"$href\">$new</a>"; |
} |
} |
return $output; |
} |
} |
?> |
/branches/livraison_menes/api/pear/Text/Wiki/Render/Xhtml/Image.php |
---|
New file |
0,0 → 1,151 |
<?php |
class Text_Wiki_Render_Xhtml_Image extends Text_Wiki_Render { |
var $conf = array( |
'base' => '/', |
'css' => null, |
'css_link' => null |
); |
/** |
* |
* Renders a token into text matching the requested format. |
* |
* @access public |
* |
* @param array $options The "options" portion of the token (second |
* element). |
* |
* @return string The text rendered from the token options. |
* |
*/ |
function token($options) |
{ |
// note the image source |
$src = $options['src']; |
// is the source a local file or URL? |
if (strpos($src, '://') === false) { |
// the source refers to a local file. |
// add the URL base to it. |
$src = $this->getConf('base', '/') . $src; |
} |
// stephane@metacites.net |
// is the image clickable? |
if (isset($options['attr']['link'])) { |
// yes, the image is clickable. |
// are we linked to a URL or a wiki page? |
if (strpos($options['attr']['link'], '://')) { |
// it's a URL |
$href = $options['attr']['link']; |
} else { |
// it's a WikiPage; assume it exists. |
/** @todo This needs to honor sprintf wikilinks (pmjones) */ |
/** @todo This needs to honor interwiki (pmjones) */ |
/** @todo This needs to honor freelinks (pmjones) */ |
$href = $this->wiki->getRenderConf('xhtml', 'wikilink', 'view_url') . |
$options['attr']['link']; |
} |
} else { |
// image is not clickable. |
$href = null; |
} |
// unset so it won't show up as an attribute |
unset($options['attr']['link']); |
// stephane@metacites.net -- 25/07/2004 |
// we make up an align="center" value for the <img> tag. |
if (isset($options['attr']['align']) && |
$options['attr']['align'] == 'center') { |
// unset so it won't show up as an attribute |
unset($options['attr']['align']); |
// make sure we have a style attribute |
if (! isset($options['attr']['style'])) { |
// no style, set up a blank one |
$options['attr']['style'] = ''; |
} else { |
// style exists, add a space |
$options['attr']['style'] .= ' '; |
} |
// add a "center" style to the existing style. |
$options['attr']['style'] .= |
'display: block; margin-left: auto; margin-right: auto;'; |
} |
// stephane@metacites.net -- 25/07/2004 |
// try to guess width and height |
if (! isset($options['attr']['width']) && |
! isset($options['attr']['height'])) { |
// does the source refer to a local file or a URL? |
if (strpos($src,'://')) { |
// is a URL link |
$imageFile = $src; |
} else { |
// is a local file |
$imageFile = $_SERVER['DOCUMENT_ROOT'] . $src; |
} |
// attempt to get the image size |
$imageSize = @getimagesize($imageFile); |
if (is_array($imageSize)) { |
$options['attr']['width'] = $imageSize[0]; |
$options['attr']['height'] = $imageSize[1]; |
} |
} |
// start the HTML output |
$output = '<img src="' . htmlspecialchars($src) . '"'; |
// get the CSS class but don't add it yet |
$css = $this->formatConf(' class="%s"', 'css'); |
// add the attributes to the output, and be sure to |
// track whether or not we find an "alt" attribute |
$alt = false; |
foreach ($options['attr'] as $key => $val) { |
// track the 'alt' attribute |
if (strtolower($key) == 'alt') { |
$alt = true; |
} |
// the 'class' attribute overrides the CSS class conf |
if (strtolower($key) == 'class') { |
$css = null; |
} |
$key = htmlspecialchars($key); |
$val = htmlspecialchars($val); |
$output .= " $key=\"$val\""; |
} |
// always add an "alt" attribute per Stephane Solliec |
if (! $alt) { |
$alt = htmlspecialchars(basename($options['src'])); |
$output .= " alt=\"$alt\""; |
} |
// end the image tag with the automatic CSS class (if any) |
$output .= "$css />"; |
// was the image clickable? |
if ($href) { |
// yes, add the href and return |
$href = htmlspecialchars($href); |
$css = $this->formatConf(' class="%s"', 'css_link'); |
$output = "<a$css href=\"$href\">$output</a>"; |
} |
return $output; |
} |
} |
?> |
/branches/livraison_menes/api/pear/Text/Wiki/Render/Xhtml/Tt.php |
---|
New file |
0,0 → 1,35 |
<?php |
class Text_Wiki_Render_Xhtml_tt extends Text_Wiki_Render { |
var $conf = array( |
'css' => null |
); |
/** |
* |
* Renders a token into text matching the requested format. |
* |
* @access public |
* |
* @param array $options The "options" portion of the token (second |
* element). |
* |
* @return string The text rendered from the token options. |
* |
*/ |
function token($options) |
{ |
if ($options['type'] == 'start') { |
$css = $this->formatConf(' class="%s"', 'css'); |
return "<tt$css>"; |
} |
if ($options['type'] == 'end') { |
return '</tt>'; |
} |
} |
} |
?> |
/branches/livraison_menes/api/pear/Text/Wiki/Render/Xhtml/Revise.php |
---|
New file |
0,0 → 1,45 |
<?php |
class Text_Wiki_Render_Xhtml_Revise extends Text_Wiki_Render { |
var $conf = array( |
'css_ins' => null, |
'css_del' => null |
); |
/** |
* |
* Renders a token into text matching the requested format. |
* |
* @access public |
* |
* @param array $options The "options" portion of the token (second |
* element). |
* |
* @return string The text rendered from the token options. |
* |
*/ |
function token($options) |
{ |
if ($options['type'] == 'del_start') { |
$css = $this->formatConf(' class="%s"', 'css_del'); |
return "<del$css>"; |
} |
if ($options['type'] == 'del_end') { |
return "</del>"; |
} |
if ($options['type'] == 'ins_start') { |
$css = $this->formatConf(' class="%s"', 'css_ins'); |
return "<ins$css>"; |
} |
if ($options['type'] == 'ins_end') { |
return "</ins>"; |
} |
} |
} |
?> |
/branches/livraison_menes/api/pear/Text/Wiki/Render/Xhtml/Freelink.php |
---|
New file |
0,0 → 1,9 |
<?php |
require_once 'Text/Wiki/Render/Xhtml/Wikilink.php'; |
class Text_Wiki_Render_Xhtml_Freelink extends Text_Wiki_Render_Xhtml_Wikilink { |
// renders identically to wikilinks, only the parsing is different :-) |
} |
?> |
/branches/livraison_menes/api/pear/Text/Wiki/Render/Xhtml/Newline.php |
---|
New file |
0,0 → 1,12 |
<?php |
class Text_Wiki_Render_Xhtml_Newline extends Text_Wiki_Render { |
function token($options) |
{ |
return "<br />\n"; |
} |
} |
?> |
/branches/livraison_menes/api/pear/Text/Wiki/Render/Xhtml/Url.php |
---|
New file |
0,0 → 1,91 |
<?php |
class Text_Wiki_Render_Xhtml_Url extends Text_Wiki_Render { |
var $conf = array( |
'target' => '_blank', |
'images' => true, |
'img_ext' => array('jpg', 'jpeg', 'gif', 'png'), |
'css_inline' => null, |
'css_footnote' => null, |
'css_descr' => null, |
'css_img' => null |
); |
/** |
* |
* Renders a token into text matching the requested format. |
* |
* @access public |
* |
* @param array $options The "options" portion of the token (second |
* element). |
* |
* @return string The text rendered from the token options. |
* |
*/ |
function token($options) |
{ |
// create local variables from the options array (text, |
// href, type) |
extract($options); |
// find the rightmost dot and determine the filename |
// extension. |
$pos = strrpos($href, '.'); |
$ext = strtolower(substr($href, $pos + 1)); |
$href = htmlspecialchars($href); |
// does the filename extension indicate an image file? |
if ($this->getConf('images') && |
in_array($ext, $this->getConf('img_ext', array()))) { |
// create alt text for the image |
if (! isset($text) || $text == '') { |
$text = basename($href); |
$text = htmlspecialchars($text); |
} |
// generate an image tag |
$css = $this->formatConf(' class="%s"', 'css_img'); |
$output = "<img$css src=\"$href\" alt=\"$text\" />"; |
} else { |
// allow for alternative targets on non-anchor HREFs |
if ($href{0} == '#') { |
$target = ''; |
} else { |
$target = $this->getConf('target'); |
} |
// generate a regular link (not an image) |
$text = htmlspecialchars($text); |
$css = $this->formatConf(' class="%s"', "css_$type"); |
$output = "<a$css href=\"$href\""; |
if ($target) { |
// use a "popup" window. this is XHTML compliant, suggested by |
// Aaron Kalin. uses the $target as the new window name. |
$target = htmlspecialchars($target); |
$output .= " onclick=\"window.open(this.href, '$target');"; |
$output .= " return false;\""; |
} |
// finish up output |
$output .= ">$text</a>"; |
// make numbered references look like footnotes when no |
// CSS class specified, make them superscript by default |
if ($type == 'footnote' && ! $css) { |
$output = '<sup>' . $output . '</sup>'; |
} |
} |
return $output; |
} |
} |
?> |
/branches/livraison_menes/api/pear/Text/Wiki/Render/Xhtml/Emphasis.php |
---|
New file |
0,0 → 1,35 |
<?php |
class Text_Wiki_Render_Xhtml_Emphasis extends Text_Wiki_Render { |
var $conf = array( |
'css' => null |
); |
/** |
* |
* Renders a token into text matching the requested format. |
* |
* @access public |
* |
* @param array $options The "options" portion of the token (second |
* element). |
* |
* @return string The text rendered from the token options. |
* |
*/ |
function token($options) |
{ |
if ($options['type'] == 'start') { |
$css = $this->formatConf(' class="%s"', 'css'); |
return "<em$css>"; |
} |
if ($options['type'] == 'end') { |
return '</em>'; |
} |
} |
} |
?> |
/branches/livraison_menes/api/pear/Text/Wiki/Render/Latex/Tt.php |
---|
New file |
0,0 → 1,30 |
<?php |
class Text_Wiki_Render_Latex_tt extends Text_Wiki_Render { |
/** |
* |
* Renders a token into text matching the requested format. |
* |
* @access public |
* |
* @param array $options The "options" portion of the token (second |
* element). |
* |
* @return string The text rendered from the token options. |
* |
*/ |
function token($options) |
{ |
if ($options['type'] == 'start') { |
return '\texttt{'; |
} |
if ($options['type'] == 'end') { |
return '}'; |
} |
} |
} |
?> |
/branches/livraison_menes/api/pear/Text/Wiki/Render/Latex/Revise.php |
---|
New file |
0,0 → 1,38 |
<?php |
class Text_Wiki_Render_Latex_Revise extends Text_Wiki_Render { |
/** |
* |
* Renders a token into text matching the requested format. |
* |
* @access public |
* |
* @param array $options The "options" portion of the token (second |
* element). |
* |
* @return string The text rendered from the token options. |
* |
*/ |
function token($options) |
{ |
if ($options['type'] == 'del_start') { |
return '\sout{'; |
} |
if ($options['type'] == 'del_end') { |
return '}'; |
} |
if ($options['type'] == 'ins_start') { |
return '\underline{'; |
} |
if ($options['type'] == 'ins_end') { |
return '}'; |
} |
} |
} |
?> |
/branches/livraison_menes/api/pear/Text/Wiki/Render/Latex/Freelink.php |
---|
New file |
0,0 → 1,34 |
<?php |
class Text_Wiki_Render_Latex_Freelink extends Text_Wiki_Render { |
var $conf = array( |
'pages' => array(), |
'view_url' => 'http://example.com/index.php?page=%s', |
'new_url' => 'http://example.com/new.php?page=%s', |
'new_text' => '?' |
); |
/** |
* |
* Renders a token into text matching the requested format. |
* |
* @access public |
* |
* @param array $options The "options" portion of the token (second |
* element). |
* |
* @return string The text rendered from the token options. |
* |
*/ |
function token($options) |
{ |
// get nice variable names (page, text, anchor) |
extract($options); |
return "$text\\footnote\{$anchor} "; |
} |
} |
?> |
/branches/livraison_menes/api/pear/Text/Wiki/Render/Latex/Newline.php |
---|
New file |
0,0 → 1,12 |
<?php |
class Text_Wiki_Render_Latex_Newline extends Text_Wiki_Render { |
function token($options) |
{ |
return "\n"; |
} |
} |
?> |
/branches/livraison_menes/api/pear/Text/Wiki/Render/Latex/Url.php |
---|
New file |
0,0 → 1,35 |
<?php |
class Text_Wiki_Render_Latex_Url extends Text_Wiki_Render { |
var $conf = array( |
'target' => false, |
'images' => true, |
'img_ext' => array('jpg', 'jpeg', 'gif', 'png') |
); |
/** |
* |
* Renders a token into text matching the requested format. |
* |
* @access public |
* |
* @param array $options The "options" portion of the token (second |
* element). |
* |
* @return string The text rendered from the token options. |
* |
*/ |
function token($options) |
{ |
// create local variables from the options array (text, |
// href, type) |
extract($options); |
return " $text\\footnote\{$href}"; |
} |
} |
?> |
/branches/livraison_menes/api/pear/Text/Wiki/Render/Latex/Emphasis.php |
---|
New file |
0,0 → 1,29 |
<?php |
class Text_Wiki_Render_Latex_Emphasis extends Text_Wiki_Render { |
/** |
* |
* Renders a token into text matching the requested format. |
* |
* @access public |
* |
* @param array $options The "options" portion of the token (second |
* element). |
* |
* @return string The text rendered from the token options. |
* |
*/ |
function token($options) |
{ |
if ($options['type'] == 'start') { |
return '\textsl{'; |
} |
if ($options['type'] == 'end') { |
return '}'; |
} |
} |
} |
?> |
/branches/livraison_menes/api/pear/Text/Wiki/Render/Latex/Code.php |
---|
New file |
0,0 → 1,26 |
<?php |
class Text_Wiki_Render_Latex_Code extends Text_Wiki_Render { |
/** |
* |
* Renders a token into text matching the requested format. |
* |
* @access public |
* |
* @param array $options The "options" portion of the token (second |
* element). |
* |
* @return string The text rendered from the token options. |
* |
*/ |
function token($options) |
{ |
$text = $options['text']; |
return "\\begin{verbatim}\n$text\n\\end{verbatim}\n\n"; |
} |
} |
?> |
/branches/livraison_menes/api/pear/Text/Wiki/Render/Latex/Strong.php |
---|
New file |
0,0 → 1,30 |
<?php |
class Text_Wiki_Render_Latex_Strong extends Text_Wiki_Render { |
/** |
* |
* Renders a token into text matching the requested format. |
* |
* @access public |
* |
* @param array $options The "options" portion of the token (second |
* element). |
* |
* @return string The text rendered from the token options. |
* |
*/ |
function token($options) |
{ |
if ($options['type'] == 'start') { |
return '\textbf{'; |
} |
if ($options['type'] == 'end') { |
return '}'; |
} |
} |
} |
?> |
/branches/livraison_menes/api/pear/Text/Wiki/Render/Latex/Center.php |
---|
New file |
0,0 → 1,33 |
<?php |
class Text_Wiki_Render_Latex_Center extends Text_Wiki_Render { |
/** |
* |
* Renders a token into text matching the requested format. |
* |
* @access public |
* |
* @param array $options The "options" portion of the token (second |
* element). |
* |
* @return string The text rendered from the token options. |
* |
*/ |
function token($options) |
{ |
return 'Center: NI'; |
if ($options['type'] == 'start') { |
//return "\n<center>\n"; |
return '<div style="text-align: center;">'; |
} |
if ($options['type'] == 'end') { |
//return "</center>\n"; |
return '</div>'; |
} |
} |
} |
?> |
/branches/livraison_menes/api/pear/Text/Wiki/Render/Latex/Phplookup.php |
---|
New file |
0,0 → 1,34 |
<?php |
class Text_Wiki_Render_Latex_Phplookup extends Text_Wiki_Render { |
var $conf = array('target' => '_blank'); |
/** |
* |
* Renders a token into text matching the requested format. |
* |
* @access public |
* |
* @param array $options The "options" portion of the token (second |
* element). |
* |
* @return string The text rendered from the token options. |
* |
*/ |
function token($options) |
{ |
return 'Phplookup: NI'; |
$text = trim($options['text']); |
$target = $this->getConf('target', ''); |
if ($target) { |
$target = " target=\"$target\""; |
} |
return "<a$target href=\"http://php.net/$text\">$text</a>"; |
} |
} |
?> |
/branches/livraison_menes/api/pear/Text/Wiki/Render/Latex/Colortext.php |
---|
New file |
0,0 → 1,58 |
<?php |
class Text_Wiki_Render_Latex_Colortext extends Text_Wiki_Render { |
var $colors = array( |
'aqua', |
'black', |
'blue', |
'fuchsia', |
'gray', |
'green', |
'lime', |
'maroon', |
'navy', |
'olive', |
'purple', |
'red', |
'silver', |
'teal', |
'white', |
'yellow' |
); |
/** |
* |
* Renders a token into text matching the requested format. |
* |
* @access public |
* |
* @param array $options The "options" portion of the token (second |
* element). |
* |
* @return string The text rendered from the token options. |
* |
*/ |
function token($options) |
{ |
return 'Colortext: NI'; |
$type = $options['type']; |
$color = $options['color']; |
if (! in_array($color, $this->colors)) { |
$color = '#' . $color; |
} |
if ($type == 'start') { |
return "<span style=\"color: $color;\">"; |
} |
if ($options['type'] == 'end') { |
return '</span>'; |
} |
} |
} |
?> |
/branches/livraison_menes/api/pear/Text/Wiki/Render/Latex/Include.php |
---|
New file |
0,0 → 1,8 |
<?php |
class Text_Wiki_Render_Latex_Include extends Text_Wiki_Render { |
function token() |
{ |
return ''; |
} |
} |
?> |
/branches/livraison_menes/api/pear/Text/Wiki/Render/Latex/Superscript.php |
---|
New file |
0,0 → 1,31 |
<?php |
class Text_Wiki_Render_Latex_Superscript extends Text_Wiki_Render { |
/** |
* |
* Renders a token into text matching the requested format. |
* |
* @access public |
* |
* @param array $options The "options" portion of the token (second |
* element). |
* |
* @return string The text rendered from the token options. |
* |
*/ |
function token($options) |
{ |
return 'Superscript: NI'; |
if ($options['type'] == 'start') { |
return '<sup>'; |
} |
if ($options['type'] == 'end') { |
return '</sup>'; |
} |
} |
} |
?> |
/branches/livraison_menes/api/pear/Text/Wiki/Render/Latex/Break.php |
---|
New file |
0,0 → 1,24 |
<?php |
class Text_Wiki_Render_Latex_Break extends Text_Wiki_Render { |
/** |
* |
* Renders a token into text matching the requested format. |
* |
* @access public |
* |
* @param array $options The "options" portion of the token (second |
* element). |
* |
* @return string The text rendered from the token options. |
* |
*/ |
function token($options) |
{ |
return "\\newline\n"; |
} |
} |
?> |
/branches/livraison_menes/api/pear/Text/Wiki/Render/Latex/Toc.php |
---|
New file |
0,0 → 1,30 |
<?php |
class Text_Wiki_Render_Latex_Toc extends Text_Wiki_Render { |
/** |
* |
* Renders a token into text matching the requested format. |
* |
* @access public |
* |
* @param array $options The "options" portion of the token (second |
* element). |
* |
* @return string The text rendered from the token options. |
* |
*/ |
function token($options) |
{ |
if($options['type'] == 'list_start') { |
return "\\tableofcontents\n\n"; |
} |
return ''; |
} |
} |
?> |
/branches/livraison_menes/api/pear/Text/Wiki/Render/Latex/Function.php |
---|
New file |
0,0 → 1,23 |
<?php |
class Text_Wiki_Render_Latex_Function extends Text_Wiki_Render { |
/** |
* |
* Renders a token into text matching the requested format. |
* |
* @access public |
* |
* @param array $options The "options" portion of the token (second |
* element). |
* |
* @return string The text rendered from the token options. |
* |
*/ |
function token($options) |
{ |
return "Function: NI"; |
} |
} |
?> |
/branches/livraison_menes/api/pear/Text/Wiki/Render/Latex/Table.php |
---|
New file |
0,0 → 1,93 |
<?php |
class Text_Wiki_Render_Latex_Table extends Text_Wiki_Render { |
var $cell_id = 0; |
var $cell_count = 0; |
var $is_spanning = false; |
var $conf = array( |
'css_table' => null, |
'css_tr' => null, |
'css_th' => null, |
'css_td' => null |
); |
/** |
* |
* Renders a token into text matching the requested format. |
* |
* @access public |
* |
* @param array $options The "options" portion of the token (second |
* element). |
* |
* @return string The text rendered from the token options. |
* |
*/ |
function token($options) |
{ |
// make nice variable names (type, attr, span) |
extract($options); |
switch ($type) |
{ |
case 'table_start': |
$this->cell_count = $cols; |
$tbl_start = '\begin{tabular}{|'; |
for ($a=0; $a < $this->cell_count; $a++) { |
$tbl_start .= 'l|'; |
} |
$tbl_start .= "}\n"; |
return $tbl_start; |
case 'table_end': |
return "\\hline\n\\end{tabular}\n"; |
case 'row_start': |
$this->is_spanning = false; |
$this->cell_id = 0; |
return "\\hline\n"; |
case 'row_end': |
return "\\\\\n"; |
case 'cell_start': |
if ($span > 1) { |
$col_spec = ''; |
if ($this->cell_id == 0) { |
$col_spec = '|'; |
} |
$col_spec .= 'l|'; |
$this->cell_id += $span; |
$this->is_spanning = true; |
return "\\multicolumn\{$span}\{$col_spec}{"; |
} |
$this->cell_id += 1; |
return ''; |
case 'cell_end': |
$out = ''; |
if ($this->is_spanning) { |
$this->is_spanning = false; |
$out = '}'; |
} |
if ($this->cell_id != $this->cell_count) { |
$out .= ' & '; |
} |
return $out; |
default: |
return ''; |
} |
} |
} |
?> |
/branches/livraison_menes/api/pear/Text/Wiki/Render/Latex/Raw.php |
---|
New file |
0,0 → 1,23 |
<?php |
class Text_Wiki_Render_Latex_Raw extends Text_Wiki_Render { |
/** |
* |
* Renders a token into text matching the requested format. |
* |
* @access public |
* |
* @param array $options The "options" portion of the token (second |
* element). |
* |
* @return string The text rendered from the token options. |
* |
*/ |
function token($options) |
{ |
return "Raw: ".$options['text']; |
} |
} |
?> |
/branches/livraison_menes/api/pear/Text/Wiki/Render/Latex/Deflist.php |
---|
New file |
0,0 → 1,53 |
<?php |
class Text_Wiki_Render_Latex_Deflist extends Text_Wiki_Render { |
var $conf = array( |
'css_dl' => null, |
'css_dt' => null, |
'css_dd' => null |
); |
/** |
* |
* Renders a token into text matching the requested format. |
* |
* @access public |
* |
* @param array $options The "options" portion of the token (second |
* element). |
* |
* @return string The text rendered from the token options. |
* |
*/ |
function token($options) |
{ |
$type = $options['type']; |
switch ($type) |
{ |
case 'list_start': |
return "\\begin{description}\n"; |
case 'list_end': |
return "\\end{description}\n\n"; |
case 'term_start': |
return '\item['; |
case 'term_end': |
return '] '; |
case 'narr_start': |
return '{'; |
case 'narr_end': |
return "}\n"; |
default: |
return ''; |
} |
} |
} |
?> |
/branches/livraison_menes/api/pear/Text/Wiki/Render/Latex/Horiz.php |
---|
New file |
0,0 → 1,23 |
<?php |
class Text_Wiki_Render_Latex_Horiz extends Text_Wiki_Render { |
/** |
* |
* Renders a token into text matching the requested format. |
* |
* @access public |
* |
* @param array $options The "options" portion of the token (second |
* element). |
* |
* @return string The text rendered from the token options. |
* |
*/ |
function token($options) |
{ |
return "\n\\noindent\\rule{\\textwidth}{1pt}\n"; |
} |
} |
?> |
/branches/livraison_menes/api/pear/Text/Wiki/Render/Latex/Prefilter.php |
---|
New file |
0,0 → 1,40 |
<?php |
/* vim: set expandtab tabstop=4 shiftwidth=4: */ |
// +----------------------------------------------------------------------+ |
// | PHP version 4 | |
// +----------------------------------------------------------------------+ |
// | Copyright (c) 1997-2003 The PHP Group | |
// +----------------------------------------------------------------------+ |
// | This source file is subject to version 2.0 of the PHP license, | |
// | that is bundled with this package in the file LICENSE, and is | |
// | available through the world-wide-web at | |
// | http://www.php.net/license/2_02.txt. | |
// | If you did not receive a copy of the PHP license and are unable to | |
// | obtain it through the world-wide-web, please send a note to | |
// | license@php.net so we can mail you a copy immediately. | |
// +----------------------------------------------------------------------+ |
// | Authors: Jeremy Cowgar <jeremy@cowgar.com> | |
// +----------------------------------------------------------------------+ |
// |
// $Id: Prefilter.php,v 1.1 2005-01-20 19:43:20 jpm Exp $ |
/** |
* |
* This class implements a Text_Wiki_Render_Latex to "pre-filter" source text so |
* that line endings are consistently \n, lines ending in a backslash \ |
* are concatenated with the next line, and tabs are converted to spaces. |
* |
* @author Jeremy Cowgar <jeremy@cowgar.com> |
* |
* @package Text_Wiki |
* |
*/ |
class Text_Wiki_Render_Latex_Prefilter extends Text_Wiki_Render { |
function token() |
{ |
return ''; |
} |
} |
?> |
/branches/livraison_menes/api/pear/Text/Wiki/Render/Latex/Heading.php |
---|
New file |
0,0 → 1,33 |
<?php |
class Text_Wiki_Render_Latex_Heading extends Text_Wiki_Render { |
function token($options) |
{ |
// get nice variable names (type, level) |
extract($options); |
if ($type == 'start') { |
switch ($level) |
{ |
case '1': |
return '\part{'; |
case '2': |
return '\section{'; |
case '3': |
return '\subsection{'; |
case '4': |
return '\subsubsection{'; |
case '5': |
return '\paragraph{'; |
case '6': |
return '\subparagraph{'; |
} |
} |
if ($type == 'end') { |
return "}\n"; |
} |
} |
} |
?> |
/branches/livraison_menes/api/pear/Text/Wiki/Render/Latex/Tighten.php |
---|
New file |
0,0 → 1,9 |
<?php |
class Text_Wiki_Render_Latex_Tighten extends Text_Wiki_Render { |
function token() |
{ |
return ''; |
} |
} |
?> |
/branches/livraison_menes/api/pear/Text/Wiki/Render/Latex/Html.php |
---|
New file |
0,0 → 1,25 |
<?php |
class Text_Wiki_Render_Latex_Html extends Text_Wiki_Render { |
/** |
* |
* Renders a token into text matching the requested format. |
* |
* @access public |
* |
* @param array $options The "options" portion of the token (second |
* element). |
* |
* @return string The text rendered from the token options. |
* |
*/ |
function token($options) |
{ |
print_r($this); |
return ''; |
} |
} |
?> |
/branches/livraison_menes/api/pear/Text/Wiki/Render/Latex/Paragraph.php |
---|
New file |
0,0 → 1,31 |
<?php |
class Text_Wiki_Render_Latex_Paragraph extends Text_Wiki_Render { |
/** |
* |
* Renders a token into text matching the requested format. |
* |
* @access public |
* |
* @param array $options The "options" portion of the token (second |
* element). |
* |
* @return string The text rendered from the token options. |
* |
*/ |
function token($options) |
{ |
extract($options); //type |
if ($type == 'start') { |
return ''; |
} |
if ($type == 'end') { |
return "\n\n"; |
} |
} |
} |
?> |
/branches/livraison_menes/api/pear/Text/Wiki/Render/Latex/Interwiki.php |
---|
New file |
0,0 → 1,60 |
<?php |
class Text_Wiki_Render_Latex_Interwiki extends Text_Wiki_Render { |
var $conf = array( |
'sites' => array( |
'MeatBall' => 'http://www.usemod.com/cgi-bin/mb.pl?%s', |
'Advogato' => 'http://advogato.org/%s', |
'Wiki' => 'http://c2.com/cgi/wiki?%s' |
), |
'target' => '_blank' |
); |
/** |
* |
* Renders a token into text matching the requested format. |
* |
* @access public |
* |
* @param array $options The "options" portion of the token (second |
* element). |
* |
* @return string The text rendered from the token options. |
* |
*/ |
function token($options) |
{ |
$site = $options['site']; |
$page = $options['page']; |
$text = $options['text']; |
if (isset($this->conf['sites'][$site])) { |
$href = $this->conf['sites'][$site]; |
} else { |
return $text; |
} |
// old form where page is at end, |
// or new form with %s placeholder for sprintf()? |
if (strpos($href, '%s') === false) { |
// use the old form |
$href = $href . $page; |
} else { |
// use the new form |
$href = sprintf($href, $page); |
} |
// allow for alternative targets |
$target = $this->getConf('target', ''); |
if ($target && trim($target) != '') { |
$target = " target=\"$target\""; |
} |
return "$text\\footnote\{$href}"; |
} |
} |
?> |
/branches/livraison_menes/api/pear/Text/Wiki/Render/Latex/Italic.php |
---|
New file |
0,0 → 1,5 |
<?php |
class Text_Wiki_Render_Latex_Italic extends Text_Wiki_Render_Latex_Emphasis { |
} |
?> |
/branches/livraison_menes/api/pear/Text/Wiki/Render/Latex/Blockquote.php |
---|
New file |
0,0 → 1,36 |
<?php |
class Text_Wiki_Render_Latex_Blockquote extends Text_Wiki_Render { |
var $conf = array('css' => null); |
/** |
* |
* Renders a token into text matching the requested format. |
* |
* @access public |
* |
* @param array $options The "options" portion of the token (second |
* element). |
* |
* @return string The text rendered from the token options. |
* |
*/ |
function token($options) |
{ |
$type = $options['type']; |
$level = $options['level']; |
// starting |
if ($type == 'start') { |
return "\\begin{quote}\n"; |
} |
// ending |
if ($type == 'end') { |
return "\\end{quote}\n\n"; |
} |
} |
} |
?> |
/branches/livraison_menes/api/pear/Text/Wiki/Render/Latex/Anchor.php |
---|
New file |
0,0 → 1,33 |
<?php |
/** |
* |
* This class renders an anchor target name in LaTeX. |
* |
* $Id: Anchor.php,v 1.1 2005-01-20 19:43:20 jpm Exp $ |
* |
* @author Jeremy Cowgar <jeremy@cowgar.com> |
* |
* @package Text_Wiki |
* |
*/ |
class Text_Wiki_Render_Latex_Anchor extends Text_Wiki_Render { |
function token($options) |
{ |
extract($options); // $type, $name |
if ($type == 'start') { |
//return sprintf('<a id="%s">',$name); |
return ''; |
} |
if ($type == 'end') { |
//return '</a>'; |
return ''; |
} |
} |
} |
?> |
/branches/livraison_menes/api/pear/Text/Wiki/Render/Latex/List.php |
---|
New file |
0,0 → 1,57 |
<?php |
class Text_Wiki_Render_Latex_List extends Text_Wiki_Render { |
/** |
* |
* Renders a token into text matching the requested format. |
* |
* This rendering method is syntactically and semantically compliant |
* with XHTML 1.1 in that sub-lists are part of the previous list item. |
* |
* @access public |
* |
* @param array $options The "options" portion of the token (second |
* element). |
* |
* @return string The text rendered from the token options. |
* |
*/ |
function token($options) |
{ |
// make nice variables (type, level, count) |
extract($options); |
switch ($type) |
{ |
case 'bullet_list_start': |
return "\\begin{itemize}\n"; |
case 'bullet_list_end': |
return "\\end{itemize}\n"; |
case 'number_list_start': |
return "\\begin{enumerate}\n"; |
case 'number_list_end': |
return "\\end{enumerate}\n"; |
case 'bullet_item_start': |
case 'number_item_start': |
return "\\item{"; |
case 'bullet_item_end': |
case 'number_item_end': |
return "}\n"; |
default: |
// ignore item endings and all other types. |
// item endings are taken care of by the other types |
// depending on their place in the list. |
return ''; |
break; |
} |
} |
} |
?> |
/branches/livraison_menes/api/pear/Text/Wiki/Render/Latex/Embed.php |
---|
New file |
0,0 → 1,23 |
<?php |
class Text_Wiki_Render_Latex_Embed extends Text_Wiki_Render { |
/** |
* |
* Renders a token into text matching the requested format. |
* |
* @access public |
* |
* @param array $options The "options" portion of the token (second |
* element). |
* |
* @return string The text rendered from the token options. |
* |
*/ |
function token($options) |
{ |
return "Embed: ".$options['text']; |
} |
} |
?> |
/branches/livraison_menes/api/pear/Text/Wiki/Render/Latex/Delimiter.php |
---|
New file |
0,0 → 1,25 |
<?php |
class Text_Wiki_Render_Latex_Delimiter extends Text_Wiki_Render { |
/** |
* |
* Renders a token into text matching the requested format. |
* |
* @access public |
* |
* @param array $options The "options" portion of the token (second |
* element). |
* |
* @return string The text rendered from the token options. |
* |
*/ |
function token($options) |
{ |
// TODO: Is this where I can do some LaTeX escaping for items |
// such as $ { } _ ? |
return "Delimiter: ".$options['text']; |
} |
} |
?> |
/branches/livraison_menes/api/pear/Text/Wiki/Render/Latex/Bold.php |
---|
New file |
0,0 → 1,4 |
<?php |
class Text_Wiki_Render_Latex_Bold extends Text_Wiki_Render_Latex_Strong {} |
?> |
/branches/livraison_menes/api/pear/Text/Wiki/Render/Latex/Wikilink.php |
---|
New file |
0,0 → 1,60 |
<?php |
class Text_Wiki_Render_Latex_Wikilink extends Text_Wiki_Render { |
var $conf = array( |
'pages' => array(), |
'view_url' => 'http://example.com/index.php?page=%s', |
'new_url' => 'http://example.com/new.php?page=%s', |
'new_text' => '?' |
); |
/** |
* |
* Renders a token into XHTML. |
* |
* @access public |
* |
* @param array $options The "options" portion of the token (second |
* element). |
* |
* @return string The text rendered from the token options. |
* |
*/ |
function token($options) |
{ |
// make nice variable names (page, anchor, text) |
extract($options); |
// are we checking page existence? |
$list =& $this->getConf('pages'); |
if (is_array($list)) { |
// yes, check against the page list |
$exists = in_array($page, $list); |
} else { |
// no, assume it exists |
$exists = true; |
} |
// convert *after* checking against page names so as not to mess |
// up what the user typed and what we're checking. |
$page = htmlspecialchars($page); |
$anchor = htmlspecialchars($anchor); |
$text = htmlspecialchars($text); |
$href = $this->getConf('view_url'); |
if (strpos($href, '%s') === false) { |
// use the old form (page-at-end) |
$href = $href . $page . $anchor; |
} else { |
// use the new form (sprintf format string) |
$href = sprintf($href, $page . $anchor); |
} |
// get the CSS class and generate output |
$css = $this->formatConf(' class="%s"', 'css'); |
return "$text\\footnote\{$href}"; |
} |
} |
?> |
/branches/livraison_menes/api/pear/Text/Wiki/Render/Latex/Image.php |
---|
New file |
0,0 → 1,70 |
<?php |
class Text_Wiki_Render_Latex_Image extends Text_Wiki_Render { |
var $conf = array( |
'base' => '/' |
); |
/** |
* |
* Renders a token into text matching the requested format. |
* |
* @access public |
* |
* @param array $options The "options" portion of the token (second |
* element). |
* |
* @return string The text rendered from the token options. |
* |
*/ |
function token($options) |
{ |
return 'Image: NI'; |
$src = '"' . |
$this->getConf('base', '/') . |
$options['src'] . '"'; |
if (isset($options['attr']['link'])) { |
// this image has a link |
if (strpos($options['attr']['link'], '://')) { |
// it's a URL |
$href = $options['attr']['link']; |
} else { |
$href = $this->wiki->getRenderConf('xhtml', 'wikilink', 'view_url') . |
$options['attr']['link']; |
} |
} else { |
// image is not linked |
$href = null; |
} |
// unset these so they don't show up as attributes |
unset($options['attr']['link']); |
$attr = ''; |
$alt = false; |
foreach ($options['attr'] as $key => $val) { |
if (strtolower($key) == 'alt') { |
$alt = true; |
} |
$attr .= " $key=\"$val\""; |
} |
// always add an "alt" attribute per Stephane Solliec |
if (! $alt) { |
$attr .= ' alt="' . basename($options['src']) . '"'; |
} |
if ($href) { |
return "<a href=\"$href\"><img src=$src$attr/></a>"; |
} else { |
return "<img src=$src$attr/>"; |
} |
} |
} |
?> |
/branches/livraison_menes/api/pear/Text/Wiki/Render/Xhtml.php |
---|
New file |
0,0 → 1,33 |
<?php |
class Text_Wiki_Render_Xhtml extends Text_Wiki_Render { |
var $conf = array('translate' => HTML_ENTITIES); |
function pre() |
{ |
// attempt to translate HTML entities in the source before continuing. |
$type = $this->getConf('translate', null); |
// are we translating html? |
if ($type) { |
// yes! get the translation table. |
$xlate = get_html_translation_table($type); |
// remove the delimiter character it doesn't get translated |
unset($xlate[$this->wiki->delim]); |
// translate! |
$this->wiki->source = strtr($this->wiki->source, $xlate); |
} |
} |
function post() |
{ |
return; |
} |
} |
?> |
/branches/livraison_menes/api/pear/Text/Wiki/Render/Latex.php |
---|
New file |
0,0 → 1,90 |
<?php |
/** |
* |
* Formats parsed Text_Wiki for LaTeX rendering. |
* |
* $Id: Latex.php,v 1.1 2005-01-20 19:44:30 jpm Exp $ |
* |
* @author Jeremy Cowgar <jeremy@cowgar.com> |
* |
* @package Text_Wiki |
* |
* @todo [http://google.com] becomes 1 with a LaTeX footnote in subscript. |
* This should be a normal LaTeX footnote associated with the |
* previous word? |
* |
* @todo parse "..." to be ``...'' |
* |
* @todo parse '...' to be `...' |
* |
* @todo move escape_latex to a static function, move escaping to the |
* individual .php files they are associated with |
* |
* @todo allow the user to add conf items to do things like |
* + A custom document header |
* + Custom page headings |
* + Include packages |
* + Set Title, Author, Date |
* + Include a title page |
* + Not output Document Head/Foot (maybe combinding many pages?) |
* |
*/ |
class Text_Wiki_Render_Latex extends Text_Wiki_Render { |
function escape_latex ($txt) { |
$txt = str_replace("\\", "\\\\", $txt); |
$txt = str_replace('#', '\#', $txt); |
$txt = str_replace('$', '\$', $txt); |
$txt = str_replace('%', '\%', $txt); |
$txt = str_replace('^', '\^', $txt); |
$txt = str_replace('&', '\&', $txt); |
$txt = str_replace('_', '\_', $txt); |
$txt = str_replace('{', '\{', $txt); |
$txt = str_replace('}', '\}', $txt); |
// Typeset things a bit prettier than normas |
$txt = str_replace('~', '$\sim$', $txt); |
$txt = str_replace('...', '\ldots', $txt); |
return $txt; |
} |
function escape($tok, $ele) { |
if (isset($tok[$ele])) { |
$tok[$ele] = $this->escape_latex($tok[$ele]); |
} |
return $tok; |
} |
function pre() |
{ |
foreach ($this->wiki->tokens as $k => $tok) { |
if ($tok[0] == 'Code') { |
continue; |
} |
$tok[1] = $this->escape($tok[1], 'text'); |
$tok[1] = $this->escape($tok[1], 'page'); |
$tok[1] = $this->escape($tok[1], 'href'); |
$this->wiki->tokens[$k] = $tok; |
} |
$this->wiki->source = $this->escape_latex($this->wiki->source); |
return |
"\\documentclass{article}\n". |
"\\usepackage{ulem}\n". |
"\\pagestyle{headings}\n". |
"\\begin{document}\n"; |
} |
function post() |
{ |
return "\\end{document}\n"; |
} |
} |
?> |
/branches/livraison_menes/api/pear/Text/Wiki/Render/Plain/Tighten.php |
---|
New file |
0,0 → 1,10 |
<?php |
class Text_Wiki_Render_Plain_Tighten extends Text_Wiki_Render { |
function token() |
{ |
return ''; |
} |
} |
?> |
/branches/livraison_menes/api/pear/Text/Wiki/Render/Plain/Html.php |
---|
New file |
0,0 → 1,24 |
<?php |
class Text_Wiki_Render_Plain_Html extends Text_Wiki_Render { |
/** |
* |
* Renders a token into text matching the requested format. |
* |
* @access public |
* |
* @param array $options The "options" portion of the token (second |
* element). |
* |
* @return string The text rendered from the token options. |
* |
*/ |
function token($options) |
{ |
return strip_tags($options['text']); |
} |
} |
?> |
/branches/livraison_menes/api/pear/Text/Wiki/Render/Plain/Interwiki.php |
---|
New file |
0,0 → 1,23 |
<?php |
class Text_Wiki_Render_Plain_Interwiki extends Text_Wiki_Render { |
/** |
* |
* Renders a token into text matching the requested format. |
* |
* @access public |
* |
* @param array $options The "options" portion of the token (second |
* element). |
* |
* @return string The text rendered from the token options. |
* |
*/ |
function token($options) |
{ |
return $options['text']; |
} |
} |
?> |
/branches/livraison_menes/api/pear/Text/Wiki/Render/Plain/Paragraph.php |
---|
New file |
0,0 → 1,31 |
<?php |
class Text_Wiki_Render_Plain_Paragraph extends Text_Wiki_Render { |
/** |
* |
* Renders a token into text matching the requested format. |
* |
* @access public |
* |
* @param array $options The "options" portion of the token (second |
* element). |
* |
* @return string The text rendered from the token options. |
* |
*/ |
function token($options) |
{ |
extract($options); //type |
if ($type == 'start') { |
return ''; |
} |
if ($type == 'end') { |
return "\n\n"; |
} |
} |
} |
?> |
/branches/livraison_menes/api/pear/Text/Wiki/Render/Plain/Italic.php |
---|
New file |
0,0 → 1,23 |
<?php |
class Text_Wiki_Render_Plain_Italic extends Text_Wiki_Render { |
/** |
* |
* Renders a token into text matching the requested format. |
* |
* @access public |
* |
* @param array $options The "options" portion of the token (second |
* element). |
* |
* @return string The text rendered from the token options. |
* |
*/ |
function token($options) |
{ |
return; |
} |
} |
?> |
/branches/livraison_menes/api/pear/Text/Wiki/Render/Plain/Blockquote.php |
---|
New file |
0,0 → 1,39 |
<?php |
class Text_Wiki_Render_Plain_Blockquote extends Text_Wiki_Render { |
/** |
* |
* Renders a token into text matching the requested format. |
* |
* @access public |
* |
* @param array $options The "options" portion of the token (second |
* element). |
* |
* @return string The text rendered from the token options. |
* |
*/ |
function token($options) |
{ |
$type = $options['type']; |
$level = $options['level']; |
// set up indenting so that the results look nice; we do this |
// in two steps to avoid str_pad mathematics. ;-) |
$pad = str_pad('', $level + 1, "\t"); |
$pad = str_replace("\t", ' ', $pad); |
// starting |
if ($type == 'start') { |
return "\n$pad"; |
} |
// ending |
if ($type == 'end') { |
return "\n$pad"; |
} |
} |
} |
?> |
/branches/livraison_menes/api/pear/Text/Wiki/Render/Plain/Anchor.php |
---|
New file |
0,0 → 1,23 |
<?php |
/** |
* |
* This class renders an anchor target name in XHTML. |
* |
* @author Manuel Holtgrewe <purestorm at ggnore dot net> |
* |
* @author Paul M. Jones <pmjones at ciaweb dot net> |
* |
* @package Text_Wiki |
* |
*/ |
class Text_Wiki_Render_Plain_Anchor extends Text_Wiki_Render { |
function token($options) |
{ |
return $options['name']; |
} |
} |
?> |
/branches/livraison_menes/api/pear/Text/Wiki/Render/Plain/List.php |
---|
New file |
0,0 → 1,68 |
<?php |
class Text_Wiki_Render_Plain_List extends Text_Wiki_Render { |
/** |
* |
* Renders a token into text matching the requested format. |
* |
* This rendering method is syntactically and semantically compliant |
* with XHTML 1.1 in that sub-lists are part of the previous list item. |
* |
* @access public |
* |
* @param array $options The "options" portion of the token (second |
* element). |
* |
* @return string The text rendered from the token options. |
* |
*/ |
function token($options) |
{ |
// make nice variables (type, level, count) |
extract($options); |
// set up indenting so that the results look nice; we do this |
// in two steps to avoid str_pad mathematics. ;-) |
$pad = str_pad('', $level, "\t"); |
$pad = str_replace("\t", ' ', $pad); |
switch ($type) { |
case 'bullet_list_start': |
break; |
case 'bullet_list_end': |
if ($level == 0) { |
return "\n\n"; |
} |
break; |
case 'number_list_start': |
break; |
case 'number_list_end': |
if ($level == 0) { |
return "\n\n"; |
} |
break; |
case 'bullet_item_start': |
case 'number_item_start': |
return "\n$pad"; |
break; |
case 'bullet_item_end': |
case 'number_item_end': |
default: |
// ignore item endings and all other types. |
// item endings are taken care of by the other types |
// depending on their place in the list. |
return; |
break; |
} |
} |
} |
?> |
/branches/livraison_menes/api/pear/Text/Wiki/Render/Plain/Embed.php |
---|
New file |
0,0 → 1,23 |
<?php |
class Text_Wiki_Render_Plain_Embed extends Text_Wiki_Render { |
/** |
* |
* Renders a token into text matching the requested format. |
* |
* @access public |
* |
* @param array $options The "options" portion of the token (second |
* element). |
* |
* @return string The text rendered from the token options. |
* |
*/ |
function token($options) |
{ |
return strip_tags($options['text']); |
} |
} |
?> |
/branches/livraison_menes/api/pear/Text/Wiki/Render/Plain/Delimiter.php |
---|
New file |
0,0 → 1,23 |
<?php |
class Text_Wiki_Render_Plain_Delimiter extends Text_Wiki_Render { |
/** |
* |
* Renders a token into text matching the requested format. |
* |
* @access public |
* |
* @param array $options The "options" portion of the token (second |
* element). |
* |
* @return string The text rendered from the token options. |
* |
*/ |
function token($options) |
{ |
return; |
} |
} |
?> |
/branches/livraison_menes/api/pear/Text/Wiki/Render/Plain/Bold.php |
---|
New file |
0,0 → 1,23 |
<?php |
class Text_Wiki_Render_Plain_Bold extends Text_Wiki_Render { |
/** |
* |
* Renders a token into text matching the requested format. |
* |
* @access public |
* |
* @param array $options The "options" portion of the token (second |
* element). |
* |
* @return string The text rendered from the token options. |
* |
*/ |
function token($options) |
{ |
return; |
} |
} |
?> |
/branches/livraison_menes/api/pear/Text/Wiki/Render/Plain/Wikilink.php |
---|
New file |
0,0 → 1,24 |
<?php |
class Text_Wiki_Render_Plain_Wikilink extends Text_Wiki_Render { |
/** |
* |
* Renders a token into plain text. |
* |
* @access public |
* |
* @param array $options The "options" portion of the token (second |
* element). |
* |
* @return string The text rendered from the token options. |
* |
*/ |
function token($options) |
{ |
return $options['text']; |
} |
} |
?> |
/branches/livraison_menes/api/pear/Text/Wiki/Render/Plain/Image.php |
---|
New file |
0,0 → 1,22 |
<?php |
class Text_Wiki_Render_Plain_Image extends Text_Wiki_Render { |
/** |
* |
* Renders a token into text matching the requested format. |
* |
* @access public |
* |
* @param array $options The "options" portion of the token (second |
* element). |
* |
* @return string The text rendered from the token options. |
* |
*/ |
function token($options) |
{ |
return; |
} |
} |
?> |
/branches/livraison_menes/api/pear/Text/Wiki/Render/Plain/Tt.php |
---|
New file |
0,0 → 1,24 |
<?php |
class Text_Wiki_Render_Plain_tt extends Text_Wiki_Render { |
/** |
* |
* Renders a token into text matching the requested format. |
* |
* @access public |
* |
* @param array $options The "options" portion of the token (second |
* element). |
* |
* @return string The text rendered from the token options. |
* |
*/ |
function token($options) |
{ |
return; |
} |
} |
?> |
/branches/livraison_menes/api/pear/Text/Wiki/Render/Plain/Revise.php |
---|
New file |
0,0 → 1,24 |
<?php |
class Text_Wiki_Render_Plain_Revise extends Text_Wiki_Render { |
/** |
* |
* Renders a token into text matching the requested format. |
* |
* @access public |
* |
* @param array $options The "options" portion of the token (second |
* element). |
* |
* @return string The text rendered from the token options. |
* |
*/ |
function token($options) |
{ |
return; |
} |
} |
?> |
/branches/livraison_menes/api/pear/Text/Wiki/Render/Plain/Freelink.php |
---|
New file |
0,0 → 1,23 |
<?php |
class Text_Wiki_Render_Plain_Freelink extends Text_Wiki_Render { |
/** |
* |
* Renders a token into text matching the requested format. |
* |
* @access public |
* |
* @param array $options The "options" portion of the token (second |
* element). |
* |
* @return string The text rendered from the token options. |
* |
*/ |
function token($options) |
{ |
return $options['text']; |
} |
} |
?> |
/branches/livraison_menes/api/pear/Text/Wiki/Render/Plain/Newline.php |
---|
New file |
0,0 → 1,12 |
<?php |
class Text_Wiki_Render_Plain_Newline extends Text_Wiki_Render { |
function token($options) |
{ |
return "\n"; |
} |
} |
?> |
/branches/livraison_menes/api/pear/Text/Wiki/Render/Plain/Url.php |
---|
New file |
0,0 → 1,25 |
<?php |
class Text_Wiki_Render_Plain_Url extends Text_Wiki_Render { |
/** |
* |
* Renders a token into text matching the requested format. |
* |
* @access public |
* |
* @param array $options The "options" portion of the token (second |
* element). |
* |
* @return string The text rendered from the token options. |
* |
*/ |
function token($options) |
{ |
return $options['text']; |
} |
} |
?> |
/branches/livraison_menes/api/pear/Text/Wiki/Render/Plain/Emphasis.php |
---|
New file |
0,0 → 1,23 |
<?php |
class Text_Wiki_Render_Plain_Emphasis extends Text_Wiki_Render { |
/** |
* |
* Renders a token into text matching the requested format. |
* |
* @access public |
* |
* @param array $options The "options" portion of the token (second |
* element). |
* |
* @return string The text rendered from the token options. |
* |
*/ |
function token($options) |
{ |
return; |
} |
} |
?> |
/branches/livraison_menes/api/pear/Text/Wiki/Render/Plain/Code.php |
---|
New file |
0,0 → 1,24 |
<?php |
class Text_Wiki_Render_Plain_Code extends Text_Wiki_Render { |
/** |
* |
* Renders a token into text matching the requested format. |
* |
* @access public |
* |
* @param array $options The "options" portion of the token (second |
* element). |
* |
* @return string The text rendered from the token options. |
* |
*/ |
function token($options) |
{ |
return "\n" . $options['text'] . "\n\n"; |
} |
} |
?> |
/branches/livraison_menes/api/pear/Text/Wiki/Render/Plain/Strong.php |
---|
New file |
0,0 → 1,24 |
<?php |
class Text_Wiki_Render_Plain_Strong extends Text_Wiki_Render { |
/** |
* |
* Renders a token into text matching the requested format. |
* |
* @access public |
* |
* @param array $options The "options" portion of the token (second |
* element). |
* |
* @return string The text rendered from the token options. |
* |
*/ |
function token($options) |
{ |
return; |
} |
} |
?> |
/branches/livraison_menes/api/pear/Text/Wiki/Render/Plain/Center.php |
---|
New file |
0,0 → 1,23 |
<?php |
class Text_Wiki_Render_Plain_Center extends Text_Wiki_Render { |
/** |
* |
* Renders a token into text matching the requested format. |
* |
* @access public |
* |
* @param array $options The "options" portion of the token (second |
* element). |
* |
* @return string The text rendered from the token options. |
* |
*/ |
function token($options) |
{ |
return; |
} |
} |
?> |
/branches/livraison_menes/api/pear/Text/Wiki/Render/Plain/Phplookup.php |
---|
New file |
0,0 → 1,25 |
<?php |
class Text_Wiki_Render_Plain_Phplookup extends Text_Wiki_Render { |
var $conf = array('target' => '_blank'); |
/** |
* |
* Renders a token into text matching the requested format. |
* |
* @access public |
* |
* @param array $options The "options" portion of the token (second |
* element). |
* |
* @return string The text rendered from the token options. |
* |
*/ |
function token($options) |
{ |
return trim($options['text']); |
} |
} |
?> |
/branches/livraison_menes/api/pear/Text/Wiki/Render/Plain/Superscript.php |
---|
New file |
0,0 → 1,23 |
<?php |
class Text_Wiki_Render_Plain_Superscript extends Text_Wiki_Render { |
/** |
* |
* Renders a token into text matching the requested format. |
* |
* @access public |
* |
* @param array $options The "options" portion of the token (second |
* element). |
* |
* @return string The text rendered from the token options. |
* |
*/ |
function token($options) |
{ |
return; |
} |
} |
?> |
/branches/livraison_menes/api/pear/Text/Wiki/Render/Plain/Include.php |
---|
New file |
0,0 → 1,8 |
<?php |
class Text_Wiki_Render_Plain_Include extends Text_Wiki_Render { |
function token() |
{ |
return ''; |
} |
} |
?> |
/branches/livraison_menes/api/pear/Text/Wiki/Render/Plain/Colortext.php |
---|
New file |
0,0 → 1,23 |
<?php |
class Text_Wiki_Render_Plain_Colortext extends Text_Wiki_Render { |
/** |
* |
* Renders a token into text matching the requested format. |
* |
* @access public |
* |
* @param array $options The "options" portion of the token (second |
* element). |
* |
* @return string The text rendered from the token options. |
* |
*/ |
function token($options) |
{ |
return; |
} |
} |
?> |
/branches/livraison_menes/api/pear/Text/Wiki/Render/Plain/Break.php |
---|
New file |
0,0 → 1,24 |
<?php |
class Text_Wiki_Render_Plain_Break extends Text_Wiki_Render { |
/** |
* |
* Renders a token into text matching the requested format. |
* |
* @access public |
* |
* @param array $options The "options" portion of the token (second |
* element). |
* |
* @return string The text rendered from the token options. |
* |
*/ |
function token($options) |
{ |
return "\n"; |
} |
} |
?> |
/branches/livraison_menes/api/pear/Text/Wiki/Render/Plain/Function.php |
---|
New file |
0,0 → 1,39 |
<?php |
// $Id: Function.php,v 1.1 2005-01-20 19:43:21 jpm Exp $ |
class Text_Wiki_Render_Plain_Function extends Text_Wiki_Render { |
/** |
* |
* Renders a token into text matching the requested format. |
* |
* @access public |
* |
* @param array $options The "options" portion of the token (second |
* element). |
* |
* @return string The text rendered from the token options. |
* |
*/ |
function token($options) |
{ |
extract($options); // access, return, name, params, throws |
$output = "$access $return $name ( "; |
foreach ($params as $key => $val) { |
$output .= "{$val['type']} {$val['descr']} {$val['default']} "; |
} |
$output .= ') '; |
foreach ($throws as $key => $val) { |
$output .= "{$val['type']} {$val['descr']} "; |
} |
return $output; |
} |
} |
?> |
/branches/livraison_menes/api/pear/Text/Wiki/Render/Plain/Toc.php |
---|
New file |
0,0 → 1,39 |
<?php |
class Text_Wiki_Render_Plain_Toc extends Text_Wiki_Render { |
/** |
* |
* Renders a token into text matching the requested format. |
* |
* @access public |
* |
* @param array $options The "options" portion of the token (second |
* element). |
* |
* @return string The text rendered from the token options. |
* |
*/ |
function token($options) |
{ |
// type, count, level |
extract($options); |
if ($type == 'item_start') { |
// build some indenting spaces for the text |
$indent = ($level - 2) * 4; |
$pad = str_pad('', $indent); |
return $pad; |
} |
if ($type == 'item_end') { |
return "\n"; |
} |
} |
} |
?> |
/branches/livraison_menes/api/pear/Text/Wiki/Render/Plain/Table.php |
---|
New file |
0,0 → 1,57 |
<?php |
class Text_Wiki_Render_Plain_Table extends Text_Wiki_Render { |
/** |
* |
* Renders a token into text matching the requested format. |
* |
* @access public |
* |
* @param array $options The "options" portion of the token (second |
* element). |
* |
* @return string The text rendered from the token options. |
* |
*/ |
function token($options) |
{ |
// make nice variable names (type, attr, span) |
extract($options); |
$pad = ' '; |
switch ($type) { |
case 'table_start': |
return; |
break; |
case 'table_end': |
return; |
break; |
case 'row_start': |
return; |
break; |
case 'row_end': |
return " ||\n"; |
break; |
case 'cell_start': |
return " || "; |
break; |
case 'cell_end': |
return; |
break; |
default: |
return ''; |
} |
} |
} |
?> |
/branches/livraison_menes/api/pear/Text/Wiki/Render/Plain/Raw.php |
---|
New file |
0,0 → 1,23 |
<?php |
class Text_Wiki_Render_Plain_Raw extends Text_Wiki_Render { |
/** |
* |
* Renders a token into text matching the requested format. |
* |
* @access public |
* |
* @param array $options The "options" portion of the token (second |
* element). |
* |
* @return string The text rendered from the token options. |
* |
*/ |
function token($options) |
{ |
return $options['text']; |
} |
} |
?> |
/branches/livraison_menes/api/pear/Text/Wiki/Render/Plain/Deflist.php |
---|
New file |
0,0 → 1,59 |
<?php |
class Text_Wiki_Render_Plain_Deflist extends Text_Wiki_Render { |
/** |
* |
* Renders a token into text matching the requested format. |
* |
* @access public |
* |
* @param array $options The "options" portion of the token (second |
* element). |
* |
* @return string The text rendered from the token options. |
* |
*/ |
function token($options) |
{ |
$type = $options['type']; |
$pad = " "; |
switch ($type) { |
case 'list_start': |
return "\n"; |
break; |
case 'list_end': |
return "\n\n"; |
break; |
case 'term_start': |
// done! |
return $pad; |
break; |
case 'term_end': |
return "\n"; |
break; |
case 'narr_start': |
// done! |
return $pad . $pad; |
break; |
case 'narr_end': |
return "\n"; |
break; |
default: |
return ''; |
} |
} |
} |
?> |
/branches/livraison_menes/api/pear/Text/Wiki/Render/Plain/Horiz.php |
---|
New file |
0,0 → 1,23 |
<?php |
class Text_Wiki_Render_Plain_Horiz extends Text_Wiki_Render { |
/** |
* |
* Renders a token into text matching the requested format. |
* |
* @access public |
* |
* @param array $options The "options" portion of the token (second |
* element). |
* |
* @return string The text rendered from the token options. |
* |
*/ |
function token($options) |
{ |
return "\n"; |
} |
} |
?> |
/branches/livraison_menes/api/pear/Text/Wiki/Render/Plain/Prefilter.php |
---|
New file |
0,0 → 1,40 |
<?php |
/* vim: set expandtab tabstop=4 shiftwidth=4: */ |
// +----------------------------------------------------------------------+ |
// | PHP version 4 | |
// +----------------------------------------------------------------------+ |
// | Copyright (c) 1997-2003 The PHP Group | |
// +----------------------------------------------------------------------+ |
// | This source file is subject to version 2.0 of the PHP license, | |
// | that is bundled with this package in the file LICENSE, and is | |
// | available through the world-wide-web at | |
// | http://www.php.net/license/2_02.txt. | |
// | If you did not receive a copy of the PHP license and are unable to | |
// | obtain it through the world-wide-web, please send a note to | |
// | license@php.net so we can mail you a copy immediately. | |
// +----------------------------------------------------------------------+ |
// | Authors: Paul M. Jones <pmjones@ciaweb.net> | |
// +----------------------------------------------------------------------+ |
// |
// $Id: Prefilter.php,v 1.1 2005-01-20 19:43:21 jpm Exp $ |
/** |
* |
* This class implements a Text_Wiki_Render_Xhtml to "pre-filter" source text so |
* that line endings are consistently \n, lines ending in a backslash \ |
* are concatenated with the next line, and tabs are converted to spaces. |
* |
* @author Paul M. Jones <pmjones@ciaweb.net> |
* |
* @package Text_Wiki |
* |
*/ |
class Text_Wiki_Render_Plain_Prefilter extends Text_Wiki_Render { |
function token() |
{ |
return ''; |
} |
} |
?> |
/branches/livraison_menes/api/pear/Text/Wiki/Render/Plain/Heading.php |
---|
New file |
0,0 → 1,14 |
<?php |
class Text_Wiki_Render_Plain_Heading extends Text_Wiki_Render { |
function token($options) |
{ |
if ($options['type'] == 'end') { |
return "\n\n"; |
} else { |
return "\n"; |
} |
} |
} |
?> |
/branches/livraison_menes/api/pear/Text/Wiki/Parse.php |
---|
New file |
0,0 → 1,253 |
<?php |
/** |
* |
* Baseline rule class for extension into a "real" parser component. |
* |
* Text_Wiki_Rule classes do not stand on their own; they are called by a |
* Text_Wiki object, typcially in the transform()method. Each rule class |
* performs three main activities: parse, process, and render. |
* |
* The parse() method takes a regex and applies it to the whole block of |
* source text at one time. Each match is sent as $matches to the |
* process() method. |
* |
* The process() method acts on the matched text from the source, and |
* then processes the source text is some way. This may mean the |
* creation of a delimited token using addToken(). In every case, the |
* process() method returns the text that should replace the matched text |
* from parse(). |
* |
* @author Paul M. Jones <pmjones@ciaweb.net> |
* |
* @package Text_Wiki |
* |
* $Id: Parse.php,v 1.1 2005-01-20 19:43:20 jpm Exp $ |
* |
*/ |
class Text_Wiki_Parse { |
/** |
* |
* Configuration options for this parser rule. |
* |
* @access public |
* |
* @var string |
* |
*/ |
var $conf = array(); |
/** |
* |
* Regular expression to find matching text for this rule. |
* |
* @access public |
* |
* @var string |
* |
* @see parse() |
* |
*/ |
var $regex = null; |
/** |
* |
* The name of this rule for new token array elements. |
* |
* @access public |
* |
* @var string |
* |
*/ |
var $rule = null; |
/** |
* |
* A reference to the calling Text_Wiki object. |
* |
* This is needed so that each rule has access to the same source |
* text, token set, URLs, interwiki maps, page names, etc. |
* |
* @access public |
* |
* @var object |
*/ |
var $wiki = null; |
/** |
* |
* Constructor for this parser rule. |
* |
* @access public |
* |
* @param object &$obj The calling "parent" Text_Wiki object. |
* |
*/ |
function Text_Wiki_Parse(&$obj) |
{ |
// set the reference to the calling Text_Wiki object; |
// this allows us access to the shared source text, token |
// array, etc. |
$this->wiki =& $obj; |
// set the name of this rule; generally used when adding |
// to the tokens array. strip off the Text_Wiki_Parse_ portion. |
// text_wiki_parse_ |
// 0123456789012345 |
$tmp = substr(get_class($this), 16); |
$this->rule = ucwords(strtolower($tmp)); |
// override config options for the rule if specified |
if (isset($this->wiki->parseConf[$this->rule]) && |
is_array($this->wiki->parseConf[$this->rule])) { |
$this->conf = array_merge( |
$this->conf, |
$this->wiki->parseConf[$this->rule] |
); |
} |
} |
/** |
* |
* Abstrct method to parse source text for matches. |
* |
* Applies the rule's regular expression to the source text, passes |
* every match to the process() method, and replaces the matched text |
* with the results of the processing. |
* |
* @access public |
* |
* @see Text_Wiki_Parse::process() |
* |
*/ |
function parse() |
{ |
$this->wiki->source = preg_replace_callback( |
$this->regex, |
array(&$this, 'process'), |
$this->wiki->source |
); |
} |
/** |
* |
* Abstract method to generate replacements for matched text. |
* |
* @access public |
* |
* @param array $matches An array of matches from the parse() method |
* as generated by preg_replace_callback. $matches[0] is the full |
* matched string, $matches[1] is the first matched pattern, |
* $matches[2] is the second matched pattern, and so on. |
* |
* @return string The processed text replacement; defaults to the |
* full matched string (i.e., no changes to the text). |
* |
* @see Text_Wiki_Parse::parse() |
* |
*/ |
function process(&$matches) |
{ |
return $matches[0]; |
} |
/** |
* |
* Simple method to safely get configuration key values. |
* |
* @access public |
* |
* @param string $key The configuration key. |
* |
* @param mixed $default If the key does not exist, return this value |
* instead. |
* |
* @return mixed The configuration key value (if it exists) or the |
* default value (if not). |
* |
*/ |
function getConf($key, $default = null) |
{ |
if (isset($this->conf[$key])) { |
return $this->conf[$key]; |
} else { |
return $default; |
} |
} |
/** |
* |
* Extract 'attribute="value"' portions of wiki markup. |
* |
* This kind of markup is typically used only in macros, but is useful |
* anywhere. |
* |
* The syntax is pretty strict; there can be no spaces between the |
* option name, the equals, and the first double-quote; the value |
* must be surrounded by double-quotes. You can escape characters in |
* the value with a backslash, and the backslash will be stripped for |
* you. |
* |
* @access public |
* |
* @param string $text The "attributes" portion of markup. |
* |
* @return array An associative array of key-value pairs where the |
* key is the option name and the value is the option value. |
* |
*/ |
function getAttrs($text) |
{ |
// find the =" sections; |
$tmp = explode('="', trim($text)); |
// basic setup |
$k = count($tmp) - 1; |
$attrs = array(); |
$key = null; |
// loop through the sections |
foreach ($tmp as $i => $val) { |
// first element is always the first key |
if ($i == 0) { |
$key = trim($val); |
continue; |
} |
// find the last double-quote in the value. |
// the part to the left is the value for the last key, |
// the part to the right is the next key name |
$pos = strrpos($val, '"'); |
$attrs[$key] = stripslashes(substr($val, 0, $pos)); |
$key = trim(substr($val, $pos+1)); |
} |
return $attrs; |
} |
} |
?> |
/branches/livraison_menes/api/pear/Text/Wiki/Render.php |
---|
New file |
0,0 → 1,167 |
<?php |
class Text_Wiki_Render { |
/** |
* |
* Configuration options for this render rule. |
* |
* @access public |
* |
* @var string |
* |
*/ |
var $conf = array(); |
/** |
* |
* The name of this rule's format. |
* |
* @access public |
* |
* @var string |
* |
*/ |
var $format = null; |
/** |
* |
* The name of this rule's token array elements. |
* |
* @access public |
* |
* @var string |
* |
*/ |
var $rule = null; |
/** |
* |
* A reference to the calling Text_Wiki object. |
* |
* This is needed so that each rule has access to the same source |
* text, token set, URLs, interwiki maps, page names, etc. |
* |
* @access public |
* |
* @var object |
*/ |
var $wiki = null; |
/** |
* |
* Constructor for this render format or rule. |
* |
* @access public |
* |
* @param object &$obj The calling "parent" Text_Wiki object. |
* |
*/ |
function Text_Wiki_Render(&$obj) |
{ |
// keep a reference to the calling Text_Wiki object |
$this->wiki =& $obj; |
// get the config-key-name for this object, |
// strip the Text_Wiki_Render_ part |
// 01234567890123456 |
$tmp = get_class($this); |
$tmp = substr($tmp, 17); |
// split into pieces at the _ mark. |
// first part is format, second part is rule. |
$part = explode('_', $tmp); |
$this->format = isset($part[0]) ? ucwords(strtolower($part[0])) : null; |
$this->rule = isset($part[1]) ? ucwords(strtolower($part[1])) : null; |
// is there a format but no rule? |
// then this is the "main" render object, with |
// pre() and post() methods. |
if ($this->format && ! $this->rule && |
isset($this->wiki->formatConf[$this->format]) && |
is_array($this->wiki->formatConf[$this->format])) { |
// this is a format render object |
$this->conf = array_merge( |
$this->conf, |
$this->wiki->formatConf[$this->format] |
); |
} |
// is there a format and a rule? |
if ($this->format && $this->rule && |
isset($this->wiki->renderConf[$this->format][$this->rule]) && |
is_array($this->wiki->renderConf[$this->format][$this->rule])) { |
// this is a rule render object |
$this->conf = array_merge( |
$this->conf, |
$this->wiki->renderConf[$this->format][$this->rule] |
); |
} |
} |
/** |
* |
* Simple method to safely get configuration key values. |
* |
* @access public |
* |
* @param string $key The configuration key. |
* |
* @param mixed $default If the key does not exist, return this value |
* instead. |
* |
* @return mixed The configuration key value (if it exists) or the |
* default value (if not). |
* |
*/ |
function getConf($key, $default = null) |
{ |
if (isset($this->conf[$key])) { |
return $this->conf[$key]; |
} else { |
return $default; |
} |
} |
/** |
* |
* Simple method to wrap a configuration in an sprintf() format. |
* |
* @access public |
* |
* @param string $key The configuration key. |
* |
* @param string $format The sprintf() format string. |
* |
* @return mixed The formatted configuration key value (if it exists) |
* or null (if it does not). |
* |
*/ |
function formatConf($format, $key) |
{ |
if (isset($this->conf[$key])) { |
return sprintf($format, $this->conf[$key]); |
} else { |
return null; |
} |
} |
} |
?> |
/branches/livraison_menes/api/pear/Text/Wiki.php |
---|
New file |
0,0 → 1,1258 |
<?php |
/** |
* The baseline abstract parser class. |
*/ |
require_once 'Wiki/Parse.php'; |
/** |
* The baseline abstract render class. |
*/ |
require_once 'Wiki/Render.php'; |
/** |
* |
* Parse structured wiki text and render into arbitrary formats such as XHTML. |
* |
* This is the "master" class for handling the management and convenience |
* functions to transform Wiki-formatted text. |
* |
* $Id: Wiki.php,v 1.2 2005-06-24 10:47:09 jpm Exp $ |
* |
* @author Paul M. Jones <pmjones@ciaweb.net> |
* |
* @package Text_Wiki |
* |
* @version 0.23.1 |
* |
* @license LGPL |
* |
*/ |
class Text_Wiki { |
/** |
* |
* The default list of rules, in order, to apply to the source text. |
* |
* @access public |
* |
* @var array |
* |
*/ |
var $rules = array( |
'Prefilter', |
'Delimiter', |
'Code', |
'Function', |
'Html', |
'Raw', |
'Include', |
'Embed', |
'Anchor', |
'Heading', |
'Toc', |
'Horiz', |
'Break', |
'Blockquote', |
'List', |
'Deflist', |
'Table', |
'Image', |
'Phplookup', |
'Center', |
'Newline', |
'Paragraph', |
'Url', |
'Freelink', |
'Interwiki', |
'Wikilink', |
'Colortext', |
'Strong', |
'Bold', |
'Emphasis', |
'Italic', |
'Tt', |
'Superscript', |
'Revise', |
'Tighten' |
); |
/** |
* |
* The list of rules to not-apply to the source text. |
* |
* @access public |
* |
* @var array |
* |
*/ |
var $disable = array( |
'Html', |
'Include', |
'Embed' |
); |
/** |
* |
* Custom configuration for rules at the parsing stage. |
* |
* In this array, the key is the parsing rule name, and the value is |
* an array of key-value configuration pairs corresponding to the $conf |
* property in the target parsing rule. |
* |
* For example: |
* |
* <code> |
* $parseConf = array( |
* 'Include' => array( |
* 'base' => '/path/to/scripts/' |
* ) |
* ); |
* </code> |
* |
* Note that most default rules do not need any parsing configuration. |
* |
* @access public |
* |
* @var array |
* |
*/ |
var $parseConf = array(); |
/** |
* |
* Custom configuration for rules at the rendering stage. |
* |
* Because rendering may be different for each target format, the |
* first-level element in this array is always a format name (e.g., |
* 'Xhtml'). |
* |
* Within that first level element, the subsequent elements match the |
* $parseConf format. That is, the sub-key is the rendering rule name, |
* and the sub-value is an array of key-value configuration pairs |
* corresponding to the $conf property in the target rendering rule. |
* |
* @access public |
* |
* @var array |
* |
*/ |
var $renderConf = array( |
'Docbook' => array(), |
'Latex' => array(), |
'Pdf' => array(), |
'Plain' => array(), |
'Rtf' => array(), |
'Xhtml' => array() |
); |
/** |
* |
* Custom configuration for the output format itself. |
* |
* Even though Text_Wiki will render the tokens from parsed text, |
* the format itself may require some configuration. For example, |
* RTF needs to know font names and sizes, PDF requires page layout |
* information, and DocBook needs a section hierarchy. This array |
* matches the $conf property of the the format-level renderer |
* (e.g., Text_Wiki_Render_Xhtml). |
* |
* In this array, the key is the rendering format name, and the value is |
* an array of key-value configuration pairs corresponding to the $conf |
* property in the rendering format rule. |
* |
* @access public |
* |
* @var array |
* |
*/ |
var $formatConf = array( |
'Docbook' => array(), |
'Latex' => array(), |
'Pdf' => array(), |
'Plain' => array(), |
'Rtf' => array(), |
'Xhtml' => array() |
); |
/** |
* |
* The delimiter for token numbers of parsed elements in source text. |
* |
* @access public |
* |
* @var string |
* |
*/ |
var $delim = "\xFF"; |
/** |
* |
* The tokens generated by rules as the source text is parsed. |
* |
* As Text_Wiki applies rule classes to the source text, it will |
* replace portions of the text with a delimited token number. This |
* is the array of those tokens, representing the replaced text and |
* any options set by the parser for that replaced text. |
* |
* The tokens array is sequential; each element is itself a sequential |
* array where element 0 is the name of the rule that generated the |
* token, and element 1 is an associative array where the key is an |
* option name and the value is an option value. |
* |
* @access private |
* |
* @var array |
* |
*/ |
var $tokens = array(); |
/** |
* |
* The source text to which rules will be applied. |
* |
* This text will be transformed in-place, which means that it will |
* change as the rules are applied. |
* |
* @access private |
* |
* @var string |
* |
*/ |
var $source = ''; |
/** |
* |
* Array of rule parsers. |
* |
* Text_Wiki creates one instance of every rule that is applied to |
* the source text; this array holds those instances. The array key |
* is the rule name, and the array value is an instance of the rule |
* class. |
* |
* @access private |
* |
* @var array |
* |
*/ |
var $parseObj = array(); |
/** |
* |
* Array of rule renderers. |
* |
* Text_Wiki creates one instance of every rule that is applied to |
* the source text; this array holds those instances. The array key |
* is the rule name, and the array value is an instance of the rule |
* class. |
* |
* @access private |
* |
* @var array |
* |
*/ |
var $renderObj = array(); |
/** |
* |
* Array of format renderers. |
* |
* @access private |
* |
* @var array |
* |
*/ |
var $formatObj = array(); |
/** |
* |
* Array of paths to search, in order, for parsing and rendering rules. |
* |
* @access private |
* |
* @var array |
* |
*/ |
var $path = array( |
'parse' => array(), |
'render' => array() |
); |
/** |
* |
* The directory separator character. |
* |
* @access private |
* |
* @var string |
* |
*/ |
var $_dirSep = DIRECTORY_SEPARATOR; |
/** |
* |
* Constructor. |
* |
* @access public |
* |
* @param array $rules The set of rules to load for this object. |
* |
*/ |
function Text_Wiki($rules = null) |
{ |
if (is_array($rules)) { |
$this->rules = $rules; |
} |
$this->addPath( |
'parse', |
$this->fixPath(dirname(__FILE__)) . 'Wiki/Parse/' |
); |
$this->addPath( |
'render', |
$this->fixPath(dirname(__FILE__)) . 'Wiki/Render/' |
); |
} |
/** |
* |
* Set parser configuration for a specific rule and key. |
* |
* @access public |
* |
* @param string $rule The parse rule to set config for. |
* |
* @param array|string $arg1 The full config array to use for the |
* parse rule, or a conf key in that array. |
* |
* @param string $arg2 The config value for the key. |
* |
* @return void |
* |
*/ |
function setParseConf($rule, $arg1, $arg2 = null) |
{ |
$rule = ucwords(strtolower($rule)); |
if (! isset($this->parseConf[$rule])) { |
$this->parseConf[$rule] = array(); |
} |
// if first arg is an array, use it as the entire |
// conf array for the rule. otherwise, treat arg1 |
// as a key and arg2 as a value for the rule conf. |
if (is_array($arg1)) { |
$this->parseConf[$rule] = $arg1; |
} else { |
$this->parseConf[$rule][$arg1] = $arg2; |
} |
} |
/** |
* |
* Get parser configuration for a specific rule and key. |
* |
* @access public |
* |
* @param string $rule The parse rule to get config for. |
* |
* @param string $key A key in the conf array; if null, |
* returns the entire conf array. |
* |
* @return mixed The whole conf array if no key is specified, |
* or the specific conf key value. |
* |
*/ |
function getParseConf($rule, $key = null) |
{ |
$rule = ucwords(strtolower($rule)); |
// the rule does not exist |
if (! isset($this->parseConf[$rule])) { |
return null; |
} |
// no key requested, return the whole array |
if (is_null($key)) { |
return $this->parseConf[$rule]; |
} |
// does the requested key exist? |
if (isset($this->parseConf[$rule][$key])) { |
// yes, return that value |
return $this->parseConf[$rule][$key]; |
} else { |
// no |
return null; |
} |
} |
/** |
* |
* Set renderer configuration for a specific format, rule, and key. |
* |
* @access public |
* |
* @param string $format The render format to set config for. |
* |
* @param string $rule The render rule to set config for in the format. |
* |
* @param array|string $arg1 The config array, or the config key |
* within the render rule. |
* |
* @param string $arg2 The config value for the key. |
* |
* @return void |
* |
*/ |
function setRenderConf($format, $rule, $arg1, $arg2 = null) |
{ |
$format = ucwords(strtolower($format)); |
$rule = ucwords(strtolower($rule)); |
if (! isset($this->renderConf[$format])) { |
$this->renderConf[$format] = array(); |
} |
if (! isset($this->renderConf[$format][$rule])) { |
$this->renderConf[$format][$rule] = array(); |
} |
// if first arg is an array, use it as the entire |
// conf array for the render rule. otherwise, treat arg1 |
// as a key and arg2 as a value for the render rule conf. |
if (is_array($arg1)) { |
$this->renderConf[$format][$rule] = $arg1; |
} else { |
$this->renderConf[$format][$rule][$arg1] = $arg2; |
} |
} |
/** |
* |
* Get renderer configuration for a specific format, rule, and key. |
* |
* @access public |
* |
* @param string $format The render format to get config for. |
* |
* @param string $rule The render format rule to get config for. |
* |
* @param string $key A key in the conf array; if null, |
* returns the entire conf array. |
* |
* @return mixed The whole conf array if no key is specified, |
* or the specific conf key value. |
* |
*/ |
function getRenderConf($format, $rule, $key = null) |
{ |
$format = ucwords(strtolower($format)); |
$rule = ucwords(strtolower($rule)); |
if (! isset($this->renderConf[$format]) || |
! isset($this->renderConf[$format][$rule])) { |
return null; |
} |
// no key requested, return the whole array |
if (is_null($key)) { |
return $this->renderConf[$format][$rule]; |
} |
// does the requested key exist? |
if (isset($this->renderConf[$format][$rule][$key])) { |
// yes, return that value |
return $this->renderConf[$format][$rule][$key]; |
} else { |
// no |
return null; |
} |
} |
/** |
* |
* Set format configuration for a specific rule and key. |
* |
* @access public |
* |
* @param string $format The format to set config for. |
* |
* @param string $key The config key within the format. |
* |
* @param string $val The config value for the key. |
* |
* @return void |
* |
*/ |
function setFormatConf($format, $arg1, $arg2 = null) |
{ |
if (! is_array($this->formatConf[$format])) { |
$this->formatConf[$format] = array(); |
} |
// if first arg is an array, use it as the entire |
// conf array for the format. otherwise, treat arg1 |
// as a key and arg2 as a value for the format conf. |
if (is_array($arg1)) { |
$this->formatConf[$format] = $arg1; |
} else { |
$this->formatConf[$format][$arg1] = $arg2; |
} |
} |
/** |
* |
* Get configuration for a specific format and key. |
* |
* @access public |
* |
* @param string $format The format to get config for. |
* |
* @param mixed $key A key in the conf array; if null, |
* returns the entire conf array. |
* |
* @return mixed The whole conf array if no key is specified, |
* or the specific conf key value. |
* |
*/ |
function getFormatConf($format, $key = null) |
{ |
// the format does not exist |
if (! isset($this->formatConf[$format])) { |
return null; |
} |
// no key requested, return the whole array |
if (is_null($key)) { |
return $this->formatConf[$format]; |
} |
// does the requested key exist? |
if (isset($this->formatConf[$format][$key])) { |
// yes, return that value |
return $this->formatConf[$format][$key]; |
} else { |
// no |
return null; |
} |
} |
/** |
* |
* Inserts a rule into to the rule set. |
* |
* @access public |
* |
* @param string $name The name of the rule. Should be different from |
* all other keys in the rule set. |
* |
* @param string $tgt The rule after which to insert this new rule. By |
* default (null) the rule is inserted at the end; if set to '', inserts |
* at the beginning. |
* |
* @return void |
* |
*/ |
function insertRule($name, $tgt = null) |
{ |
$name = ucwords(strtolower($name)); |
if (! is_null($tgt)) { |
$tgt = ucwords(strtolower($tgt)); |
} |
// does the rule name to be inserted already exist? |
if (in_array($name, $this->rules)) { |
// yes, return |
return null; |
} |
// the target name is not null, and not '', but does not exist |
// in the list of rules. this means we're trying to insert after |
// a target key, but the target key isn't there. |
if (! is_null($tgt) && $tgt != '' && |
! in_array($tgt, $this->rules)) { |
return false; |
} |
// if $tgt is null, insert at the end. We know this is at the |
// end (instead of resetting an existing rule) becuase we exited |
// at the top of this method if the rule was already in place. |
if (is_null($tgt)) { |
$this->rules[] = $name; |
return true; |
} |
// save a copy of the current rules, then reset the rule set |
// so we can insert in the proper place later. |
// where to insert the rule? |
if ($tgt == '') { |
// insert at the beginning |
array_unshift($this->rules, $name); |
return true; |
} |
// insert after the named rule |
$tmp = $this->rules; |
$this->rules = array(); |
foreach ($tmp as $val) { |
$this->rules[] = $val; |
if ($val == $tgt) { |
$this->rules[] = $name; |
} |
} |
return true; |
} |
/** |
* |
* Delete (remove or unset) a rule from the $rules property. |
* |
* @access public |
* |
* @param string $rule The name of the rule to remove. |
* |
* @return void |
* |
*/ |
function deleteRule($name) |
{ |
$name = ucwords(strtolower($name)); |
$key = array_search($name, $this->rules); |
if ($key !== false) { |
unset($this->rules[$key]); |
} |
} |
/** |
* |
* Change from one rule to another in-place. |
* |
* @access public |
* |
* @param string $old The name of the rule to change from. |
* |
* @param string $new The name of the rule to change to. |
* |
* @return void |
* |
*/ |
function changeRule($old, $new) |
{ |
$old = ucwords(strtolower($old)); |
$new = ucwords(strtolower($new)); |
$key = array_search($old, $this->rules); |
if ($key !== false) { |
$this->rules[$old] = $new; |
} |
} |
/** |
* |
* Enables a rule so that it is applied when parsing. |
* |
* @access public |
* |
* @param string $rule The name of the rule to enable. |
* |
* @return void |
* |
*/ |
function enableRule($name) |
{ |
$name = ucwords(strtolower($name)); |
$key = array_search($name, $this->disable); |
if ($key !== false) { |
unset($this->disable[$key]); |
} |
} |
/** |
* |
* Disables a rule so that it is not applied when parsing. |
* |
* @access public |
* |
* @param string $rule The name of the rule to disable. |
* |
* @return void |
* |
*/ |
function disableRule($name) |
{ |
$name = ucwords(strtolower($name)); |
$key = array_search($name, $this->disable); |
if ($key === false) { |
$this->disable[] = $name; |
} |
} |
/** |
* |
* Parses and renders the text passed to it, and returns the results. |
* |
* First, the method parses the source text, applying rules to the |
* text as it goes. These rules will modify the source text |
* in-place, replacing some text with delimited tokens (and |
* populating the $this->tokens array as it goes). |
* |
* Next, the method renders the in-place tokens into the requested |
* output format. |
* |
* Finally, the method returns the transformed text. Note that the |
* source text is transformed in place; once it is transformed, it is |
* no longer the same as the original source text. |
* |
* @access public |
* |
* @param string $text The source text to which wiki rules should be |
* applied, both for parsing and for rendering. |
* |
* @param string $format The target output format, typically 'xhtml'. |
* If a rule does not support a given format, the output from that |
* rule is rule-specific. |
* |
* @return string The transformed wiki text. |
* |
*/ |
function transform($text, $format = 'Xhtml') |
{ |
$this->parse($text); |
return $this->render($format); |
} |
/** |
* |
* Sets the $_source text property, then parses it in place and |
* retains tokens in the $_tokens array property. |
* |
* @access public |
* |
* @param string $text The source text to which wiki rules should be |
* applied, both for parsing and for rendering. |
* |
* @return void |
* |
*/ |
function parse($text) |
{ |
// set the object property for the source text |
$this->source = $text; |
// reset the tokens. |
$this->tokens = array(); |
// apply the parse() method of each requested rule to the source |
// text. |
foreach ($this->rules as $name) { |
// do not parse the rules listed in $disable |
if (! in_array($name, $this->disable)) { |
// load the parsing object |
$this->loadParseObj($name); |
// load may have failed; only parse if |
// an object is in the array now |
if (is_object($this->parseObj[$name])) { |
$this->parseObj[$name]->parse(); |
} |
} |
} |
} |
/** |
* |
* Renders tokens back into the source text, based on the requested format. |
* |
* @access public |
* |
* @param string $format The target output format, typically 'xhtml'. |
* If a rule does not support a given format, the output from that |
* rule is rule-specific. |
* |
* @return string The transformed wiki text. |
* |
*/ |
function render($format = 'Xhtml') |
{ |
// the rendering method we're going to use from each rule |
$format = ucwords(strtolower($format)); |
// the eventual output text |
$output = ''; |
// when passing through the parsed source text, keep track of when |
// we are in a delimited section |
$in_delim = false; |
// when in a delimited section, capture the token key number |
$key = ''; |
// load the format object |
$this->loadFormatObj($format); |
// pre-rendering activity |
if (is_object($this->formatObj[$format])) { |
$output .= $this->formatObj[$format]->pre(); |
} |
// load the render objects |
foreach (array_keys($this->parseObj) as $rule) { |
$this->loadRenderObj($format, $rule); |
} |
// pass through the parsed source text character by character |
$k = strlen($this->source); |
for ($i = 0; $i < $k; $i++) { |
// the current character |
$char = $this->source{$i}; |
// are alredy in a delimited section? |
if ($in_delim) { |
// yes; are we ending the section? |
if ($char == $this->delim) { |
// yes, get the replacement text for the delimited |
// token number and unset the flag. |
$key = (int)$key; |
$rule = $this->tokens[$key][0]; |
$opts = $this->tokens[$key][1]; |
$output .= $this->renderObj[$rule]->token($opts); |
$in_delim = false; |
} else { |
// no, add to the dlimited token key number |
$key .= $char; |
} |
} else { |
// not currently in a delimited section. |
// are we starting into a delimited section? |
if ($char == $this->delim) { |
// yes, reset the previous key and |
// set the flag. |
$key = ''; |
$in_delim = true; |
} else { |
// no, add to the output as-is |
$output .= $char; |
} |
} |
} |
// post-rendering activity |
if (is_object($this->formatObj[$format])) { |
$output .= $this->formatObj[$format]->post(); |
} |
// return the rendered source text. |
return $output; |
} |
/** |
* |
* Returns the parsed source text with delimited token placeholders. |
* |
* @access public |
* |
* @return string The parsed source text. |
* |
*/ |
function getSource() |
{ |
return $this->source; |
} |
/** |
* |
* Returns tokens that have been parsed out of the source text. |
* |
* @access public |
* |
* @param array $rules If an array of rule names is passed, only return |
* tokens matching these rule names. If no array is passed, return all |
* tokens. |
* |
* @return array An array of tokens. |
* |
*/ |
function getTokens($rules = null) |
{ |
if (is_null($rules)) { |
return $this->tokens; |
} else { |
settype($rules, 'array'); |
$result = array(); |
foreach ($this->tokens as $key => $val) { |
if (in_array($val[0], $rules)) { |
$result[] = $val; |
} |
} |
return $result; |
} |
} |
/** |
* |
* Add a token to the Text_Wiki tokens array, and return a delimited |
* token number. |
* |
* @access public |
* |
* @param array $options An associative array of options for the new |
* token array element. The keys and values are specific to the |
* rule, and may or may not be common to other rule options. Typical |
* options keys are 'text' and 'type' but may include others. |
* |
* @param boolean $id_only If true, return only the token number, not |
* a delimited token string. |
* |
* @return string|int By default, return the number of the |
* newly-created token array element with a delimiter prefix and |
* suffix; however, if $id_only is set to true, return only the token |
* number (no delimiters). |
* |
*/ |
function addToken($rule, $options = array(), $id_only = false) |
{ |
// increment the token ID number. note that if you parse |
// multiple times with the same Text_Wiki object, the ID number |
// will not reset to zero. |
static $id; |
if (! isset($id)) { |
$id = 0; |
} else { |
$id ++; |
} |
// force the options to be an array |
settype($options, 'array'); |
// add the token |
$this->tokens[$id] = array( |
0 => $rule, |
1 => $options |
); |
// return a value |
if ($id_only) { |
// return the last token number |
return $id; |
} else { |
// return the token number with delimiters |
return $this->delim . $id . $this->delim; |
} |
} |
/** |
* |
* Set or re-set a token with specific information, overwriting any |
* previous rule name and rule options. |
* |
* @access public |
* |
* @param int $id The token number to reset. |
* |
* @param int $rule The rule name to use. |
* |
* @param array $options An associative array of options for the |
* token array element. The keys and values are specific to the |
* rule, and may or may not be common to other rule options. Typical |
* options keys are 'text' and 'type' but may include others. |
* |
* @return void |
* |
*/ |
function setToken($id, $rule, $options = array()) |
{ |
// reset the token |
$this->tokens[$id] = array( |
0 => $rule, |
1 => $options |
); |
} |
/** |
* |
* Load a rule parser class file. |
* |
* @access public |
* |
* @return bool True if loaded, false if not. |
* |
*/ |
function loadParseObj($rule) |
{ |
$rule = ucwords(strtolower($rule)); |
$file = $rule . '.php'; |
$class = "Text_Wiki_Parse_$rule"; |
if (! class_exists($class)) { |
$loc = $this->findFile('parse', $file); |
if ($loc) { |
// found the class |
include_once $loc; |
} else { |
// can't find the class |
$this->parseObj[$rule] = null; |
return false; |
} |
} |
$this->parseObj[$rule] =& new $class($this); |
} |
/** |
* |
* Load a rule-render class file. |
* |
* @access public |
* |
* @return bool True if loaded, false if not. |
* |
*/ |
function loadRenderObj($format, $rule) |
{ |
$format = ucwords(strtolower($format)); |
$rule = ucwords(strtolower($rule)); |
$file = "$format/$rule.php"; |
$class = "Text_Wiki_Render_$format" . "_$rule"; |
if (! class_exists($class)) { |
// load the class |
$loc = $this->findFile('render', $file); |
if ($loc) { |
// found the class |
include_once $loc; |
} else { |
// can't find the class |
return false; |
} |
} |
$this->renderObj[$rule] =& new $class($this); |
} |
/** |
* |
* Load a format-render class file. |
* |
* @access public |
* |
* @return bool True if loaded, false if not. |
* |
*/ |
function loadFormatObj($format) |
{ |
$format = ucwords(strtolower($format)); |
$file = $format . '.php'; |
$class = "Text_Wiki_Render_$format"; |
if (! class_exists($class)) { |
$loc = $this->findFile('render', $file); |
if ($loc) { |
// found the class |
include_once $loc; |
} else { |
// can't find the class |
return false; |
} |
} |
$this->formatObj[$format] =& new $class($this); |
} |
/** |
* |
* Add a path to a path array. |
* |
* @access public |
* |
* @param string $type The path-type to add (parse or render). |
* |
* @param string $dir The directory to add to the path-type. |
* |
* @return void |
* |
*/ |
function addPath($type, $dir) |
{ |
$dir = $this->fixPath($dir); |
if (! isset($this->path[$type])) { |
$this->path[$type] = array($dir); |
} else { |
array_unshift($this->path[$type], $dir); |
} |
} |
/** |
* |
* Get the current path array for a path-type. |
* |
* @access public |
* |
* @param string $type The path-type to look up (plugin, filter, or |
* template). If not set, returns all path types. |
* |
* @return array The array of paths for the requested type. |
* |
*/ |
function getPath($type = null) |
{ |
if (is_null($type)) { |
return $this->path; |
} elseif (! isset($this->path[$type])) { |
return array(); |
} else { |
return $this->path[$type]; |
} |
} |
/** |
* |
* Searches a series of paths for a given file. |
* |
* @param array $type The type of paths to search (template, plugin, |
* or filter). |
* |
* @param string $file The file name to look for. |
* |
* @return string|bool The full path and file name for the target file, |
* or boolean false if the file is not found in any of the paths. |
* |
*/ |
function findFile($type, $file) |
{ |
// get the set of paths |
$set = $this->getPath($type); |
// start looping through them |
foreach ($set as $path) { |
$fullname = $path . $file; |
if (file_exists($fullname) && is_readable($fullname)) { |
return $fullname; |
} |
} |
// could not find the file in the set of paths |
return false; |
} |
/** |
* |
* Append a trailing '/' to paths, unless the path is empty. |
* |
* @access private |
* |
* @param string $path The file path to fix |
* |
* @return string The fixed file path |
* |
*/ |
function fixPath($path) |
{ |
$len = strlen($this->_dirSep); |
if (! empty($path) && |
substr($path, -1 * $len, $len) != $this->_dirSep) { |
return $path . $this->_dirSep; |
} else { |
return $path; |
} |
} |
} |
?> |
/branches/livraison_menes/api/pear/DB/msql.php |
---|
New 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.2 2005-09-20 17:01:22 ddelon 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: |
*/ |
?> |
/branches/livraison_menes/api/pear/DB/dbase.php |
---|
New 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.2 2005-09-20 17:01:22 ddelon 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: |
*/ |
?> |
/branches/livraison_menes/api/pear/DB/mysqli.php |
---|
New file |
0,0 → 1,1076 |
<?php |
/* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4: */ |
/** |
* The PEAR DB driver for PHP's mysqli extension |
* for interacting with MySQL 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 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: mysqli.php,v 1.2 2005-09-20 17:01:22 ddelon 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 mysqli extension |
* for interacting with MySQL databases |
* |
* This is for MySQL versions 4.1 and above. Requires PHP 5. |
* |
* Note that persistent connections no longer exist. |
* |
* These methods overload the ones declared in DB_common. |
* |
* @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 functional since Release 1.6.3 |
*/ |
class DB_mysqli extends DB_common |
{ |
// {{{ properties |
/** |
* The DB driver type (mysql, oci8, odbc, etc.) |
* @var string |
*/ |
var $phptype = 'mysqli'; |
/** |
* The database syntax variant to be used (db2, access, etc.), if any |
* @var string |
*/ |
var $dbsyntax = 'mysqli'; |
/** |
* 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' => false, |
'prepare' => false, |
'ssl' => true, |
'transactions' => true, |
); |
/** |
* A mapping of native error codes to DB error codes |
* @var array |
*/ |
var $errorcode_map = array( |
1004 => DB_ERROR_CANNOT_CREATE, |
1005 => DB_ERROR_CANNOT_CREATE, |
1006 => DB_ERROR_CANNOT_CREATE, |
1007 => DB_ERROR_ALREADY_EXISTS, |
1008 => DB_ERROR_CANNOT_DROP, |
1022 => DB_ERROR_ALREADY_EXISTS, |
1044 => DB_ERROR_ACCESS_VIOLATION, |
1046 => DB_ERROR_NODBSELECTED, |
1048 => DB_ERROR_CONSTRAINT, |
1049 => DB_ERROR_NOSUCHDB, |
1050 => DB_ERROR_ALREADY_EXISTS, |
1051 => DB_ERROR_NOSUCHTABLE, |
1054 => DB_ERROR_NOSUCHFIELD, |
1061 => DB_ERROR_ALREADY_EXISTS, |
1062 => DB_ERROR_ALREADY_EXISTS, |
1064 => DB_ERROR_SYNTAX, |
1091 => DB_ERROR_NOT_FOUND, |
1100 => DB_ERROR_NOT_LOCKED, |
1136 => DB_ERROR_VALUE_COUNT_ON_ROW, |
1142 => DB_ERROR_ACCESS_VIOLATION, |
1146 => DB_ERROR_NOSUCHTABLE, |
1216 => DB_ERROR_CONSTRAINT, |
1217 => 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(); |
/** |
* 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 = ''; |
/** |
* Array for converting MYSQLI_*_FLAG constants to text values |
* @var array |
* @access public |
* @since Property available since Release 1.6.5 |
*/ |
var $mysqli_flags = array( |
MYSQLI_NOT_NULL_FLAG => 'not_null', |
MYSQLI_PRI_KEY_FLAG => 'primary_key', |
MYSQLI_UNIQUE_KEY_FLAG => 'unique_key', |
MYSQLI_MULTIPLE_KEY_FLAG => 'multiple_key', |
MYSQLI_BLOB_FLAG => 'blob', |
MYSQLI_UNSIGNED_FLAG => 'unsigned', |
MYSQLI_ZEROFILL_FLAG => 'zerofill', |
MYSQLI_AUTO_INCREMENT_FLAG => 'auto_increment', |
MYSQLI_TIMESTAMP_FLAG => 'timestamp', |
MYSQLI_SET_FLAG => 'set', |
// MYSQLI_NUM_FLAG => 'numeric', // unnecessary |
// MYSQLI_PART_KEY_FLAG => 'multiple_key', // duplicatvie |
MYSQLI_GROUP_FLAG => 'group_by' |
); |
/** |
* Array for converting MYSQLI_TYPE_* constants to text values |
* @var array |
* @access public |
* @since Property available since Release 1.6.5 |
*/ |
var $mysqli_types = array( |
MYSQLI_TYPE_DECIMAL => 'decimal', |
MYSQLI_TYPE_TINY => 'tinyint', |
MYSQLI_TYPE_SHORT => 'int', |
MYSQLI_TYPE_LONG => 'int', |
MYSQLI_TYPE_FLOAT => 'float', |
MYSQLI_TYPE_DOUBLE => 'double', |
// MYSQLI_TYPE_NULL => 'DEFAULT NULL', // let flags handle it |
MYSQLI_TYPE_TIMESTAMP => 'timestamp', |
MYSQLI_TYPE_LONGLONG => 'bigint', |
MYSQLI_TYPE_INT24 => 'mediumint', |
MYSQLI_TYPE_DATE => 'date', |
MYSQLI_TYPE_TIME => 'time', |
MYSQLI_TYPE_DATETIME => 'datetime', |
MYSQLI_TYPE_YEAR => 'year', |
MYSQLI_TYPE_NEWDATE => 'date', |
MYSQLI_TYPE_ENUM => 'enum', |
MYSQLI_TYPE_SET => 'set', |
MYSQLI_TYPE_TINY_BLOB => 'tinyblob', |
MYSQLI_TYPE_MEDIUM_BLOB => 'mediumblob', |
MYSQLI_TYPE_LONG_BLOB => 'longblob', |
MYSQLI_TYPE_BLOB => 'blob', |
MYSQLI_TYPE_VAR_STRING => 'varchar', |
MYSQLI_TYPE_STRING => 'char', |
MYSQLI_TYPE_GEOMETRY => 'geometry', |
); |
// }}} |
// {{{ constructor |
/** |
* This constructor calls <kbd>$this->DB_common()</kbd> |
* |
* @return void |
*/ |
function DB_mysqli() |
{ |
$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 mysqli driver supports the following extra DSN options: |
* + When the 'ssl' $option passed to DB::connect() is true: |
* + key The path to the key file. |
* + cert The path to the certificate file. |
* + ca The path to the certificate authority file. |
* + capath The path to a directory that contains trusted SSL |
* CA certificates in pem format. |
* + cipher The list of allowable ciphers for SSL encryption. |
* |
* Example of how to connect using SSL: |
* <code> |
* require_once 'DB.php'; |
* |
* $dsn = array( |
* 'phptype' => 'mysqli', |
* 'username' => 'someuser', |
* 'password' => 'apasswd', |
* 'hostspec' => 'localhost', |
* 'database' => 'thedb', |
* 'key' => 'client-key.pem', |
* 'cert' => 'client-cert.pem', |
* 'ca' => 'cacert.pem', |
* 'capath' => '/path/to/ca/dir', |
* 'cipher' => 'AES', |
* ); |
* |
* $options = array( |
* 'ssl' => true, |
* ); |
* |
* $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('mysqli')) { |
return $this->raiseError(DB_ERROR_EXTENSION_NOT_FOUND); |
} |
$this->dsn = $dsn; |
if ($dsn['dbsyntax']) { |
$this->dbsyntax = $dsn['dbsyntax']; |
} |
$ini = ini_get('track_errors'); |
ini_set('track_errors', 1); |
$php_errormsg = ''; |
if ($this->getOption('ssl') === true) { |
$init = mysqli_init(); |
mysqli_ssl_set( |
$init, |
empty($dsn['key']) ? null : $dsn['key'], |
empty($dsn['cert']) ? null : $dsn['cert'], |
empty($dsn['ca']) ? null : $dsn['ca'], |
empty($dsn['capath']) ? null : $dsn['capath'], |
empty($dsn['cipher']) ? null : $dsn['cipher'] |
); |
if ($this->connection = @mysqli_real_connect( |
$init, |
$dsn['hostspec'], |
$dsn['username'], |
$dsn['password'], |
$dsn['database'], |
$dsn['port'], |
$dsn['socket'])) |
{ |
$this->connection = $init; |
} |
} else { |
$this->connection = @mysqli_connect( |
$dsn['hostspec'], |
$dsn['username'], |
$dsn['password'], |
$dsn['database'], |
$dsn['port'], |
$dsn['socket'] |
); |
} |
ini_set('track_errors', $ini); |
if (!$this->connection) { |
if (($err = @mysqli_connect_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 ($dsn['database']) { |
$this->_db = $dsn['database']; |
} |
return DB_OK; |
} |
// }}} |
// {{{ disconnect() |
/** |
* Disconnects from the database server |
* |
* @return bool TRUE on success, FALSE on failure |
*/ |
function disconnect() |
{ |
$ret = @mysqli_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; |
$query = $this->modifyQuery($query); |
if ($this->_db) { |
if (!@mysqli_select_db($this->connection, $this->_db)) { |
return $this->mysqliRaiseError(DB_ERROR_NODBSELECTED); |
} |
} |
if (!$this->autocommit && $ismanip) { |
if ($this->transaction_opcount == 0) { |
$result = @mysqli_query($this->connection, 'SET AUTOCOMMIT=0'); |
$result = @mysqli_query($this->connection, 'BEGIN'); |
if (!$result) { |
return $this->mysqliRaiseError(); |
} |
} |
$this->transaction_opcount++; |
} |
$result = @mysqli_query($this->connection, $query); |
if (!$result) { |
return $this->mysqliRaiseError(); |
} |
if (is_object($result)) { |
return $result; |
} |
return DB_OK; |
} |
// }}} |
// {{{ nextResult() |
/** |
* Move the internal mysql result pointer to the next available result. |
* |
* This method has not been implemented yet. |
* |
* @param resource $result a valid sql result resource |
* @return false |
* @access public |
*/ |
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 (!@mysqli_data_seek($result, $rownum)) { |
return null; |
} |
} |
if ($fetchmode & DB_FETCHMODE_ASSOC) { |
$arr = @mysqli_fetch_array($result, MYSQLI_ASSOC); |
if ($this->options['portability'] & DB_PORTABILITY_LOWERCASE && $arr) { |
$arr = array_change_key_case($arr, CASE_LOWER); |
} |
} else { |
$arr = @mysqli_fetch_row($result); |
} |
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) |
{ |
return @mysqli_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 = @mysqli_num_fields($result); |
if (!$cols) { |
return $this->mysqliRaiseError(); |
} |
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 = @mysqli_num_rows($result); |
if ($rows === null) { |
return $this->mysqliRaiseError(); |
} |
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 ($this->_db) { |
if (!@mysqli_select_db($this->connection, $this->_db)) { |
return $this->mysqliRaiseError(DB_ERROR_NODBSELECTED); |
} |
} |
$result = @mysqli_query($this->connection, 'COMMIT'); |
$result = @mysqli_query($this->connection, 'SET AUTOCOMMIT=1'); |
$this->transaction_opcount = 0; |
if (!$result) { |
return $this->mysqliRaiseError(); |
} |
} |
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 ($this->_db) { |
if (!@mysqli_select_db($this->connection, $this->_db)) { |
return $this->mysqliRaiseError(DB_ERROR_NODBSELECTED); |
} |
} |
$result = @mysqli_query($this->connection, 'ROLLBACK'); |
$result = @mysqli_query($this->connection, 'SET AUTOCOMMIT=1'); |
$this->transaction_opcount = 0; |
if (!$result) { |
return $this->mysqliRaiseError(); |
} |
} |
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)) { |
return @mysqli_affected_rows($this->connection); |
} else { |
return 0; |
} |
} |
// }}} |
// {{{ 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_mysqli::createSequence(), DB_mysqli::dropSequence() |
*/ |
function nextId($seq_name, $ondemand = true) |
{ |
$seqname = $this->getSequenceName($seq_name); |
do { |
$repeat = 0; |
$this->pushErrorHandling(PEAR_ERROR_RETURN); |
$result = $this->query('UPDATE ' . $seqname |
. ' SET id = LAST_INSERT_ID(id + 1)'); |
$this->popErrorHandling(); |
if ($result === DB_OK) { |
// COMMON CASE |
$id = @mysqli_insert_id($this->connection); |
if ($id != 0) { |
return $id; |
} |
// EMPTY SEQ TABLE |
// Sequence table must be empty for some reason, |
// so fill it and return 1 |
// Obtain a user-level lock |
$result = $this->getOne('SELECT GET_LOCK(' |
. "'${seqname}_lock', 10)"); |
if (DB::isError($result)) { |
return $this->raiseError($result); |
} |
if ($result == 0) { |
return $this->mysqliRaiseError(DB_ERROR_NOT_LOCKED); |
} |
// add the default value |
$result = $this->query('REPLACE INTO ' . $seqname |
. ' (id) VALUES (0)'); |
if (DB::isError($result)) { |
return $this->raiseError($result); |
} |
// Release the lock |
$result = $this->getOne('SELECT RELEASE_LOCK(' |
. "'${seqname}_lock')"); |
if (DB::isError($result)) { |
return $this->raiseError($result); |
} |
// We know what the result will be, so no need to try again |
return 1; |
} elseif ($ondemand && DB::isError($result) && |
$result->getCode() == DB_ERROR_NOSUCHTABLE) |
{ |
// ONDEMAND TABLE CREATION |
$result = $this->createSequence($seq_name); |
// Since createSequence initializes the ID to be 1, |
// we do not need to retrieve the ID again (or we will get 2) |
if (DB::isError($result)) { |
return $this->raiseError($result); |
} else { |
// First ID of a newly created sequence is 1 |
return 1; |
} |
} elseif (DB::isError($result) && |
$result->getCode() == DB_ERROR_ALREADY_EXISTS) |
{ |
// BACKWARDS COMPAT |
// see _BCsequence() comment |
$result = $this->_BCsequence($seqname); |
if (DB::isError($result)) { |
return $this->raiseError($result); |
} |
$repeat = 1; |
} |
} while ($repeat); |
return $this->raiseError($result); |
} |
/** |
* 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_mysqli::nextID(), DB_mysqli::dropSequence() |
*/ |
function createSequence($seq_name) |
{ |
$seqname = $this->getSequenceName($seq_name); |
$res = $this->query('CREATE TABLE ' . $seqname |
. ' (id INTEGER UNSIGNED AUTO_INCREMENT NOT NULL,' |
. ' PRIMARY KEY(id))'); |
if (DB::isError($res)) { |
return $res; |
} |
// insert yields value 1, nextId call will generate ID 2 |
return $this->query("INSERT INTO ${seqname} (id) VALUES (0)"); |
} |
// }}} |
// {{{ 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_mysql::nextID(), DB_mysql::createSequence() |
*/ |
function dropSequence($seq_name) |
{ |
return $this->query('DROP TABLE ' . $this->getSequenceName($seq_name)); |
} |
// }}} |
// {{{ _BCsequence() |
/** |
* Backwards compatibility with old sequence emulation implementation |
* (clean up the dupes) |
* |
* @param string $seqname the sequence name to clean up |
* |
* @return bool true on success. A DB_Error object on failure. |
* |
* @access private |
*/ |
function _BCsequence($seqname) |
{ |
// Obtain a user-level lock... this will release any previous |
// application locks, but unlike LOCK TABLES, it does not abort |
// the current transaction and is much less frequently used. |
$result = $this->getOne("SELECT GET_LOCK('${seqname}_lock',10)"); |
if (DB::isError($result)) { |
return $result; |
} |
if ($result == 0) { |
// Failed to get the lock, can't do the conversion, bail |
// with a DB_ERROR_NOT_LOCKED error |
return $this->mysqliRaiseError(DB_ERROR_NOT_LOCKED); |
} |
$highest_id = $this->getOne("SELECT MAX(id) FROM ${seqname}"); |
if (DB::isError($highest_id)) { |
return $highest_id; |
} |
// This should kill all rows except the highest |
// We should probably do something if $highest_id isn't |
// numeric, but I'm at a loss as how to handle that... |
$result = $this->query('DELETE FROM ' . $seqname |
. " WHERE id <> $highest_id"); |
if (DB::isError($result)) { |
return $result; |
} |
// If another thread has been waiting for this lock, |
// it will go thru the above procedure, but will have no |
// real effect |
$result = $this->getOne("SELECT RELEASE_LOCK('${seqname}_lock')"); |
if (DB::isError($result)) { |
return $result; |
} |
return true; |
} |
// }}} |
// {{{ quoteIdentifier() |
/** |
* Quotes a string so it can be safely used as a table or column name |
* |
* MySQL can't handle the backtick character (<kbd>`</kbd>) in |
* table or column names. |
* |
* @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 . '`'; |
} |
// }}} |
// {{{ 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.6.0 |
*/ |
function escapeSimple($str) |
{ |
return @mysqli_real_escape_string($this->connection, $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()) |
{ |
if (DB::isManip($query)) { |
return $query . " LIMIT $count"; |
} else { |
return $query . " LIMIT $from, $count"; |
} |
} |
// }}} |
// {{{ mysqliRaiseError() |
/** |
* 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_mysqli::errorNative(), DB_common::errorCode() |
*/ |
function mysqliRaiseError($errno = null) |
{ |
if ($errno === null) { |
if ($this->options['portability'] & DB_PORTABILITY_ERRORS) { |
$this->errorcode_map[1022] = DB_ERROR_CONSTRAINT; |
$this->errorcode_map[1048] = DB_ERROR_CONSTRAINT_NOT_NULL; |
$this->errorcode_map[1062] = DB_ERROR_CONSTRAINT; |
} else { |
// Doing this in case mode changes during runtime. |
$this->errorcode_map[1022] = DB_ERROR_ALREADY_EXISTS; |
$this->errorcode_map[1048] = DB_ERROR_CONSTRAINT; |
$this->errorcode_map[1062] = DB_ERROR_ALREADY_EXISTS; |
} |
$errno = $this->errorCode(mysqli_errno($this->connection)); |
} |
return $this->raiseError($errno, null, null, null, |
@mysqli_errno($this->connection) . ' ** ' . |
@mysqli_error($this->connection)); |
} |
// }}} |
// {{{ errorNative() |
/** |
* Gets the DBMS' native error code produced by the last query |
* |
* @return int the DBMS' error code |
*/ |
function errorNative() |
{ |
return @mysqli_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::setOption() |
*/ |
function tableInfo($result, $mode = null) |
{ |
if (is_string($result)) { |
/* |
* Probably received a table name. |
* Create a result resource identifier. |
*/ |
$id = @mysqli_query($this->connection, |
"SELECT * FROM $result LIMIT 0"); |
$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_a($id, 'mysqli_result')) { |
return $this->mysqliRaiseError(DB_ERROR_NEED_MORE_DATA); |
} |
if ($this->options['portability'] & DB_PORTABILITY_LOWERCASE) { |
$case_func = 'strtolower'; |
} else { |
$case_func = 'strval'; |
} |
$count = @mysqli_num_fields($id); |
$res = array(); |
if ($mode) { |
$res['num_fields'] = $count; |
} |
for ($i = 0; $i < $count; $i++) { |
$tmp = @mysqli_fetch_field($id); |
$flags = ''; |
foreach ($this->mysqli_flags as $const => $means) { |
if ($tmp->flags & $const) { |
$flags .= $means . ' '; |
} |
} |
if ($tmp->def) { |
$flags .= 'default_' . rawurlencode($tmp->def); |
} |
$flags = trim($flags); |
$res[$i] = array( |
'table' => $case_func($tmp->table), |
'name' => $case_func($tmp->name), |
'type' => isset($this->mysqli_types[$tmp->type]) |
? $this->mysqli_types[$tmp->type] |
: 'unknown', |
'len' => $tmp->max_length, |
'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) { |
@mysqli_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 'SHOW TABLES'; |
case 'users': |
return 'SELECT DISTINCT User FROM mysql.user'; |
case 'databases': |
return 'SHOW DATABASES'; |
default: |
return null; |
} |
} |
// }}} |
} |
/* |
* Local variables: |
* tab-width: 4 |
* c-basic-offset: 4 |
* End: |
*/ |
?> |
/branches/livraison_menes/api/pear/DB/mssql.php |
---|
New 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.2 2005-09-20 17:01:22 ddelon 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: |
*/ |
?> |
/branches/livraison_menes/api/pear/DB/sqlite.php |
---|
New 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.2 2005-09-20 17:01:22 ddelon 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: |
*/ |
?> |
/branches/livraison_menes/api/pear/DB/oci8.php |
---|
New file |
0,0 → 1,1117 |
<?php |
/* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4: */ |
/** |
* The PEAR DB driver for PHP's oci8 extension |
* for interacting with Oracle 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 James L. Pine <jlp@valinux.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: oci8.php,v 1.2 2005-09-20 17:01:22 ddelon 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 oci8 extension |
* for interacting with Oracle databases |
* |
* Definitely works with versions 8 and 9 of Oracle. |
* |
* These methods overload the ones declared in DB_common. |
* |
* Be aware... OCIError() only appears to return anything when given a |
* statement, so functions return the generic DB_ERROR instead of more |
* useful errors that have to do with feedback from the database. |
* |
* @category Database |
* @package DB |
* @author James L. Pine <jlp@valinux.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_oci8 extends DB_common |
{ |
// {{{ properties |
/** |
* The DB driver type (mysql, oci8, odbc, etc.) |
* @var string |
*/ |
var $phptype = 'oci8'; |
/** |
* The database syntax variant to be used (db2, access, etc.), if any |
* @var string |
*/ |
var $dbsyntax = 'oci8'; |
/** |
* 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' => '5.0.0', |
'numrows' => 'subquery', |
'pconnect' => true, |
'prepare' => true, |
'ssl' => false, |
'transactions' => true, |
); |
/** |
* A mapping of native error codes to DB error codes |
* @var array |
*/ |
var $errorcode_map = array( |
1 => DB_ERROR_CONSTRAINT, |
900 => DB_ERROR_SYNTAX, |
904 => DB_ERROR_NOSUCHFIELD, |
913 => DB_ERROR_VALUE_COUNT_ON_ROW, |
921 => DB_ERROR_SYNTAX, |
923 => DB_ERROR_SYNTAX, |
942 => DB_ERROR_NOSUCHTABLE, |
955 => DB_ERROR_ALREADY_EXISTS, |
1400 => DB_ERROR_CONSTRAINT_NOT_NULL, |
1401 => DB_ERROR_INVALID, |
1407 => DB_ERROR_CONSTRAINT_NOT_NULL, |
1418 => DB_ERROR_NOT_FOUND, |
1476 => DB_ERROR_DIVZERO, |
1722 => DB_ERROR_INVALID_NUMBER, |
2289 => DB_ERROR_NOSUCHTABLE, |
2291 => DB_ERROR_CONSTRAINT, |
2292 => DB_ERROR_CONSTRAINT, |
2449 => 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(); |
/** |
* Should data manipulation queries be committed automatically? |
* @var bool |
* @access private |
*/ |
var $autocommit = true; |
/** |
* Stores the $data passed to execute() in the oci8 driver |
* |
* Gets reset to array() when simpleQuery() is run. |
* |
* Needed in case user wants to call numRows() after prepare/execute |
* was used. |
* |
* @var array |
* @access private |
*/ |
var $_data = array(); |
/** |
* The result or statement handle from the most recently executed query |
* @var resource |
*/ |
var $last_stmt; |
/** |
* Is the given prepared statement a data manipulation query? |
* @var array |
* @access private |
*/ |
var $manip_query = array(); |
// }}} |
// {{{ constructor |
/** |
* This constructor calls <kbd>$this->DB_common()</kbd> |
* |
* @return void |
*/ |
function DB_oci8() |
{ |
$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. |
* |
* If PHP is at version 5.0.0 or greater: |
* + Generally, oci_connect() or oci_pconnect() are used. |
* + But if the new_link DSN option is set to true, oci_new_connect() |
* is used. |
* |
* When using PHP version 4.x, OCILogon() or OCIPLogon() are used. |
* |
* PEAR DB's oci8 driver supports the following extra DSN options: |
* + charset The character set to be used on the connection. |
* Only used if PHP is at version 5.0.0 or greater |
* and the Oracle server is at 9.2 or greater. |
* Available since PEAR DB 1.7.0. |
* + new_link If set to true, causes subsequent calls to |
* connect() to return a new connection link |
* instead of the existing one. WARNING: this is |
* not portable to other DBMS's. |
* 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('oci8')) { |
return $this->raiseError(DB_ERROR_EXTENSION_NOT_FOUND); |
} |
$this->dsn = $dsn; |
if ($dsn['dbsyntax']) { |
$this->dbsyntax = $dsn['dbsyntax']; |
} |
if (function_exists('oci_connect')) { |
if (isset($dsn['new_link']) |
&& ($dsn['new_link'] == 'true' || $dsn['new_link'] === true)) |
{ |
$connect_function = 'oci_new_connect'; |
} else { |
$connect_function = $persistent ? 'oci_pconnect' |
: 'oci_connect'; |
} |
// Backwards compatibility with DB < 1.7.0 |
if (empty($dsn['database']) && !empty($dsn['hostspec'])) { |
$db = $dsn['hostspec']; |
} else { |
$db = $dsn['database']; |
} |
$char = empty($dsn['charset']) ? null : $dsn['charset']; |
$this->connection = @$connect_function($dsn['username'], |
$dsn['password'], |
$db, |
$char); |
$error = OCIError(); |
if (!empty($error) && $error['code'] == 12541) { |
// Couldn't find TNS listener. Try direct connection. |
$this->connection = @$connect_function($dsn['username'], |
$dsn['password'], |
null, |
$char); |
} |
} else { |
$connect_function = $persistent ? 'OCIPLogon' : 'OCILogon'; |
if ($dsn['hostspec']) { |
$this->connection = @$connect_function($dsn['username'], |
$dsn['password'], |
$dsn['hostspec']); |
} elseif ($dsn['username'] || $dsn['password']) { |
$this->connection = @$connect_function($dsn['username'], |
$dsn['password']); |
} |
} |
if (!$this->connection) { |
$error = OCIError(); |
$error = (is_array($error)) ? $error['message'] : null; |
return $this->raiseError(DB_ERROR_CONNECT_FAILED, |
null, null, null, |
$error); |
} |
return DB_OK; |
} |
// }}} |
// {{{ disconnect() |
/** |
* Disconnects from the database server |
* |
* @return bool TRUE on success, FALSE on failure |
*/ |
function disconnect() |
{ |
if (function_exists('oci_close')) { |
$ret = @oci_close($this->connection); |
} else { |
$ret = @OCILogOff($this->connection); |
} |
$this->connection = null; |
return $ret; |
} |
// }}} |
// {{{ simpleQuery() |
/** |
* Sends a query to the database server |
* |
* To determine how many rows of a result set get buffered using |
* ocisetprefetch(), see the "result_buffering" option in setOptions(). |
* This option was added in Release 1.7.0. |
* |
* @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->_data = array(); |
$this->last_parameters = array(); |
$this->last_query = $query; |
$query = $this->modifyQuery($query); |
$result = @OCIParse($this->connection, $query); |
if (!$result) { |
return $this->oci8RaiseError(); |
} |
if ($this->autocommit) { |
$success = @OCIExecute($result,OCI_COMMIT_ON_SUCCESS); |
} else { |
$success = @OCIExecute($result,OCI_DEFAULT); |
} |
if (!$success) { |
return $this->oci8RaiseError($result); |
} |
$this->last_stmt = $result; |
if (DB::isManip($query)) { |
return DB_OK; |
} else { |
@ocisetprefetch($result, $this->options['result_buffering']); |
return $result; |
} |
} |
// }}} |
// {{{ nextResult() |
/** |
* Move the internal oracle result pointer to the next available result |
* |
* @param a valid oci8 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) { |
return $this->raiseError(DB_ERROR_NOT_CAPABLE); |
} |
if ($fetchmode & DB_FETCHMODE_ASSOC) { |
$moredata = @OCIFetchInto($result,$arr,OCI_ASSOC+OCI_RETURN_NULLS+OCI_RETURN_LOBS); |
if ($this->options['portability'] & DB_PORTABILITY_LOWERCASE && |
$moredata) |
{ |
$arr = array_change_key_case($arr, CASE_LOWER); |
} |
} else { |
$moredata = OCIFetchInto($result,$arr,OCI_RETURN_NULLS+OCI_RETURN_LOBS); |
} |
if (!$moredata) { |
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 @OCIFreeStatement($result); |
} |
/** |
* Frees the internal resources associated with a prepared query |
* |
* @param resource $stmt the prepared statement's resource |
* @param bool $free_resource should the PHP resource be freed too? |
* Use false if you need to get data |
* from the result set later. |
* |
* @return bool TRUE on success, FALSE if $result is invalid |
* |
* @see DB_oci8::prepare() |
*/ |
function freePrepared($stmt, $free_resource = true) |
{ |
if (!is_resource($stmt)) { |
return false; |
} |
if ($free_resource) { |
@ocifreestatement($stmt); |
} |
if (isset($this->prepare_types[(int)$stmt])) { |
unset($this->prepare_types[(int)$stmt]); |
unset($this->manip_query[(int)$stmt]); |
} else { |
return false; |
} |
return true; |
} |
// }}} |
// {{{ numRows() |
/** |
* Gets the number of rows in a result set |
* |
* Only works if the DB_PORTABILITY_NUMROWS portability option |
* is turned on. |
* |
* 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(), DB_common::setOption() |
*/ |
function numRows($result) |
{ |
// emulate numRows for Oracle. yuck. |
if ($this->options['portability'] & DB_PORTABILITY_NUMROWS && |
$result === $this->last_stmt) |
{ |
$countquery = 'SELECT COUNT(*) FROM ('.$this->last_query.')'; |
$save_query = $this->last_query; |
$save_stmt = $this->last_stmt; |
if (count($this->_data)) { |
$smt = $this->prepare('SELECT COUNT(*) FROM ('.$this->last_query.')'); |
$count = $this->execute($smt, $this->_data); |
} else { |
$count =& $this->query($countquery); |
} |
if (DB::isError($count) || |
DB::isError($row = $count->fetchRow(DB_FETCHMODE_ORDERED))) |
{ |
$this->last_query = $save_query; |
$this->last_stmt = $save_stmt; |
return $this->raiseError(DB_ERROR_NOT_CAPABLE); |
} |
return $row[0]; |
} |
return $this->raiseError(DB_ERROR_NOT_CAPABLE); |
} |
// }}} |
// {{{ 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 = @OCINumCols($result); |
if (!$cols) { |
return $this->oci8RaiseError($result); |
} |
return $cols; |
} |
// }}} |
// {{{ prepare() |
/** |
* Prepares a query for multiple execution with execute(). |
* |
* With oci8, this is emulated. |
* |
* prepare() requires a generic query as string like <code> |
* INSERT INTO numbers VALUES (?, ?, ?) |
* </code>. The <kbd>?</kbd> characters are placeholders. |
* |
* Three types of placeholders can be used: |
* + <kbd>?</kbd> a quoted scalar value, i.e. strings, integers |
* + <kbd>!</kbd> value is inserted 'as is' |
* + <kbd>&</kbd> requires a file name. The file's contents get |
* inserted into the query (i.e. saving binary |
* data in a db) |
* |
* Use backslashes to escape placeholder characters if you don't want |
* them to be interpreted as placeholders. Example: <code> |
* "UPDATE foo SET col=? WHERE col='over \& under'" |
* </code> |
* |
* @param string $query the query to be prepared |
* |
* @return mixed DB statement resource on success. DB_Error on failure. |
* |
* @see DB_oci8::execute() |
*/ |
function prepare($query) |
{ |
$tokens = preg_split('/((?<!\\\)[&?!])/', $query, -1, |
PREG_SPLIT_DELIM_CAPTURE); |
$binds = count($tokens) - 1; |
$token = 0; |
$types = array(); |
$newquery = ''; |
foreach ($tokens as $key => $val) { |
switch ($val) { |
case '?': |
$types[$token++] = DB_PARAM_SCALAR; |
unset($tokens[$key]); |
break; |
case '&': |
$types[$token++] = DB_PARAM_OPAQUE; |
unset($tokens[$key]); |
break; |
case '!': |
$types[$token++] = DB_PARAM_MISC; |
unset($tokens[$key]); |
break; |
default: |
$tokens[$key] = preg_replace('/\\\([&?!])/', "\\1", $val); |
if ($key != $binds) { |
$newquery .= $tokens[$key] . ':bind' . $token; |
} else { |
$newquery .= $tokens[$key]; |
} |
} |
} |
$this->last_query = $query; |
$newquery = $this->modifyQuery($newquery); |
if (!$stmt = @OCIParse($this->connection, $newquery)) { |
return $this->oci8RaiseError(); |
} |
$this->prepare_types[(int)$stmt] = $types; |
$this->manip_query[(int)$stmt] = DB::isManip($query); |
return $stmt; |
} |
// }}} |
// {{{ execute() |
/** |
* Executes a DB statement prepared with prepare(). |
* |
* To determine how many rows of a result set get buffered using |
* ocisetprefetch(), see the "result_buffering" option in setOptions(). |
* This option was added in Release 1.7.0. |
* |
* @param resource $stmt a DB statement resource returned from prepare() |
* @param mixed $data 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 for non-array items or the |
* quantity of elements in the array. |
* |
* @return mixed returns an oic8 result resource for successful SELECT |
* queries, DB_OK for other successful queries. |
* A DB error object is returned on failure. |
* |
* @see DB_oci8::prepare() |
*/ |
function &execute($stmt, $data = array()) |
{ |
$data = (array)$data; |
$this->last_parameters = $data; |
$this->_data = $data; |
$types =& $this->prepare_types[(int)$stmt]; |
if (count($types) != count($data)) { |
$tmp =& $this->raiseError(DB_ERROR_MISMATCH); |
return $tmp; |
} |
$i = 0; |
foreach ($data as $key => $value) { |
if ($types[$i] == DB_PARAM_MISC) { |
/* |
* Oracle doesn't seem to have the ability to pass a |
* parameter along unchanged, so strip off quotes from start |
* and end, plus turn two single quotes to one single quote, |
* in order to avoid the quotes getting escaped by |
* Oracle and ending up in the database. |
*/ |
$data[$key] = preg_replace("/^'(.*)'$/", "\\1", $data[$key]); |
$data[$key] = str_replace("''", "'", $data[$key]); |
} elseif ($types[$i] == DB_PARAM_OPAQUE) { |
$fp = @fopen($data[$key], 'rb'); |
if (!$fp) { |
$tmp =& $this->raiseError(DB_ERROR_ACCESS_VIOLATION); |
return $tmp; |
} |
$data[$key] = fread($fp, filesize($data[$key])); |
fclose($fp); |
} |
if (!@OCIBindByName($stmt, ':bind' . $i, $data[$key], -1)) { |
$tmp = $this->oci8RaiseError($stmt); |
return $tmp; |
} |
$i++; |
} |
if ($this->autocommit) { |
$success = @OCIExecute($stmt, OCI_COMMIT_ON_SUCCESS); |
} else { |
$success = @OCIExecute($stmt, OCI_DEFAULT); |
} |
if (!$success) { |
$tmp = $this->oci8RaiseError($stmt); |
return $tmp; |
} |
$this->last_stmt = $stmt; |
if ($this->manip_query[(int)$stmt]) { |
$tmp = DB_OK; |
} else { |
@ocisetprefetch($stmt, $this->options['result_buffering']); |
$tmp =& new DB_result($this, $stmt); |
} |
return $tmp; |
} |
// }}} |
// {{{ 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) |
{ |
$this->autocommit = (bool)$onoff;; |
return DB_OK; |
} |
// }}} |
// {{{ commit() |
/** |
* Commits the current transaction |
* |
* @return int DB_OK on success. A DB_Error object on failure. |
*/ |
function commit() |
{ |
$result = @OCICommit($this->connection); |
if (!$result) { |
return $this->oci8RaiseError(); |
} |
return DB_OK; |
} |
// }}} |
// {{{ rollback() |
/** |
* Reverts the current transaction |
* |
* @return int DB_OK on success. A DB_Error object on failure. |
*/ |
function rollback() |
{ |
$result = @OCIRollback($this->connection); |
if (!$result) { |
return $this->oci8RaiseError(); |
} |
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 ($this->last_stmt === false) { |
return $this->oci8RaiseError(); |
} |
$result = @OCIRowCount($this->last_stmt); |
if ($result === false) { |
return $this->oci8RaiseError($this->last_stmt); |
} |
return $result; |
} |
// }}} |
// {{{ modifyQuery() |
/** |
* Changes a query string for various DBMS specific reasons |
* |
* "SELECT 2+2" must be "SELECT 2+2 FROM dual" in Oracle. |
* |
* @param string $query the query string to modify |
* |
* @return string the modified query string |
* |
* @access protected |
*/ |
function modifyQuery($query) |
{ |
if (preg_match('/^\s*SELECT/i', $query) && |
!preg_match('/\sFROM\s/i', $query)) { |
$query .= ' FROM dual'; |
} |
return $query; |
} |
// }}} |
// {{{ 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()) |
{ |
// Let Oracle return the name of the columns instead of |
// coding a "home" SQL parser |
if (count($params)) { |
$result = $this->prepare("SELECT * FROM ($query) " |
. 'WHERE NULL = NULL'); |
$tmp =& $this->execute($result, $params); |
} else { |
$q_fields = "SELECT * FROM ($query) WHERE NULL = NULL"; |
if (!$result = @OCIParse($this->connection, $q_fields)) { |
$this->last_query = $q_fields; |
return $this->oci8RaiseError(); |
} |
if (!@OCIExecute($result, OCI_DEFAULT)) { |
$this->last_query = $q_fields; |
return $this->oci8RaiseError($result); |
} |
} |
$ncols = OCINumCols($result); |
$cols = array(); |
for ( $i = 1; $i <= $ncols; $i++ ) { |
$cols[] = '"' . OCIColumnName($result, $i) . '"'; |
} |
$fields = implode(', ', $cols); |
// XXX Test that (tip by John Lim) |
//if (preg_match('/^\s*SELECT\s+/is', $query, $match)) { |
// // Introduce the FIRST_ROWS Oracle query optimizer |
// $query = substr($query, strlen($match[0]), strlen($query)); |
// $query = "SELECT /* +FIRST_ROWS */ " . $query; |
//} |
// Construct the query |
// more at: http://marc.theaimsgroup.com/?l=php-db&m=99831958101212&w=2 |
// Perhaps this could be optimized with the use of Unions |
$query = "SELECT $fields FROM". |
" (SELECT rownum as linenum, $fields FROM". |
" ($query)". |
' WHERE rownum <= '. ($from + $count) . |
') WHERE linenum >= ' . ++$from; |
return $query; |
} |
// }}} |
// {{{ 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_oci8::createSequence(), DB_oci8::dropSequence() |
*/ |
function nextId($seq_name, $ondemand = true) |
{ |
$seqname = $this->getSequenceName($seq_name); |
$repeat = 0; |
do { |
$this->expectError(DB_ERROR_NOSUCHTABLE); |
$result =& $this->query("SELECT ${seqname}.nextval FROM dual"); |
$this->popExpect(); |
if ($ondemand && DB::isError($result) && |
$result->getCode() == DB_ERROR_NOSUCHTABLE) { |
$repeat = 1; |
$result = $this->createSequence($seq_name); |
if (DB::isError($result)) { |
return $this->raiseError($result); |
} |
} else { |
$repeat = 0; |
} |
} while ($repeat); |
if (DB::isError($result)) { |
return $this->raiseError($result); |
} |
$arr = $result->fetchRow(DB_FETCHMODE_ORDERED); |
return $arr[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_oci8::nextID(), DB_oci8::dropSequence() |
*/ |
function createSequence($seq_name) |
{ |
return $this->query('CREATE SEQUENCE ' |
. $this->getSequenceName($seq_name)); |
} |
// }}} |
// {{{ 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_oci8::nextID(), DB_oci8::createSequence() |
*/ |
function dropSequence($seq_name) |
{ |
return $this->query('DROP SEQUENCE ' |
. $this->getSequenceName($seq_name)); |
} |
// }}} |
// {{{ oci8RaiseError() |
/** |
* 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_oci8::errorNative(), DB_oci8::errorCode() |
*/ |
function oci8RaiseError($errno = null) |
{ |
if ($errno === null) { |
$error = @OCIError($this->connection); |
return $this->raiseError($this->errorCode($error['code']), |
null, null, null, $error['message']); |
} elseif (is_resource($errno)) { |
$error = @OCIError($errno); |
return $this->raiseError($this->errorCode($error['code']), |
null, null, null, $error['message']); |
} |
return $this->raiseError($this->errorCode($errno)); |
} |
// }}} |
// {{{ errorNative() |
/** |
* Gets the DBMS' native error code produced by the last query |
* |
* @return int the DBMS' error code. FALSE if the code could not be |
* determined |
*/ |
function errorNative() |
{ |
if (is_resource($this->last_stmt)) { |
$error = @OCIError($this->last_stmt); |
} else { |
$error = @OCIError($this->connection); |
} |
if (is_array($error)) { |
return $error['code']; |
} |
return false; |
} |
// }}} |
// {{{ tableInfo() |
/** |
* Returns information about a table or a result set |
* |
* NOTE: only supports 'table' and 'flags' if <var>$result</var> |
* is a table name. |
* |
* NOTE: flags won't contain index information. |
* |
* @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 ($this->options['portability'] & DB_PORTABILITY_LOWERCASE) { |
$case_func = 'strtolower'; |
} else { |
$case_func = 'strval'; |
} |
$res = array(); |
if (is_string($result)) { |
/* |
* Probably received a table name. |
* Create a result resource identifier. |
*/ |
$result = strtoupper($result); |
$q_fields = 'SELECT column_name, data_type, data_length, ' |
. 'nullable ' |
. 'FROM user_tab_columns ' |
. "WHERE table_name='$result' ORDER BY column_id"; |
$this->last_query = $q_fields; |
if (!$stmt = @OCIParse($this->connection, $q_fields)) { |
return $this->oci8RaiseError(DB_ERROR_NEED_MORE_DATA); |
} |
if (!@OCIExecute($stmt, OCI_DEFAULT)) { |
return $this->oci8RaiseError($stmt); |
} |
$i = 0; |
while (@OCIFetch($stmt)) { |
$res[$i] = array( |
'table' => $case_func($result), |
'name' => $case_func(@OCIResult($stmt, 1)), |
'type' => @OCIResult($stmt, 2), |
'len' => @OCIResult($stmt, 3), |
'flags' => (@OCIResult($stmt, 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++; |
} |
if ($mode) { |
$res['num_fields'] = $i; |
} |
@OCIFreeStatement($stmt); |
} else { |
if (isset($result->result)) { |
/* |
* Probably received a result object. |
* Extract the result resource identifier. |
*/ |
$result = $result->result; |
} |
$res = array(); |
if ($result === $this->last_stmt) { |
$count = @OCINumCols($result); |
if ($mode) { |
$res['num_fields'] = $count; |
} |
for ($i = 0; $i < $count; $i++) { |
$res[$i] = array( |
'table' => '', |
'name' => $case_func(@OCIColumnName($result, $i+1)), |
'type' => @OCIColumnType($result, $i+1), |
'len' => @OCIColumnSize($result, $i+1), |
'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; |
} |
} |
} else { |
return $this->raiseError(DB_ERROR_NOT_CAPABLE); |
} |
} |
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 user_tables'; |
case 'synonyms': |
return 'SELECT synonym_name FROM user_synonyms'; |
default: |
return null; |
} |
} |
// }}} |
} |
/* |
* Local variables: |
* tab-width: 4 |
* c-basic-offset: 4 |
* End: |
*/ |
?> |
/branches/livraison_menes/api/pear/DB/ibase.php |
---|
New file |
0,0 → 1,1071 |
<?php |
/* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4: */ |
/** |
* The PEAR DB driver for PHP's interbase extension |
* for interacting with Interbase and Firebird databases |
* |
* While this class works with PHP 4, PHP's InterBase extension is |
* unstable in PHP 4. Use PHP 5. |
* |
* 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: ibase.php,v 1.2 2005-09-20 17:01:22 ddelon 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 interbase extension |
* for interacting with Interbase and Firebird databases |
* |
* These methods overload the ones declared in DB_common. |
* |
* While this class works with PHP 4, PHP's InterBase extension is |
* unstable in PHP 4. Use PHP 5. |
* |
* NOTICE: limitQuery() only works for Firebird. |
* |
* @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 |
* @since Class became stable in Release 1.7.0 |
*/ |
class DB_ibase extends DB_common |
{ |
// {{{ properties |
/** |
* The DB driver type (mysql, oci8, odbc, etc.) |
* @var string |
*/ |
var $phptype = 'ibase'; |
/** |
* The database syntax variant to be used (db2, access, etc.), if any |
* @var string |
*/ |
var $dbsyntax = 'ibase'; |
/** |
* 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: only firebird supports limit. |
* |
* @var array |
*/ |
var $features = array( |
'limit' => false, |
'new_link' => false, |
'numrows' => 'emulate', |
'pconnect' => true, |
'prepare' => true, |
'ssl' => false, |
'transactions' => true, |
); |
/** |
* A mapping of native error codes to DB error codes |
* @var array |
*/ |
var $errorcode_map = array( |
-104 => DB_ERROR_SYNTAX, |
-150 => DB_ERROR_ACCESS_VIOLATION, |
-151 => DB_ERROR_ACCESS_VIOLATION, |
-155 => DB_ERROR_NOSUCHTABLE, |
-157 => DB_ERROR_NOSUCHFIELD, |
-158 => DB_ERROR_VALUE_COUNT_ON_ROW, |
-170 => DB_ERROR_MISMATCH, |
-171 => DB_ERROR_MISMATCH, |
-172 => DB_ERROR_INVALID, |
// -204 => // Covers too many errors, need to use regex on msg |
-205 => DB_ERROR_NOSUCHFIELD, |
-206 => DB_ERROR_NOSUCHFIELD, |
-208 => DB_ERROR_INVALID, |
-219 => DB_ERROR_NOSUCHTABLE, |
-297 => DB_ERROR_CONSTRAINT, |
-303 => DB_ERROR_INVALID, |
-413 => DB_ERROR_INVALID_NUMBER, |
-530 => DB_ERROR_CONSTRAINT, |
-551 => DB_ERROR_ACCESS_VIOLATION, |
-552 => DB_ERROR_ACCESS_VIOLATION, |
// -607 => // Covers too many errors, need to use regex on msg |
-625 => DB_ERROR_CONSTRAINT_NOT_NULL, |
-803 => DB_ERROR_CONSTRAINT, |
-804 => DB_ERROR_VALUE_COUNT_ON_ROW, |
-904 => DB_ERROR_CONNECT_FAILED, |
-922 => DB_ERROR_NOSUCHDB, |
-923 => DB_ERROR_CONNECT_FAILED, |
-924 => DB_ERROR_CONNECT_FAILED |
); |
/** |
* 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; |
/** |
* Should data manipulation queries be committed automatically? |
* @var bool |
* @access private |
*/ |
var $autocommit = true; |
/** |
* The prepared statement handle from the most recently executed statement |
* |
* {@internal Mainly here because the InterBase/Firebird API is only |
* able to retrieve data from result sets if the statemnt handle is |
* still in scope.}} |
* |
* @var resource |
*/ |
var $last_stmt; |
/** |
* Is the given prepared statement a data manipulation query? |
* @var array |
* @access private |
*/ |
var $manip_query = array(); |
// }}} |
// {{{ constructor |
/** |
* This constructor calls <kbd>$this->DB_common()</kbd> |
* |
* @return void |
*/ |
function DB_ibase() |
{ |
$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 ibase driver supports the following extra DSN options: |
* + buffers The number of database buffers to allocate for the |
* server-side cache. |
* + charset The default character set for a database. |
* + dialect The default SQL dialect for any statement |
* executed within a connection. Defaults to the |
* highest one supported by client libraries. |
* Functional only with InterBase 6 and up. |
* + role Functional only with InterBase 5 and up. |
* |
* @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('interbase')) { |
return $this->raiseError(DB_ERROR_EXTENSION_NOT_FOUND); |
} |
$this->dsn = $dsn; |
if ($dsn['dbsyntax']) { |
$this->dbsyntax = $dsn['dbsyntax']; |
} |
if ($this->dbsyntax == 'firebird') { |
$this->features['limit'] = 'alter'; |
} |
$params = array( |
$dsn['hostspec'] |
? ($dsn['hostspec'] . ':' . $dsn['database']) |
: $dsn['database'], |
$dsn['username'] ? $dsn['username'] : null, |
$dsn['password'] ? $dsn['password'] : null, |
isset($dsn['charset']) ? $dsn['charset'] : null, |
isset($dsn['buffers']) ? $dsn['buffers'] : null, |
isset($dsn['dialect']) ? $dsn['dialect'] : null, |
isset($dsn['role']) ? $dsn['role'] : null, |
); |
$connect_function = $persistent ? 'ibase_pconnect' : 'ibase_connect'; |
$this->connection = @call_user_func_array($connect_function, $params); |
if (!$this->connection) { |
return $this->ibaseRaiseError(DB_ERROR_CONNECT_FAILED); |
} |
return DB_OK; |
} |
// }}} |
// {{{ disconnect() |
/** |
* Disconnects from the database server |
* |
* @return bool TRUE on success, FALSE on failure |
*/ |
function disconnect() |
{ |
$ret = @ibase_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; |
$query = $this->modifyQuery($query); |
$result = @ibase_query($this->connection, $query); |
if (!$result) { |
return $this->ibaseRaiseError(); |
} |
if ($this->autocommit && $ismanip) { |
@ibase_commit($this->connection); |
} |
if ($ismanip) { |
$this->affected = $result; |
return DB_OK; |
} else { |
$this->affected = 0; |
return $result; |
} |
} |
// }}} |
// {{{ modifyLimitQuery() |
/** |
* Adds LIMIT clauses to a query string according to current DBMS standards |
* |
* Only works with Firebird. |
* |
* @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 ($this->dsn['dbsyntax'] == 'firebird') { |
$query = preg_replace('/^([\s(])*SELECT/i', |
"SELECT FIRST $count SKIP $from", $query); |
} |
return $query; |
} |
// }}} |
// {{{ nextResult() |
/** |
* Move the internal ibase 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. |
* |
* @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) { |
return $this->ibaseRaiseError(DB_ERROR_NOT_CAPABLE); |
} |
if ($fetchmode & DB_FETCHMODE_ASSOC) { |
if (function_exists('ibase_fetch_assoc')) { |
$arr = @ibase_fetch_assoc($result); |
} else { |
$arr = get_object_vars(ibase_fetch_object($result)); |
} |
if ($this->options['portability'] & DB_PORTABILITY_LOWERCASE && $arr) { |
$arr = array_change_key_case($arr, CASE_LOWER); |
} |
} else { |
$arr = @ibase_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 @ibase_free_result($result); |
} |
// }}} |
// {{{ freeQuery() |
function freeQuery($query) |
{ |
@ibase_free_query($query); |
return true; |
} |
// }}} |
// {{{ 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 (is_integer($this->affected)) { |
return $this->affected; |
} |
return $this->ibaseRaiseError(DB_ERROR_NOT_CAPABLE); |
} |
// }}} |
// {{{ 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 = @ibase_num_fields($result); |
if (!$cols) { |
return $this->ibaseRaiseError(); |
} |
return $cols; |
} |
// }}} |
// {{{ prepare() |
/** |
* Prepares a query for multiple execution with execute(). |
* |
* prepare() requires a generic query as string like <code> |
* INSERT INTO numbers VALUES (?, ?, ?) |
* </code>. The <kbd>?</kbd> characters are placeholders. |
* |
* Three types of placeholders can be used: |
* + <kbd>?</kbd> a quoted scalar value, i.e. strings, integers |
* + <kbd>!</kbd> value is inserted 'as is' |
* + <kbd>&</kbd> requires a file name. The file's contents get |
* inserted into the query (i.e. saving binary |
* data in a db) |
* |
* Use backslashes to escape placeholder characters if you don't want |
* them to be interpreted as placeholders. Example: <code> |
* "UPDATE foo SET col=? WHERE col='over \& under'" |
* </code> |
* |
* @param string $query query to be prepared |
* @return mixed DB statement resource on success. DB_Error on failure. |
*/ |
function prepare($query) |
{ |
$tokens = preg_split('/((?<!\\\)[&?!])/', $query, -1, |
PREG_SPLIT_DELIM_CAPTURE); |
$token = 0; |
$types = array(); |
$newquery = ''; |
foreach ($tokens as $key => $val) { |
switch ($val) { |
case '?': |
$types[$token++] = DB_PARAM_SCALAR; |
break; |
case '&': |
$types[$token++] = DB_PARAM_OPAQUE; |
break; |
case '!': |
$types[$token++] = DB_PARAM_MISC; |
break; |
default: |
$tokens[$key] = preg_replace('/\\\([&?!])/', "\\1", $val); |
$newquery .= $tokens[$key] . '?'; |
} |
} |
$newquery = substr($newquery, 0, -1); |
$this->last_query = $query; |
$newquery = $this->modifyQuery($newquery); |
$stmt = @ibase_prepare($this->connection, $newquery); |
$this->prepare_types[(int)$stmt] = $types; |
$this->manip_query[(int)$stmt] = DB::isManip($query); |
return $stmt; |
} |
// }}} |
// {{{ execute() |
/** |
* Executes a DB statement prepared with prepare(). |
* |
* @param resource $stmt a DB statement resource returned from prepare() |
* @param mixed $data 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 for non-array items or the |
* quantity of elements in the array. |
* @return object a new DB_Result or a DB_Error when fail |
* @see DB_ibase::prepare() |
* @access public |
*/ |
function &execute($stmt, $data = array()) |
{ |
$data = (array)$data; |
$this->last_parameters = $data; |
$types =& $this->prepare_types[(int)$stmt]; |
if (count($types) != count($data)) { |
$tmp =& $this->raiseError(DB_ERROR_MISMATCH); |
return $tmp; |
} |
$i = 0; |
foreach ($data as $key => $value) { |
if ($types[$i] == DB_PARAM_MISC) { |
/* |
* ibase doesn't seem to have the ability to pass a |
* parameter along unchanged, so strip off quotes from start |
* and end, plus turn two single quotes to one single quote, |
* in order to avoid the quotes getting escaped by |
* ibase and ending up in the database. |
*/ |
$data[$key] = preg_replace("/^'(.*)'$/", "\\1", $data[$key]); |
$data[$key] = str_replace("''", "'", $data[$key]); |
} elseif ($types[$i] == DB_PARAM_OPAQUE) { |
$fp = @fopen($data[$key], 'rb'); |
if (!$fp) { |
$tmp =& $this->raiseError(DB_ERROR_ACCESS_VIOLATION); |
return $tmp; |
} |
$data[$key] = fread($fp, filesize($data[$key])); |
fclose($fp); |
} |
$i++; |
} |
array_unshift($data, $stmt); |
$res = call_user_func_array('ibase_execute', $data); |
if (!$res) { |
$tmp =& $this->ibaseRaiseError(); |
return $tmp; |
} |
/* XXX need this? |
if ($this->autocommit && $this->manip_query[(int)$stmt]) { |
@ibase_commit($this->connection); |
}*/ |
$this->last_stmt = $stmt; |
if ($this->manip_query[(int)$stmt]) { |
$tmp = DB_OK; |
} else { |
$tmp =& new DB_result($this, $res); |
} |
return $tmp; |
} |
/** |
* Frees the internal resources associated with a prepared query |
* |
* @param resource $stmt the prepared statement's PHP resource |
* @param bool $free_resource should the PHP resource be freed too? |
* Use false if you need to get data |
* from the result set later. |
* |
* @return bool TRUE on success, FALSE if $result is invalid |
* |
* @see DB_ibase::prepare() |
*/ |
function freePrepared($stmt, $free_resource = true) |
{ |
if (!is_resource($stmt)) { |
return false; |
} |
if ($free_resource) { |
@ibase_free_query($stmt); |
} |
unset($this->prepare_tokens[(int)$stmt]); |
unset($this->prepare_types[(int)$stmt]); |
unset($this->manip_query[(int)$stmt]); |
return true; |
} |
// }}} |
// {{{ 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) |
{ |
$this->autocommit = $onoff ? 1 : 0; |
return DB_OK; |
} |
// }}} |
// {{{ commit() |
/** |
* Commits the current transaction |
* |
* @return int DB_OK on success. A DB_Error object on failure. |
*/ |
function commit() |
{ |
return @ibase_commit($this->connection); |
} |
// }}} |
// {{{ rollback() |
/** |
* Reverts the current transaction |
* |
* @return int DB_OK on success. A DB_Error object on failure. |
*/ |
function rollback() |
{ |
return @ibase_rollback($this->connection); |
} |
// }}} |
// {{{ transactionInit() |
function transactionInit($trans_args = 0) |
{ |
return $trans_args |
? @ibase_trans($trans_args, $this->connection) |
: @ibase_trans(); |
} |
// }}} |
// {{{ 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_ibase::createSequence(), DB_ibase::dropSequence() |
*/ |
function nextId($seq_name, $ondemand = true) |
{ |
$sqn = strtoupper($this->getSequenceName($seq_name)); |
$repeat = 0; |
do { |
$this->pushErrorHandling(PEAR_ERROR_RETURN); |
$result =& $this->query("SELECT GEN_ID(${sqn}, 1) " |
. 'FROM RDB$GENERATORS ' |
. "WHERE RDB\$GENERATOR_NAME='${sqn}'"); |
$this->popErrorHandling(); |
if ($ondemand && DB::isError($result)) { |
$repeat = 1; |
$result = $this->createSequence($seq_name); |
if (DB::isError($result)) { |
return $result; |
} |
} else { |
$repeat = 0; |
} |
} 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 |
* |
* @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_ibase::nextID(), DB_ibase::dropSequence() |
*/ |
function createSequence($seq_name) |
{ |
$sqn = strtoupper($this->getSequenceName($seq_name)); |
$this->pushErrorHandling(PEAR_ERROR_RETURN); |
$result = $this->query("CREATE GENERATOR ${sqn}"); |
$this->popErrorHandling(); |
return $result; |
} |
// }}} |
// {{{ 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_ibase::nextID(), DB_ibase::createSequence() |
*/ |
function dropSequence($seq_name) |
{ |
return $this->query('DELETE FROM RDB$GENERATORS ' |
. "WHERE RDB\$GENERATOR_NAME='" |
. strtoupper($this->getSequenceName($seq_name)) |
. "'"); |
} |
// }}} |
// {{{ _ibaseFieldFlags() |
/** |
* Get the column's flags |
* |
* Supports "primary_key", "unique_key", "not_null", "default", |
* "computed" and "blob". |
* |
* @param string $field_name the name of the field |
* @param string $table_name the name of the table |
* |
* @return string the flags |
* |
* @access private |
*/ |
function _ibaseFieldFlags($field_name, $table_name) |
{ |
$sql = 'SELECT R.RDB$CONSTRAINT_TYPE CTYPE' |
.' FROM RDB$INDEX_SEGMENTS I' |
.' JOIN RDB$RELATION_CONSTRAINTS R ON I.RDB$INDEX_NAME=R.RDB$INDEX_NAME' |
.' WHERE I.RDB$FIELD_NAME=\'' . $field_name . '\'' |
.' AND UPPER(R.RDB$RELATION_NAME)=\'' . strtoupper($table_name) . '\''; |
$result = @ibase_query($this->connection, $sql); |
if (!$result) { |
return $this->ibaseRaiseError(); |
} |
$flags = ''; |
if ($obj = @ibase_fetch_object($result)) { |
@ibase_free_result($result); |
if (isset($obj->CTYPE) && trim($obj->CTYPE) == 'PRIMARY KEY') { |
$flags .= 'primary_key '; |
} |
if (isset($obj->CTYPE) && trim($obj->CTYPE) == 'UNIQUE') { |
$flags .= 'unique_key '; |
} |
} |
$sql = 'SELECT R.RDB$NULL_FLAG AS NFLAG,' |
.' R.RDB$DEFAULT_SOURCE AS DSOURCE,' |
.' F.RDB$FIELD_TYPE AS FTYPE,' |
.' F.RDB$COMPUTED_SOURCE AS CSOURCE' |
.' FROM RDB$RELATION_FIELDS R ' |
.' JOIN RDB$FIELDS F ON R.RDB$FIELD_SOURCE=F.RDB$FIELD_NAME' |
.' WHERE UPPER(R.RDB$RELATION_NAME)=\'' . strtoupper($table_name) . '\'' |
.' AND R.RDB$FIELD_NAME=\'' . $field_name . '\''; |
$result = @ibase_query($this->connection, $sql); |
if (!$result) { |
return $this->ibaseRaiseError(); |
} |
if ($obj = @ibase_fetch_object($result)) { |
@ibase_free_result($result); |
if (isset($obj->NFLAG)) { |
$flags .= 'not_null '; |
} |
if (isset($obj->DSOURCE)) { |
$flags .= 'default '; |
} |
if (isset($obj->CSOURCE)) { |
$flags .= 'computed '; |
} |
if (isset($obj->FTYPE) && $obj->FTYPE == 261) { |
$flags .= 'blob '; |
} |
} |
return trim($flags); |
} |
// }}} |
// {{{ ibaseRaiseError() |
/** |
* 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_ibase::errorNative(), DB_ibase::errorCode() |
*/ |
function &ibaseRaiseError($errno = null) |
{ |
if ($errno === null) { |
$errno = $this->errorCode($this->errorNative()); |
} |
$tmp =& $this->raiseError($errno, null, null, null, @ibase_errmsg()); |
return $tmp; |
} |
// }}} |
// {{{ errorNative() |
/** |
* Gets the DBMS' native error code produced by the last query |
* |
* @return int the DBMS' error code. NULL if there is no error code. |
* |
* @since Method available since Release 1.7.0 |
*/ |
function errorNative() |
{ |
if (function_exists('ibase_errcode')) { |
return @ibase_errcode(); |
} |
if (preg_match('/^Dynamic SQL Error SQL error code = ([0-9-]+)/i', |
@ibase_errmsg(), $m)) { |
return (int)$m[1]; |
} |
return null; |
} |
// }}} |
// {{{ errorCode() |
/** |
* Maps native error codes to DB's portable ones |
* |
* @param int $nativecode the error code returned by the DBMS |
* |
* @return int the portable DB error code. Return DB_ERROR if the |
* current driver doesn't have a mapping for the |
* $nativecode submitted. |
* |
* @since Method available since Release 1.7.0 |
*/ |
function errorCode($nativecode = null) |
{ |
if (isset($this->errorcode_map[$nativecode])) { |
return $this->errorcode_map[$nativecode]; |
} |
static $error_regexps; |
if (!isset($error_regexps)) { |
$error_regexps = array( |
'/generator .* is not defined/' |
=> DB_ERROR_SYNTAX, // for compat. w ibase_errcode() |
'/table.*(not exist|not found|unknown)/i' |
=> DB_ERROR_NOSUCHTABLE, |
'/table .* already exists/i' |
=> DB_ERROR_ALREADY_EXISTS, |
'/unsuccessful metadata update .* failed attempt to store duplicate value/i' |
=> DB_ERROR_ALREADY_EXISTS, |
'/unsuccessful metadata update .* not found/i' |
=> DB_ERROR_NOT_FOUND, |
'/validation error for column .* value "\*\*\* null/i' |
=> DB_ERROR_CONSTRAINT_NOT_NULL, |
'/violation of [\w ]+ constraint/i' |
=> DB_ERROR_CONSTRAINT, |
'/conversion error from string/i' |
=> DB_ERROR_INVALID_NUMBER, |
'/no permission for/i' |
=> DB_ERROR_ACCESS_VIOLATION, |
'/arithmetic exception, numeric overflow, or string truncation/i' |
=> DB_ERROR_INVALID, |
); |
} |
$errormsg = @ibase_errmsg(); |
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() |
*/ |
function tableInfo($result, $mode = null) |
{ |
if (is_string($result)) { |
/* |
* Probably received a table name. |
* Create a result resource identifier. |
*/ |
$id = @ibase_query($this->connection, |
"SELECT * FROM $result WHERE 1=0"); |
$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->ibaseRaiseError(DB_ERROR_NEED_MORE_DATA); |
} |
if ($this->options['portability'] & DB_PORTABILITY_LOWERCASE) { |
$case_func = 'strtolower'; |
} else { |
$case_func = 'strval'; |
} |
$count = @ibase_num_fields($id); |
$res = array(); |
if ($mode) { |
$res['num_fields'] = $count; |
} |
for ($i = 0; $i < $count; $i++) { |
$info = @ibase_field_info($id, $i); |
$res[$i] = array( |
'table' => $got_string ? $case_func($result) : '', |
'name' => $case_func($info['name']), |
'type' => $info['type'], |
'len' => $info['length'], |
'flags' => ($got_string) |
? $this->_ibaseFieldFlags($info['name'], $result) |
: '', |
); |
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) { |
@ibase_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 DISTINCT R.RDB$RELATION_NAME FROM ' |
. 'RDB$RELATION_FIELDS R WHERE R.RDB$SYSTEM_FLAG=0'; |
case 'views': |
return 'SELECT DISTINCT RDB$VIEW_NAME from RDB$VIEW_RELATIONS'; |
case 'users': |
return 'SELECT DISTINCT RDB$USER FROM RDB$USER_PRIVILEGES'; |
default: |
return null; |
} |
} |
// }}} |
} |
/* |
* Local variables: |
* tab-width: 4 |
* c-basic-offset: 4 |
* End: |
*/ |
?> |
/branches/livraison_menes/api/pear/DB/storage.php |
---|
New 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.2 2005-09-20 17:01:22 ddelon 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: |
*/ |
?> |
/branches/livraison_menes/api/pear/DB/mysql.php |
---|
New file |
0,0 → 1,1034 |
<?php |
/* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4: */ |
/** |
* The PEAR DB driver for PHP's mysql extension |
* for interacting with MySQL 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 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: mysql.php,v 1.2 2005-09-20 17:01:22 ddelon 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 mysql extension |
* for interacting with MySQL databases |
* |
* These methods overload the ones declared in DB_common. |
* |
* @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_mysql extends DB_common |
{ |
// {{{ properties |
/** |
* The DB driver type (mysql, oci8, odbc, etc.) |
* @var string |
*/ |
var $phptype = 'mysql'; |
/** |
* The database syntax variant to be used (db2, access, etc.), if any |
* @var string |
*/ |
var $dbsyntax = 'mysql'; |
/** |
* 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' => '4.2.0', |
'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( |
1004 => DB_ERROR_CANNOT_CREATE, |
1005 => DB_ERROR_CANNOT_CREATE, |
1006 => DB_ERROR_CANNOT_CREATE, |
1007 => DB_ERROR_ALREADY_EXISTS, |
1008 => DB_ERROR_CANNOT_DROP, |
1022 => DB_ERROR_ALREADY_EXISTS, |
1044 => DB_ERROR_ACCESS_VIOLATION, |
1046 => DB_ERROR_NODBSELECTED, |
1048 => DB_ERROR_CONSTRAINT, |
1049 => DB_ERROR_NOSUCHDB, |
1050 => DB_ERROR_ALREADY_EXISTS, |
1051 => DB_ERROR_NOSUCHTABLE, |
1054 => DB_ERROR_NOSUCHFIELD, |
1061 => DB_ERROR_ALREADY_EXISTS, |
1062 => DB_ERROR_ALREADY_EXISTS, |
1064 => DB_ERROR_SYNTAX, |
1091 => DB_ERROR_NOT_FOUND, |
1100 => DB_ERROR_NOT_LOCKED, |
1136 => DB_ERROR_VALUE_COUNT_ON_ROW, |
1142 => DB_ERROR_ACCESS_VIOLATION, |
1146 => DB_ERROR_NOSUCHTABLE, |
1216 => DB_ERROR_CONSTRAINT, |
1217 => 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(); |
/** |
* 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_mysql() |
{ |
$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 mysql driver supports the following extra DSN options: |
* + new_link If set to true, causes subsequent calls to connect() |
* to return a new connection link instead of the |
* existing one. WARNING: this is not portable to |
* other DBMS's. Available since PEAR DB 1.7.0. |
* + client_flags Any combination of MYSQL_CLIENT_* constants. |
* Only used if PHP is at version 4.3.0 or greater. |
* 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('mysql')) { |
return $this->raiseError(DB_ERROR_EXTENSION_NOT_FOUND); |
} |
$this->dsn = $dsn; |
if ($dsn['dbsyntax']) { |
$this->dbsyntax = $dsn['dbsyntax']; |
} |
$params = array(); |
if ($dsn['protocol'] && $dsn['protocol'] == 'unix') { |
$params[0] = ':' . $dsn['socket']; |
} else { |
$params[0] = $dsn['hostspec'] ? $dsn['hostspec'] |
: 'localhost'; |
if ($dsn['port']) { |
$params[0] .= ':' . $dsn['port']; |
} |
} |
$params[] = $dsn['username'] ? $dsn['username'] : null; |
$params[] = $dsn['password'] ? $dsn['password'] : null; |
if (!$persistent) { |
if (isset($dsn['new_link']) |
&& ($dsn['new_link'] == 'true' || $dsn['new_link'] === true)) |
{ |
$params[] = true; |
} else { |
$params[] = false; |
} |
} |
if (version_compare(phpversion(), '4.3.0', '>=')) { |
$params[] = isset($dsn['client_flags']) |
? $dsn['client_flags'] : null; |
} |
$connect_function = $persistent ? 'mysql_pconnect' : 'mysql_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 = @mysql_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 ($dsn['database']) { |
if (!@mysql_select_db($dsn['database'], $this->connection)) { |
return $this->mysqlRaiseError(); |
} |
$this->_db = $dsn['database']; |
} |
return DB_OK; |
} |
// }}} |
// {{{ disconnect() |
/** |
* Disconnects from the database server |
* |
* @return bool TRUE on success, FALSE on failure |
*/ |
function disconnect() |
{ |
$ret = @mysql_close($this->connection); |
$this->connection = null; |
return $ret; |
} |
// }}} |
// {{{ simpleQuery() |
/** |
* Sends a query to the database server |
* |
* Generally uses mysql_query(). If you want to use |
* mysql_unbuffered_query() set the "result_buffering" option to 0 using |
* setOptions(). This option was added in Release 1.7.0. |
* |
* @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); |
if ($this->_db) { |
if (!@mysql_select_db($this->_db, $this->connection)) { |
return $this->mysqlRaiseError(DB_ERROR_NODBSELECTED); |
} |
} |
if (!$this->autocommit && $ismanip) { |
if ($this->transaction_opcount == 0) { |
$result = @mysql_query('SET AUTOCOMMIT=0', $this->connection); |
$result = @mysql_query('BEGIN', $this->connection); |
if (!$result) { |
return $this->mysqlRaiseError(); |
} |
} |
$this->transaction_opcount++; |
} |
if (!$this->options['result_buffering']) { |
$result = @mysql_unbuffered_query($query, $this->connection); |
} else { |
$result = @mysql_query($query, $this->connection); |
} |
if (!$result) { |
return $this->mysqlRaiseError(); |
} |
if (is_resource($result)) { |
return $result; |
} |
return DB_OK; |
} |
// }}} |
// {{{ nextResult() |
/** |
* Move the internal mysql result pointer to the next available result |
* |
* This method has not been implemented yet. |
* |
* @param a valid sql result resource |
* |
* @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 (!@mysql_data_seek($result, $rownum)) { |
return null; |
} |
} |
if ($fetchmode & DB_FETCHMODE_ASSOC) { |
$arr = @mysql_fetch_array($result, MYSQL_ASSOC); |
if ($this->options['portability'] & DB_PORTABILITY_LOWERCASE && $arr) { |
$arr = array_change_key_case($arr, CASE_LOWER); |
} |
} else { |
$arr = @mysql_fetch_row($result); |
} |
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) |
{ |
return @mysql_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 = @mysql_num_fields($result); |
if (!$cols) { |
return $this->mysqlRaiseError(); |
} |
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 = @mysql_num_rows($result); |
if ($rows === null) { |
return $this->mysqlRaiseError(); |
} |
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 ($this->_db) { |
if (!@mysql_select_db($this->_db, $this->connection)) { |
return $this->mysqlRaiseError(DB_ERROR_NODBSELECTED); |
} |
} |
$result = @mysql_query('COMMIT', $this->connection); |
$result = @mysql_query('SET AUTOCOMMIT=1', $this->connection); |
$this->transaction_opcount = 0; |
if (!$result) { |
return $this->mysqlRaiseError(); |
} |
} |
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 ($this->_db) { |
if (!@mysql_select_db($this->_db, $this->connection)) { |
return $this->mysqlRaiseError(DB_ERROR_NODBSELECTED); |
} |
} |
$result = @mysql_query('ROLLBACK', $this->connection); |
$result = @mysql_query('SET AUTOCOMMIT=1', $this->connection); |
$this->transaction_opcount = 0; |
if (!$result) { |
return $this->mysqlRaiseError(); |
} |
} |
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)) { |
return @mysql_affected_rows($this->connection); |
} else { |
return 0; |
} |
} |
// }}} |
// {{{ 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_mysql::createSequence(), DB_mysql::dropSequence() |
*/ |
function nextId($seq_name, $ondemand = true) |
{ |
$seqname = $this->getSequenceName($seq_name); |
do { |
$repeat = 0; |
$this->pushErrorHandling(PEAR_ERROR_RETURN); |
$result = $this->query("UPDATE ${seqname} ". |
'SET id=LAST_INSERT_ID(id+1)'); |
$this->popErrorHandling(); |
if ($result === DB_OK) { |
// COMMON CASE |
$id = @mysql_insert_id($this->connection); |
if ($id != 0) { |
return $id; |
} |
// EMPTY SEQ TABLE |
// Sequence table must be empty for some reason, so fill |
// it and return 1 and obtain a user-level lock |
$result = $this->getOne("SELECT GET_LOCK('${seqname}_lock',10)"); |
if (DB::isError($result)) { |
return $this->raiseError($result); |
} |
if ($result == 0) { |
// Failed to get the lock |
return $this->mysqlRaiseError(DB_ERROR_NOT_LOCKED); |
} |
// add the default value |
$result = $this->query("REPLACE INTO ${seqname} (id) VALUES (0)"); |
if (DB::isError($result)) { |
return $this->raiseError($result); |
} |
// Release the lock |
$result = $this->getOne('SELECT RELEASE_LOCK(' |
. "'${seqname}_lock')"); |
if (DB::isError($result)) { |
return $this->raiseError($result); |
} |
// We know what the result will be, so no need to try again |
return 1; |
} elseif ($ondemand && DB::isError($result) && |
$result->getCode() == DB_ERROR_NOSUCHTABLE) |
{ |
// ONDEMAND TABLE CREATION |
$result = $this->createSequence($seq_name); |
if (DB::isError($result)) { |
return $this->raiseError($result); |
} else { |
$repeat = 1; |
} |
} elseif (DB::isError($result) && |
$result->getCode() == DB_ERROR_ALREADY_EXISTS) |
{ |
// BACKWARDS COMPAT |
// see _BCsequence() comment |
$result = $this->_BCsequence($seqname); |
if (DB::isError($result)) { |
return $this->raiseError($result); |
} |
$repeat = 1; |
} |
} while ($repeat); |
return $this->raiseError($result); |
} |
// }}} |
// {{{ createSequence() |
/** |
* 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_mysql::nextID(), DB_mysql::dropSequence() |
*/ |
function createSequence($seq_name) |
{ |
$seqname = $this->getSequenceName($seq_name); |
$res = $this->query('CREATE TABLE ' . $seqname |
. ' (id INTEGER UNSIGNED AUTO_INCREMENT NOT NULL,' |
. ' PRIMARY KEY(id))'); |
if (DB::isError($res)) { |
return $res; |
} |
// insert yields value 1, nextId call will generate ID 2 |
$res = $this->query("INSERT INTO ${seqname} (id) VALUES (0)"); |
if (DB::isError($res)) { |
return $res; |
} |
// so reset to zero |
return $this->query("UPDATE ${seqname} SET id = 0"); |
} |
// }}} |
// {{{ 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_mysql::nextID(), DB_mysql::createSequence() |
*/ |
function dropSequence($seq_name) |
{ |
return $this->query('DROP TABLE ' . $this->getSequenceName($seq_name)); |
} |
// }}} |
// {{{ _BCsequence() |
/** |
* Backwards compatibility with old sequence emulation implementation |
* (clean up the dupes) |
* |
* @param string $seqname the sequence name to clean up |
* |
* @return bool true on success. A DB_Error object on failure. |
* |
* @access private |
*/ |
function _BCsequence($seqname) |
{ |
// Obtain a user-level lock... this will release any previous |
// application locks, but unlike LOCK TABLES, it does not abort |
// the current transaction and is much less frequently used. |
$result = $this->getOne("SELECT GET_LOCK('${seqname}_lock',10)"); |
if (DB::isError($result)) { |
return $result; |
} |
if ($result == 0) { |
// Failed to get the lock, can't do the conversion, bail |
// with a DB_ERROR_NOT_LOCKED error |
return $this->mysqlRaiseError(DB_ERROR_NOT_LOCKED); |
} |
$highest_id = $this->getOne("SELECT MAX(id) FROM ${seqname}"); |
if (DB::isError($highest_id)) { |
return $highest_id; |
} |
// This should kill all rows except the highest |
// We should probably do something if $highest_id isn't |
// numeric, but I'm at a loss as how to handle that... |
$result = $this->query('DELETE FROM ' . $seqname |
. " WHERE id <> $highest_id"); |
if (DB::isError($result)) { |
return $result; |
} |
// If another thread has been waiting for this lock, |
// it will go thru the above procedure, but will have no |
// real effect |
$result = $this->getOne("SELECT RELEASE_LOCK('${seqname}_lock')"); |
if (DB::isError($result)) { |
return $result; |
} |
return true; |
} |
// }}} |
// {{{ quoteIdentifier() |
/** |
* Quotes a string so it can be safely used as a table or column name |
* |
* MySQL can't handle the backtick character (<kbd>`</kbd>) in |
* table or column names. |
* |
* @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 . '`'; |
} |
// }}} |
// {{{ quote() |
/** |
* @deprecated Deprecated in release 1.6.0 |
*/ |
function quote($str) |
{ |
return $this->quoteSmart($str); |
} |
// }}} |
// {{{ 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.6.0 |
*/ |
function escapeSimple($str) |
{ |
if (function_exists('mysql_real_escape_string')) { |
return @mysql_real_escape_string($str, $this->connection); |
} else { |
return @mysql_escape_string($str); |
} |
} |
// }}} |
// {{{ 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) { |
// "DELETE FROM table" gives 0 affected rows in MySQL. |
// This little hack lets you know how many rows were deleted. |
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; |
} |
// }}} |
// {{{ 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 $query . " LIMIT $count"; |
} else { |
return $query . " LIMIT $from, $count"; |
} |
} |
// }}} |
// {{{ mysqlRaiseError() |
/** |
* 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_mysql::errorNative(), DB_common::errorCode() |
*/ |
function mysqlRaiseError($errno = null) |
{ |
if ($errno === null) { |
if ($this->options['portability'] & DB_PORTABILITY_ERRORS) { |
$this->errorcode_map[1022] = DB_ERROR_CONSTRAINT; |
$this->errorcode_map[1048] = DB_ERROR_CONSTRAINT_NOT_NULL; |
$this->errorcode_map[1062] = DB_ERROR_CONSTRAINT; |
} else { |
// Doing this in case mode changes during runtime. |
$this->errorcode_map[1022] = DB_ERROR_ALREADY_EXISTS; |
$this->errorcode_map[1048] = DB_ERROR_CONSTRAINT; |
$this->errorcode_map[1062] = DB_ERROR_ALREADY_EXISTS; |
} |
$errno = $this->errorCode(mysql_errno($this->connection)); |
} |
return $this->raiseError($errno, null, null, null, |
@mysql_errno($this->connection) . ' ** ' . |
@mysql_error($this->connection)); |
} |
// }}} |
// {{{ errorNative() |
/** |
* Gets the DBMS' native error code produced by the last query |
* |
* @return int the DBMS' error code |
*/ |
function errorNative() |
{ |
return @mysql_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 = @mysql_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->mysqlRaiseError(DB_ERROR_NEED_MORE_DATA); |
} |
if ($this->options['portability'] & DB_PORTABILITY_LOWERCASE) { |
$case_func = 'strtolower'; |
} else { |
$case_func = 'strval'; |
} |
$count = @mysql_num_fields($id); |
$res = array(); |
if ($mode) { |
$res['num_fields'] = $count; |
} |
for ($i = 0; $i < $count; $i++) { |
$res[$i] = array( |
'table' => $case_func(@mysql_field_table($id, $i)), |
'name' => $case_func(@mysql_field_name($id, $i)), |
'type' => @mysql_field_type($id, $i), |
'len' => @mysql_field_len($id, $i), |
'flags' => @mysql_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) { |
@mysql_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 'SHOW TABLES'; |
case 'users': |
return 'SELECT DISTINCT User FROM mysql.user'; |
case 'databases': |
return 'SHOW DATABASES'; |
default: |
return null; |
} |
} |
// }}} |
} |
/* |
* Local variables: |
* tab-width: 4 |
* c-basic-offset: 4 |
* End: |
*/ |
?> |
/branches/livraison_menes/api/pear/DB/ifx.php |
---|
New 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.2 2005-09-20 17:01:22 ddelon 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: |
*/ |
?> |
/branches/livraison_menes/api/pear/DB/pgsql.php |
---|
New file |
0,0 → 1,1097 |
<?php |
/* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4: */ |
/** |
* The PEAR DB driver for PHP's pgsql extension |
* for interacting with PostgreSQL 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 Rui Hirokawa <hirokawa@php.net> |
* @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: pgsql.php,v 1.2 2005-09-20 17:01:22 ddelon 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 pgsql extension |
* for interacting with PostgreSQL databases |
* |
* These methods overload the ones declared in DB_common. |
* |
* @category Database |
* @package DB |
* @author Rui Hirokawa <hirokawa@php.net> |
* @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_pgsql extends DB_common |
{ |
// {{{ properties |
/** |
* The DB driver type (mysql, oci8, odbc, etc.) |
* @var string |
*/ |
var $phptype = 'pgsql'; |
/** |
* The database syntax variant to be used (db2, access, etc.), if any |
* @var string |
*/ |
var $dbsyntax = 'pgsql'; |
/** |
* 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' => '4.3.0', |
'numrows' => true, |
'pconnect' => true, |
'prepare' => false, |
'ssl' => true, |
'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 number of rows affected by a data manipulation query |
* @var integer |
*/ |
var $affected = 0; |
/** |
* The current row being looked at in fetchInto() |
* @var array |
* @access private |
*/ |
var $row = array(); |
/** |
* The number of rows in a given result set |
* @var array |
* @access private |
*/ |
var $_num_rows = array(); |
// }}} |
// {{{ constructor |
/** |
* This constructor calls <kbd>$this->DB_common()</kbd> |
* |
* @return void |
*/ |
function DB_pgsql() |
{ |
$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 pgsql driver supports the following extra DSN options: |
* + connect_timeout How many seconds to wait for a connection to |
* be established. Available since PEAR DB 1.7.0. |
* + new_link If set to true, causes subsequent calls to |
* connect() to return a new connection link |
* instead of the existing one. WARNING: this is |
* not portable to other DBMS's. Available only |
* if PHP is >= 4.3.0 and PEAR DB is >= 1.7.0. |
* + options Command line options to be sent to the server. |
* Available since PEAR DB 1.6.4. |
* + service Specifies a service name in pg_service.conf that |
* holds additional connection parameters. |
* Available since PEAR DB 1.7.0. |
* + sslmode How should SSL be used when connecting? Values: |
* disable, allow, prefer or require. |
* Available since PEAR DB 1.7.0. |
* + tty This was used to specify where to send server |
* debug output. Available since PEAR DB 1.6.4. |
* |
* Example of connecting to a new link via a socket: |
* <code> |
* require_once 'DB.php'; |
* |
* $dsn = 'pgsql://user:pass@unix(/tmp)/dbname?new_link=true'; |
* $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. |
* |
* @link http://www.postgresql.org/docs/current/static/libpq.html#LIBPQ-CONNECT |
*/ |
function connect($dsn, $persistent = false) |
{ |
if (!PEAR::loadExtension('pgsql')) { |
return $this->raiseError(DB_ERROR_EXTENSION_NOT_FOUND); |
} |
$this->dsn = $dsn; |
if ($dsn['dbsyntax']) { |
$this->dbsyntax = $dsn['dbsyntax']; |
} |
$protocol = $dsn['protocol'] ? $dsn['protocol'] : 'tcp'; |
$params = array(''); |
if ($protocol == 'tcp') { |
if ($dsn['hostspec']) { |
$params[0] .= 'host=' . $dsn['hostspec']; |
} |
if ($dsn['port']) { |
$params[0] .= ' port=' . $dsn['port']; |
} |
} elseif ($protocol == 'unix') { |
// Allow for pg socket in non-standard locations. |
if ($dsn['socket']) { |
$params[0] .= 'host=' . $dsn['socket']; |
} |
if ($dsn['port']) { |
$params[0] .= ' port=' . $dsn['port']; |
} |
} |
if ($dsn['database']) { |
$params[0] .= ' dbname=\'' . addslashes($dsn['database']) . '\''; |
} |
if ($dsn['username']) { |
$params[0] .= ' user=\'' . addslashes($dsn['username']) . '\''; |
} |
if ($dsn['password']) { |
$params[0] .= ' password=\'' . addslashes($dsn['password']) . '\''; |
} |
if (!empty($dsn['options'])) { |
$params[0] .= ' options=' . $dsn['options']; |
} |
if (!empty($dsn['tty'])) { |
$params[0] .= ' tty=' . $dsn['tty']; |
} |
if (!empty($dsn['connect_timeout'])) { |
$params[0] .= ' connect_timeout=' . $dsn['connect_timeout']; |
} |
if (!empty($dsn['sslmode'])) { |
$params[0] .= ' sslmode=' . $dsn['sslmode']; |
} |
if (!empty($dsn['service'])) { |
$params[0] .= ' service=' . $dsn['service']; |
} |
if (isset($dsn['new_link']) |
&& ($dsn['new_link'] == 'true' || $dsn['new_link'] === true)) |
{ |
if (version_compare(phpversion(), '4.3.0', '>=')) { |
$params[] = PGSQL_CONNECT_FORCE_NEW; |
} |
} |
$connect_function = $persistent ? 'pg_pconnect' : 'pg_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); |
} |
return DB_OK; |
} |
// }}} |
// {{{ disconnect() |
/** |
* Disconnects from the database server |
* |
* @return bool TRUE on success, FALSE on failure |
*/ |
function disconnect() |
{ |
$ret = @pg_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; |
$query = $this->modifyQuery($query); |
if (!$this->autocommit && $ismanip) { |
if ($this->transaction_opcount == 0) { |
$result = @pg_exec($this->connection, 'begin;'); |
if (!$result) { |
return $this->pgsqlRaiseError(); |
} |
} |
$this->transaction_opcount++; |
} |
$result = @pg_exec($this->connection, $query); |
if (!$result) { |
return $this->pgsqlRaiseError(); |
} |
// Determine which queries that should return data, and which |
// should return an error code only. |
if ($ismanip) { |
$this->affected = @pg_affected_rows($result); |
return DB_OK; |
} elseif (preg_match('/^\s*\(*\s*(SELECT|EXPLAIN|SHOW)\s/si', $query)) { |
/* PostgreSQL commands: |
ABORT, ALTER, BEGIN, CLOSE, CLUSTER, COMMIT, COPY, |
CREATE, DECLARE, DELETE, DROP TABLE, EXPLAIN, FETCH, |
GRANT, INSERT, LISTEN, LOAD, LOCK, MOVE, NOTIFY, RESET, |
REVOKE, ROLLBACK, SELECT, SELECT INTO, SET, SHOW, |
UNLISTEN, UPDATE, VACUUM |
*/ |
$this->row[(int)$result] = 0; // reset the row counter. |
$numrows = $this->numRows($result); |
if (is_object($numrows)) { |
return $numrows; |
} |
$this->_num_rows[(int)$result] = $numrows; |
$this->affected = 0; |
return $result; |
} else { |
$this->affected = 0; |
return DB_OK; |
} |
} |
// }}} |
// {{{ nextResult() |
/** |
* Move the internal pgsql 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. |
* |
* @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) |
{ |
$result_int = (int)$result; |
$rownum = ($rownum !== null) ? $rownum : $this->row[$result_int]; |
if ($rownum >= $this->_num_rows[$result_int]) { |
return null; |
} |
if ($fetchmode & DB_FETCHMODE_ASSOC) { |
$arr = @pg_fetch_array($result, $rownum, PGSQL_ASSOC); |
if ($this->options['portability'] & DB_PORTABILITY_LOWERCASE && $arr) { |
$arr = array_change_key_case($arr, CASE_LOWER); |
} |
} else { |
$arr = @pg_fetch_row($result, $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); |
} |
$this->row[$result_int] = ++$rownum; |
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) |
{ |
if (is_resource($result)) { |
unset($this->row[(int)$result]); |
unset($this->_num_rows[(int)$result]); |
$this->affected = 0; |
return @pg_freeresult($result); |
} |
return false; |
} |
// }}} |
// {{{ quote() |
/** |
* @deprecated Deprecated in release 1.6.0 |
* @internal |
*/ |
function quote($str) |
{ |
return $this->quoteSmart($str); |
} |
// }}} |
// {{{ 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 MySQL'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) . "'"; |
} |
} |
// }}} |
// {{{ escapeSimple() |
/** |
* Escapes a string according to the current DBMS's standards |
* |
* {@internal PostgreSQL treats a backslash as an escape character, |
* so they are escaped as well. |
* |
* Not using pg_escape_string() yet because it requires PostgreSQL |
* to be at version 7.2 or greater.}} |
* |
* @param string $str the string to be escaped |
* |
* @return string the escaped string |
* |
* @see DB_common::quoteSmart() |
* @since Method available since Release 1.6.0 |
*/ |
function escapeSimple($str) |
{ |
return str_replace("'", "''", str_replace('\\', '\\\\', $str)); |
} |
// }}} |
// {{{ 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 = @pg_numfields($result); |
if (!$cols) { |
return $this->pgsqlRaiseError(); |
} |
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 = @pg_numrows($result); |
if ($rows === null) { |
return $this->pgsqlRaiseError(); |
} |
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) { |
// (disabled) hack to shut up error messages from libpq.a |
//@fclose(@fopen("php://stderr", "w")); |
$result = @pg_exec($this->connection, 'end;'); |
$this->transaction_opcount = 0; |
if (!$result) { |
return $this->pgsqlRaiseError(); |
} |
} |
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 = @pg_exec($this->connection, 'abort;'); |
$this->transaction_opcount = 0; |
if (!$result) { |
return $this->pgsqlRaiseError(); |
} |
} |
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() |
{ |
return $this->affected; |
} |
// }}} |
// {{{ 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_pgsql::createSequence(), DB_pgsql::dropSequence() |
*/ |
function nextId($seq_name, $ondemand = true) |
{ |
$seqname = $this->getSequenceName($seq_name); |
$repeat = false; |
do { |
$this->pushErrorHandling(PEAR_ERROR_RETURN); |
$result =& $this->query("SELECT NEXTVAL('${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 |
* |
* @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_pgsql::nextID(), DB_pgsql::dropSequence() |
*/ |
function createSequence($seq_name) |
{ |
$seqname = $this->getSequenceName($seq_name); |
$result = $this->query("CREATE SEQUENCE ${seqname}"); |
return $result; |
} |
// }}} |
// {{{ 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_pgsql::nextID(), DB_pgsql::createSequence() |
*/ |
function dropSequence($seq_name) |
{ |
return $this->query('DROP SEQUENCE ' |
. $this->getSequenceName($seq_name)); |
} |
// }}} |
// {{{ 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"; |
} |
// }}} |
// {{{ pgsqlRaiseError() |
/** |
* 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_pgsql::errorNative(), DB_pgsql::errorCode() |
*/ |
function pgsqlRaiseError($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 |
* |
* {@internal Error messages are used instead of error codes |
* in order to support older versions of PostgreSQL.}} |
* |
* @return string the DBMS' error message |
*/ |
function errorNative() |
{ |
return @pg_errormessage($this->connection); |
} |
// }}} |
// {{{ 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( |
'/(relation|sequence|table).*does not exist|class .* not found/i' |
=> DB_ERROR_NOSUCHTABLE, |
'/index .* does not exist/' |
=> DB_ERROR_NOT_FOUND, |
'/column .* does not exist/i' |
=> DB_ERROR_NOSUCHFIELD, |
'/relation .* already exists/i' |
=> DB_ERROR_ALREADY_EXISTS, |
'/(divide|division) by zero$/i' |
=> DB_ERROR_DIVZERO, |
'/pg_atoi: error in .*: can\'t parse /i' |
=> DB_ERROR_INVALID_NUMBER, |
'/invalid input syntax for( type)? (integer|numeric)/i' |
=> DB_ERROR_INVALID_NUMBER, |
'/value .* is out of range for type \w*int/i' |
=> DB_ERROR_INVALID_NUMBER, |
'/integer out of range/i' |
=> DB_ERROR_INVALID_NUMBER, |
'/value too long for type character/i' |
=> DB_ERROR_INVALID, |
'/attribute .* not found|relation .* does not have attribute/i' |
=> DB_ERROR_NOSUCHFIELD, |
'/column .* specified in USING clause does not exist in (left|right) table/i' |
=> DB_ERROR_NOSUCHFIELD, |
'/parser: parse error at or near/i' |
=> DB_ERROR_SYNTAX, |
'/syntax error at/' |
=> DB_ERROR_SYNTAX, |
'/column reference .* is ambiguous/i' |
=> DB_ERROR_SYNTAX, |
'/permission denied/' |
=> DB_ERROR_ACCESS_VIOLATION, |
'/violates not-null constraint/' |
=> DB_ERROR_CONSTRAINT_NOT_NULL, |
'/violates [\w ]+ constraint/' |
=> DB_ERROR_CONSTRAINT, |
'/referential integrity violation/' |
=> DB_ERROR_CONSTRAINT, |
'/more expressions than target 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 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. |
*/ |
$id = @pg_exec($this->connection, "SELECT * FROM $result LIMIT 0"); |
$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->pgsqlRaiseError(DB_ERROR_NEED_MORE_DATA); |
} |
if ($this->options['portability'] & DB_PORTABILITY_LOWERCASE) { |
$case_func = 'strtolower'; |
} else { |
$case_func = 'strval'; |
} |
$count = @pg_numfields($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(@pg_fieldname($id, $i)), |
'type' => @pg_fieldtype($id, $i), |
'len' => @pg_fieldsize($id, $i), |
'flags' => $got_string |
? $this->_pgFieldFlags($id, $i, $result) |
: '', |
); |
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) { |
@pg_freeresult($id); |
} |
return $res; |
} |
// }}} |
// {{{ _pgFieldFlags() |
/** |
* Get a column's flags |
* |
* Supports "not_null", "default_value", "primary_key", "unique_key" |
* and "multiple_key". The default value is passed through |
* rawurlencode() in case there are spaces in it. |
* |
* @param int $resource the PostgreSQL result identifier |
* @param int $num_field the field number |
* |
* @return string the flags |
* |
* @access private |
*/ |
function _pgFieldFlags($resource, $num_field, $table_name) |
{ |
$field_name = @pg_fieldname($resource, $num_field); |
$result = @pg_exec($this->connection, "SELECT f.attnotnull, f.atthasdef |
FROM pg_attribute f, pg_class tab, pg_type typ |
WHERE tab.relname = typ.typname |
AND typ.typrelid = f.attrelid |
AND f.attname = '$field_name' |
AND tab.relname = '$table_name'"); |
if (@pg_numrows($result) > 0) { |
$row = @pg_fetch_row($result, 0); |
$flags = ($row[0] == 't') ? 'not_null ' : ''; |
if ($row[1] == 't') { |
$result = @pg_exec($this->connection, "SELECT a.adsrc |
FROM pg_attribute f, pg_class tab, pg_type typ, pg_attrdef a |
WHERE tab.relname = typ.typname AND typ.typrelid = f.attrelid |
AND f.attrelid = a.adrelid AND f.attname = '$field_name' |
AND tab.relname = '$table_name' AND f.attnum = a.adnum"); |
$row = @pg_fetch_row($result, 0); |
$num = preg_replace("/'(.*)'::\w+/", "\\1", $row[0]); |
$flags .= 'default_' . rawurlencode($num) . ' '; |
} |
} else { |
$flags = ''; |
} |
$result = @pg_exec($this->connection, "SELECT i.indisunique, i.indisprimary, i.indkey |
FROM pg_attribute f, pg_class tab, pg_type typ, pg_index i |
WHERE tab.relname = typ.typname |
AND typ.typrelid = f.attrelid |
AND f.attrelid = i.indrelid |
AND f.attname = '$field_name' |
AND tab.relname = '$table_name'"); |
$count = @pg_numrows($result); |
for ($i = 0; $i < $count ; $i++) { |
$row = @pg_fetch_row($result, $i); |
$keys = explode(' ', $row[2]); |
if (in_array($num_field + 1, $keys)) { |
$flags .= ($row[0] == 't' && $row[1] == 'f') ? 'unique_key ' : ''; |
$flags .= ($row[1] == 't') ? 'primary_key ' : ''; |
if (count($keys) > 1) |
$flags .= 'multiple_key '; |
} |
} |
return trim($flags); |
} |
// }}} |
// {{{ 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 c.relname AS "Name"' |
. ' FROM pg_class c, pg_user u' |
. ' WHERE c.relowner = u.usesysid' |
. " AND c.relkind = 'r'" |
. ' AND NOT EXISTS' |
. ' (SELECT 1 FROM pg_views' |
. ' WHERE viewname = c.relname)' |
. " AND c.relname !~ '^(pg_|sql_)'" |
. ' UNION' |
. ' SELECT c.relname AS "Name"' |
. ' FROM pg_class c' |
. " WHERE c.relkind = 'r'" |
. ' AND NOT EXISTS' |
. ' (SELECT 1 FROM pg_views' |
. ' WHERE viewname = c.relname)' |
. ' AND NOT EXISTS' |
. ' (SELECT 1 FROM pg_user' |
. ' WHERE usesysid = c.relowner)' |
. " AND c.relname !~ '^pg_'"; |
case 'schema.tables': |
return "SELECT schemaname || '.' || tablename" |
. ' AS "Name"' |
. ' FROM pg_catalog.pg_tables' |
. ' WHERE schemaname NOT IN' |
. " ('pg_catalog', 'information_schema', 'pg_toast')"; |
case 'views': |
// Table cols: viewname | viewowner | definition |
return 'SELECT viewname from pg_views WHERE schemaname' |
. " NOT IN ('information_schema', 'pg_catalog')"; |
case 'users': |
// cols: usename |usesysid|usecreatedb|usetrace|usesuper|usecatupd|passwd |valuntil |
return 'SELECT usename FROM pg_user'; |
case 'databases': |
return 'SELECT datname FROM pg_database'; |
case 'functions': |
case 'procedures': |
return 'SELECT proname FROM pg_proc WHERE proowner <> 1'; |
default: |
return null; |
} |
} |
// }}} |
} |
/* |
* Local variables: |
* tab-width: 4 |
* c-basic-offset: 4 |
* End: |
*/ |
?> |
/branches/livraison_menes/api/pear/DB/sybase.php |
---|
New 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.2 2005-09-20 17:01:22 ddelon 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: |
*/ |
?> |
/branches/livraison_menes/api/pear/DB/fbsql.php |
---|
New 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.2 2005-09-20 17:01:22 ddelon 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: |
*/ |
?> |
/branches/livraison_menes/api/pear/DB/odbc.php |
---|
New 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.2 2005-09-20 17:01:22 ddelon 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: |
*/ |
?> |
/branches/livraison_menes/api/pear/DB/common.php |
---|
New file |
0,0 → 1,2157 |
<?php |
/* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4: */ |
/** |
* Contains the DB_common base class |
* |
* 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 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: common.php,v 1.2 2005-09-20 17:01:22 ddelon Exp $ |
* @link http://pear.php.net/package/DB |
*/ |
/** |
* Obtain the PEAR class so it can be extended from |
*/ |
require_once 'PEAR.php'; |
/** |
* DB_common is the base class from which each database driver class extends |
* |
* All common methods are declared here. If a given DBMS driver contains |
* a particular method, that method will overload the one here. |
* |
* @category Database |
* @package DB |
* @author Stig Bakken <ssb@php.net> |
* @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_common extends PEAR |
{ |
// {{{ properties |
/** |
* The current default fetch mode |
* @var integer |
*/ |
var $fetchmode = DB_FETCHMODE_ORDERED; |
/** |
* The name of the class into which results should be fetched when |
* DB_FETCHMODE_OBJECT is in effect |
* |
* @var string |
*/ |
var $fetchmode_object_class = 'stdClass'; |
/** |
* Was a connection present when the object was serialized()? |
* @var bool |
* @see DB_common::__sleep(), DB_common::__wake() |
*/ |
var $was_connected = null; |
/** |
* The most recently executed query |
* @var string |
*/ |
var $last_query = ''; |
/** |
* Run-time configuration options |
* |
* The 'optimize' option has been deprecated. Use the 'portability' |
* option instead. |
* |
* @var array |
* @see DB_common::setOption() |
*/ |
var $options = array( |
'result_buffering' => 500, |
'persistent' => false, |
'ssl' => false, |
'debug' => 0, |
'seqname_format' => '%s_seq', |
'autofree' => false, |
'portability' => DB_PORTABILITY_NONE, |
'optimize' => 'performance', // Deprecated. Use 'portability'. |
); |
/** |
* The parameters from the most recently executed query |
* @var array |
* @since Property available since Release 1.7.0 |
*/ |
var $last_parameters = array(); |
/** |
* The elements from each prepared statement |
* @var array |
*/ |
var $prepare_tokens = array(); |
/** |
* The data types of the various elements in each prepared statement |
* @var array |
*/ |
var $prepare_types = array(); |
/** |
* The prepared queries |
* @var array |
*/ |
var $prepared_queries = array(); |
// }}} |
// {{{ DB_common |
/** |
* This constructor calls <kbd>$this->PEAR('DB_Error')</kbd> |
* |
* @return void |
*/ |
function DB_common() |
{ |
$this->PEAR('DB_Error'); |
} |
// }}} |
// {{{ __sleep() |
/** |
* Automatically indicates which properties should be saved |
* when PHP's serialize() function is called |
* |
* @return array the array of properties names that should be saved |
*/ |
function __sleep() |
{ |
if ($this->connection) { |
// Don't disconnect(), people use serialize() for many reasons |
$this->was_connected = true; |
} else { |
$this->was_connected = false; |
} |
if (isset($this->autocommit)) { |
return array('autocommit', |
'dbsyntax', |
'dsn', |
'features', |
'fetchmode', |
'fetchmode_object_class', |
'options', |
'was_connected', |
); |
} else { |
return array('dbsyntax', |
'dsn', |
'features', |
'fetchmode', |
'fetchmode_object_class', |
'options', |
'was_connected', |
); |
} |
} |
// }}} |
// {{{ __wakeup() |
/** |
* Automatically reconnects to the database when PHP's unserialize() |
* function is called |
* |
* The reconnection attempt is only performed if the object was connected |
* at the time PHP's serialize() function was run. |
* |
* @return void |
*/ |
function __wakeup() |
{ |
if ($this->was_connected) { |
$this->connect($this->dsn, $this->options); |
} |
} |
// }}} |
// {{{ __toString() |
/** |
* Automatic string conversion for PHP 5 |
* |
* @return string a string describing the current PEAR DB object |
* |
* @since Method available since Release 1.7.0 |
*/ |
function __toString() |
{ |
$info = strtolower(get_class($this)); |
$info .= ': (phptype=' . $this->phptype . |
', dbsyntax=' . $this->dbsyntax . |
')'; |
if ($this->connection) { |
$info .= ' [connected]'; |
} |
return $info; |
} |
// }}} |
// {{{ toString() |
/** |
* DEPRECATED: String conversion method |
* |
* @return string a string describing the current PEAR DB object |
* |
* @deprecated Method deprecated in Release 1.7.0 |
*/ |
function toString() |
{ |
return $this->__toString(); |
} |
// }}} |
// {{{ quoteString() |
/** |
* DEPRECATED: Quotes a string so it can be safely used within string |
* delimiters in a query |
* |
* @param string $string the string to be quoted |
* |
* @return string the quoted string |
* |
* @see DB_common::quoteSmart(), DB_common::escapeSimple() |
* @deprecated Method deprecated some time before Release 1.2 |
*/ |
function quoteString($string) |
{ |
$string = $this->quote($string); |
if ($string{0} == "'") { |
return substr($string, 1, -1); |
} |
return $string; |
} |
// }}} |
// {{{ quote() |
/** |
* DEPRECATED: Quotes a string so it can be safely used in a query |
* |
* @param string $string the string to quote |
* |
* @return string the quoted string or the string <samp>NULL</samp> |
* if the value submitted is <kbd>null</kbd>. |
* |
* @see DB_common::quoteSmart(), DB_common::escapeSimple() |
* @deprecated Deprecated in release 1.6.0 |
*/ |
function quote($string = null) |
{ |
return ($string === null) ? 'NULL' |
: "'" . str_replace("'", "''", $string) . "'"; |
} |
// }}} |
// {{{ quoteIdentifier() |
/** |
* Quotes a string so it can be safely used as a table or column name |
* |
* Delimiting style depends on which database driver is being used. |
* |
* NOTE: just because you CAN use delimited identifiers doesn't mean |
* you SHOULD use them. In general, they end up causing way more |
* problems than they solve. |
* |
* Portability is broken by using the following characters inside |
* delimited identifiers: |
* + backtick (<kbd>`</kbd>) -- due to MySQL |
* + double quote (<kbd>"</kbd>) -- due to Oracle |
* + brackets (<kbd>[</kbd> or <kbd>]</kbd>) -- due to Access |
* |
* Delimited identifiers are known to generally work correctly under |
* the following drivers: |
* + mssql |
* + mysql |
* + mysqli |
* + oci8 |
* + odbc(access) |
* + odbc(db2) |
* + pgsql |
* + sqlite |
* + sybase (must execute <kbd>set quoted_identifier on</kbd> sometime |
* prior to use) |
* |
* InterBase doesn't seem to be able to use delimited identifiers |
* via PHP 4. They work fine under PHP 5. |
* |
* @param string $str the identifier name to be quoted |
* |
* @return string the quoted identifier |
* |
* @since Method available since Release 1.6.0 |
*/ |
function quoteIdentifier($str) |
{ |
return '"' . str_replace('"', '""', $str) . '"'; |
} |
// }}} |
// {{{ quoteSmart() |
/** |
* Formats input so it can be safely used in a query |
* |
* The output depends on the PHP data type of input and the database |
* type being used. |
* |
* @param mixed $in the data to be formatted |
* |
* @return mixed the formatted data. The format depends on the input's |
* PHP type: |
* <ul> |
* <li> |
* <kbd>input</kbd> -> <samp>returns</samp> |
* </li> |
* <li> |
* <kbd>null</kbd> -> the string <samp>NULL</samp> |
* </li> |
* <li> |
* <kbd>integer</kbd> or <kbd>double</kbd> -> the unquoted number |
* </li> |
* <li> |
* <kbd>bool</kbd> -> output depends on the driver in use |
* Most drivers return integers: <samp>1</samp> if |
* <kbd>true</kbd> or <samp>0</samp> if |
* <kbd>false</kbd>. |
* Some return strings: <samp>TRUE</samp> if |
* <kbd>true</kbd> or <samp>FALSE</samp> if |
* <kbd>false</kbd>. |
* Finally one returns strings: <samp>T</samp> if |
* <kbd>true</kbd> or <samp>F</samp> if |
* <kbd>false</kbd>. Here is a list of each DBMS, |
* the values returned and the suggested column type: |
* <ul> |
* <li> |
* <kbd>dbase</kbd> -> <samp>T/F</samp> |
* (<kbd>Logical</kbd>) |
* </li> |
* <li> |
* <kbd>fbase</kbd> -> <samp>TRUE/FALSE</samp> |
* (<kbd>BOOLEAN</kbd>) |
* </li> |
* <li> |
* <kbd>ibase</kbd> -> <samp>1/0</samp> |
* (<kbd>SMALLINT</kbd>) [1] |
* </li> |
* <li> |
* <kbd>ifx</kbd> -> <samp>1/0</samp> |
* (<kbd>SMALLINT</kbd>) [1] |
* </li> |
* <li> |
* <kbd>msql</kbd> -> <samp>1/0</samp> |
* (<kbd>INTEGER</kbd>) |
* </li> |
* <li> |
* <kbd>mssql</kbd> -> <samp>1/0</samp> |
* (<kbd>BIT</kbd>) |
* </li> |
* <li> |
* <kbd>mysql</kbd> -> <samp>1/0</samp> |
* (<kbd>TINYINT(1)</kbd>) |
* </li> |
* <li> |
* <kbd>mysqli</kbd> -> <samp>1/0</samp> |
* (<kbd>TINYINT(1)</kbd>) |
* </li> |
* <li> |
* <kbd>oci8</kbd> -> <samp>1/0</samp> |
* (<kbd>NUMBER(1)</kbd>) |
* </li> |
* <li> |
* <kbd>odbc</kbd> -> <samp>1/0</samp> |
* (<kbd>SMALLINT</kbd>) [1] |
* </li> |
* <li> |
* <kbd>pgsql</kbd> -> <samp>TRUE/FALSE</samp> |
* (<kbd>BOOLEAN</kbd>) |
* </li> |
* <li> |
* <kbd>sqlite</kbd> -> <samp>1/0</samp> |
* (<kbd>INTEGER</kbd>) |
* </li> |
* <li> |
* <kbd>sybase</kbd> -> <samp>1/0</samp> |
* (<kbd>TINYINT(1)</kbd>) |
* </li> |
* </ul> |
* [1] Accommodate the lowest common denominator because not all |
* versions of have <kbd>BOOLEAN</kbd>. |
* </li> |
* <li> |
* other (including strings and numeric strings) -> |
* the data with single quotes escaped by preceeding |
* single quotes, backslashes are escaped by preceeding |
* backslashes, then the whole string is encapsulated |
* between single quotes |
* </li> |
* </ul> |
* |
* @see DB_common::escapeSimple() |
* @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 ? 1 : 0; |
} elseif (is_null($in)) { |
return 'NULL'; |
} else { |
return "'" . $this->escapeSimple($in) . "'"; |
} |
} |
// }}} |
// {{{ 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 |
* |
* @see DB_common::quoteSmart() |
* @since Method available since Release 1.6.0 |
*/ |
function escapeSimple($str) |
{ |
return str_replace("'", "''", $str); |
} |
// }}} |
// {{{ provides() |
/** |
* Tells whether the present driver supports a given feature |
* |
* @param string $feature the feature you're curious about |
* |
* @return bool whether this driver supports $feature |
*/ |
function provides($feature) |
{ |
return $this->features[$feature]; |
} |
// }}} |
// {{{ setFetchMode() |
/** |
* Sets the fetch mode that should be used by default for query results |
* |
* @param integer $fetchmode DB_FETCHMODE_ORDERED, DB_FETCHMODE_ASSOC |
* or DB_FETCHMODE_OBJECT |
* @param string $object_class the class name of the object to be returned |
* by the fetch methods when the |
* DB_FETCHMODE_OBJECT mode is selected. |
* If no class is specified by default a cast |
* to object from the assoc array row will be |
* done. There is also the posibility to use |
* and extend the 'DB_row' class. |
* |
* @see DB_FETCHMODE_ORDERED, DB_FETCHMODE_ASSOC, DB_FETCHMODE_OBJECT |
*/ |
function setFetchMode($fetchmode, $object_class = 'stdClass') |
{ |
switch ($fetchmode) { |
case DB_FETCHMODE_OBJECT: |
$this->fetchmode_object_class = $object_class; |
case DB_FETCHMODE_ORDERED: |
case DB_FETCHMODE_ASSOC: |
$this->fetchmode = $fetchmode; |
break; |
default: |
return $this->raiseError('invalid fetchmode mode'); |
} |
} |
// }}} |
// {{{ setOption() |
/** |
* Sets run-time configuration options for PEAR DB |
* |
* Options, their data types, default values and description: |
* <ul> |
* <li> |
* <var>autofree</var> <kbd>boolean</kbd> = <samp>false</samp> |
* <br />should results be freed automatically when there are no |
* more rows? |
* </li><li> |
* <var>result_buffering</var> <kbd>integer</kbd> = <samp>500</samp> |
* <br />how many rows of the result set should be buffered? |
* <br />In mysql: mysql_unbuffered_query() is used instead of |
* mysql_query() if this value is 0. (Release 1.7.0) |
* <br />In oci8: this value is passed to ocisetprefetch(). |
* (Release 1.7.0) |
* </li><li> |
* <var>debug</var> <kbd>integer</kbd> = <samp>0</samp> |
* <br />debug level |
* </li><li> |
* <var>persistent</var> <kbd>boolean</kbd> = <samp>false</samp> |
* <br />should the connection be persistent? |
* </li><li> |
* <var>portability</var> <kbd>integer</kbd> = <samp>DB_PORTABILITY_NONE</samp> |
* <br />portability mode constant (see below) |
* </li><li> |
* <var>seqname_format</var> <kbd>string</kbd> = <samp>%s_seq</samp> |
* <br />the sprintf() format string used on sequence names. This |
* format is applied to sequence names passed to |
* createSequence(), nextID() and dropSequence(). |
* </li><li> |
* <var>ssl</var> <kbd>boolean</kbd> = <samp>false</samp> |
* <br />use ssl to connect? |
* </li> |
* </ul> |
* |
* ----------------------------------------- |
* |
* PORTABILITY MODES |
* |
* These modes are bitwised, so they can be combined using <kbd>|</kbd> |
* and removed using <kbd>^</kbd>. See the examples section below on how |
* to do this. |
* |
* <samp>DB_PORTABILITY_NONE</samp> |
* turn off all portability features |
* |
* This mode gets automatically turned on if the deprecated |
* <var>optimize</var> option gets set to <samp>performance</samp>. |
* |
* |
* <samp>DB_PORTABILITY_LOWERCASE</samp> |
* convert names of tables and fields to lower case when using |
* <kbd>get*()</kbd>, <kbd>fetch*()</kbd> and <kbd>tableInfo()</kbd> |
* |
* This mode gets automatically turned on in the following databases |
* if the deprecated option <var>optimize</var> gets set to |
* <samp>portability</samp>: |
* + oci8 |
* |
* |
* <samp>DB_PORTABILITY_RTRIM</samp> |
* right trim the data output by <kbd>get*()</kbd> <kbd>fetch*()</kbd> |
* |
* |
* <samp>DB_PORTABILITY_DELETE_COUNT</samp> |
* force reporting the number of rows deleted |
* |
* Some DBMS's don't count the number of rows deleted when performing |
* simple <kbd>DELETE FROM tablename</kbd> queries. This portability |
* mode tricks such DBMS's into telling the count by adding |
* <samp>WHERE 1=1</samp> to the end of <kbd>DELETE</kbd> queries. |
* |
* This mode gets automatically turned on in the following databases |
* if the deprecated option <var>optimize</var> gets set to |
* <samp>portability</samp>: |
* + fbsql |
* + mysql |
* + mysqli |
* + sqlite |
* |
* |
* <samp>DB_PORTABILITY_NUMROWS</samp> |
* enable hack that makes <kbd>numRows()</kbd> work in Oracle |
* |
* This mode gets automatically turned on in the following databases |
* if the deprecated option <var>optimize</var> gets set to |
* <samp>portability</samp>: |
* + oci8 |
* |
* |
* <samp>DB_PORTABILITY_ERRORS</samp> |
* makes certain error messages in certain drivers compatible |
* with those from other DBMS's |
* |
* + mysql, mysqli: change unique/primary key constraints |
* DB_ERROR_ALREADY_EXISTS -> DB_ERROR_CONSTRAINT |
* |
* + odbc(access): MS's ODBC driver reports 'no such field' as code |
* 07001, which means 'too few parameters.' When this option is on |
* that code gets mapped to DB_ERROR_NOSUCHFIELD. |
* DB_ERROR_MISMATCH -> DB_ERROR_NOSUCHFIELD |
* |
* <samp>DB_PORTABILITY_NULL_TO_EMPTY</samp> |
* convert null values to empty strings in data output by get*() and |
* fetch*(). Needed because Oracle considers empty strings to be null, |
* while most other DBMS's know the difference between empty and null. |
* |
* |
* <samp>DB_PORTABILITY_ALL</samp> |
* turn on all portability features |
* |
* ----------------------------------------- |
* |
* Example 1. Simple setOption() example |
* <code> |
* $db->setOption('autofree', true); |
* </code> |
* |
* Example 2. Portability for lowercasing and trimming |
* <code> |
* $db->setOption('portability', |
* DB_PORTABILITY_LOWERCASE | DB_PORTABILITY_RTRIM); |
* </code> |
* |
* Example 3. All portability options except trimming |
* <code> |
* $db->setOption('portability', |
* DB_PORTABILITY_ALL ^ DB_PORTABILITY_RTRIM); |
* </code> |
* |
* @param string $option option name |
* @param mixed $value value for the option |
* |
* @return int DB_OK on success. A DB_Error object on failure. |
* |
* @see DB_common::$options |
*/ |
function setOption($option, $value) |
{ |
if (isset($this->options[$option])) { |
$this->options[$option] = $value; |
/* |
* Backwards compatibility check for the deprecated 'optimize' |
* option. Done here in case settings change after connecting. |
*/ |
if ($option == 'optimize') { |
if ($value == 'portability') { |
switch ($this->phptype) { |
case 'oci8': |
$this->options['portability'] = |
DB_PORTABILITY_LOWERCASE | |
DB_PORTABILITY_NUMROWS; |
break; |
case 'fbsql': |
case 'mysql': |
case 'mysqli': |
case 'sqlite': |
$this->options['portability'] = |
DB_PORTABILITY_DELETE_COUNT; |
break; |
} |
} else { |
$this->options['portability'] = DB_PORTABILITY_NONE; |
} |
} |
return DB_OK; |
} |
return $this->raiseError("unknown option $option"); |
} |
// }}} |
// {{{ getOption() |
/** |
* Returns the value of an option |
* |
* @param string $option the option name you're curious about |
* |
* @return mixed the option's value |
*/ |
function getOption($option) |
{ |
if (isset($this->options[$option])) { |
return $this->options[$option]; |
} |
return $this->raiseError("unknown option $option"); |
} |
// }}} |
// {{{ prepare() |
/** |
* Prepares a query for multiple execution with execute() |
* |
* Creates a query that can be run multiple times. Each time it is run, |
* the placeholders, if any, will be replaced by the contents of |
* execute()'s $data argument. |
* |
* Three types of placeholders can be used: |
* + <kbd>?</kbd> scalar value (i.e. strings, integers). The system |
* will automatically quote and escape the data. |
* + <kbd>!</kbd> value is inserted 'as is' |
* + <kbd>&</kbd> requires a file name. The file's contents get |
* inserted into the query (i.e. saving binary |
* data in a db) |
* |
* Example 1. |
* <code> |
* $sth = $db->prepare('INSERT INTO tbl (a, b, c) VALUES (?, !, &)'); |
* $data = array( |
* "John's text", |
* "'it''s good'", |
* 'filename.txt' |
* ); |
* $res = $db->execute($sth, $data); |
* </code> |
* |
* Use backslashes to escape placeholder characters if you don't want |
* them to be interpreted as placeholders: |
* <pre> |
* "UPDATE foo SET col=? WHERE col='over \& under'" |
* </pre> |
* |
* With some database backends, this is emulated. |
* |
* {@internal ibase and oci8 have their own prepare() methods.}} |
* |
* @param string $query the query to be prepared |
* |
* @return mixed DB statement resource on success. A DB_Error object |
* on failure. |
* |
* @see DB_common::execute() |
*/ |
function prepare($query) |
{ |
$tokens = preg_split('/((?<!\\\)[&?!])/', $query, -1, |
PREG_SPLIT_DELIM_CAPTURE); |
$token = 0; |
$types = array(); |
$newtokens = array(); |
foreach ($tokens as $val) { |
switch ($val) { |
case '?': |
$types[$token++] = DB_PARAM_SCALAR; |
break; |
case '&': |
$types[$token++] = DB_PARAM_OPAQUE; |
break; |
case '!': |
$types[$token++] = DB_PARAM_MISC; |
break; |
default: |
$newtokens[] = preg_replace('/\\\([&?!])/', "\\1", $val); |
} |
} |
$this->prepare_tokens[] = &$newtokens; |
end($this->prepare_tokens); |
$k = key($this->prepare_tokens); |
$this->prepare_types[$k] = $types; |
$this->prepared_queries[$k] = implode(' ', $newtokens); |
return $k; |
} |
// }}} |
// {{{ autoPrepare() |
/** |
* Automaticaly generates an insert or update query and pass it to prepare() |
* |
* @param string $table the table name |
* @param array $table_fields the array of field names |
* @param int $mode a type of query to make: |
* DB_AUTOQUERY_INSERT or DB_AUTOQUERY_UPDATE |
* @param string $where for update queries: the WHERE clause to |
* append to the SQL statement. Don't |
* include the "WHERE" keyword. |
* |
* @return resource the query handle |
* |
* @uses DB_common::prepare(), DB_common::buildManipSQL() |
*/ |
function autoPrepare($table, $table_fields, $mode = DB_AUTOQUERY_INSERT, |
$where = false) |
{ |
$query = $this->buildManipSQL($table, $table_fields, $mode, $where); |
if (DB::isError($query)) { |
return $query; |
} |
return $this->prepare($query); |
} |
// }}} |
// {{{ autoExecute() |
/** |
* Automaticaly generates an insert or update query and call prepare() |
* and execute() with it |
* |
* @param string $table the table name |
* @param array $fields_values the associative array where $key is a |
* field name and $value its value |
* @param int $mode a type of query to make: |
* DB_AUTOQUERY_INSERT or DB_AUTOQUERY_UPDATE |
* @param string $where for update queries: the WHERE clause to |
* append to the SQL statement. Don't |
* include the "WHERE" keyword. |
* |
* @return mixed a new DB_result object for successful SELECT queries |
* or DB_OK for successul data manipulation queries. |
* A DB_Error object on failure. |
* |
* @uses DB_common::autoPrepare(), DB_common::execute() |
*/ |
function autoExecute($table, $fields_values, $mode = DB_AUTOQUERY_INSERT, |
$where = false) |
{ |
$sth = $this->autoPrepare($table, array_keys($fields_values), $mode, |
$where); |
if (DB::isError($sth)) { |
return $sth; |
} |
$ret =& $this->execute($sth, array_values($fields_values)); |
$this->freePrepared($sth); |
return $ret; |
} |
// }}} |
// {{{ buildManipSQL() |
/** |
* Produces an SQL query string for autoPrepare() |
* |
* Example: |
* <pre> |
* buildManipSQL('table_sql', array('field1', 'field2', 'field3'), |
* DB_AUTOQUERY_INSERT); |
* </pre> |
* |
* That returns |
* <samp> |
* INSERT INTO table_sql (field1,field2,field3) VALUES (?,?,?) |
* </samp> |
* |
* NOTES: |
* - This belongs more to a SQL Builder class, but this is a simple |
* facility. |
* - Be carefull! If you don't give a $where param with an UPDATE |
* query, all the records of the table will be updated! |
* |
* @param string $table the table name |
* @param array $table_fields the array of field names |
* @param int $mode a type of query to make: |
* DB_AUTOQUERY_INSERT or DB_AUTOQUERY_UPDATE |
* @param string $where for update queries: the WHERE clause to |
* append to the SQL statement. Don't |
* include the "WHERE" keyword. |
* |
* @return string the sql query for autoPrepare() |
*/ |
function buildManipSQL($table, $table_fields, $mode, $where = false) |
{ |
if (count($table_fields) == 0) { |
return $this->raiseError(DB_ERROR_NEED_MORE_DATA); |
} |
$first = true; |
switch ($mode) { |
case DB_AUTOQUERY_INSERT: |
$values = ''; |
$names = ''; |
foreach ($table_fields as $value) { |
if ($first) { |
$first = false; |
} else { |
$names .= ','; |
$values .= ','; |
} |
$names .= $value; |
$values .= '?'; |
} |
return "INSERT INTO $table ($names) VALUES ($values)"; |
case DB_AUTOQUERY_UPDATE: |
$set = ''; |
foreach ($table_fields as $value) { |
if ($first) { |
$first = false; |
} else { |
$set .= ','; |
} |
$set .= "$value = ?"; |
} |
$sql = "UPDATE $table SET $set"; |
if ($where) { |
$sql .= " WHERE $where"; |
} |
return $sql; |
default: |
return $this->raiseError(DB_ERROR_SYNTAX); |
} |
} |
// }}} |
// {{{ execute() |
/** |
* Executes a DB statement prepared with prepare() |
* |
* Example 1. |
* <code> |
* $sth = $db->prepare('INSERT INTO tbl (a, b, c) VALUES (?, !, &)'); |
* $data = array( |
* "John's text", |
* "'it''s good'", |
* 'filename.txt' |
* ); |
* $res =& $db->execute($sth, $data); |
* </code> |
* |
* @param resource $stmt a DB statement resource returned from prepare() |
* @param mixed $data 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 mixed a new DB_result object for successful SELECT queries |
* or DB_OK for successul data manipulation queries. |
* A DB_Error object on failure. |
* |
* {@internal ibase and oci8 have their own execute() methods.}} |
* |
* @see DB_common::prepare() |
*/ |
function &execute($stmt, $data = array()) |
{ |
$realquery = $this->executeEmulateQuery($stmt, $data); |
if (DB::isError($realquery)) { |
return $realquery; |
} |
$result = $this->simpleQuery($realquery); |
if ($result === DB_OK || DB::isError($result)) { |
return $result; |
} else { |
$tmp =& new DB_result($this, $result); |
return $tmp; |
} |
} |
// }}} |
// {{{ executeEmulateQuery() |
/** |
* Emulates executing prepared statements if the DBMS not support them |
* |
* @param resource $stmt a DB statement resource returned from execute() |
* @param mixed $data 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 mixed a string containing the real query run when emulating |
* prepare/execute. A DB_Error object on failure. |
* |
* @access protected |
* @see DB_common::execute() |
*/ |
function executeEmulateQuery($stmt, $data = array()) |
{ |
$stmt = (int)$stmt; |
$data = (array)$data; |
$this->last_parameters = $data; |
if (count($this->prepare_types[$stmt]) != count($data)) { |
$this->last_query = $this->prepared_queries[$stmt]; |
return $this->raiseError(DB_ERROR_MISMATCH); |
} |
$realquery = $this->prepare_tokens[$stmt][0]; |
$i = 0; |
foreach ($data as $value) { |
if ($this->prepare_types[$stmt][$i] == DB_PARAM_SCALAR) { |
$realquery .= $this->quoteSmart($value); |
} elseif ($this->prepare_types[$stmt][$i] == DB_PARAM_OPAQUE) { |
$fp = @fopen($value, 'rb'); |
if (!$fp) { |
return $this->raiseError(DB_ERROR_ACCESS_VIOLATION); |
} |
$realquery .= $this->quoteSmart(fread($fp, filesize($value))); |
fclose($fp); |
} else { |
$realquery .= $value; |
} |
$realquery .= $this->prepare_tokens[$stmt][++$i]; |
} |
return $realquery; |
} |
// }}} |
// {{{ executeMultiple() |
/** |
* Performs several execute() calls on the same statement handle |
* |
* $data must be an array indexed numerically |
* from 0, one execute call is done for every "row" in the array. |
* |
* If an error occurs during execute(), executeMultiple() does not |
* execute the unfinished rows, but rather returns that error. |
* |
* @param resource $stmt query handle from prepare() |
* @param array $data numeric array containing the |
* data to insert into the query |
* |
* @return int DB_OK on success. A DB_Error object on failure. |
* |
* @see DB_common::prepare(), DB_common::execute() |
*/ |
function executeMultiple($stmt, $data) |
{ |
foreach ($data as $value) { |
$res =& $this->execute($stmt, $value); |
if (DB::isError($res)) { |
return $res; |
} |
} |
return DB_OK; |
} |
// }}} |
// {{{ freePrepared() |
/** |
* Frees the internal resources associated with a prepared query |
* |
* @param resource $stmt the prepared statement's PHP resource |
* @param bool $free_resource should the PHP resource be freed too? |
* Use false if you need to get data |
* from the result set later. |
* |
* @return bool TRUE on success, FALSE if $result is invalid |
* |
* @see DB_common::prepare() |
*/ |
function freePrepared($stmt, $free_resource = true) |
{ |
$stmt = (int)$stmt; |
if (isset($this->prepare_tokens[$stmt])) { |
unset($this->prepare_tokens[$stmt]); |
unset($this->prepare_types[$stmt]); |
unset($this->prepared_queries[$stmt]); |
return true; |
} |
return false; |
} |
// }}} |
// {{{ modifyQuery() |
/** |
* Changes a query string for various DBMS specific reasons |
* |
* It is defined here to ensure all drivers have this method available. |
* |
* @param string $query the query string to modify |
* |
* @return string the modified query string |
* |
* @access protected |
* @see DB_mysql::modifyQuery(), DB_oci8::modifyQuery(), |
* DB_sqlite::modifyQuery() |
*/ |
function modifyQuery($query) |
{ |
return $query; |
} |
// }}} |
// {{{ modifyLimitQuery() |
/** |
* Adds LIMIT clauses to a query string according to current DBMS standards |
* |
* It is defined here to assure that all implementations |
* have this method defined. |
* |
* @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; |
} |
// }}} |
// {{{ query() |
/** |
* Sends a query to the database server |
* |
* The query string can be either a normal statement to be sent directly |
* to the server OR if <var>$params</var> are passed the query can have |
* placeholders and it will be passed through prepare() and execute(). |
* |
* @param string $query the SQL query or the statement to prepare |
* @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 mixed a new DB_result object for successful SELECT queries |
* or DB_OK for successul data manipulation queries. |
* A DB_Error object on failure. |
* |
* @see DB_result, DB_common::prepare(), DB_common::execute() |
*/ |
function &query($query, $params = array()) |
{ |
if (sizeof($params) > 0) { |
$sth = $this->prepare($query); |
if (DB::isError($sth)) { |
return $sth; |
} |
$ret =& $this->execute($sth, $params); |
$this->freePrepared($sth, false); |
return $ret; |
} else { |
$this->last_parameters = array(); |
$result = $this->simpleQuery($query); |
if ($result === DB_OK || DB::isError($result)) { |
return $result; |
} else { |
$tmp =& new DB_result($this, $result); |
return $tmp; |
} |
} |
} |
// }}} |
// {{{ limitQuery() |
/** |
* Generates and executes a LIMIT query |
* |
* @param string $query the query |
* @param intr $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 mixed a new DB_result object for successful SELECT queries |
* or DB_OK for successul data manipulation queries. |
* A DB_Error object on failure. |
*/ |
function &limitQuery($query, $from, $count, $params = array()) |
{ |
$query = $this->modifyLimitQuery($query, $from, $count, $params); |
if (DB::isError($query)){ |
return $query; |
} |
$result =& $this->query($query, $params); |
if (is_a($result, 'DB_result')) { |
$result->setOption('limit_from', $from); |
$result->setOption('limit_count', $count); |
} |
return $result; |
} |
// }}} |
// {{{ getOne() |
/** |
* Fetches the first column of the first row from a query result |
* |
* Takes care of doing the query and freeing the results when finished. |
* |
* @param string $query the SQL query |
* @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 mixed the returned value of the query. |
* A DB_Error object on failure. |
*/ |
function &getOne($query, $params = array()) |
{ |
$params = (array)$params; |
// modifyLimitQuery() would be nice here, but it causes BC issues |
if (sizeof($params) > 0) { |
$sth = $this->prepare($query); |
if (DB::isError($sth)) { |
return $sth; |
} |
$res =& $this->execute($sth, $params); |
$this->freePrepared($sth); |
} else { |
$res =& $this->query($query); |
} |
if (DB::isError($res)) { |
return $res; |
} |
$err = $res->fetchInto($row, DB_FETCHMODE_ORDERED); |
$res->free(); |
if ($err !== DB_OK) { |
return $err; |
} |
return $row[0]; |
} |
// }}} |
// {{{ getRow() |
/** |
* Fetches the first row of data returned from a query result |
* |
* Takes care of doing the query and freeing the results when finished. |
* |
* @param string $query the SQL query |
* @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. |
* @param int $fetchmode the fetch mode to use |
* |
* @return array the first row of results as an array. |
* A DB_Error object on failure. |
*/ |
function &getRow($query, $params = array(), |
$fetchmode = DB_FETCHMODE_DEFAULT) |
{ |
// compat check, the params and fetchmode parameters used to |
// have the opposite order |
if (!is_array($params)) { |
if (is_array($fetchmode)) { |
if ($params === null) { |
$tmp = DB_FETCHMODE_DEFAULT; |
} else { |
$tmp = $params; |
} |
$params = $fetchmode; |
$fetchmode = $tmp; |
} elseif ($params !== null) { |
$fetchmode = $params; |
$params = array(); |
} |
} |
// modifyLimitQuery() would be nice here, but it causes BC issues |
if (sizeof($params) > 0) { |
$sth = $this->prepare($query); |
if (DB::isError($sth)) { |
return $sth; |
} |
$res =& $this->execute($sth, $params); |
$this->freePrepared($sth); |
} else { |
$res =& $this->query($query); |
} |
if (DB::isError($res)) { |
return $res; |
} |
$err = $res->fetchInto($row, $fetchmode); |
$res->free(); |
if ($err !== DB_OK) { |
return $err; |
} |
return $row; |
} |
// }}} |
// {{{ getCol() |
/** |
* Fetches a single column from a query result and returns it as an |
* indexed array |
* |
* @param string $query the SQL query |
* @param mixed $col which column to return (integer [column number, |
* starting at 0] or string [column name]) |
* @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 array the results as an array. A DB_Error object on failure. |
* |
* @see DB_common::query() |
*/ |
function &getCol($query, $col = 0, $params = array()) |
{ |
$params = (array)$params; |
if (sizeof($params) > 0) { |
$sth = $this->prepare($query); |
if (DB::isError($sth)) { |
return $sth; |
} |
$res =& $this->execute($sth, $params); |
$this->freePrepared($sth); |
} else { |
$res =& $this->query($query); |
} |
if (DB::isError($res)) { |
return $res; |
} |
$fetchmode = is_int($col) ? DB_FETCHMODE_ORDERED : DB_FETCHMODE_ASSOC; |
if (!is_array($row = $res->fetchRow($fetchmode))) { |
$ret = array(); |
} else { |
if (!array_key_exists($col, $row)) { |
$ret =& $this->raiseError(DB_ERROR_NOSUCHFIELD); |
} else { |
$ret = array($row[$col]); |
while (is_array($row = $res->fetchRow($fetchmode))) { |
$ret[] = $row[$col]; |
} |
} |
} |
$res->free(); |
if (DB::isError($row)) { |
$ret = $row; |
} |
return $ret; |
} |
// }}} |
// {{{ getAssoc() |
/** |
* Fetches an entire query result and returns it as an |
* associative array using the first column as the key |
* |
* If the result set contains more than two columns, the value |
* will be an array of the values from column 2-n. If the result |
* set contains only two columns, the returned value will be a |
* scalar with the value of the second column (unless forced to an |
* array with the $force_array parameter). A DB error code is |
* returned on errors. If the result set contains fewer than two |
* columns, a DB_ERROR_TRUNCATED error is returned. |
* |
* For example, if the table "mytable" contains: |
* |
* <pre> |
* ID TEXT DATE |
* -------------------------------- |
* 1 'one' 944679408 |
* 2 'two' 944679408 |
* 3 'three' 944679408 |
* </pre> |
* |
* Then the call getAssoc('SELECT id,text FROM mytable') returns: |
* <pre> |
* array( |
* '1' => 'one', |
* '2' => 'two', |
* '3' => 'three', |
* ) |
* </pre> |
* |
* ...while the call getAssoc('SELECT id,text,date FROM mytable') returns: |
* <pre> |
* array( |
* '1' => array('one', '944679408'), |
* '2' => array('two', '944679408'), |
* '3' => array('three', '944679408') |
* ) |
* </pre> |
* |
* If the more than one row occurs with the same value in the |
* first column, the last row overwrites all previous ones by |
* default. Use the $group parameter if you don't want to |
* overwrite like this. Example: |
* |
* <pre> |
* getAssoc('SELECT category,id,name FROM mytable', false, null, |
* DB_FETCHMODE_ASSOC, true) returns: |
* |
* array( |
* '1' => array(array('id' => '4', 'name' => 'number four'), |
* array('id' => '6', 'name' => 'number six') |
* ), |
* '9' => array(array('id' => '4', 'name' => 'number four'), |
* array('id' => '6', 'name' => 'number six') |
* ) |
* ) |
* </pre> |
* |
* Keep in mind that database functions in PHP usually return string |
* values for results regardless of the database's internal type. |
* |
* @param string $query the SQL query |
* @param bool $force_array used only when the query returns |
* exactly two columns. If true, the values |
* of the returned array will be one-element |
* arrays instead of scalars. |
* @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. |
* @param int $fetchmode the fetch mode to use |
* @param bool $group if true, the values of the returned array |
* is wrapped in another array. If the same |
* key value (in the first column) repeats |
* itself, the values will be appended to |
* this array instead of overwriting the |
* existing values. |
* |
* @return array the associative array containing the query results. |
* A DB_Error object on failure. |
*/ |
function &getAssoc($query, $force_array = false, $params = array(), |
$fetchmode = DB_FETCHMODE_DEFAULT, $group = false) |
{ |
$params = (array)$params; |
if (sizeof($params) > 0) { |
$sth = $this->prepare($query); |
if (DB::isError($sth)) { |
return $sth; |
} |
$res =& $this->execute($sth, $params); |
$this->freePrepared($sth); |
} else { |
$res =& $this->query($query); |
} |
if (DB::isError($res)) { |
return $res; |
} |
if ($fetchmode == DB_FETCHMODE_DEFAULT) { |
$fetchmode = $this->fetchmode; |
} |
$cols = $res->numCols(); |
if ($cols < 2) { |
$tmp =& $this->raiseError(DB_ERROR_TRUNCATED); |
return $tmp; |
} |
$results = array(); |
if ($cols > 2 || $force_array) { |
// return array values |
// XXX this part can be optimized |
if ($fetchmode == DB_FETCHMODE_ASSOC) { |
while (is_array($row = $res->fetchRow(DB_FETCHMODE_ASSOC))) { |
reset($row); |
$key = current($row); |
unset($row[key($row)]); |
if ($group) { |
$results[$key][] = $row; |
} else { |
$results[$key] = $row; |
} |
} |
} elseif ($fetchmode == DB_FETCHMODE_OBJECT) { |
while ($row = $res->fetchRow(DB_FETCHMODE_OBJECT)) { |
$arr = get_object_vars($row); |
$key = current($arr); |
if ($group) { |
$results[$key][] = $row; |
} else { |
$results[$key] = $row; |
} |
} |
} else { |
while (is_array($row = $res->fetchRow(DB_FETCHMODE_ORDERED))) { |
// we shift away the first element to get |
// indices running from 0 again |
$key = array_shift($row); |
if ($group) { |
$results[$key][] = $row; |
} else { |
$results[$key] = $row; |
} |
} |
} |
if (DB::isError($row)) { |
$results = $row; |
} |
} else { |
// return scalar values |
while (is_array($row = $res->fetchRow(DB_FETCHMODE_ORDERED))) { |
if ($group) { |
$results[$row[0]][] = $row[1]; |
} else { |
$results[$row[0]] = $row[1]; |
} |
} |
if (DB::isError($row)) { |
$results = $row; |
} |
} |
$res->free(); |
return $results; |
} |
// }}} |
// {{{ getAll() |
/** |
* Fetches all of the rows from a query result |
* |
* @param string $query the SQL query |
* @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. |
* @param int $fetchmode the fetch mode to use: |
* + DB_FETCHMODE_ORDERED |
* + DB_FETCHMODE_ASSOC |
* + DB_FETCHMODE_ORDERED | DB_FETCHMODE_FLIPPED |
* + DB_FETCHMODE_ASSOC | DB_FETCHMODE_FLIPPED |
* |
* @return array the nested array. A DB_Error object on failure. |
*/ |
function &getAll($query, $params = array(), |
$fetchmode = DB_FETCHMODE_DEFAULT) |
{ |
// compat check, the params and fetchmode parameters used to |
// have the opposite order |
if (!is_array($params)) { |
if (is_array($fetchmode)) { |
if ($params === null) { |
$tmp = DB_FETCHMODE_DEFAULT; |
} else { |
$tmp = $params; |
} |
$params = $fetchmode; |
$fetchmode = $tmp; |
} elseif ($params !== null) { |
$fetchmode = $params; |
$params = array(); |
} |
} |
if (sizeof($params) > 0) { |
$sth = $this->prepare($query); |
if (DB::isError($sth)) { |
return $sth; |
} |
$res =& $this->execute($sth, $params); |
$this->freePrepared($sth); |
} else { |
$res =& $this->query($query); |
} |
if ($res === DB_OK || DB::isError($res)) { |
return $res; |
} |
$results = array(); |
while (DB_OK === $res->fetchInto($row, $fetchmode)) { |
if ($fetchmode & DB_FETCHMODE_FLIPPED) { |
foreach ($row as $key => $val) { |
$results[$key][] = $val; |
} |
} else { |
$results[] = $row; |
} |
} |
$res->free(); |
if (DB::isError($row)) { |
$tmp =& $this->raiseError($row); |
return $tmp; |
} |
return $results; |
} |
// }}} |
// {{{ 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) |
{ |
return $this->raiseError(DB_ERROR_NOT_CAPABLE); |
} |
// }}} |
// {{{ commit() |
/** |
* Commits the current transaction |
* |
* @return int DB_OK on success. A DB_Error object on failure. |
*/ |
function commit() |
{ |
return $this->raiseError(DB_ERROR_NOT_CAPABLE); |
} |
// }}} |
// {{{ rollback() |
/** |
* Reverts the current transaction |
* |
* @return int DB_OK on success. A DB_Error object on failure. |
*/ |
function rollback() |
{ |
return $this->raiseError(DB_ERROR_NOT_CAPABLE); |
} |
// }}} |
// {{{ numRows() |
/** |
* Determines the number of rows in a query result |
* |
* @param resource $result the query result idenifier produced by PHP |
* |
* @return int the number of rows. A DB_Error object on failure. |
*/ |
function numRows($result) |
{ |
return $this->raiseError(DB_ERROR_NOT_CAPABLE); |
} |
// }}} |
// {{{ 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() |
{ |
return $this->raiseError(DB_ERROR_NOT_CAPABLE); |
} |
// }}} |
// {{{ getSequenceName() |
/** |
* Generates the name used inside the database for a sequence |
* |
* The createSequence() docblock contains notes about storing sequence |
* names. |
* |
* @param string $sqn the sequence's public name |
* |
* @return string the sequence's name in the backend |
* |
* @access protected |
* @see DB_common::createSequence(), DB_common::dropSequence(), |
* DB_common::nextID(), DB_common::setOption() |
*/ |
function getSequenceName($sqn) |
{ |
return sprintf($this->getOption('seqname_format'), |
preg_replace('/[^a-z0-9_.]/i', '_', $sqn)); |
} |
// }}} |
// {{{ 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::createSequence(), DB_common::dropSequence(), |
* DB_common::getSequenceName() |
*/ |
function nextId($seq_name, $ondemand = true) |
{ |
return $this->raiseError(DB_ERROR_NOT_CAPABLE); |
} |
// }}} |
// {{{ createSequence() |
/** |
* Creates a new sequence |
* |
* The name of a given sequence is determined by passing the string |
* provided in the <var>$seq_name</var> argument through PHP's sprintf() |
* function using the value from the <var>seqname_format</var> option as |
* the sprintf()'s format argument. |
* |
* <var>seqname_format</var> is set via setOption(). |
* |
* @param string $seq_name name of the new sequence |
* |
* @return int DB_OK on success. A DB_Error object on failure. |
* |
* @see DB_common::dropSequence(), DB_common::getSequenceName(), |
* DB_common::nextID() |
*/ |
function createSequence($seq_name) |
{ |
return $this->raiseError(DB_ERROR_NOT_CAPABLE); |
} |
// }}} |
// {{{ 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::createSequence(), DB_common::getSequenceName(), |
* DB_common::nextID() |
*/ |
function dropSequence($seq_name) |
{ |
return $this->raiseError(DB_ERROR_NOT_CAPABLE); |
} |
// }}} |
// {{{ raiseError() |
/** |
* Communicates an error and invoke error callbacks, etc |
* |
* Basically a wrapper for PEAR::raiseError without the message string. |
* |
* @param mixed integer error code, or a PEAR error object (all |
* other parameters are ignored if this parameter is |
* an object |
* @param int error mode, see PEAR_Error docs |
* @param mixed if error mode is PEAR_ERROR_TRIGGER, this is the |
* error level (E_USER_NOTICE etc). If error mode is |
* PEAR_ERROR_CALLBACK, this is the callback function, |
* either as a function name, or as an array of an |
* object and method name. For other error modes this |
* parameter is ignored. |
* @param string extra debug information. Defaults to the last |
* query and native error code. |
* @param mixed native error code, integer or string depending the |
* backend |
* |
* @return object the PEAR_Error object |
* |
* @see PEAR_Error |
*/ |
function &raiseError($code = DB_ERROR, $mode = null, $options = null, |
$userinfo = null, $nativecode = null) |
{ |
// The error is yet a DB error object |
if (is_object($code)) { |
// because we the static PEAR::raiseError, our global |
// handler should be used if it is set |
if ($mode === null && !empty($this->_default_error_mode)) { |
$mode = $this->_default_error_mode; |
$options = $this->_default_error_options; |
} |
$tmp = PEAR::raiseError($code, null, $mode, $options, |
null, null, true); |
return $tmp; |
} |
if ($userinfo === null) { |
$userinfo = $this->last_query; |
} |
if ($nativecode) { |
$userinfo .= ' [nativecode=' . trim($nativecode) . ']'; |
} else { |
$userinfo .= ' [DB Error: ' . DB::errorMessage($code) . ']'; |
} |
$tmp = PEAR::raiseError(null, $code, $mode, $options, $userinfo, |
'DB_Error', true); |
return $tmp; |
} |
// }}} |
// {{{ errorNative() |
/** |
* Gets the DBMS' native error code produced by the last query |
* |
* @return mixed the DBMS' error code. A DB_Error object on failure. |
*/ |
function errorNative() |
{ |
return $this->raiseError(DB_ERROR_NOT_CAPABLE); |
} |
// }}} |
// {{{ errorCode() |
/** |
* Maps native error codes to DB's portable ones |
* |
* Uses the <var>$errorcode_map</var> property defined in each driver. |
* |
* @param string|int $nativecode the error code returned by the DBMS |
* |
* @return int the portable DB error code. Return DB_ERROR if the |
* current driver doesn't have a mapping for the |
* $nativecode submitted. |
*/ |
function errorCode($nativecode) |
{ |
if (isset($this->errorcode_map[$nativecode])) { |
return $this->errorcode_map[$nativecode]; |
} |
// Fall back to DB_ERROR if there was no mapping. |
return DB_ERROR; |
} |
// }}} |
// {{{ errorMessage() |
/** |
* Maps a DB error code to a textual message |
* |
* @param integer $dbcode the DB error code |
* |
* @return string the error message corresponding to the error code |
* submitted. FALSE if the error code is unknown. |
* |
* @see DB::errorMessage() |
*/ |
function errorMessage($dbcode) |
{ |
return DB::errorMessage($this->errorcode_map[$dbcode]); |
} |
// }}} |
// {{{ tableInfo() |
/** |
* Returns information about a table or a result set |
* |
* The format of the resulting array depends on which <var>$mode</var> |
* you select. The sample output below is based on this query: |
* <pre> |
* SELECT tblFoo.fldID, tblFoo.fldPhone, tblBar.fldId |
* FROM tblFoo |
* JOIN tblBar ON tblFoo.fldId = tblBar.fldId |
* </pre> |
* |
* <ul> |
* <li> |
* |
* <kbd>null</kbd> (default) |
* <pre> |
* [0] => Array ( |
* [table] => tblFoo |
* [name] => fldId |
* [type] => int |
* [len] => 11 |
* [flags] => primary_key not_null |
* ) |
* [1] => Array ( |
* [table] => tblFoo |
* [name] => fldPhone |
* [type] => string |
* [len] => 20 |
* [flags] => |
* ) |
* [2] => Array ( |
* [table] => tblBar |
* [name] => fldId |
* [type] => int |
* [len] => 11 |
* [flags] => primary_key not_null |
* ) |
* </pre> |
* |
* </li><li> |
* |
* <kbd>DB_TABLEINFO_ORDER</kbd> |
* |
* <p>In addition to the information found in the default output, |
* a notation of the number of columns is provided by the |
* <samp>num_fields</samp> element while the <samp>order</samp> |
* element provides an array with the column names as the keys and |
* their location index number (corresponding to the keys in the |
* the default output) as the values.</p> |
* |
* <p>If a result set has identical field names, the last one is |
* used.</p> |
* |
* <pre> |
* [num_fields] => 3 |
* [order] => Array ( |
* [fldId] => 2 |
* [fldTrans] => 1 |
* ) |
* </pre> |
* |
* </li><li> |
* |
* <kbd>DB_TABLEINFO_ORDERTABLE</kbd> |
* |
* <p>Similar to <kbd>DB_TABLEINFO_ORDER</kbd> but adds more |
* dimensions to the array in which the table names are keys and |
* the field names are sub-keys. This is helpful for queries that |
* join tables which have identical field names.</p> |
* |
* <pre> |
* [num_fields] => 3 |
* [ordertable] => Array ( |
* [tblFoo] => Array ( |
* [fldId] => 0 |
* [fldPhone] => 1 |
* ) |
* [tblBar] => Array ( |
* [fldId] => 2 |
* ) |
* ) |
* </pre> |
* |
* </li> |
* </ul> |
* |
* The <samp>flags</samp> element contains a space separated list |
* of extra information about the field. This data is inconsistent |
* between DBMS's due to the way each DBMS works. |
* + <samp>primary_key</samp> |
* + <samp>unique_key</samp> |
* + <samp>multiple_key</samp> |
* + <samp>not_null</samp> |
* |
* Most DBMS's only provide the <samp>table</samp> and <samp>flags</samp> |
* elements if <var>$result</var> is a table name. The following DBMS's |
* provide full information from queries: |
* + fbsql |
* + mysql |
* |
* If the 'portability' option has <samp>DB_PORTABILITY_LOWERCASE</samp> |
* turned on, the names of tables and fields will be lowercased. |
* |
* @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 either unused or one of the tableInfo modes: |
* <kbd>DB_TABLEINFO_ORDERTABLE</kbd>, |
* <kbd>DB_TABLEINFO_ORDER</kbd> or |
* <kbd>DB_TABLEINFO_FULL</kbd> (which does both). |
* These are bitwise, so the first two can be |
* combined using <kbd>|</kbd>. |
* |
* @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 the DB_<driver> class has a tableInfo() method, that one |
* overrides this one. But, if the driver doesn't have one, |
* this method runs and tells users about that fact. |
*/ |
return $this->raiseError(DB_ERROR_NOT_CAPABLE); |
} |
// }}} |
// {{{ getTables() |
/** |
* Lists the tables in the current database |
* |
* @return array the list of tables. A DB_Error object on failure. |
* |
* @deprecated Method deprecated some time before Release 1.2 |
*/ |
function getTables() |
{ |
return $this->getListOf('tables'); |
} |
// }}} |
// {{{ getListOf() |
/** |
* Lists internal database information |
* |
* @param string $type type of information being sought. |
* Common items being sought are: |
* tables, databases, users, views, functions |
* Each DBMS's has its own capabilities. |
* |
* @return array an array listing the items sought. |
* A DB DB_Error object on failure. |
*/ |
function getListOf($type) |
{ |
$sql = $this->getSpecialQuery($type); |
if ($sql === null) { |
$this->last_query = ''; |
return $this->raiseError(DB_ERROR_UNSUPPORTED); |
} elseif (is_int($sql) || DB::isError($sql)) { |
// Previous error |
return $this->raiseError($sql); |
} elseif (is_array($sql)) { |
// Already the result |
return $sql; |
} |
// Launch this query |
return $this->getCol($sql); |
} |
// }}} |
// {{{ 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) |
{ |
return $this->raiseError(DB_ERROR_UNSUPPORTED); |
} |
// }}} |
// {{{ _rtrimArrayValues() |
/** |
* Right-trims all strings in an array |
* |
* @param array $array the array to be trimmed (passed by reference) |
* |
* @return void |
* |
* @access protected |
*/ |
function _rtrimArrayValues(&$array) |
{ |
foreach ($array as $key => $value) { |
if (is_string($value)) { |
$array[$key] = rtrim($value); |
} |
} |
} |
// }}} |
// {{{ _convertNullArrayValuesToEmpty() |
/** |
* Converts all null values in an array to empty strings |
* |
* @param array $array the array to be de-nullified (passed by reference) |
* |
* @return void |
* |
* @access protected |
*/ |
function _convertNullArrayValuesToEmpty(&$array) |
{ |
foreach ($array as $key => $value) { |
if (is_null($value)) { |
$array[$key] = ''; |
} |
} |
} |
// }}} |
} |
/* |
* Local variables: |
* tab-width: 4 |
* c-basic-offset: 4 |
* End: |
*/ |
?> |
/branches/livraison_menes/api/pear/HTTP.php |
---|
New file |
0,0 → 1,353 |
<?php |
// +----------------------------------------------------------------------+ |
// | PEAR :: HTTP | |
// +----------------------------------------------------------------------+ |
// | This source file is subject to version 3.0 of the PHP license, | |
// | that is available 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: Stig Bakken <ssb@fast.no> | |
// | Sterling Hughes <sterling@php.net> | |
// | Tomas V.V.Cox <cox@idecnet.com> | |
// | Richard Heyes <richard@php.net> | |
// | Philippe Jausions <Philippe.Jausions@11abacus.com> | |
// | Michael Wallner <mike@php.net> | |
// +----------------------------------------------------------------------+ |
// |
// $Id: HTTP.php,v 1.1 2005-03-30 08:50:19 jpm Exp $ |
/** |
* HTTP |
* |
* HTTP utility functions |
* |
* @package HTTP |
* @category HTTP |
* @license PHP License |
* @access public |
* @version $Revision: 1.1 $ |
*/ |
class HTTP |
{ |
/** |
* Date |
* |
* Format a RFC compliant GMT date HTTP header. This function honors the |
* "y2k_compliance" php.ini directive and formats the GMT date corresponding |
* to either RFC850 or RFC822. |
* |
* @static |
* @access public |
* @return mixed GMT date string, or false for an invalid $time parameter |
* @param mixed $time unix timestamp or date (default = current time) |
*/ |
function Date($time = null) |
{ |
if (!isset($time)) { |
$time = time(); |
} elseif (!is_numeric($time) && (-1 === $time = strtotime($time))) { |
return false; |
} |
// RFC822 or RFC850 |
$format = ini_get('y2k_compliance') ? 'D, d M Y' : 'l, d-M-y'; |
return gmdate($format .' H:i:s \G\M\T', $time); |
} |
/** |
* Negotiate Language |
* |
* Negotiate language with the user's browser through the Accept-Language |
* HTTP header or the user's host address. Language codes are generally in |
* the form "ll" for a language spoken in only one country, or "ll-CC" for a |
* language spoken in a particular country. For example, U.S. English is |
* "en-US", while British English is "en-UK". Portugese as spoken in |
* Portugal is "pt-PT", while Brazilian Portugese is "pt-BR". |
* |
* Quality factors in the Accept-Language: header are supported, e.g.: |
* Accept-Language: en-UK;q=0.7, en-US;q=0.6, no, dk;q=0.8 |
* |
* <code> |
* require_once 'HTTP.php'; |
* $langs = array( |
* 'en' => 'locales/en', |
* 'en-US'=> 'locales/en', |
* 'en-UK'=> 'locales/en', |
* 'de' => 'locales/de', |
* 'de-DE'=> 'locales/de', |
* 'de-AT'=> 'locales/de', |
* ); |
* $neg = HTTP::negotiateLanguage($langs); |
* $dir = $langs[$neg]; |
* </code> |
* |
* @static |
* @access public |
* @return string The negotiated language result or the supplied default. |
* @param array $supported An associative array of supported languages, |
* whose values must evaluate to true. |
* @param string $default The default language to use if none is found. |
*/ |
function negotiateLanguage($supported, $default = 'en-US') |
{ |
$supp = array(); |
foreach ($supported as $lang => $isSupported) { |
if ($isSupported) { |
$supp[strToLower($lang)] = $lang; |
} |
} |
if (!count($supp)) { |
return $default; |
} |
$matches = array(); |
if (isset($_SERVER['HTTP_ACCEPT_LANGUAGE'])) { |
foreach (explode(',', $_SERVER['HTTP_ACCEPT_LANGUAGE']) as $lang) { |
$lang = array_map('trim', explode(';', $lang)); |
if (isset($lang[1])) { |
$l = strtolower($lang[0]); |
$q = (float) str_replace('q=', '', $lang[1]); |
} else { |
$l = strtolower($lang[0]); |
$q = null; |
} |
if (isset($supp[$l])) { |
$matches[$l] = isset($q) ? $q : 1000 - count($matches); |
} |
} |
} |
if (count($matches)) { |
asort($matches, SORT_NUMERIC); |
return $supp[array_pop(array_keys($matches))]; |
} |
if (isset($_SERVER['REMOTE_HOST'])) { |
$lang = strtolower(array_pop(explode('.', $_SERVER['REMOTE_HOST']))); |
if (isset($supp[$lang])) { |
return $supp[$lang]; |
} |
} |
return $default; |
} |
/** |
* Head |
* |
* Sends a "HEAD" HTTP command to a server and returns the headers |
* as an associative array. Example output could be: |
* <code> |
* Array |
* ( |
* [response_code] => 200 // The HTTP response code |
* [response] => HTTP/1.1 200 OK // The full HTTP response string |
* [Date] => Fri, 11 Jan 2002 01:41:44 GMT |
* [Server] => Apache/1.3.20 (Unix) PHP/4.1.1 |
* [X-Powered-By] => PHP/4.1.1 |
* [Connection] => close |
* [Content-Type] => text/html |
* ) |
* </code> |
* |
* @see HTTP_Client::head() |
* @see HTTP_Request |
* |
* @static |
* @access public |
* @return mixed Returns associative array of response headers on success |
* or PEAR error on failure. |
* @param string $url A valid URL, e.g.: http://pear.php.net/credits.php |
* @param integer $timeout Timeout in seconds (default = 10) |
*/ |
function head($url, $timeout = 10) |
{ |
$p = parse_url($url); |
if (!isset($p['scheme'])) { |
$p = parse_url(HTTP::absoluteURI($url)); |
} elseif ($p['scheme'] != 'http') { |
return HTTP::raiseError('Unsupported protocol: '. $p['scheme']); |
} |
$port = isset($p['port']) ? $p['port'] : 80; |
if (!$fp = @fsockopen($p['host'], $port, $eno, $estr, $timeout)) { |
return HTTP::raiseError("Connection error: $estr ($eno)"); |
} |
$path = !empty($p['path']) ? $p['path'] : '/'; |
$path .= !empty($p['query']) ? '?' . $p['query'] : ''; |
fputs($fp, "HEAD $path HTTP/1.0\r\n"); |
fputs($fp, 'Host: ' . $p['host'] . ':' . $port . "\r\n"); |
fputs($fp, "Connection: close\r\n\r\n"); |
$response = rtrim(fgets($fp, 4096)); |
if (preg_match("|^HTTP/[^\s]*\s(.*?)\s|", $response, $status)) { |
$headers['response_code'] = $status[1]; |
} |
$headers['response'] = $response; |
while ($line = fgets($fp, 4096)) { |
if (!trim($line)) { |
break; |
} |
if (($pos = strpos($line, ':')) !== false) { |
$header = substr($line, 0, $pos); |
$value = trim(substr($line, $pos + 1)); |
$headers[$header] = $value; |
} |
} |
fclose($fp); |
return $headers; |
} |
/** |
* Redirect |
* |
* This function redirects the client. This is done by issuing |
* a "Location" header and exiting if wanted. If you set $rfc2616 to true |
* HTTP will output a hypertext note with the location of the redirect. |
* |
* @static |
* @access public |
* @return mixed Returns true on succes (or exits) or false if headers |
* have already been sent. |
* @param string $url URL where the redirect should go to. |
* @param bool $exit Whether to exit immediately after redirection. |
* @param bool $rfc2616 Wheter to output a hypertext note where we're |
* redirecting to (Redirecting to <a href="...">...</a>.) |
*/ |
function redirect($url, $exit = true, $rfc2616 = false) |
{ |
if (headers_sent()) { |
return false; |
} |
$url = HTTP::absoluteURI($url); |
header('Location: '. $url); |
if ( $rfc2616 && isset($_SERVER['REQUEST_METHOD']) && |
$_SERVER['REQUEST_METHOD'] != 'HEAD') { |
printf('Redirecting to: <a href="%s">%s</a>.', $url, $url); |
} |
if ($exit) { |
exit; |
} |
return true; |
} |
/** |
* Absolute URI |
* |
* This function returns the absolute URI for the partial URL passed. |
* The current scheme (HTTP/HTTPS), host server, port, current script |
* location are used if necessary to resolve any relative URLs. |
* |
* Offsets potentially created by PATH_INFO are taken care of to resolve |
* relative URLs to the current script. |
* |
* You can choose a new protocol while resolving the URI. This is |
* particularly useful when redirecting a web browser using relative URIs |
* and to switch from HTTP to HTTPS, or vice-versa, at the same time. |
* |
* @author Philippe Jausions <Philippe.Jausions@11abacus.com> |
* @static |
* @access public |
* @return string The absolute URI. |
* @param string $url Absolute or relative URI the redirect should go to. |
* @param string $protocol Protocol to use when redirecting URIs. |
* @param integer $port A new port number. |
*/ |
function absoluteURI($url = null, $protocol = null, $port = null) |
{ |
// filter CR/LF |
$url = str_replace(array("\r", "\n"), ' ', $url); |
// Mess around with already absolute URIs |
if (preg_match('!^([a-z0-9]+)://!i', $url)) { |
if (empty($protocol) && empty($port)) { |
return $url; |
} |
if (!empty($protocol)) { |
$url = $protocol .':'. array_pop(explode(':', $url, 2)); |
} |
if (!empty($port)) { |
$url = preg_replace('!^(([a-z0-9]+)://[^/:]+)(:[\d]+)?!i', |
'\1:'. $port, $url); |
} |
return $url; |
} |
$host = 'localhost'; |
if (!empty($_SERVER['HTTP_HOST'])) { |
list($host) = explode(':', $_SERVER['HTTP_HOST']); |
} elseif (!empty($_SERVER['SERVER_NAME'])) { |
list($host) = explode(':', $_SERVER['SERVER_NAME']); |
} |
if (empty($protocol)) { |
if (isset($_SERVER['HTTPS']) && !strcasecmp($_SERVER['HTTPS'], 'on')) { |
$protocol = 'https'; |
} else { |
$protocol = 'http'; |
} |
if (!isset($port) || $port != intval($port)) { |
$port = isset($_SERVER['SERVER_PORT']) ? $_SERVER['SERVER_PORT'] : 80; |
} |
} |
if ($protocol == 'http' && $port == 80) { |
unset($port); |
} |
if ($protocol == 'https' && $port == 443) { |
unset($port); |
} |
$server = $protocol .'://'. $host . (isset($port) ? ':'. $port : ''); |
if (!strlen($url)) { |
$url = isset($_SERVER['REQUEST_URI']) ? |
$_SERVER['REQUEST_URI'] : $_SERVER['PHP_SELF']; |
} |
if ($url{0} == '/') { |
return $server . $url; |
} |
// Check for PATH_INFO |
if (isset($_SERVER['PATH_INFO']) && $_SERVER['PHP_SELF'] != $_SERVER['PATH_INFO']) { |
$path = dirname(substr($_SERVER['PHP_SELF'], 0, -strlen($_SERVER['PATH_INFO']))); |
} else { |
$path = dirname($_SERVER['PHP_SELF']); |
} |
if (substr($path = strtr($path, '\\', '/'), -1) != '/') { |
$path .= '/'; |
} |
return $server . $path . $url; |
} |
/** |
* Raise Error |
* |
* Lazy raising of PEAR_Errors. |
* |
* @static |
* @access protected |
* @return object PEAR_Error |
* @param mixed $error |
* @param int $code |
*/ |
function raiseError($error = null, $code = null) |
{ |
require_once 'PEAR.php'; |
return PEAR::raiseError($error, $code); |
} |
} |
?> |
/branches/livraison_menes/api/pear/Net/Socket.php |
---|
New file |
0,0 → 1,528 |
<?php |
// |
// +----------------------------------------------------------------------+ |
// | PHP Version 4 | |
// +----------------------------------------------------------------------+ |
// | Copyright (c) 1997-2003 The PHP Group | |
// +----------------------------------------------------------------------+ |
// | This source file is subject to version 2.0 of the PHP license, | |
// | that is bundled with this package in the file LICENSE, and is | |
// | available at through the world-wide-web at | |
// | http://www.php.net/license/2_02.txt. | |
// | If you did not receive a copy of the PHP license and are unable to | |
// | obtain it through the world-wide-web, please send a note to | |
// | license@php.net so we can mail you a copy immediately. | |
// +----------------------------------------------------------------------+ |
// | Authors: Stig Bakken <ssb@php.net> | |
// | Chuck Hagenbuch <chuck@horde.org> | |
// +----------------------------------------------------------------------+ |
// |
// $Id: Socket.php,v 1.1 2005-03-30 08:50:33 jpm Exp $ |
require_once 'PEAR.php'; |
define('NET_SOCKET_READ', 1); |
define('NET_SOCKET_WRITE', 2); |
define('NET_SOCKET_ERROR', 3); |
/** |
* Generalized Socket class. |
* |
* @version 1.1 |
* @author Stig Bakken <ssb@php.net> |
* @author Chuck Hagenbuch <chuck@horde.org> |
*/ |
class Net_Socket extends PEAR { |
/** |
* Socket file pointer. |
* @var resource $fp |
*/ |
var $fp = null; |
/** |
* Whether the socket is blocking. Defaults to true. |
* @var boolean $blocking |
*/ |
var $blocking = true; |
/** |
* Whether the socket is persistent. Defaults to false. |
* @var boolean $persistent |
*/ |
var $persistent = false; |
/** |
* The IP address to connect to. |
* @var string $addr |
*/ |
var $addr = ''; |
/** |
* The port number to connect to. |
* @var integer $port |
*/ |
var $port = 0; |
/** |
* Number of seconds to wait on socket connections before assuming |
* there's no more data. Defaults to no timeout. |
* @var integer $timeout |
*/ |
var $timeout = false; |
/** |
* Number of bytes to read at a time in readLine() and |
* readAll(). Defaults to 2048. |
* @var integer $lineLength |
*/ |
var $lineLength = 2048; |
/** |
* Connect to the specified port. If called when the socket is |
* already connected, it disconnects and connects again. |
* |
* @param string $addr IP address or host name. |
* @param integer $port TCP port number. |
* @param boolean $persistent (optional) Whether the connection is |
* persistent (kept open between requests |
* by the web server). |
* @param integer $timeout (optional) How long to wait for data. |
* @param array $options See options for stream_context_create. |
* |
* @access public |
* |
* @return boolean | PEAR_Error True on success or a PEAR_Error on failure. |
*/ |
function connect($addr, $port = 0, $persistent = null, $timeout = null, $options = null) |
{ |
if (is_resource($this->fp)) { |
@fclose($this->fp); |
$this->fp = null; |
} |
if (!$addr) { |
return $this->raiseError('$addr cannot be empty'); |
} elseif (strspn($addr, '.0123456789') == strlen($addr) || |
strstr($addr, '/') !== false) { |
$this->addr = $addr; |
} else { |
$this->addr = @gethostbyname($addr); |
} |
$this->port = $port % 65536; |
if ($persistent !== null) { |
$this->persistent = $persistent; |
} |
if ($timeout !== null) { |
$this->timeout = $timeout; |
} |
$openfunc = $this->persistent ? 'pfsockopen' : 'fsockopen'; |
$errno = 0; |
$errstr = ''; |
if ($options && function_exists('stream_context_create')) { |
if ($this->timeout) { |
$timeout = $this->timeout; |
} else { |
$timeout = 0; |
} |
$context = stream_context_create($options); |
$fp = @$openfunc($this->addr, $this->port, $errno, $errstr, $timeout, $context); |
} else { |
if ($this->timeout) { |
$fp = @$openfunc($this->addr, $this->port, $errno, $errstr, $this->timeout); |
} else { |
$fp = @$openfunc($this->addr, $this->port, $errno, $errstr); |
} |
} |
if (!$fp) { |
return $this->raiseError($errstr, $errno); |
} |
$this->fp = $fp; |
return $this->setBlocking($this->blocking); |
} |
/** |
* Disconnects from the peer, closes the socket. |
* |
* @access public |
* @return mixed true on success or an error object otherwise |
*/ |
function disconnect() |
{ |
if (!is_resource($this->fp)) { |
return $this->raiseError('not connected'); |
} |
@fclose($this->fp); |
$this->fp = null; |
return true; |
} |
/** |
* Find out if the socket is in blocking mode. |
* |
* @access public |
* @return boolean The current blocking mode. |
*/ |
function isBlocking() |
{ |
return $this->blocking; |
} |
/** |
* Sets whether the socket connection should be blocking or |
* not. A read call to a non-blocking socket will return immediately |
* if there is no data available, whereas it will block until there |
* is data for blocking sockets. |
* |
* @param boolean $mode True for blocking sockets, false for nonblocking. |
* @access public |
* @return mixed true on success or an error object otherwise |
*/ |
function setBlocking($mode) |
{ |
if (!is_resource($this->fp)) { |
return $this->raiseError('not connected'); |
} |
$this->blocking = $mode; |
socket_set_blocking($this->fp, $this->blocking); |
return true; |
} |
/** |
* Sets the timeout value on socket descriptor, |
* expressed in the sum of seconds and microseconds |
* |
* @param integer $seconds Seconds. |
* @param integer $microseconds Microseconds. |
* @access public |
* @return mixed true on success or an error object otherwise |
*/ |
function setTimeout($seconds, $microseconds) |
{ |
if (!is_resource($this->fp)) { |
return $this->raiseError('not connected'); |
} |
return socket_set_timeout($this->fp, $seconds, $microseconds); |
} |
/** |
* Returns information about an existing socket resource. |
* Currently returns four entries in the result array: |
* |
* <p> |
* timed_out (bool) - The socket timed out waiting for data<br> |
* blocked (bool) - The socket was blocked<br> |
* eof (bool) - Indicates EOF event<br> |
* unread_bytes (int) - Number of bytes left in the socket buffer<br> |
* </p> |
* |
* @access public |
* @return mixed Array containing information about existing socket resource or an error object otherwise |
*/ |
function getStatus() |
{ |
if (!is_resource($this->fp)) { |
return $this->raiseError('not connected'); |
} |
return socket_get_status($this->fp); |
} |
/** |
* Get a specified line of data |
* |
* @access public |
* @return $size bytes of data from the socket, or a PEAR_Error if |
* not connected. |
*/ |
function gets($size) |
{ |
if (!is_resource($this->fp)) { |
return $this->raiseError('not connected'); |
} |
return @fgets($this->fp, $size); |
} |
/** |
* Read a specified amount of data. This is guaranteed to return, |
* and has the added benefit of getting everything in one fread() |
* chunk; if you know the size of the data you're getting |
* beforehand, this is definitely the way to go. |
* |
* @param integer $size The number of bytes to read from the socket. |
* @access public |
* @return $size bytes of data from the socket, or a PEAR_Error if |
* not connected. |
*/ |
function read($size) |
{ |
if (!is_resource($this->fp)) { |
return $this->raiseError('not connected'); |
} |
return @fread($this->fp, $size); |
} |
/** |
* Write a specified amount of data. |
* |
* @param string $data Data to write. |
* @param integer $blocksize Amount of data to write at once. |
* NULL means all at once. |
* |
* @access public |
* @return mixed true on success or an error object otherwise |
*/ |
function write($data, $blocksize = null) |
{ |
if (!is_resource($this->fp)) { |
return $this->raiseError('not connected'); |
} |
if (is_null($blocksize) && !OS_WINDOWS) { |
return fwrite($this->fp, $data); |
} else { |
if (is_null($blocksize)) { |
$blocksize = 1024; |
} |
$pos = 0; |
$size = strlen($data); |
while ($pos < $size) { |
$written = @fwrite($this->fp, substr($data, $pos, $blocksize)); |
if ($written === false) { |
return false; |
} |
$pos += $written; |
} |
return $pos; |
} |
} |
/** |
* Write a line of data to the socket, followed by a trailing "\r\n". |
* |
* @access public |
* @return mixed fputs result, or an error |
*/ |
function writeLine($data) |
{ |
if (!is_resource($this->fp)) { |
return $this->raiseError('not connected'); |
} |
return fwrite($this->fp, $data . "\r\n"); |
} |
/** |
* Tests for end-of-file on a socket descriptor. |
* |
* @access public |
* @return bool |
*/ |
function eof() |
{ |
return (is_resource($this->fp) && feof($this->fp)); |
} |
/** |
* Reads a byte of data |
* |
* @access public |
* @return 1 byte of data from the socket, or a PEAR_Error if |
* not connected. |
*/ |
function readByte() |
{ |
if (!is_resource($this->fp)) { |
return $this->raiseError('not connected'); |
} |
return ord(@fread($this->fp, 1)); |
} |
/** |
* Reads a word of data |
* |
* @access public |
* @return 1 word of data from the socket, or a PEAR_Error if |
* not connected. |
*/ |
function readWord() |
{ |
if (!is_resource($this->fp)) { |
return $this->raiseError('not connected'); |
} |
$buf = @fread($this->fp, 2); |
return (ord($buf[0]) + (ord($buf[1]) << 8)); |
} |
/** |
* Reads an int of data |
* |
* @access public |
* @return integer 1 int of data from the socket, or a PEAR_Error if |
* not connected. |
*/ |
function readInt() |
{ |
if (!is_resource($this->fp)) { |
return $this->raiseError('not connected'); |
} |
$buf = @fread($this->fp, 4); |
return (ord($buf[0]) + (ord($buf[1]) << 8) + |
(ord($buf[2]) << 16) + (ord($buf[3]) << 24)); |
} |
/** |
* Reads a zero-terminated string of data |
* |
* @access public |
* @return string, or a PEAR_Error if |
* not connected. |
*/ |
function readString() |
{ |
if (!is_resource($this->fp)) { |
return $this->raiseError('not connected'); |
} |
$string = ''; |
while (($char = @fread($this->fp, 1)) != "\x00") { |
$string .= $char; |
} |
return $string; |
} |
/** |
* Reads an IP Address and returns it in a dot formated string |
* |
* @access public |
* @return Dot formated string, or a PEAR_Error if |
* not connected. |
*/ |
function readIPAddress() |
{ |
if (!is_resource($this->fp)) { |
return $this->raiseError('not connected'); |
} |
$buf = @fread($this->fp, 4); |
return sprintf("%s.%s.%s.%s", ord($buf[0]), ord($buf[1]), |
ord($buf[2]), ord($buf[3])); |
} |
/** |
* Read until either the end of the socket or a newline, whichever |
* comes first. Strips the trailing newline from the returned data. |
* |
* @access public |
* @return All available data up to a newline, without that |
* newline, or until the end of the socket, or a PEAR_Error if |
* not connected. |
*/ |
function readLine() |
{ |
if (!is_resource($this->fp)) { |
return $this->raiseError('not connected'); |
} |
$line = ''; |
$timeout = time() + $this->timeout; |
while (!feof($this->fp) && (!$this->timeout || time() < $timeout)) { |
$line .= @fgets($this->fp, $this->lineLength); |
if (substr($line, -1) == "\n") { |
return rtrim($line, "\r\n"); |
} |
} |
return $line; |
} |
/** |
* Read until the socket closes, or until there is no more data in |
* the inner PHP buffer. If the inner buffer is empty, in blocking |
* mode we wait for at least 1 byte of data. Therefore, in |
* blocking mode, if there is no data at all to be read, this |
* function will never exit (unless the socket is closed on the |
* remote end). |
* |
* @access public |
* |
* @return string All data until the socket closes, or a PEAR_Error if |
* not connected. |
*/ |
function readAll() |
{ |
if (!is_resource($this->fp)) { |
return $this->raiseError('not connected'); |
} |
$data = ''; |
while (!feof($this->fp)) { |
$data .= @fread($this->fp, $this->lineLength); |
} |
return $data; |
} |
/** |
* Runs the equivalent of the select() system call on the socket |
* with a timeout specified by tv_sec and tv_usec. |
* |
* @param integer $state Which of read/write/error to check for. |
* @param integer $tv_sec Number of seconds for timeout. |
* @param integer $tv_usec Number of microseconds for timeout. |
* |
* @access public |
* @return False if select fails, integer describing which of read/write/error |
* are ready, or PEAR_Error if not connected. |
*/ |
function select($state, $tv_sec, $tv_usec = 0) |
{ |
if (!is_resource($this->fp)) { |
return $this->raiseError('not connected'); |
} |
$read = null; |
$write = null; |
$except = null; |
if ($state & NET_SOCKET_READ) { |
$read[] = $this->fp; |
} |
if ($state & NET_SOCKET_WRITE) { |
$write[] = $this->fp; |
} |
if ($state & NET_SOCKET_ERROR) { |
$except[] = $this->fp; |
} |
if (false === ($sr = stream_select($read, $write, $except, $tv_sec, $tv_usec))) { |
return false; |
} |
$result = 0; |
if (count($read)) { |
$result |= NET_SOCKET_READ; |
} |
if (count($write)) { |
$result |= NET_SOCKET_WRITE; |
} |
if (count($except)) { |
$result |= NET_SOCKET_ERROR; |
} |
return $result; |
} |
} |
/branches/livraison_menes/api/pear/Net/FTP.php |
---|
New file |
0,0 → 1,2148 |
<?php |
/* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4: */ |
/** |
* Net_FTP main file. |
* |
* This file must be included to use the Net_FTP package. |
* |
* 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 Networking |
* @package FTP |
* @author Tobias Schlitt <toby@php.net> |
* @copyright 1997-2005 The PHP Group |
* @license http://www.php.net/license/3_0.txt PHP License 3.0 |
* @version CVS: $Id: FTP.php,v 1.2 2006-10-05 08:55:35 florian Exp $ |
* @link http://pear.php.net/package/Net_FTP |
* @since File available since Release 0.0.1 |
*/ |
require_once 'PEAR.php'; |
/** |
* Option to let the ls() method return only files. |
* |
* @since 1.3 |
* @name NET_FTP_FILES_ONLY |
* @see Net_FTP::ls() |
*/ |
define('NET_FTP_FILES_ONLY', 0, true); |
/** |
* Option to let the ls() method return only directories. |
* |
* @since 1.3 |
* @name NET_FTP_DIRS_ONLY |
* @see Net_FTP::ls() |
*/ |
define('NET_FTP_DIRS_ONLY', 1, true); |
/** |
* Option to let the ls() method return directories and files (default). |
* |
* @since 1.3 |
* @name NET_FTP_DIRS_FILES |
* @see Net_FTP::ls() |
*/ |
define('NET_FTP_DIRS_FILES', 2, true); |
/** |
* Option to let the ls() method return the raw directory listing from ftp_rawlist(). |
* |
* @since 1.3 |
* @name NET_FTP_RAWLIST |
* @see Net_FTP::ls() |
*/ |
define('NET_FTP_RAWLIST', 3, true); |
/** |
* Error code to indicate a failed connection |
* This error code indicates, that the connection you tryed to set up |
* could not be established. Check your connection settings (host & port)! |
* |
* @since 1.3 |
* @name NET_FTP_ERR_CONNECT_FAILED |
* @see Net_FTP::connect() |
*/ |
define('NET_FTP_ERR_CONNECT_FAILED', -1); |
/** |
* Error code to indicate a failed login |
* This error code indicates, that the login to the FTP server failed. Check |
* your user data (username & password). |
* |
* @since 1.3 |
* @name NET_FTP_ERR_LOGIN_FAILED |
* @see Net_FTP::login() |
*/ |
define('NET_FTP_ERR_LOGIN_FAILED', -2); |
/** |
* Error code to indicate a failed directory change |
* The cd() method failed. Ensure that the directory you wanted to access exists. |
* |
* @since 1.3 |
* @name NET_FTP_ERR_DIRCHANGE_FAILED |
* @see Net_FTP::cd() |
*/ |
define('NET_FTP_ERR_DIRCHANGE_FAILED', 2); // Compatibillity reasons! |
/** |
* Error code to indicate that Net_FTP could not determine the current path |
* The cwd() method failed and could not determine the path you currently reside |
* in on the FTP server. |
* |
* @since 1.3 |
* @name NET_FTP_ERR_DETERMINEPATH_FAILED |
* @see Net_FTP::pwd() |
*/ |
define('NET_FTP_ERR_DETERMINEPATH_FAILED', 4); // Compatibillity reasons! |
/** |
* Error code to indicate that the creation of a directory failed |
* The directory you tryed to create could not be created. Check the |
* access rights on the parent directory! |
* |
* @since 1.3 |
* @name NET_FTP_ERR_CREATEDIR_FAILED |
* @see Net_FTP::mkdir() |
*/ |
define('NET_FTP_ERR_CREATEDIR_FAILED', -4); |
/** |
* Error code to indicate that the EXEC execution failed. |
* The execution of a command using EXEC failed. Ensure, that your |
* FTP server supports the EXEC command. |
* |
* @since 1.3 |
* @name NET_FTP_ERR_EXEC_FAILED |
* @see Net_FTP::execute() |
*/ |
define('NET_FTP_ERR_EXEC_FAILED', -5); |
/** |
* Error code to indicate that the SITE command failed. |
* The execution of a command using SITE failed. Ensure, that your |
* FTP server supports the SITE command. |
* |
* @since 1.3 |
* @name NET_FTP_ERR_SITE_FAILED |
* @see Net_FTP::site() |
*/ |
define('NET_FTP_ERR_SITE_FAILED', -6); |
/** |
* Error code to indicate that the CHMOD command failed. |
* The execution of CHMOD failed. Ensure, that your |
* FTP server supports the CHMOD command and that you have the appropriate |
* access rights to use CHMOD. |
* |
* @since 1.3 |
* @name NET_FTP_ERR_CHMOD_FAILED |
* @see Net_FTP::chmod() |
*/ |
define('NET_FTP_ERR_CHMOD_FAILED', -7); |
/** |
* Error code to indicate that a file rename failed |
* The renaming of a file on the server failed. Ensure that you have the |
* appropriate access rights to rename the file. |
* |
* @since 1.3 |
* @name NET_FTP_ERR_RENAME_FAILED |
* @see Net_FTP::rename() |
*/ |
define('NET_FTP_ERR_RENAME_FAILED', -8); |
/** |
* Error code to indicate that the MDTM command failed |
* The MDTM command is not supported for directories. Ensure that you gave |
* a file path to the mdtm() method, not a directory path. |
* |
* @since 1.3 |
* @name NET_FTP_ERR_MDTMDIR_UNSUPPORTED |
* @see Net_FTP::mdtm() |
*/ |
define('NET_FTP_ERR_MDTMDIR_UNSUPPORTED', -9); |
/** |
* Error code to indicate that the MDTM command failed |
* The MDTM command failed. Ensure that your server supports the MDTM command. |
* |
* @since 1.3 |
* @name NET_FTP_ERR_MDTM_FAILED |
* @see Net_FTP::mdtm() |
*/ |
define('NET_FTP_ERR_MDTM_FAILED', -10); |
/** |
* Error code to indicate that a date returned by the server was misformated |
* A date string returned by your server seems to be missformated and could not be |
* parsed. Check that the server is configured correctly. If you're sure, please |
* send an email to the auhtor with a dumped output of $ftp->ls('./', NET_FTP_RAWLIST); |
* to get the date format supported. |
* |
* @since 1.3 |
* @name NET_FTP_ERR_DATEFORMAT_FAILED |
* @see Net_FTP::mdtm(), Net_FTP::ls() |
*/ |
define('NET_FTP_ERR_DATEFORMAT_FAILED', -11); |
/** |
* Error code to indicate that the SIZE command failed |
* The determination of the filesize of a file failed. Ensure that your server supports the |
* SIZE command. |
* |
* @since 1.3 |
* @name NET_FTP_ERR_SIZE_FAILED |
* @see Net_FTP::size() |
*/ |
define('NET_FTP_ERR_SIZE_FAILED', -12); |
/** |
* Error code to indicate that a local file could not be overwritten |
* You specified not to overwrite files. Therefore the local file has not been |
* overwriten. If you want to get the file overwriten, please set the option to |
* do so. |
* |
* @since 1.3 |
* @name NET_FTP_ERR_OVERWRITELOCALFILE_FORBIDDEN |
* @see Net_FTP::get(), Net_FTP::getRecursive() |
*/ |
define('NET_FTP_ERR_OVERWRITELOCALFILE_FORBIDDEN', -13); |
/** |
* Error code to indicate that a local file could not be overwritten |
* Also you specified to overwrite the local file you want to download to, |
* it has not been possible to do so. Check that you have the appropriate access |
* rights on the local file to overwrite it. |
* |
* @since 1.3 |
* @name NET_FTP_ERR_OVERWRITELOCALFILE_FAILED |
* @see Net_FTP::get(), Net_FTP::getRecursive() |
*/ |
define('NET_FTP_ERR_OVERWRITELOCALFILE_FAILED', -14); |
/** |
* Error code to indicate that the file you wanted to upload does not exist |
* The file you tried to upload does not exist. Ensure that it exists. |
* |
* @since 1.3 |
* @name NET_FTP_ERR_LOCALFILENOTEXIST |
* @see Net_FTP::put(), Net_FTP::putRecursive() |
*/ |
define('NET_FTP_ERR_LOCALFILENOTEXIST', -15); |
/** |
* Error code to indicate that a remote file could not be overwritten |
* You specified not to overwrite files. Therefore the remote file has not been |
* overwriten. If you want to get the file overwriten, please set the option to |
* do so. |
* |
* @since 1.3 |
* @name NET_FTP_ERR_OVERWRITEREMOTEFILE_FORBIDDEN |
* @see Net_FTP::put(), Net_FTP::putRecursive() |
*/ |
define('NET_FTP_ERR_OVERWRITEREMOTEFILE_FORBIDDEN', -16); |
/** |
* Error code to indicate that the upload of a file failed |
* The upload you tried failed. Ensure that you have appropriate access rights |
* to upload the desired file. |
* |
* @since 1.3 |
* @name NET_FTP_ERR_UPLOADFILE_FAILED |
* @see Net_FTP::put(), Net_FTP::putRecursive() |
*/ |
define('NET_FTP_ERR_UPLOADFILE_FAILED', -17); |
/** |
* Error code to indicate that you specified an incorrect directory path |
* The remote path you specified seems not to be a directory. Ensure that |
* the path you specify is a directory and that the path string ends with |
* a /. |
* |
* @since 1.3 |
* @name NET_FTP_ERR_REMOTEPATHNODIR |
* @see Net_FTP::putRecursive(), Net_FTP::getRecursive() |
*/ |
define('NET_FTP_ERR_REMOTEPATHNODIR', -18); |
/** |
* Error code to indicate that you specified an incorrect directory path |
* The local path you specified seems not to be a directory. Ensure that |
* the path you specify is a directory and that the path string ends with |
* a /. |
* |
* @since 1.3 |
* @name NET_FTP_ERR_LOCALPATHNODIR |
* @see Net_FTP::putRecursive(), Net_FTP::getRecursive() |
*/ |
define('NET_FTP_ERR_LOCALPATHNODIR', -19); |
/** |
* Error code to indicate that a local directory failed to be created |
* You tried to create a local directory through getRecursive() method, |
* which has failed. Ensure that you have the appropriate access rights |
* to create it. |
* |
* @since 1.3 |
* @name NET_FTP_ERR_CREATELOCALDIR_FAILED |
* @see Net_FTP::getRecursive() |
*/ |
define('NET_FTP_ERR_CREATELOCALDIR_FAILED', -20); |
/** |
* Error code to indicate that the provided hostname was incorrect |
* The hostname you provided was invalid. Ensure to provide either a |
* full qualified domain name or an IP address. |
* |
* @since 1.3 |
* @name NET_FTP_ERR_HOSTNAMENOSTRING |
* @see Net_FTP::setHostname() |
*/ |
define('NET_FTP_ERR_HOSTNAMENOSTRING', -21); |
/** |
* Error code to indicate that the provided port was incorrect |
* The port number you provided was invalid. Ensure to provide either a |
* a numeric port number greater zero. |
* |
* @since 1.3 |
* @name NET_FTP_ERR_PORTLESSZERO |
* @see Net_FTP::setPort() |
*/ |
define('NET_FTP_ERR_PORTLESSZERO', -22); |
/** |
* Error code to indicate that you provided an invalid mode constant |
* The mode constant you provided was invalid. You may only provide |
* FTP_ASCII or FTP_BINARY. |
* |
* @since 1.3 |
* @name NET_FTP_ERR_NOMODECONST |
* @see Net_FTP::setMode() |
*/ |
define('NET_FTP_ERR_NOMODECONST', -23); |
/** |
* Error code to indicate that you provided an invalid timeout |
* The timeout you provided was invalid. You have to provide a timeout greater |
* or equal to zero. |
* |
* @since 1.3 |
* @name NET_FTP_ERR_TIMEOUTLESSZERO |
* @see Net_FTP::Net_FTP(), Net_FTP::setTimeout() |
*/ |
define('NET_FTP_ERR_TIMEOUTLESSZERO', -24); |
/** |
* Error code to indicate that you provided an invalid timeout |
* An error occured while setting the timeout. Ensure that you provide a |
* valid integer for the timeount and that your PHP installation works |
* correctly. |
* |
* @since 1.3 |
* @name NET_FTP_ERR_SETTIMEOUT_FAILED |
* @see Net_FTP::Net_FTP(), Net_FTP::setTimeout() |
*/ |
define('NET_FTP_ERR_SETTIMEOUT_FAILED', -25); |
/** |
* Error code to indicate that the provided extension file doesn't exist |
* The provided extension file does not exist. Ensure to provided an |
* existant extension file. |
* |
* @since 1.3 |
* @name NET_FTP_ERR_EXTFILENOTEXIST |
* @see Net_FTP::getExtensionFile() |
*/ |
define('NET_FTP_ERR_EXTFILENOTEXIST', -26); |
/** |
* Error code to indicate that the provided extension file is not readable |
* The provided extension file is not readable. Ensure to have sufficient |
* access rights for it. |
* |
* @since 1.3 |
* @name NET_FTP_ERR_EXTFILEREAD_FAILED |
* @see Net_FTP::getExtensionFile() |
*/ |
define('NET_FTP_ERR_EXTFILEREAD_FAILED', -27); |
/** |
* Error code to indicate that the deletion of a file failed |
* The specified file could not be deleted. Ensure to have sufficient |
* access rights to delete the file. |
* |
* @since 1.3 |
* @name NET_FTP_ERR_EXTFILEREAD_FAILED |
* @see Net_FTP::rm() |
*/ |
define('NET_FTP_ERR_DELETEFILE_FAILED', -28); |
/** |
* Error code to indicate that the deletion of a directory faild |
* The specified file could not be deleted. Ensure to have sufficient |
* access rights to delete the file. |
* |
* @since 1.3 |
* @name NET_FTP_ERR_EXTFILEREAD_FAILED |
* @see Net_FTP::rm() |
*/ |
define('NET_FTP_ERR_DELETEDIR_FAILED', -29); |
/** |
* Error code to indicate that the directory listing failed |
* PHP could not list the directory contents on the server. Ensure |
* that your server is configured appropriate. |
* |
* @since 1.3 |
* @name NET_FTP_ERR_RAWDIRLIST_FAILED |
* @see Net_FTP::ls() |
*/ |
define('NET_FTP_ERR_RAWDIRLIST_FAILED', -30); |
/** |
* Error code to indicate that the directory listing failed |
* The directory listing format your server uses seems not to |
* be supported by Net_FTP. Please send the output of the |
* call ls('./', NET_FTP_RAWLIST); to the author of this |
* class to get it supported. |
* |
* @since 1.3 |
* @name NET_FTP_ERR_DIRLIST_UNSUPPORTED |
* @see Net_FTP::ls() |
*/ |
define('NET_FTP_ERR_DIRLIST_UNSUPPORTED', -31); |
/** |
* Error code to indicate failed disconnecting |
* This error code indicates, that disconnection was not possible. |
* |
* @since 1.3 |
* @name NET_FTP_ERR_DISCONNECT_FAILED |
* @see Net_FTP::disconnect() |
*/ |
define('NET_FTP_ERR_DISCONNECT_FAILED', -32); |
/** |
* Error code to indicate that the username you provided was invalid. |
* Check that you provided a non-empty string as the username. |
* |
* @since 1.3 |
* @name NET_FTP_ERR_USERNAMENOSTRING |
* @see Net_FTP::setUsername() |
*/ |
define('NET_FTP_ERR_USERNAMENOSTRING', -33); |
/** |
* Error code to indicate that the username you provided was invalid. |
* Check that you provided a non-empty string as the username. |
* |
* @since 1.3 |
* @name NET_FTP_ERR_PASSWORDNOSTRING |
* @see Net_FTP::setPassword() |
*/ |
define('NET_FTP_ERR_PASSWORDNOSTRING', -33); |
/** |
* Class for comfortable FTP-communication |
* |
* This class provides comfortable communication with FTP-servers. You may do everything |
* enabled by the PHP-FTP-extension and further functionalities, like recursive-deletion, |
* -up- and -download. Another feature is to create directories recursively. |
* |
* @license http://www.php.net/license/3_0.txt PHP License 3.0 |
* @category Networking |
* @package FTP |
* @author Tobias Schlitt <toby@php.net> |
* @copyright 1997-2005 The PHP Group |
* @version Release: @package_version@ |
* @link http://pear.php.net/package/Net_FTP |
* @since 0.0.1 |
* @access public |
*/ |
class Net_FTP extends PEAR |
{ |
/** |
* The host to connect to |
* |
* @access private |
* @var string |
*/ |
var $_hostname; |
/** |
* The port for ftp-connection (standard is 21) |
* |
* @access private |
* @var int |
*/ |
var $_port = 21; |
/** |
* The username for login |
* |
* @access private |
* @var string |
*/ |
var $_username; |
/** |
* The password for login |
* |
* @access private |
* @var string |
*/ |
var $_password; |
/** |
* Determine whether to use passive-mode (true) or active-mode (false) |
* |
* @access private |
* @var bool |
*/ |
var $_passv; |
/** |
* The standard mode for ftp-transfer |
* |
* @access private |
* @var int |
*/ |
var $_mode = FTP_BINARY; |
/** |
* This holds the handle for the ftp-connection |
* |
* @access private |
* @var resource |
*/ |
var $_handle; |
/** |
* Contains the timeout for FTP operations |
* |
* @access private |
* @var int |
* @since 1.3 |
*/ |
var $_timeout = 90; |
/** |
* Saves file-extensions for ascii- and binary-mode |
* |
* The array contains 2 sub-arrays ("ascii" and "binary"), which both contain |
* file-extensions without the "." (".php" = "php"). |
* |
* @access private |
* @var array |
*/ |
var $_file_extensions; |
/** |
* ls match |
* Matches the ls entries against a regex and maps the resulting array to speaking names |
* |
* @access private |
* @var array |
* @since 1.3 |
*/ |
var $_ls_match = array( |
'unix' => array( |
'pattern' => '/(?:(d)|.)([rwxt-]+)\s+(\w+)\s+([\w\d-]+)\s+([\w\d-]+)\s+(\w+)\s+(\S+\s+\S+\s+\S+)\s+(.+)/', |
'map' => array( |
'is_dir' => 1, |
'rights' => 2, |
'files_inside' => 3, |
'user' => 4, |
'group' => 5, |
'size' => 6, |
'date' => 7, |
'name' => 8, |
) |
), |
'windows' => array( |
'pattern' => '/(.+)\s+(.+)\s+((<DIR>)|[0-9]+)\s+(.+)/', |
'map' => array( |
'name' => 5, |
'date' => 1, |
'size' => 3, |
'is_dir' => 4, |
) |
) |
); |
/** |
* matcher |
* Stores the matcher for the current connection |
* |
* @access private |
* @var array |
* @since 1.3 |
*/ |
var $_matcher = null; |
/** |
* Holds all Net_FTP_Observer objects |
* that wish to be notified of new messages. |
* |
* @var array |
* @access private |
* @since 1.3 |
*/ |
var $_listeners = array(); |
/** |
* This generates a new FTP-Object. The FTP-connection will not be established, yet. |
* You can leave $host and $port blank, if you want. The $host will not be set |
* and the $port will be left at 21. You have to set the $host manualy before |
* trying to connect or with the connect() method. |
* |
* @access public |
* @param string $host (optional) The hostname |
* @param int $port (optional) The port |
* @param int $timeout (optional) Sets the standard timeout |
* @return void |
* @see Net_FTP::setHostname(), Net_FTP::setPort(), Net_FTP::connect() |
*/ |
function Net_FTP($host = null, $port = null, $timeout = 90) |
{ |
$this->PEAR(); |
if (isset($host)) { |
$this->setHostname($host); |
} |
if (isset($port)) { |
$this->setPort($port); |
} |
$this->_timeout = $timeout; |
$this->_file_extensions[FTP_ASCII] = array(); |
$this->_file_extensions[FTP_BINARY] = array(); |
} |
/** |
* This function generates the FTP-connection. You can optionally define a |
* hostname and/or a port. If you do so, this data is stored inside the object. |
* |
* @access public |
* @param string $host (optional) The Hostname |
* @param int $port (optional) The Port |
* @return mixed True on success, otherwise PEAR::Error |
* @see NET_FTP_ERR_CONNECT_FAILED |
*/ |
function connect($host = null, $port = null) |
{ |
$this->_matcher = null; |
if (isset($host)) { |
$this->setHostname($host); |
} |
if (isset($port)) { |
$this->setPort($port); |
} |
$handle = @ftp_connect($this->getHostname(), $this->getPort(), $this->_timeout); |
if (!$handle) { |
return $this->raiseError("Connection to host failed", NET_FTP_ERR_CONNECT_FAILED); |
} else { |
$this->_handle =& $handle; |
return true; |
} |
} |
/** |
* This function close the FTP-connection |
* |
* @access public |
* @return bool|PEAR_Error Returns true on success, PEAR_Error on failure |
*/ |
function disconnect() |
{ |
$res = @ftp_close($this->_handle); |
if (!$res) { |
return PEAR::raiseError('Disconnect failed.', NET_FTP_ERR_DISCONNECT_FAILED); |
} |
return true; |
} |
/** |
* This logges you into the ftp-server. You are free to specify username and password |
* in this method. If you specify it, the values will be taken into the corresponding |
* attributes, if do not specify, the attributes are taken. |
* |
* @access public |
* @param string $username (optional) The username to use |
* @param string $password (optional) The password to use |
* @return mixed True on success, otherwise PEAR::Error |
* @see NET_FTP_ERR_LOGIN_FAILED |
*/ |
function login($username = null, $password = null) |
{ |
if (!isset($username)) { |
$username = $this->getUsername(); |
} else { |
$this->setUsername($username); |
} |
if (!isset($password)) { |
$password = $this->getPassword(); |
} else { |
$this->setPassword($password); |
} |
$res = @ftp_login($this->_handle, $username, $password); |
if (!$res) { |
return $this->raiseError("Unable to login", NET_FTP_ERR_LOGIN_FAILED); |
} else { |
return true; |
} |
} |
/** |
* This changes the currently used directory. You can use either an absolute |
* directory-path (e.g. "/home/blah") or a relative one (e.g. "../test"). |
* |
* @access public |
* @param string $dir The directory to go to. |
* @return mixed True on success, otherwise PEAR::Error |
* @see NET_FTP_ERR_DIRCHANGE_FAILED |
*/ |
function cd($dir) |
{ |
$erg = @ftp_chdir($this->_handle, $dir); |
if (!$erg) { |
return $this->raiseError("Directory change failed", NET_FTP_ERR_DIRCHANGE_FAILED); |
} else { |
return true; |
} |
} |
/** |
* Show's you the actual path on the server |
* This function questions the ftp-handle for the actual selected path and returns it. |
* |
* @access public |
* @return mixed The actual path or PEAR::Error |
* @see NET_FTP_ERR_DETERMINEPATH_FAILED |
*/ |
function pwd() |
{ |
$res = @ftp_pwd($this->_handle); |
if (!$res) { |
return $this->raiseError("Could not determine the actual path.", NET_FTP_ERR_DETERMINEPATH_FAILED); |
} else { |
return $res; |
} |
} |
/** |
* This works similar to the mkdir-command on your local machine. You can either give |
* it an absolute or relative path. The relative path will be completed with the actual |
* selected server-path. (see: pwd()) |
* |
* @access public |
* @param string $dir Absolute or relative dir-path |
* @param bool $recursive (optional) Create all needed directories |
* @return mixed True on success, otherwise PEAR::Error |
* @see NET_FTP_ERR_CREATEDIR_FAILED |
*/ |
function mkdir($dir, $recursive = false) |
{ |
$dir = $this->_construct_path($dir); |
$savedir = $this->pwd(); |
$this->pushErrorHandling(PEAR_ERROR_RETURN); |
$e = $this->cd($dir); |
$this->popErrorHandling(); |
if ($e === true) { |
$this->cd($savedir); |
return true; |
} |
$this->cd($savedir); |
if ($recursive === false){ |
$res = @ftp_mkdir($this->_handle, $dir); |
if (!$res) { |
return $this->raiseError("Creation of '$dir' failed", NET_FTP_ERR_CREATEDIR_FAILED); |
} else { |
return true; |
} |
} else { |
if(strpos($dir, '/') === false) { |
return $this->mkdir($dir,false); |
} |
$pos = 0; |
$res = $this->mkdir(dirname($dir), true); |
$res = $this->mkdir($dir, false); |
if ($res !== true) { |
return $res; |
} |
return true; |
} |
} |
/** |
* This method tries executing a command on the ftp, using SITE EXEC. |
* |
* @access public |
* @param string $command The command to execute |
* @return mixed The result of the command (if successfull), otherwise PEAR::Error |
* @see NET_FTP_ERR_EXEC_FAILED |
*/ |
function execute($command) |
{ |
$res = @ftp_exec($this->_handle, $command); |
if (!$res) { |
return $this->raiseError("Execution of command '$command' failed.", NET_FTP_ERR_EXEC_FAILED); |
} else { |
return $res; |
} |
} |
/** |
* Execute a SITE command on the server |
* This method tries to execute a SITE command on the ftp server. |
* |
* @access public |
* @param string $command The command with parameters to execute |
* @return mixed True if successful, otherwise PEAR::Error |
* @see NET_FTP_ERR_SITE_FAILED |
*/ |
function site($command) |
{ |
$res = @ftp_site($this->_handle, $command); |
if (!$res) { |
return $this->raiseError("Execution of SITE command '$command' failed.", NET_FTP_ERR_SITE_FAILED); |
} else { |
return $res; |
} |
} |
/** |
* This method will try to chmod the file specified on the server |
* Currently, you must give a number as the the permission argument (777 or |
* similar). The file can be either a relative or absolute path. |
* NOTE: Some servers do not support this feature. In that case, you will |
* get a PEAR error object returned. If successful, the method returns true |
* |
* @access public |
* @param mixed $target The file or array of files to set permissions for |
* @param integer $permissions The mode to set the file permissions to |
* @return mixed True if successful, otherwise PEAR::Error |
* @see NET_FTP_ERR_CHMOD_FAILED |
*/ |
function chmod($target, $permissions) |
{ |
// If $target is an array: Loop through it. |
if (is_array($target)) { |
for ($i = 0; $i < count($target); $i++) { |
$res = $this->chmod($target[$i], $permissions); |
if (PEAR::isError($res)) { |
return $res; |
} // end if isError |
} // end for i < count($target) |
} else { |
$res = $this->site("CHMOD " . $permissions . " " . $target); |
if (!$res) { |
return PEAR::raiseError("CHMOD " . $permissions . " " . $target . " failed", NET_FTP_ERR_CHMOD_FAILED); |
} else { |
return $res; |
} |
} // end if is_array |
} // end method chmod |
/** |
* This method will try to chmod a folder and all of its contents |
* on the server. The target argument must be a folder or an array of folders |
* and the permissions argument have to be an integer (i.e. 777). |
* The file can be either a relative or absolute path. |
* NOTE: Some servers do not support this feature. In that case, you |
* will get a PEAR error object returned. If successful, the method |
* returns true |
* |
* @access public |
* @param mixed $target The folder or array of folders to |
* set permissions for |
* @param integer $permissions The mode to set the folder |
* and file permissions to |
* @return mixed True if successful, otherwise PEAR::Error |
* @see NET_FTP_ERR_CHMOD_FAILED, NET_FTP_ERR_DETERMINEPATH_FAILED, NET_FTP_ERR_RAWDIRLIST_FAILED, NET_FTP_ERR_DIRLIST_UNSUPPORTED |
*/ |
function chmodRecursive($target, $permissions) |
{ |
static $dir_permissions; |
if(!isset($dir_permissions)){ // Making directory specific permissions |
$dir_permissions = $this->_makeDirPermissions($permissions); |
} |
// If $target is an array: Loop through it |
if (is_array($target)) { |
for ($i = 0; $i < count($target); $i++) { |
$res = $this->chmodRecursive($target[$i], $permissions); |
if (PEAR::isError($res)) { |
return $res; |
} // end if isError |
} // end for i < count($target) |
} else { |
$remote_path = $this->_construct_path($target); |
// Chmod the directory itself |
$result = $this->chmod($remote_path, $dir_permissions); |
if (PEAR::isError($result)) { |
return $result; |
} |
// If $remote_path last character is not a slash, add one |
if (substr($remote_path, strlen($remote_path)-1) != "/") { |
$remote_path .= "/"; |
} |
$dir_list = array(); |
$mode = NET_FTP_DIRS_ONLY; |
$dir_list = $this->ls($remote_path, $mode); |
foreach ($dir_list as $dir_entry) { |
if ($dir_entry == '.' || $dir_entry == '..') {; |
continue; |
} |
$remote_path_new = $remote_path.$dir_entry["name"]."/"; |
// Chmod the directory we're about to enter |
$result = $this->chmod($remote_path_new, $dir_permissions); |
if (PEAR::isError($result)) { |
return $result; |
} |
$result = $this->chmodRecursive($remote_path_new, $permissions); |
if (PEAR::isError($result)) { |
return $result; |
} |
} // end foreach dir_list as dir_entry |
$file_list = array(); |
$mode = NET_FTP_FILES_ONLY; |
$file_list = $this->ls($remote_path, $mode); |
foreach ($file_list as $file_entry) { |
$remote_file = $remote_path.$file_entry["name"]; |
$result = $this->chmod($remote_file, $permissions); |
if (PEAR::isError($result)) { |
return $result; |
} |
} // end foreach $file_list |
} // end if is_array |
return true; // No errors |
} // end method chmodRecursive |
/** |
* Rename or move a file or a directory from the ftp-server |
* |
* @access public |
* @param string $remote_from The remote file or directory original to rename or move |
* @param string $remote_to The remote file or directory final to rename or move |
* @return bool $res True on success, otherwise PEAR::Error |
* @see NET_FTP_ERR_RENAME_FAILED |
*/ |
function rename ($remote_from, $remote_to) |
{ |
$res = @ftp_rename($this->_handle, $remote_from, $remote_to); |
if(!$res) { |
return $this->raiseError("Could not rename ".$remote_from." to ".$remote_to." !", NET_FTP_ERR_RENAME_FAILED); |
} |
return true; |
} |
/** |
* This will return logical permissions mask for directory. |
* if directory have to be writeable it have also be executable |
* |
* @access private |
* @param string $permissions File permissions in digits for file (i.e. 666) |
* @return string File permissions in digits for directory (i.e. 777) |
*/ |
function _makeDirPermissions($permissions){ |
$permissions = (string)$permissions; |
for($i = 0; $i < strlen($permissions); $i++){ // going through (user, group, world) |
if((int)$permissions{$i} & 4 and !((int)$permissions{$i} & 1)){ // Read permission is set |
// but execute not yet |
(int)$permissions{$i} = (int)$permissions{$i} + 1; // Adding execute flag |
} |
} |
return (string)$permissions; |
} |
/** |
* This will return the last modification-time of a file. You can either give this |
* function a relative or an absolute path to the file to check. |
* NOTE: Some servers will not support this feature and the function works |
* only on files, not directories! When successful, |
* it will return the last modification-time as a unix-timestamp or, when $format is |
* specified, a preformated timestring. |
* |
* @access public |
* @param string $file The file to check |
* @param string $format (optional) The format to give the date back |
* if not set, it will return a Unix timestamp |
* @return mixed Unix timestamp, a preformated date-string or PEAR::Error |
* @see NET_FTP_ERR_MDTMDIR_UNSUPPORTED, NET_FTP_ERR_MDTM_FAILED, NET_FTP_ERR_DATEFORMAT_FAILED |
*/ |
function mdtm($file, $format = null) |
{ |
$file = $this->_construct_path($file); |
if ($this->_check_dir($file)) { |
return $this->raiseError("Filename '$file' seems to be a directory.", NET_FTP_ERR_MDTMDIR_UNSUPPORTED); |
} |
$res = @ftp_mdtm($this->_handle, $file); |
if ($res == -1) { |
return $this->raiseError("Could not get last-modification-date of '$file'.", NET_FTP_ERR_MDTM_FAILED); |
} |
if (isset($format)) { |
$res = date($format, $res); |
if (!$res) { |
return $this->raiseError("Date-format failed on timestamp '$res'.", NET_FTP_ERR_DATEFORMAT_FAILED); |
} |
} |
return $res; |
} |
/** |
* This will return the size of a given file in bytes. You can either give this function |
* a relative or an absolute file-path. NOTE: Some servers do not support this feature! |
* |
* @access public |
* @param string $file The file to check |
* @return mixed Size in bytes or PEAR::Error |
* @see NET_FTP_ERR_SIZE_FAILED |
*/ |
function size($file) |
{ |
$file = $this->_construct_path($file); |
$res = @ftp_size($this->_handle, $file); |
if ($res == -1) { |
return $this->raiseError("Could not determine filesize of '$file'.", NET_FTP_ERR_SIZE_FAILED); |
} else { |
return $res; |
} |
} |
/** |
* This method returns a directory-list of the current directory or given one. |
* To display the current selected directory, simply set the first parameter to null |
* or leave it blank, if you do not want to use any other parameters. |
* <BR><BR> |
* There are 4 different modes of listing directories. Either to list only |
* the files (using NET_FTP_FILES_ONLY), to list only directories (using |
* NET_FTP_DIRS_ONLY) or to show both (using NET_FTP_DIRS_FILES, which is default). |
* <BR><BR> |
* The 4th one is the NET_FTP_RAWLIST, which returns just the array created by the |
* ftp_rawlist()-function build into PHP. |
* <BR><BR> |
* The other function-modes will return an array containing the requested data. |
* The files and dirs are listed in human-sorted order, but if you select |
* NET_FTP_DIRS_FILES the directories will be added above the files, |
* but although both sorted. |
* <BR><BR> |
* All elements in the arrays are associative arrays themselves. The have the following |
* structure: |
* <BR><BR> |
* Dirs:<BR> |
* ["name"] => string The name of the directory<BR> |
* ["rights"] => string The rights of the directory (in style "rwxr-xr-x")<BR> |
* ["user"] => string The owner of the directory<BR> |
* ["group"] => string The group-owner of the directory<BR> |
* ["files_inside"]=> string The number of files/dirs inside the directory |
* excluding "." and ".."<BR> |
* ["date"] => int The creation-date as Unix timestamp<BR> |
* ["is_dir"] => bool true, cause this is a dir<BR> |
* <BR><BR> |
* Files:<BR> |
* ["name"] => string The name of the file<BR> |
* ["size"] => int Size in bytes<BR> |
* ["rights"] => string The rights of the file (in style "rwxr-xr-x")<BR> |
* ["user"] => string The owner of the file<BR> |
* ["group"] => string The group-owner of the file<BR> |
* ["date"] => int The creation-date as Unix timestamp<BR> |
* ["is_dir"] => bool false, cause this is a file<BR> |
* |
* @access public |
* @param string $dir (optional) The directory to list or null, when listing the current directory. |
* @param int $mode (optional) The mode which types to list (files, directories or both). |
* @return mixed The directory list as described above or PEAR::Error on failure. |
* @see NET_FTP_DIRS_FILES, NET_FTP_DIRS_ONLY, NET_FTP_FILES_ONLY, NET_FTP_RAWLIST, NET_FTP_ERR_DETERMINEPATH_FAILED, NET_FTP_ERR_RAWDIRLIST_FAILED, NET_FTP_ERR_DIRLIST_UNSUPPORTED |
*/ |
function ls($dir = null, $mode = NET_FTP_DIRS_FILES) |
{ |
if (!isset($dir)) { |
$dir = @ftp_pwd($this->_handle); |
if (!$dir) { |
return $this->raiseError("Could not retrieve current directory", NET_FTP_ERR_DETERMINEPATH_FAILED); |
} |
} |
if (($mode != NET_FTP_FILES_ONLY) && ($mode != NET_FTP_DIRS_ONLY) && ($mode != NET_FTP_RAWLIST)) { |
$mode = NET_FTP_DIRS_FILES; |
} |
switch ($mode) { |
case NET_FTP_DIRS_FILES: $res = $this->_ls_both ( $dir ); |
break; |
case NET_FTP_DIRS_ONLY: $res = $this->_ls_dirs ( $dir ); |
break; |
case NET_FTP_FILES_ONLY: $res = $this->_ls_files ( $dir ); |
break; |
case NET_FTP_RAWLIST: $res = @ftp_rawlist($this->_handle, $dir); |
break; |
} |
return $res; |
} |
/** |
* This method will delete the given file or directory ($path) from the server |
* (maybe recursive). |
* |
* Whether the given string is a file or directory is only determined by the last |
* sign inside the string ("/" or not). |
* |
* If you specify a directory, you can optionally specify $recursive as true, |
* to let the directory be deleted recursive (with all sub-directories and files |
* inherited). |
* |
* You can either give a absolute or relative path for the file / dir. If you choose to |
* use the relative path, it will be automatically completed with the actual |
* selected directory. |
* |
* @access public |
* @param string $path The absolute or relative path to the file / directory. |
* @param bool $recursive (optional) |
* @return mixed True on success, otherwise PEAR::Error |
* @see NET_FTP_ERR_DELETEFILE_FAILED, NET_FTP_ERR_DELETEDIR_FAILED, NET_FTP_ERR_REMOTEPATHNODIR |
*/ |
function rm($path, $recursive = false) |
{ |
$path = $this->_construct_path($path); |
if ($this->_check_dir($path)) { |
if ($recursive) { |
return $this->_rm_dir_recursive($path); |
} else { |
return $this->_rm_dir($path); |
} |
} else { |
return $this->_rm_file($path); |
} |
} |
/** |
* This function will download a file from the ftp-server. You can either spcify a absolute |
* path to the file (beginning with "/") or a relative one, which will be completed |
* with the actual directory you selected on the server. You can specify |
* the path to which the file will be downloaded on the local |
* maschine, if the file should be overwritten if it exists (optionally, default is |
* no overwriting) and in which mode (FTP_ASCII or FTP_BINARY) the file should be |
* downloaded (if you do not specify this, the method tries to determine it automatically |
* from the mode-directory or uses the default-mode, set by you). If you give a relative |
* path to the local-file, the script-path is used as basepath. |
* |
* @access public |
* @param string $remote_file The absolute or relative path to the file to download |
* @param string $local_file The local file to put the downloaded in |
* @param bool $overwrite (optional) Whether to overwrite existing file |
* @param int $mode (optional) Either FTP_ASCII or FTP_BINARY |
* @return mixed True on success, otherwise PEAR::Error |
* @see NET_FTP_ERR_OVERWRITELOCALFILE_FORBIDDEN, NET_FTP_ERR_OVERWRITELOCALFILE_FAILED, NET_FTP_ERR_OVERWRITELOCALFILE_FAILED |
*/ |
function get($remote_file, $local_file, $overwrite = false, $mode = null) |
{ |
if (!isset($mode)) { |
$mode = $this->checkFileExtension($remote_file); |
} |
$remote_file = $this->_construct_path($remote_file); |
if (@file_exists($local_file) && !$overwrite) { |
return $this->raiseError("Local file '$local_file' exists and may not be overwriten.", NET_FTP_ERR_OVERWRITELOCALFILE_FORBIDDEN); |
} |
if (@file_exists($local_file) && !@is_writeable($local_file) && $overwrite) { |
return $this->raiseError("Local file '$local_file' is not writeable. Can not overwrite.", NET_FTP_ERR_OVERWRITELOCALFILE_FAILED); |
} |
if (@function_exists('ftp_nb_get')){ |
$res = @ftp_nb_get($this->_handle, $local_file, $remote_file, $mode); |
while ($res == FTP_MOREDATA) { |
$this->_announce('nb_get'); |
$res = @ftp_nb_continue ($this->_handle); |
} |
} else { |
$res = @ftp_get($this->_handle, $local_file, $remote_file, $mode); |
} |
if (!$res) { |
return $this->raiseError("File '$remote_file' could not be downloaded to '$local_file'.", NET_FTP_ERR_OVERWRITELOCALFILE_FAILED); |
} else { |
return true; |
} |
} |
/** |
* This function will upload a file to the ftp-server. You can either specify a absolute |
* path to the remote-file (beginning with "/") or a relative one, which will be completed |
* with the actual directory you selected on the server. You can specify |
* the path from which the file will be uploaded on the local |
* maschine, if the file should be overwritten if it exists (optionally, default is |
* no overwriting) and in which mode (FTP_ASCII or FTP_BINARY) the file should be |
* downloaded (if you do not specify this, the method tries to determine it automatically |
* from the mode-directory or uses the default-mode, set by you). If you give a relative |
* path to the local-file, the script-path is used as basepath. |
* |
* @access public |
* @param string $local_file The local file to upload |
* @param string $remote_file The absolute or relative path to the file to upload to |
* @param bool $overwrite (optional) Whether to overwrite existing file |
* @param int $mode (optional) Either FTP_ASCII or FTP_BINARY |
* @return mixed True on success, otherwise PEAR::Error |
* @see NET_FTP_ERR_LOCALFILENOTEXIST, NET_FTP_ERR_OVERWRITEREMOTEFILE_FORBIDDEN, NET_FTP_ERR_UPLOADFILE_FAILED |
*/ |
function put($local_file, $remote_file, $overwrite = false, $mode = null) |
{ |
if (!isset($mode)) { |
$mode = $this->checkFileExtension($local_file); |
} |
$remote_file = $this->_construct_path($remote_file); |
if (!@file_exists($local_file)) { |
return $this->raiseError("Local file '$local_file' does not exist.", NET_FTP_ERR_LOCALFILENOTEXIST); |
} |
if ((@ftp_size($this->_handle, $remote_file) != -1) && !$overwrite) { |
return $this->raiseError("Remote file '$remote_file' exists and may not be overwriten.", NET_FTP_ERR_OVERWRITEREMOTEFILE_FORBIDDEN); |
} |
if (function_exists('ftp_nb_put')){ |
$res = @ftp_nb_put($this->_handle, $remote_file, $local_file, $mode); |
while ($res == FTP_MOREDATA) { |
$this->_announce('nb_put'); |
$res = @ftp_nb_continue($this->_handle); |
} |
} else { |
$res = @ftp_put($this->_handle, $remote_file, $local_file, $mode); |
} |
if (!$res) { |
return $this->raiseError("File '$local_file' could not be uploaded to '$remote_file'.", NET_FTP_ERR_UPLOADFILE_FAILED); |
} else { |
return true; |
} |
} |
/** |
* This functionality allows you to transfer a whole directory-structure from the |
* remote-ftp to your local host. You have to give a remote-directory (ending with |
* '/') and the local directory (ending with '/') where to put the files you download. |
* The remote path is automatically completed with the current-remote-dir, if you give |
* a relative path to this function. You can give a relative path for the $local_path, |
* too. Then the script-basedir will be used for comletion of the path. |
* The parameter $overwrite will determine, whether to overwrite existing files or not. |
* Standard for this is false. Fourth you can explicitly set a mode for all transfer- |
* actions done. If you do not set this, the method tries to determine the transfer- |
* mode by checking your mode-directory for the file-extension. If the extension is not |
* inside the mode-directory, it will get your default-mode. |
* |
* @access public |
* @param string $remote_path The path to download |
* @param string $local_path The path to download to |
* @param bool $overwrite (optional) Whether to overwrite existing files (true) or not (false, standard). |
* @param int $mode (optional) The transfermode (either FTP_ASCII or FTP_BINARY). |
* @return mixed True on succes, otherwise PEAR::Error |
* @see NET_FTP_ERR_OVERWRITELOCALFILE_FORBIDDEN, NET_FTP_ERR_OVERWRITELOCALFILE_FAILED, NET_FTP_ERR_OVERWRITELOCALFILE_FAILED, NET_FTP_ERR_REMOTEPATHNODIR, NET_FTP_ERR_LOCALPATHNODIR,NET_FTP_ERR_CREATELOCALDIR_FAILED |
*/ |
function getRecursive($remote_path, $local_path, $overwrite = false, $mode = null) |
{ |
$remote_path = $this->_construct_path($remote_path); |
if (!$this->_check_dir($remote_path)) { |
return $this->raiseError("Given remote-path '$remote_path' seems not to be a directory.", NET_FTP_ERR_REMOTEPATHNODIR); |
} |
if (!$this->_check_dir($local_path)) { |
return $this->raiseError("Given local-path '$local_path' seems not to be a directory.", NET_FTP_ERR_LOCALPATHNODIR); |
} |
if (!@is_dir($local_path)) { |
$res = @mkdir($local_path); |
if (!$res) { |
return $this->raiseError("Could not create dir '$local_path'", NET_FTP_ERR_CREATELOCALDIR_FAILED); |
} |
} |
$dir_list = array(); |
$dir_list = $this->ls($remote_path, NET_FTP_DIRS_ONLY); |
foreach ($dir_list as $dir_entry) { |
if ($dir_entry['name'] != '.' && $dir_entry['name'] != '..') { |
$remote_path_new = $remote_path.$dir_entry["name"]."/"; |
$local_path_new = $local_path.$dir_entry["name"]."/"; |
$result = $this->getRecursive($remote_path_new, $local_path_new, $overwrite, $mode); |
if ($this->isError($result)) { |
return $result; |
} |
} |
} |
$file_list = array(); |
$file_list = $this->ls($remote_path, NET_FTP_FILES_ONLY); |
foreach ($file_list as $file_entry) { |
$remote_file = $remote_path.$file_entry["name"]; |
$local_file = $local_path.$file_entry["name"]; |
$result = $this->get($remote_file, $local_file, $overwrite, $mode); |
if ($this->isError($result)) { |
return $result; |
} |
} |
return true; |
} |
/** |
* This functionality allows you to transfer a whole directory-structure from your |
* local host to the remote-ftp. You have to give a remote-directory (ending with |
* '/') and the local directory (ending with '/') where to put the files you download. |
* The remote path is automatically completed with the current-remote-dir, if you give |
* a relative path to this function. You can give a relative path for the $local_path, |
* too. Then the script-basedir will be used for comletion of the path. |
* The parameter $overwrite will determine, whether to overwrite existing files or not. |
* Standard for this is false. Fourth you can explicitly set a mode for all transfer- |
* actions done. If you do not set this, the method tries to determine the transfer- |
* mode by checking your mode-directory for the file-extension. If the extension is not |
* inside the mode-directory, it will get your default-mode. |
* |
* @access public |
* @param string $remote_path The path to download |
* @param string $local_path The path to download to |
* @param bool $overwrite (optional) Whether to overwrite existing files (true) or not (false, standard). |
* @param int $mode (optional) The transfermode (either FTP_ASCII or FTP_BINARY). |
* @return mixed True on succes, otherwise PEAR::Error |
* @see NET_FTP_ERR_LOCALFILENOTEXIST, NET_FTP_ERR_OVERWRITEREMOTEFILE_FORBIDDEN, NET_FTP_ERR_UPLOADFILE_FAILED, NET_FTP_ERR_LOCALPATHNODIR, NET_FTP_ERR_REMOTEPATHNODIR |
*/ |
function putRecursive($local_path, $remote_path, $overwrite = false, $mode = null) |
{ |
$remote_path = $this->_construct_path($remote_path); |
if (!$this->_check_dir($local_path) || !is_dir($local_path)) { |
return $this->raiseError("Given local-path '$local_path' seems not to be a directory.", NET_FTP_ERR_LOCALPATHNODIR); |
} |
if (!$this->_check_dir($remote_path)) { |
return $this->raiseError("Given remote-path '$remote_path' seems not to be a directory.", NET_FTP_ERR_REMOTEPATHNODIR); |
} |
$old_path = $this->pwd(); |
if ($this->isError($this->cd($remote_path))) { |
$res = $this->mkdir($remote_path); |
if ($this->isError($res)) { |
return $res; |
} |
} |
$this->cd($old_path); |
$dir_list = $this->_ls_local($local_path); |
foreach ($dir_list["dirs"] as $dir_entry) { |
$remote_path_new = $remote_path.$dir_entry."/"; |
$local_path_new = $local_path.$dir_entry."/"; |
$result = $this->putRecursive($local_path_new, $remote_path_new, $overwrite, $mode); |
if ($this->isError($result)) { |
return $result; |
} |
} |
foreach ($dir_list["files"] as $file_entry) { |
$remote_file = $remote_path.$file_entry; |
$local_file = $local_path.$file_entry; |
$result = $this->put($local_file, $remote_file, $overwrite, $mode); |
if ($this->isError($result)) { |
return $result; |
} |
} |
return true; |
} |
/** |
* This checks, whether a file should be transfered in ascii- or binary-mode |
* by it's file-extension. If the file-extension is not set or |
* the extension is not inside one of the extension-dirs, the actual set |
* transfer-mode is returned. |
* |
* @access public |
* @param string $filename The filename to be checked |
* @return int Either FTP_ASCII or FTP_BINARY |
*/ |
function checkFileExtension($filename) |
{ |
$pattern = "/\.(.*)$/"; |
$has_extension = preg_match($pattern, $filename, $eregs); |
if (!$has_extension) { |
return $this->_mode; |
} else { |
$ext = $eregs[1]; |
} |
if (!empty($this->_file_extensions[$ext])) { |
return $this->_file_extensions[$ext]; |
} |
return $this->_mode; |
} |
/** |
* Set the Hostname |
* |
* @access public |
* @param string $host The Hostname to set |
* @return bool True on success, otherwise PEAR::Error |
* @see NET_FTP_ERR_HOSTNAMENOSTRING |
*/ |
function setHostname($host) |
{ |
if (!is_string($host)) { |
return PEAR::raiseError("Hostname must be a string.", NET_FTP_ERR_HOSTNAMENOSTRING); |
} |
$this->_hostname = $host; |
return true; |
} |
/** |
* Set the Port |
* |
* @access public |
* @param int $port The Port to set |
* @return bool True on success, otherwise PEAR::Error |
* @see NET_FTP_ERR_PORTLESSZERO |
*/ |
function setPort($port) |
{ |
if (!is_int($port) || ($port < 0)) { |
PEAR::raiseError("Invalid port. Has to be integer >= 0", NET_FTP_ERR_PORTLESSZERO); |
} |
$this->_port = $port; |
return true; |
} |
/** |
* Set the Username |
* |
* @access public |
* @param string $user The Username to set |
* @return mixed True on success, otherwise PEAR::Error |
* @see NET_FTP_ERR_USERNAMENOSTRING |
*/ |
function setUsername($user) |
{ |
if (empty($user) || !is_string($user)) { |
return PEAR::raiseError('Username $user invalid.', NET_FTP_ERR_USERNAMENOSTRING); |
} |
$this->_username = $user; |
} |
/** |
* Set the Password |
* |
* @access private |
* @param string $password The Password to set |
* @return void |
* @see NET_FTP_ERR_PASSWORDNOSTRING |
*/ |
function setPassword($password) |
{ |
if (empty($password) || !is_string($password)) { |
return PEAR::raiseError('Password xxx invalid.', NET_FTP_ERR_PASSWORDNOSTRING); |
} |
$this->_password = $password; |
} |
/** |
* Set the transfer-mode. You can use the predefined constants |
* FTP_ASCII or FTP_BINARY. The mode will be stored for any further transfers. |
* |
* @access public |
* @param int $mode The mode to set |
* @return mixed True on success, otherwise PEAR::Error |
* @see NET_FTP_ERR_NOMODECONST |
*/ |
function setMode($mode) |
{ |
if (($mode == FTP_ASCII) || ($mode == FTP_BINARY)) { |
$this->_mode = $mode; |
return true; |
} else { |
return $this->raiseError('FTP-Mode has either to be FTP_ASCII or FTP_BINARY', NET_FTP_ERR_NOMODECONST); |
} |
} |
/** |
* Set the transfer-method to passive mode |
* |
* @access public |
* @return void |
*/ |
function setPassive() |
{ |
$this->_passv = true; |
@ftp_pasv($this->_handle, true); |
} |
/** |
* Set the transfer-method to active mode |
* |
* @access public |
* @return void |
*/ |
function setActive() |
{ |
$this->_passv = false; |
@ftp_pasv($this->_handle, false); |
} |
/** |
* Set the timeout for FTP operations |
* Use this method to set a timeout for FTP operation. Timeout has to be an integer. |
* |
* @acess public |
* @param int $timeout the timeout to use |
* @return bool True on success, otherwise PEAR::Error |
* @see NET_FTP_ERR_TIMEOUTLESSZERO, NET_FTP_ERR_SETTIMEOUT_FAILED |
*/ |
function setTimeout ( $timeout = 0 ) |
{ |
if (!is_int($timeout) || ($timeout < 0)) { |
return PEAR::raiseError("Timeout $timeout is invalid, has to be an integer >= 0", NET_FTP_ERR_TIMEOUTLESSZERO); |
} |
$this->_timeout = $timeout; |
if (isset($this->_handle) && is_resource($this->_handle)) { |
$res = @ftp_set_option($this->_handle, FTP_TIMEOUT_SEC, $timeout); |
} else { |
$res = true; |
} |
if (!$res) { |
return PEAR::raiseError("Set timeout failed.", NET_FTP_ERR_SETTIMEOUT_FAILED); |
} |
return true; |
} |
/** |
* Adds an extension to a mode-directory |
* The mode-directory saves file-extensions coresponding to filetypes |
* (ascii e.g.: 'php', 'txt', 'htm',...; binary e.g.: 'jpg', 'gif', 'exe',...). |
* The extensions have to be saved without the '.'. And |
* can be predefined in an external file (see: getExtensionsFile()). |
* |
* The array is build like this: 'php' => FTP_ASCII, 'png' => FTP_BINARY |
* |
* To change the mode of an extension, just add it again with the new mode! |
* |
* @access public |
* @param int $mode Either FTP_ASCII or FTP_BINARY |
* @param string $ext Extension |
* @return void |
*/ |
function addExtension($mode, $ext) |
{ |
$this->_file_extensions[$ext] = $mode; |
} |
/** |
* This function removes an extension from the mode-directories |
* (described above). |
* |
* @access public |
* @param string $ext The extension to remove |
* @return void |
*/ |
function removeExtension($ext) |
{ |
unset($this->_file_extensions[$ext]); |
} |
/** |
* This get's both (ascii- and binary-mode-directories) from the given file. |
* Beware, if you read a file into the mode-directory, all former set values |
* will be unset! |
* |
* @access public |
* @param string $filename The file to get from |
* @return mixed True on success, otherwise PEAR::Error |
* @see NET_FTP_ERR_EXTFILENOTEXIST, NET_FTP_ERR_EXTFILEREAD_FAILED |
*/ |
function getExtensionsFile($filename) |
{ |
if (!file_exists($filename)) { |
return $this->raiseError("Extensions-file '$filename' does not exist", NET_FTP_ERR_EXTFILENOTEXIST); |
} |
if (!is_readable($filename)) { |
return $this->raiseError("Extensions-file '$filename' is not readable", NET_FTP_ERR_EXTFILEREAD_FAILED); |
} |
$this->_file_extension = @parse_ini_file($filename); |
return true; |
} |
/** |
* Returns the Hostname |
* |
* @access public |
* @return string The Hostname |
*/ |
function getHostname() |
{ |
return $this->_hostname; |
} |
/** |
* Returns the Port |
* |
* @access public |
* @return int The Port |
*/ |
function getPort() |
{ |
return $this->_port; |
} |
/** |
* Returns the Username |
* |
* @access public |
* @return string The Username |
*/ |
function getUsername() |
{ |
return $this->_username; |
} |
/** |
* Returns the Password |
* |
* @access public |
* @return string The Password |
*/ |
function getPassword() |
{ |
return $this->_password; |
} |
/** |
* Returns the Transfermode |
* |
* @access public |
* @return int The transfermode, either FTP_ASCII or FTP_BINARY. |
*/ |
function getMode() |
{ |
return $this->_mode; |
} |
/** |
* Returns, whether the connection is set to passive mode or not |
* |
* @access public |
* @return bool True if passive-, false if active-mode |
*/ |
function isPassive() |
{ |
return $this->_passv; |
} |
/** |
* Returns the mode set for a file-extension |
* |
* @access public |
* @param string $ext The extension you wanna ask for |
* @return int Either FTP_ASCII, FTP_BINARY or NULL (if not set a mode for it) |
*/ |
function getExtensionMode($ext) |
{ |
return @$this->_file_extensions[$ext]; |
} |
/** |
* Get the currently set timeout. |
* Returns the actual timeout set. |
* |
* @access public |
* @return int The actual timeout |
*/ |
function getTimeout ( ) |
{ |
return ftp_get_option($this->_handle, FTP_TIMEOUT_SEC); |
} |
/** |
* Adds a Net_FTP_Observer instance to the list of observers |
* that are listening for messages emitted by this Net_FTP instance. |
* |
* @param object $observer The Net_FTP_Observer instance to attach |
* as a listener. |
* @return boolean True if the observer is successfully attached. |
* @access public |
* @since 1.3 |
*/ |
function attach(&$observer) |
{ |
if (!is_a($observer, 'Net_FTP_Observer')) { |
return false; |
} |
$this->_listeners[$observer->getId()] = &$observer; |
return true; |
} |
/** |
* Removes a Net_FTP_Observer instance from the list of observers. |
* |
* @param object $observer The Net_FTP_Observer instance to detach |
* from the list of listeners. |
* @return boolean True if the observer is successfully detached. |
* @access public |
* @since 1.3 |
*/ |
function detach($observer) |
{ |
if (!is_a($observer, 'Net_FTP_Observer') || |
!isset($this->_listeners[$observer->getId()])) { |
return false; |
} |
unset($this->_listeners[$observer->getId()]); |
return true; |
} |
/** |
* Informs each registered observer instance that a new message has been |
* sent. |
* |
* @param mixed $event A hash describing the net event. |
* @access private |
* @since 1.3 |
*/ |
function _announce($event) |
{ |
foreach ($this->_listeners as $id => $listener) { |
$this->_listeners[$id]->notify($event); |
} |
} |
/** |
* Rebuild the path, if given relative |
* |
* @access private |
* @param string $path The path to check and construct |
* @return string The build path |
*/ |
function _construct_path($path) |
{ |
if ((substr($path, 0, 1) != "/") && (substr($path, 0, 2) != "./")) { |
$actual_dir = @ftp_pwd($this->_handle); |
if (substr($actual_dir, (strlen($actual_dir) - 2), 1) != "/") { |
$actual_dir .= "/"; |
} |
$path = $actual_dir.$path; |
} |
return $path; |
} |
/** |
* Checks, whether a given string is a directory-path (ends with "/") or not. |
* |
* @access private |
* @param string $path Path to check |
* @return bool True if $path is a directory, otherwise false |
*/ |
function _check_dir($path) |
{ |
if (!empty($path) && substr($path, (strlen($path) - 1), 1) == "/") { |
return true; |
} else { |
return false; |
} |
} |
/** |
* This will remove a file |
* |
* @access private |
* @param string $file The file to delete |
* @return mixed True on success, otherwise PEAR::Error |
* @see NET_FTP_ERR_DELETEFILE_FAILED |
*/ |
function _rm_file($file) |
{ |
if (substr($file, 0, 1) != "/") { |
$actual_dir = @ftp_pwd($this->_handle); |
if (substr($actual_dir, (strlen($actual_dir) - 2), 1) != "/") { |
$actual_dir .= "/"; |
} |
$file = $actual_dir.$file; |
} |
$res = @ftp_delete($this->_handle, $file); |
if (!$res) { |
return $this->raiseError("Could not delete file '$file'.", NET_FTP_ERR_DELETEFILE_FAILED); |
} else { |
return true; |
} |
} |
/** |
* This will remove a dir |
* |
* @access private |
* @param string $dir The dir to delete |
* @return mixed True on success, otherwise PEAR::Error |
* @see NET_FTP_ERR_REMOTEPATHNODIR, NET_FTP_ERR_DELETEDIR_FAILED |
*/ |
function _rm_dir($dir) |
{ |
if (substr($dir, (strlen($dir) - 1), 1) != "/") { |
return $this->raiseError("Directory name '$dir' is invalid, has to end with '/'", NET_FTP_ERR_REMOTEPATHNODIR); |
} |
$res = @ftp_rmdir($this->_handle, $dir); |
if (!$res) { |
return $this->raiseError("Could not delete directory '$dir'.", NET_FTP_ERR_DELETEDIR_FAILED); |
} else { |
return true; |
} |
} |
/** |
* This will remove a dir and all subdirs and -files |
* |
* @access private |
* @param string $file The dir to delete recursively |
* @return mixed True on success, otherwise PEAR::Error |
* @see NET_FTP_ERR_REMOTEPATHNODIR, NET_FTP_ERR_DELETEDIR_FAILED |
*/ |
function _rm_dir_recursive($dir) |
{ |
if (substr($dir, (strlen($dir) - 1), 1) != "/") { |
return $this->raiseError("Directory name '$dir' is invalid, has to end with '/'", NET_FTP_ERR_REMOTEPATHNODIR); |
} |
$file_list = $this->_ls_files($dir); |
foreach ($file_list as $file) { |
$file = $dir.$file["name"]; |
$res = $this->rm($file); |
if ($this->isError($res)) { |
return $res; |
} |
} |
$dir_list = $this->_ls_dirs($dir); |
foreach ($dir_list as $new_dir) { |
if ($new_dir == '.' || $new_dir == '..') { |
continue; |
} |
$new_dir = $dir.$new_dir["name"]."/"; |
$res = $this->_rm_dir_recursive($new_dir); |
if ($this->isError($res)) { |
return $res; |
} |
} |
$res = $this->_rm_dir($dir); |
if (PEAR::isError($res)) { |
return $res; |
} else { |
return true; |
} |
} |
/** |
* Lists up files and directories |
* |
* @access private |
* @param string $dir The directory to list up |
* @return array An array of dirs and files |
*/ |
function _ls_both($dir) |
{ |
$list_splitted = $this->_list_and_parse($dir); |
if (PEAR::isError($list_splitted)) { |
return $list_splitted; |
} |
if (!is_array($list_splitted["files"])) { |
$list_splitted["files"] = array(); |
} |
if (!is_array($list_splitted["dirs"])) { |
$list_splitted["dirs"] = array(); |
} |
$res = array(); |
@array_splice($res, 0, 0, $list_splitted["files"]); |
@array_splice($res, 0, 0, $list_splitted["dirs"]); |
return $res; |
} |
/** |
* Lists up directories |
* |
* @access private |
* @param string $dir The directory to list up |
* @return array An array of dirs |
*/ |
function _ls_dirs($dir) |
{ |
$list = $this->_list_and_parse($dir); |
if (PEAR::isError($list)) { |
return $list; |
} |
return $list["dirs"]; |
} |
/** |
* Lists up files |
* |
* @access private |
* @param string $dir The directory to list up |
* @return array An array of files |
*/ |
function _ls_files($dir) |
{ |
$list = $this->_list_and_parse($dir); |
if (PEAR::isError($list)) { |
return $list; |
} |
return $list["files"]; |
} |
/** |
* This lists up the directory-content and parses the items into well-formated arrays |
* The results of this array are sorted (dirs on top, sorted by name; |
* files below, sorted by name). |
* |
* @access private |
* @param string $dir The directory to parse |
* @return array Lists of dirs and files |
* @see NET_FTP_ERR_RAWDIRLIST_FAILED |
*/ |
function _list_and_parse($dir) |
{ |
$dirs_list = array(); |
$files_list = array(); |
$dir_list = @ftp_rawlist($this->_handle, $dir); |
if (!is_array($dir_list)) { |
return PEAR::raiseError('Could not get raw directory listing.', NET_FTP_ERR_RAWDIRLIST_FAILED); |
} |
// Handle empty directories |
if (count($dir_list) == 0) { |
return array('dirs' => $dirs_list, 'files' => $files_list); |
} |
// Exception for some FTP servers seem to return this wiered result instead of an empty list |
if (count($dirs_list) == 1 && $dirs_list[0] == 'total 0') { |
return array('dirs' => array(), 'files' => $files_list); |
} |
if (!isset($this->_matcher) || PEAR::isError($this->_matcher)) { |
$this->_matcher = $this->_determine_os_match($dir_list); |
if (PEAR::isError($this->_matcher)) { |
return $this->_matcher; |
} |
} |
foreach ($dir_list as $entry) { |
if (!preg_match($this->_matcher['pattern'], $entry, $m)) { |
continue; |
} |
$entry = array(); |
foreach ($this->_matcher['map'] as $key=>$val) { |
$entry[$key] = $m[$val]; |
} |
$entry['stamp'] = $this->_parse_Date($entry['date']); |
if ($entry['is_dir']) { |
$dirs_list[] = $entry; |
} else { |
$files_list[] = $entry; |
} |
} |
@usort($dirs_list, array("Net_FTP", "_nat_sort")); |
@usort($files_list, array("Net_FTP", "_nat_sort")); |
$res["dirs"] = (is_array($dirs_list)) ? $dirs_list : array(); |
$res["files"] = (is_array($files_list)) ? $files_list : array(); |
return $res; |
} |
/** |
* Determine server OS |
* This determines the server OS and returns a valid regex to parse |
* ls() output. |
* |
* @access private |
* @param array $dir_list The raw dir list to parse |
* @return mixed An array of 'pattern' and 'map' on success, otherwise PEAR::Error |
* @see NET_FTP_ERR_DIRLIST_UNSUPPORTED |
*/ |
function _determine_os_match(&$dir_list) { |
foreach ($dir_list as $entry) { |
foreach ($this->_ls_match as $os => $match) { |
if (preg_match($match['pattern'], $entry)) { |
return $match; |
} |
} |
} |
$error = 'The list style of your server seems not to be supported. Please email a "$ftp->ls(NET_FTP_RAWLIST);" output plus info on the server to the maintainer of this package to get it supported! Thanks for your help!'; |
return PEAR::raiseError($error, NET_FTP_ERR_DIRLIST_UNSUPPORTED); |
} |
/** |
* Lists a local directory |
* |
* @access private |
* @param string $dir_path The dir to list |
* @return array The list of dirs and files |
*/ |
function _ls_local($dir_path) |
{ |
$dir = dir($dir_path); |
$dir_list = array(); |
$file_list = array(); |
while (false !== ($entry = $dir->read())) { |
if (($entry != '.') && ($entry != '..')) { |
if (is_dir($dir_path.$entry)) { |
$dir_list[] = $entry; |
} else { |
$file_list[] = $entry; |
} |
} |
} |
$dir->close(); |
$res['dirs'] = $dir_list; |
$res['files'] = $file_list; |
return $res; |
} |
/** |
* Function for use with usort(). |
* Compares the list-array-elements by name. |
* |
* @access private |
*/ |
function _nat_sort($item_1, $item_2) |
{ |
return strnatcmp($item_1['name'], $item_2['name']); |
} |
/** |
* Parse dates to timestamps |
* |
* @access private |
* @param string $date Date |
* @return int Timestamp |
* @see NET_FTP_ERR_DATEFORMAT_FAILED |
*/ |
function _parse_Date($date) |
{ |
// Sep 10 22:06 => Sep 10, <year> 22:06 |
if (preg_match('/([A-Za-z]+)[ ]+([0-9]+)[ ]+([0-9]+):([0-9]+)/', $date, $res)) { |
$year = date('Y'); |
$month = $res[1]; |
$day = $res[2]; |
$hour = $res[3]; |
$minute = $res[4]; |
$date = "$month $day, $year $hour:$minute"; |
$tmpDate = strtotime($date); |
if ($tmpDate > time()) { |
$year--; |
$date = "$month $day, $year $hour:$minute"; |
} |
} |
// 09-10-04 => 09/10/04 |
elseif (preg_match('/^\d\d-\d\d-\d\d/',$date)) { |
$date = str_replace('-','/',$date); |
} |
$res = strtotime($date); |
if (!$res) { |
return $this->raiseError('Dateconversion failed.', NET_FTP_ERR_DATEFORMAT_FAILED); |
} |
return $res; |
} |
} |
?> |
/branches/livraison_menes/api/pear/Net/URL.php |
---|
New file |
0,0 → 1,411 |
<?php |
// +-----------------------------------------------------------------------+ |
// | Copyright (c) 2002-2004, Richard Heyes | |
// | All rights reserved. | |
// | | |
// | Redistribution and use in source and binary forms, with or without | |
// | modification, are permitted provided that the following conditions | |
// | are met: | |
// | | |
// | o Redistributions of source code must retain the above copyright | |
// | notice, this list of conditions and the following disclaimer. | |
// | o 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.| |
// | o The names of the authors may not be used to endorse or promote | |
// | products derived from this software without specific prior written | |
// | permission. | |
// | | |
// | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS | |
// | "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT | |
// | LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR | |
// | A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT | |
// | OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, | |
// | SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT | |
// | LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, | |
// | DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY | |
// | THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | |
// | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE | |
// | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | |
// | | |
// +-----------------------------------------------------------------------+ |
// | Author: Richard Heyes <richard at php net> | |
// +-----------------------------------------------------------------------+ |
// |
// $Id: URL.php,v 1.2 2006-03-13 21:00:48 ddelon Exp $ |
// |
// Net_URL Class |
class Net_URL |
{ |
/** |
* Full url |
* @var string |
*/ |
var $url; |
/** |
* Protocol |
* @var string |
*/ |
var $protocol; |
/** |
* Username |
* @var string |
*/ |
var $username; |
/** |
* Password |
* @var string |
*/ |
var $password; |
/** |
* Host |
* @var string |
*/ |
var $host; |
/** |
* Port |
* @var integer |
*/ |
var $port; |
/** |
* Path |
* @var string |
*/ |
var $path; |
/** |
* Query string |
* @var array |
*/ |
var $querystring; |
/** |
* Anchor |
* @var string |
*/ |
var $anchor; |
/** |
* Whether to use [] |
* @var bool |
*/ |
var $useBrackets; |
/** |
* PHP4 Constructor |
* |
* @see __construct() |
*/ |
function Net_URL($url = null, $useBrackets = true) |
{ |
$this->__construct($url, $useBrackets); |
} |
/** |
* PHP5 Constructor |
* |
* Parses the given url and stores the various parts |
* Defaults are used in certain cases |
* |
* @param string $url Optional URL |
* @param bool $useBrackets Whether to use square brackets when |
* multiple querystrings with the same name |
* exist |
*/ |
function __construct($url = null, $useBrackets = true) |
{ |
$HTTP_SERVER_VARS = !empty($_SERVER) ? $_SERVER : $GLOBALS['HTTP_SERVER_VARS']; |
$this->useBrackets = $useBrackets; |
$this->url = $url; |
$this->user = ''; |
$this->pass = ''; |
$this->host = ''; |
$this->port = 80; |
$this->path = ''; |
$this->querystring = array(); |
$this->anchor = ''; |
// Only use defaults if not an absolute URL given |
if (!preg_match('/^[a-z0-9]+:\/\//i', $url)) { |
$this->protocol = 'http'; |
/** |
* Figure out host/port |
*/ |
if (!empty($HTTP_SERVER_VARS['HTTP_HOST']) AND preg_match('/^(.*)(:([0-9]+))?$/U', $HTTP_SERVER_VARS['HTTP_HOST'], $matches)) { |
$host = $matches[1]; |
if (!empty($matches[3])) { |
$port = $matches[3]; |
} else { |
$port = $this->getStandardPort($this->protocol); |
} |
} |
$this->user = ''; |
$this->pass = ''; |
$this->host = !empty($host) ? $host : (isset($HTTP_SERVER_VARS['SERVER_NAME']) ? $HTTP_SERVER_VARS['SERVER_NAME'] : 'localhost'); |
$this->port = !empty($port) ? $port : (isset($HTTP_SERVER_VARS['SERVER_PORT']) ? $HTTP_SERVER_VARS['SERVER_PORT'] : $this->getStandardPort($this->protocol)); |
$this->path = !empty($HTTP_SERVER_VARS['PHP_SELF']) ? $HTTP_SERVER_VARS['PHP_SELF'] : '/'; |
$this->querystring = isset($HTTP_SERVER_VARS['QUERY_STRING']) ? $this->_parseRawQuerystring($HTTP_SERVER_VARS['QUERY_STRING']) : null; |
$this->anchor = ''; |
} |
// Parse the url and store the various parts |
if (!empty($url)) { |
$urlinfo = parse_url($url); |
// Default querystring |
$this->querystring = array(); |
foreach ($urlinfo as $key => $value) { |
switch ($key) { |
case 'scheme': |
$this->protocol = $value; |
$this->port = $this->getStandardPort($value); |
break; |
case 'user': |
case 'pass': |
case 'host': |
case 'port': |
$this->$key = $value; |
break; |
case 'path': |
if ($value{0} == '/') { |
$this->path = $value; |
} else { |
$path = dirname($this->path) == DIRECTORY_SEPARATOR ? '' : dirname($this->path); |
$this->path = sprintf('%s/%s', $path, $value); |
} |
break; |
case 'query': |
$this->querystring = $this->_parseRawQueryString($value); |
break; |
case 'fragment': |
$this->anchor = $value; |
break; |
} |
} |
} |
} |
/** |
* Returns full url |
* |
* @return string Full url |
* @access public |
*/ |
function getURL() |
{ |
$querystring = $this->getQueryString(); |
$this->url = $this->protocol . '://' |
. $this->user . (!empty($this->pass) ? ':' : '') |
. $this->pass . (!empty($this->user) ? '@' : '') |
. $this->host . ($this->port == $this->getStandardPort($this->protocol) ? '' : ':' . $this->port) |
. $this->path |
. (!empty($querystring) ? '?' . $querystring : '') |
. (!empty($this->anchor) ? '#' . $this->anchor : ''); |
return $this->url; |
} |
/** |
* Adds a querystring item |
* |
* @param string $name Name of item |
* @param string $value Value of item |
* @param bool $preencoded Whether value is urlencoded or not, default = not |
* @access public |
*/ |
function addQueryString($name, $value, $preencoded = false) |
{ |
if ($preencoded) { |
$this->querystring[$name] = $value; |
} else { |
$this->querystring[$name] = is_array($value) ? array_map('rawurlencode', $value): rawurlencode($value); |
} |
} |
/** |
* Removes a querystring item |
* |
* @param string $name Name of item |
* @access public |
*/ |
function removeQueryString($name) |
{ |
if (isset($this->querystring[$name])) { |
unset($this->querystring[$name]); |
} |
} |
/** |
* Sets the querystring to literally what you supply |
* |
* @param string $querystring The querystring data. Should be of the format foo=bar&x=y etc |
* @access public |
*/ |
function addRawQueryString($querystring) |
{ |
$this->querystring = $this->_parseRawQueryString($querystring); |
} |
/** |
* Returns flat querystring |
* |
* @return string Querystring |
* @access public |
*/ |
function getQueryString() |
{ |
if (!empty($this->querystring)) { |
foreach ($this->querystring as $name => $value) { |
if (is_array($value)) { |
foreach ($value as $k => $v) { |
$querystring[] = $this->useBrackets ? sprintf('%s[%s]=%s', $name, $k, $v) : ($name . '=' . $v); |
} |
} elseif (!is_null($value)) { |
$querystring[] = $name . '=' . $value; |
} else { |
$querystring[] = $name; |
} |
} |
$querystring = implode(ini_get('arg_separator.output'), $querystring); |
} else { |
$querystring = ''; |
} |
return $querystring; |
} |
/** |
* Parses raw querystring and returns an array of it |
* |
* @param string $querystring The querystring to parse |
* @return array An array of the querystring data |
* @access private |
*/ |
function _parseRawQuerystring($querystring) |
{ |
$parts = preg_split('/[' . preg_quote(ini_get('arg_separator.input'), '/') . ']/', $querystring, -1, PREG_SPLIT_NO_EMPTY); |
$return = array(); |
foreach ($parts as $part) { |
if (strpos($part, '=') !== false) { |
$value = substr($part, strpos($part, '=') + 1); |
$key = substr($part, 0, strpos($part, '=')); |
} else { |
$value = null; |
$key = $part; |
} |
if (substr($key, -2) == '[]') { |
$key = substr($key, 0, -2); |
if (@!is_array($return[$key])) { |
$return[$key] = array(); |
$return[$key][] = $value; |
} else { |
$return[$key][] = $value; |
} |
} elseif (!$this->useBrackets AND !empty($return[$key])) { |
$return[$key] = (array)$return[$key]; |
$return[$key][] = $value; |
} else { |
$return[$key] = $value; |
} |
} |
return $return; |
} |
/** |
* Resolves //, ../ and ./ from a path and returns |
* the result. Eg: |
* |
* /foo/bar/../boo.php => /foo/boo.php |
* /foo/bar/../../boo.php => /boo.php |
* /foo/bar/.././/boo.php => /foo/boo.php |
* |
* This method can also be called statically. |
* |
* @param string $url URL path to resolve |
* @return string The result |
*/ |
function resolvePath($path) |
{ |
$path = explode('/', str_replace('//', '/', $path)); |
for ($i=0; $i<count($path); $i++) { |
if ($path[$i] == '.') { |
unset($path[$i]); |
$path = array_values($path); |
$i--; |
} elseif ($path[$i] == '..' AND ($i > 1 OR ($i == 1 AND $path[0] != '') ) ) { |
unset($path[$i]); |
unset($path[$i-1]); |
$path = array_values($path); |
$i -= 2; |
} elseif ($path[$i] == '..' AND $i == 1 AND $path[0] == '') { |
unset($path[$i]); |
$path = array_values($path); |
$i--; |
} else { |
continue; |
} |
} |
return implode('/', $path); |
} |
/** |
* Returns the standard port number for a protocol |
* |
* @param string $scheme The protocol to lookup |
* @return integer Port number or NULL if no scheme matches |
* |
* @author Philippe Jausions <Philippe.Jausions@11abacus.com> |
*/ |
function getStandardPort($scheme) |
{ |
switch (strtolower($scheme)) { |
case 'http': return 80; |
case 'https': return 443; |
case 'ftp': return 21; |
case 'imap': return 143; |
case 'imaps': return 993; |
case 'pop3': return 110; |
case 'pop3s': return 995; |
default: return null; |
} |
} |
/** |
* Forces the URL to a particular protocol |
* |
* @param string $protocol Protocol to force the URL to |
* @param integer $port Optional port (standard port is used by default) |
*/ |
function setProtocol($protocol, $port = null) |
{ |
$this->protocol = $protocol; |
$this->port = is_null($port) ? $this->getStandardPort() : $port; |
} |
} |
?> |
/branches/livraison_menes/api/pear/Net/FTP/Observer.php |
---|
New file |
0,0 → 1,101 |
<?php |
/* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4: */ |
/** |
* Net_FTP observer. |
* |
* This class implements the Observer part of a Subject-Observer |
* design pattern. It listens to the events sent by a Net_FTP instance. |
* This module had many influences from the Log_observer code. |
* |
* 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 Networking |
* @package FTP |
* @author Tobias Schlitt <toby@php.net> |
* @author Laurent Laville <pear@laurent-laville.org> |
* @author Chuck Hagenbuch <chuck@horde.org> |
* @copyright 1997-2005 The PHP Group |
* @license http://www.php.net/license/3_0.txt PHP License 3.0 |
* @version CVS: $Id: Observer.php,v 1.1 2005-03-30 08:50:33 jpm Exp $ |
* @link http://pear.php.net/package/Net_FTP |
* @since File available since Release 0.0.1 |
*/ |
/** |
* This class implements the Observer part of a Subject-Observer |
* design pattern. It listens to the events sent by a Net_FTP instance. |
* This module had many influences from the Log_observer code. |
* |
* @license http://www.php.net/license/3_0.txt PHP License 3.0 |
* @category Networking |
* @package FTP |
* @author Laurent Laville <pear@laurent-laville.org> |
* @author Chuck Hagenbuch <chuck@horde.org> |
* @author Tobias Schlitt <toby@php.net> |
* @copyright 1997-2005 The PHP Group |
* @version Release: 1.3.0 |
* @link http://pear.php.net/package/Net_FTP |
* @since 1.3.0.0 |
* @access public |
* |
* @example observer_upload.php An example of Net_FTP_Observer implementation. |
*/ |
class Net_FTP_Observer |
{ |
/** |
* Instance-specific unique identification number. |
* |
* @var integer |
* @since 1.3.0 |
* @access private |
*/ |
var $_id; |
/** |
* Creates a new basic Net_FTP_Observer instance. |
* |
* @since 1.3.0 |
* @access public |
*/ |
function Net_FTP_Observer() |
{ |
$this->_id = md5(microtime()); |
} |
/** |
* Returns the listener's identifier |
* |
* @return string |
* @since 1.3.0 |
* @access public |
*/ |
function getId() |
{ |
return $this->_id; |
} |
/** |
* This is a stub method to make sure that Net_FTP_Observer classes do |
* something when they are notified of a message. The default behavior |
* is to just do nothing. |
* You should override this method. |
* |
* @param mixed $event A hash describing the net event. |
* |
* @since 1.3.0 |
* @access public |
*/ |
function notify($event) |
{ |
return; |
} |
} |
?> |
/branches/livraison_menes/api/pear/Net/SMTP.php |
---|
New file |
0,0 → 1,970 |
<?php |
/* vim: set expandtab softtabstop=4 tabstop=4 shiftwidth=4: */ |
// +----------------------------------------------------------------------+ |
// | PHP Version 4 | |
// +----------------------------------------------------------------------+ |
// | Copyright (c) 1997-2003 The PHP Group | |
// +----------------------------------------------------------------------+ |
// | This source file is subject to version 2.02 of the PHP license, | |
// | that is bundled with this package in the file LICENSE, and is | |
// | available at through the world-wide-web at | |
// | http://www.php.net/license/2_02.txt. | |
// | If you did not receive a copy of the PHP license and are unable to | |
// | obtain it through the world-wide-web, please send a note to | |
// | license@php.net so we can mail you a copy immediately. | |
// +----------------------------------------------------------------------+ |
// | Authors: Chuck Hagenbuch <chuck@horde.org> | |
// | Jon Parise <jon@php.net> | |
// | Damian Alejandro Fernandez Sosa <damlists@cnba.uba.ar> | |
// +----------------------------------------------------------------------+ |
require_once 'PEAR.php'; |
require_once 'Net/Socket.php'; |
/** |
* Provides an implementation of the SMTP protocol using PEAR's |
* Net_Socket:: class. |
* |
* @package Net_SMTP |
* @author Chuck Hagenbuch <chuck@horde.org> |
* @author Jon Parise <jon@php.net> |
* @author Damian Alejandro Fernandez Sosa <damlists@cnba.uba.ar> |
* |
* @example basic.php A basic implementation of the Net_SMTP package. |
*/ |
class Net_SMTP |
{ |
/** |
* The server to connect to. |
* @var string |
* @access public |
*/ |
var $host = 'localhost'; |
/** |
* The port to connect to. |
* @var int |
* @access public |
*/ |
var $port = 25; |
/** |
* The value to give when sending EHLO or HELO. |
* @var string |
* @access public |
*/ |
var $localhost = 'localhost'; |
/** |
* List of supported authentication methods, in preferential order. |
* @var array |
* @access public |
*/ |
var $auth_methods = array('DIGEST-MD5', 'CRAM-MD5', 'LOGIN', 'PLAIN'); |
/** |
* Should debugging output be enabled? |
* @var boolean |
* @access private |
*/ |
var $_debug = false; |
/** |
* The socket resource being used to connect to the SMTP server. |
* @var resource |
* @access private |
*/ |
var $_socket = null; |
/** |
* The most recent server response code. |
* @var int |
* @access private |
*/ |
var $_code = -1; |
/** |
* The most recent server response arguments. |
* @var array |
* @access private |
*/ |
var $_arguments = array(); |
/** |
* Stores detected features of the SMTP server. |
* @var array |
* @access private |
*/ |
var $_esmtp = array(); |
/** |
* Instantiates a new Net_SMTP object, overriding any defaults |
* with parameters that are passed in. |
* |
* @param string The server to connect to. |
* @param int The port to connect to. |
* @param string The value to give when sending EHLO or HELO. |
* |
* @access public |
* @since 1.0 |
*/ |
function Net_SMTP($host = null, $port = null, $localhost = null) |
{ |
if (isset($host)) $this->host = $host; |
if (isset($port)) $this->port = $port; |
if (isset($localhost)) $this->localhost = $localhost; |
$this->_socket = new Net_Socket(); |
/* |
* Include the Auth_SASL package. If the package is not available, |
* we disable the authentication methods that depend upon it. |
*/ |
if ((@include_once 'Auth/SASL.php') === false) { |
$pos = array_search('DIGEST-MD5', $this->auth_methods); |
unset($this->auth_methods[$pos]); |
$pos = array_search('CRAM-MD5', $this->auth_methods); |
unset($this->auth_methods[$pos]); |
} |
} |
/** |
* Set the value of the debugging flag. |
* |
* @param boolean $debug New value for the debugging flag. |
* |
* @access public |
* @since 1.1.0 |
*/ |
function setDebug($debug) |
{ |
$this->_debug = $debug; |
} |
/** |
* Send the given string of data to the server. |
* |
* @param string $data The string of data to send. |
* |
* @return mixed True on success or a PEAR_Error object on failure. |
* |
* @access private |
* @since 1.1.0 |
*/ |
function _send($data) |
{ |
if ($this->_debug) { |
echo "DEBUG: Send: $data\n"; |
} |
if (PEAR::isError($error = $this->_socket->write($data))) { |
return new PEAR_Error('Failed to write to socket: ' . |
$error->getMessage()); |
} |
return true; |
} |
/** |
* Send a command to the server with an optional string of arguments. |
* A carriage return / linefeed (CRLF) sequence will be appended to each |
* command string before it is sent to the SMTP server. |
* |
* @param string $command The SMTP command to send to the server. |
* @param string $args A string of optional arguments to append |
* to the command. |
* |
* @return mixed The result of the _send() call. |
* |
* @access private |
* @since 1.1.0 |
*/ |
function _put($command, $args = '') |
{ |
if (!empty($args)) { |
return $this->_send($command . ' ' . $args . "\r\n"); |
} |
return $this->_send($command . "\r\n"); |
} |
/** |
* Read a reply from the SMTP server. The reply consists of a response |
* code and a response message. |
* |
* @param mixed $valid The set of valid response codes. These |
* may be specified as an array of integer |
* values or as a single integer value. |
* |
* @return mixed True if the server returned a valid response code or |
* a PEAR_Error object is an error condition is reached. |
* |
* @access private |
* @since 1.1.0 |
* |
* @see getResponse |
*/ |
function _parseResponse($valid) |
{ |
$this->_code = -1; |
$this->_arguments = array(); |
while ($line = $this->_socket->readLine()) { |
if ($this->_debug) { |
echo "DEBUG: Recv: $line\n"; |
} |
/* If we receive an empty line, the connection has been closed. */ |
if (empty($line)) { |
$this->disconnect(); |
return new PEAR_Error("Connection was unexpectedly closed"); |
} |
/* Read the code and store the rest in the arguments array. */ |
$code = substr($line, 0, 3); |
$this->_arguments[] = trim(substr($line, 4)); |
/* Check the syntax of the response code. */ |
if (is_numeric($code)) { |
$this->_code = (int)$code; |
} else { |
$this->_code = -1; |
break; |
} |
/* If this is not a multiline response, we're done. */ |
if (substr($line, 3, 1) != '-') { |
break; |
} |
} |
/* Compare the server's response code with the valid code. */ |
if (is_int($valid) && ($this->_code === $valid)) { |
return true; |
} |
/* If we were given an array of valid response codes, check each one. */ |
if (is_array($valid)) { |
foreach ($valid as $valid_code) { |
if ($this->_code === $valid_code) { |
return true; |
} |
} |
} |
return new PEAR_Error("Invalid response code received from server"); |
} |
/** |
* Return a 2-tuple containing the last response from the SMTP server. |
* |
* @return array A two-element array: the first element contains the |
* response code as an integer and the second element |
* contains the response's arguments as a string. |
* |
* @access public |
* @since 1.1.0 |
*/ |
function getResponse() |
{ |
return array($this->_code, join("\n", $this->_arguments)); |
} |
/** |
* Attempt to connect to the SMTP server. |
* |
* @param int $timeout The timeout value (in seconds) for the |
* socket connection. |
* @param bool $persistent Should a persistent socket connection |
* be used? |
* |
* @return mixed Returns a PEAR_Error with an error message on any |
* kind of failure, or true on success. |
* @access public |
* @since 1.0 |
*/ |
function connect($timeout = null, $persistent = false) |
{ |
$result = $this->_socket->connect($this->host, $this->port, |
$persistent, $timeout); |
if (PEAR::isError($result)) { |
return new PEAR_Error('Failed to connect socket: ' . |
$result->getMessage()); |
} |
if (PEAR::isError($error = $this->_parseResponse(220))) { |
return $error; |
} |
if (PEAR::isError($error = $this->_negotiate())) { |
return $error; |
} |
return true; |
} |
/** |
* Attempt to disconnect from the SMTP server. |
* |
* @return mixed Returns a PEAR_Error with an error message on any |
* kind of failure, or true on success. |
* @access public |
* @since 1.0 |
*/ |
function disconnect() |
{ |
if (PEAR::isError($error = $this->_put('QUIT'))) { |
return $error; |
} |
if (PEAR::isError($error = $this->_parseResponse(221))) { |
return $error; |
} |
if (PEAR::isError($error = $this->_socket->disconnect())) { |
return new PEAR_Error('Failed to disconnect socket: ' . |
$error->getMessage()); |
} |
return true; |
} |
/** |
* Attempt to send the EHLO command and obtain a list of ESMTP |
* extensions available, and failing that just send HELO. |
* |
* @return mixed Returns a PEAR_Error with an error message on any |
* kind of failure, or true on success. |
* |
* @access private |
* @since 1.1.0 |
*/ |
function _negotiate() |
{ |
if (PEAR::isError($error = $this->_put('EHLO', $this->localhost))) { |
return $error; |
} |
if (PEAR::isError($this->_parseResponse(250))) { |
/* If we receive a 503 response, we're already authenticated. */ |
if ($this->_code === 503) { |
return true; |
} |
/* If the EHLO failed, try the simpler HELO command. */ |
if (PEAR::isError($error = $this->_put('HELO', $this->localhost))) { |
return $error; |
} |
if (PEAR::isError($this->_parseResponse(250))) { |
return new PEAR_Error('HELO was not accepted: ', $this->_code); |
} |
return true; |
} |
foreach ($this->_arguments as $argument) { |
$verb = strtok($argument, ' '); |
$arguments = substr($argument, strlen($verb) + 1, |
strlen($argument) - strlen($verb) - 1); |
$this->_esmtp[$verb] = $arguments; |
} |
return true; |
} |
/** |
* Returns the name of the best authentication method that the server |
* has advertised. |
* |
* @return mixed Returns a string containing the name of the best |
* supported authentication method or a PEAR_Error object |
* if a failure condition is encountered. |
* @access private |
* @since 1.1.0 |
*/ |
function _getBestAuthMethod() |
{ |
$available_methods = explode(' ', $this->_esmtp['AUTH']); |
foreach ($this->auth_methods as $method) { |
if (in_array($method, $available_methods)) { |
return $method; |
} |
} |
return new PEAR_Error('No supported authentication methods'); |
} |
/** |
* Attempt to do SMTP authentication. |
* |
* @param string The userid to authenticate as. |
* @param string The password to authenticate with. |
* @param string The requested authentication method. If none is |
* specified, the best supported method will be used. |
* |
* @return mixed Returns a PEAR_Error with an error message on any |
* kind of failure, or true on success. |
* @access public |
* @since 1.0 |
*/ |
function auth($uid, $pwd , $method = '') |
{ |
if (empty($this->_esmtp['AUTH'])) { |
return new PEAR_Error('SMTP server does no support authentication'); |
} |
/* |
* If no method has been specified, get the name of the best supported |
* method advertised by the SMTP server. |
*/ |
if (empty($method)) { |
if (PEAR::isError($method = $this->_getBestAuthMethod())) { |
/* Return the PEAR_Error object from _getBestAuthMethod(). */ |
return $method; |
} |
} else { |
$method = strtoupper($method); |
if (!in_array($method, $this->auth_methods)) { |
return new PEAR_Error("$method is not a supported authentication method"); |
} |
} |
switch ($method) { |
case 'DIGEST-MD5': |
$result = $this->_authDigest_MD5($uid, $pwd); |
break; |
case 'CRAM-MD5': |
$result = $this->_authCRAM_MD5($uid, $pwd); |
break; |
case 'LOGIN': |
$result = $this->_authLogin($uid, $pwd); |
break; |
case 'PLAIN': |
$result = $this->_authPlain($uid, $pwd); |
break; |
default: |
$result = new PEAR_Error("$method is not a supported authentication method"); |
break; |
} |
/* If an error was encountered, return the PEAR_Error object. */ |
if (PEAR::isError($result)) { |
return $result; |
} |
/* RFC-2554 requires us to re-negotiate ESMTP after an AUTH. */ |
if (PEAR::isError($error = $this->_negotiate())) { |
return $error; |
} |
return true; |
} |
/** |
* Authenticates the user using the DIGEST-MD5 method. |
* |
* @param string The userid to authenticate as. |
* @param string The password to authenticate with. |
* |
* @return mixed Returns a PEAR_Error with an error message on any |
* kind of failure, or true on success. |
* @access private |
* @since 1.1.0 |
*/ |
function _authDigest_MD5($uid, $pwd) |
{ |
if (PEAR::isError($error = $this->_put('AUTH', 'DIGEST-MD5'))) { |
return $error; |
} |
/* 334: Continue authentication request */ |
if (PEAR::isError($error = $this->_parseResponse(334))) { |
/* 503: Error: already authenticated */ |
if ($this->_code === 503) { |
return true; |
} |
return $error; |
} |
$challenge = base64_decode($this->_arguments[0]); |
$digest = &Auth_SASL::factory('digestmd5'); |
$auth_str = base64_encode($digest->getResponse($uid, $pwd, $challenge, |
$this->host, "smtp")); |
if (PEAR::isError($error = $this->_put($auth_str))) { |
return $error; |
} |
/* 334: Continue authentication request */ |
if (PEAR::isError($error = $this->_parseResponse(334))) { |
return $error; |
} |
/* |
* We don't use the protocol's third step because SMTP doesn't allow |
* subsequent authentication, so we just silently ignore it. |
*/ |
if (PEAR::isError($error = $this->_put(' '))) { |
return $error; |
} |
/* 235: Authentication successful */ |
if (PEAR::isError($error = $this->_parseResponse(235))) { |
return $error; |
} |
} |
/** |
* Authenticates the user using the CRAM-MD5 method. |
* |
* @param string The userid to authenticate as. |
* @param string The password to authenticate with. |
* |
* @return mixed Returns a PEAR_Error with an error message on any |
* kind of failure, or true on success. |
* @access private |
* @since 1.1.0 |
*/ |
function _authCRAM_MD5($uid, $pwd) |
{ |
if (PEAR::isError($error = $this->_put('AUTH', 'CRAM-MD5'))) { |
return $error; |
} |
/* 334: Continue authentication request */ |
if (PEAR::isError($error = $this->_parseResponse(334))) { |
/* 503: Error: already authenticated */ |
if ($this->_code === 503) { |
return true; |
} |
return $error; |
} |
$challenge = base64_decode($this->_arguments[0]); |
$cram = &Auth_SASL::factory('crammd5'); |
$auth_str = base64_encode($cram->getResponse($uid, $pwd, $challenge)); |
if (PEAR::isError($error = $this->_put($auth_str))) { |
return $error; |
} |
/* 235: Authentication successful */ |
if (PEAR::isError($error = $this->_parseResponse(235))) { |
return $error; |
} |
} |
/** |
* Authenticates the user using the LOGIN method. |
* |
* @param string The userid to authenticate as. |
* @param string The password to authenticate with. |
* |
* @return mixed Returns a PEAR_Error with an error message on any |
* kind of failure, or true on success. |
* @access private |
* @since 1.1.0 |
*/ |
function _authLogin($uid, $pwd) |
{ |
if (PEAR::isError($error = $this->_put('AUTH', 'LOGIN'))) { |
return $error; |
} |
/* 334: Continue authentication request */ |
if (PEAR::isError($error = $this->_parseResponse(334))) { |
/* 503: Error: already authenticated */ |
if ($this->_code === 503) { |
return true; |
} |
return $error; |
} |
if (PEAR::isError($error = $this->_put(base64_encode($uid)))) { |
return $error; |
} |
/* 334: Continue authentication request */ |
if (PEAR::isError($error = $this->_parseResponse(334))) { |
return $error; |
} |
if (PEAR::isError($error = $this->_put(base64_encode($pwd)))) { |
return $error; |
} |
/* 235: Authentication successful */ |
if (PEAR::isError($error = $this->_parseResponse(235))) { |
return $error; |
} |
return true; |
} |
/** |
* Authenticates the user using the PLAIN method. |
* |
* @param string The userid to authenticate as. |
* @param string The password to authenticate with. |
* |
* @return mixed Returns a PEAR_Error with an error message on any |
* kind of failure, or true on success. |
* @access private |
* @since 1.1.0 |
*/ |
function _authPlain($uid, $pwd) |
{ |
if (PEAR::isError($error = $this->_put('AUTH', 'PLAIN'))) { |
return $error; |
} |
/* 334: Continue authentication request */ |
if (PEAR::isError($error = $this->_parseResponse(334))) { |
/* 503: Error: already authenticated */ |
if ($this->_code === 503) { |
return true; |
} |
return $error; |
} |
$auth_str = base64_encode(chr(0) . $uid . chr(0) . $pwd); |
if (PEAR::isError($error = $this->_put($auth_str))) { |
return $error; |
} |
/* 235: Authentication successful */ |
if (PEAR::isError($error = $this->_parseResponse(235))) { |
return $error; |
} |
return true; |
} |
/** |
* Send the HELO command. |
* |
* @param string The domain name to say we are. |
* |
* @return mixed Returns a PEAR_Error with an error message on any |
* kind of failure, or true on success. |
* @access public |
* @since 1.0 |
*/ |
function helo($domain) |
{ |
if (PEAR::isError($error = $this->_put('HELO', $domain))) { |
return $error; |
} |
if (PEAR::isError($error = $this->_parseResponse(250))) { |
return $error; |
} |
return true; |
} |
/** |
* Send the MAIL FROM: command. |
* |
* @param string The sender (reverse path) to set. |
* |
* @return mixed Returns a PEAR_Error with an error message on any |
* kind of failure, or true on success. |
* @access public |
* @since 1.0 |
*/ |
function mailFrom($sender) |
{ |
if (PEAR::isError($error = $this->_put('MAIL', "FROM:<$sender>"))) { |
return $error; |
} |
if (PEAR::isError($error = $this->_parseResponse(250))) { |
return $error; |
} |
return true; |
} |
/** |
* Send the RCPT TO: command. |
* |
* @param string The recipient (forward path) to add. |
* |
* @return mixed Returns a PEAR_Error with an error message on any |
* kind of failure, or true on success. |
* @access public |
* @since 1.0 |
*/ |
function rcptTo($recipient) |
{ |
if (PEAR::isError($error = $this->_put('RCPT', "TO:<$recipient>"))) { |
return $error; |
} |
if (PEAR::isError($error = $this->_parseResponse(array(250, 251)))) { |
return $error; |
} |
return true; |
} |
/** |
* Quote the data so that it meets SMTP standards. |
* |
* This is provided as a separate public function to facilitate easier |
* overloading for the cases where it is desirable to customize the |
* quoting behavior. |
* |
* @param string The message text to quote. The string must be passed |
* by reference, and the text will be modified in place. |
* |
* @access public |
* @since 1.2 |
*/ |
function quotedata(&$data) |
{ |
/* |
* Change Unix (\n) and Mac (\r) linefeeds into Internet-standard CRLF |
* (\r\n) linefeeds. |
*/ |
$data = preg_replace("/([^\r]{1})\n/", "\\1\r\n", $data); |
$data = preg_replace("/\n\n/", "\n\r\n", $data); |
/* |
* Because a single leading period (.) signifies an end to the data, |
* legitimate leading periods need to be "doubled" (e.g. '..'). |
*/ |
$data = preg_replace("/\n\./", "\n..", $data); |
} |
/** |
* Send the DATA command. |
* |
* @param string The message body to send. |
* |
* @return mixed Returns a PEAR_Error with an error message on any |
* kind of failure, or true on success. |
* @access public |
* @since 1.0 |
*/ |
function data($data) |
{ |
/* |
* RFC 1870, section 3, subsection 3 states "a value of zero indicates |
* that no fixed maximum message size is in force". Furthermore, it |
* says that if "the parameter is omitted no information is conveyed |
* about the server's fixed maximum message size". |
*/ |
if (isset($this->_esmtp['SIZE']) && ($this->_esmtp['SIZE'] > 0)) { |
if (strlen($data) >= $this->_esmtp['SIZE']) { |
$this->disconnect(); |
return new PEAR_Error('Message size excedes the server limit'); |
} |
} |
/* Quote the data based on the SMTP standards. */ |
$this->quotedata($data); |
if (PEAR::isError($error = $this->_put('DATA'))) { |
return $error; |
} |
if (PEAR::isError($error = $this->_parseResponse(354))) { |
return $error; |
} |
if (PEAR::isError($this->_send($data . "\r\n.\r\n"))) { |
return new PEAR_Error('write to socket failed'); |
} |
if (PEAR::isError($error = $this->_parseResponse(250))) { |
return $error; |
} |
return true; |
} |
/** |
* Send the SEND FROM: command. |
* |
* @param string The reverse path to send. |
* |
* @return mixed Returns a PEAR_Error with an error message on any |
* kind of failure, or true on success. |
* @access public |
* @since 1.2.6 |
*/ |
function sendFrom($path) |
{ |
if (PEAR::isError($error = $this->_put('SEND', "FROM:<$path>"))) { |
return $error; |
} |
if (PEAR::isError($error = $this->_parseResponse(250))) { |
return $error; |
} |
return true; |
} |
/** |
* Backwards-compatibility wrapper for sendFrom(). |
* |
* @param string The reverse path to send. |
* |
* @return mixed Returns a PEAR_Error with an error message on any |
* kind of failure, or true on success. |
* |
* @access public |
* @since 1.0 |
* @deprecated 1.2.6 |
*/ |
function send_from($path) |
{ |
return sendFrom($path); |
} |
/** |
* Send the SOML FROM: command. |
* |
* @param string The reverse path to send. |
* |
* @return mixed Returns a PEAR_Error with an error message on any |
* kind of failure, or true on success. |
* @access public |
* @since 1.2.6 |
*/ |
function somlFrom($path) |
{ |
if (PEAR::isError($error = $this->_put('SOML', "FROM:<$path>"))) { |
return $error; |
} |
if (PEAR::isError($error = $this->_parseResponse(250))) { |
return $error; |
} |
return true; |
} |
/** |
* Backwards-compatibility wrapper for somlFrom(). |
* |
* @param string The reverse path to send. |
* |
* @return mixed Returns a PEAR_Error with an error message on any |
* kind of failure, or true on success. |
* |
* @access public |
* @since 1.0 |
* @deprecated 1.2.6 |
*/ |
function soml_from($path) |
{ |
return somlFrom($path); |
} |
/** |
* Send the SAML FROM: command. |
* |
* @param string The reverse path to send. |
* |
* @return mixed Returns a PEAR_Error with an error message on any |
* kind of failure, or true on success. |
* @access public |
* @since 1.2.6 |
*/ |
function samlFrom($path) |
{ |
if (PEAR::isError($error = $this->_put('SAML', "FROM:<$path>"))) { |
return $error; |
} |
if (PEAR::isError($error = $this->_parseResponse(250))) { |
return $error; |
} |
return true; |
} |
/** |
* Backwards-compatibility wrapper for samlFrom(). |
* |
* @param string The reverse path to send. |
* |
* @return mixed Returns a PEAR_Error with an error message on any |
* kind of failure, or true on success. |
* |
* @access public |
* @since 1.0 |
* @deprecated 1.2.6 |
*/ |
function saml_from($path) |
{ |
return samlFrom($path); |
} |
/** |
* Send the RSET command. |
* |
* @return mixed Returns a PEAR_Error with an error message on any |
* kind of failure, or true on success. |
* @access public |
* @since 1.0 |
*/ |
function rset() |
{ |
if (PEAR::isError($error = $this->_put('RSET'))) { |
return $error; |
} |
if (PEAR::isError($error = $this->_parseResponse(250))) { |
return $error; |
} |
return true; |
} |
/** |
* Send the VRFY command. |
* |
* @param string The string to verify |
* |
* @return mixed Returns a PEAR_Error with an error message on any |
* kind of failure, or true on success. |
* @access public |
* @since 1.0 |
*/ |
function vrfy($string) |
{ |
/* Note: 251 is also a valid response code */ |
if (PEAR::isError($error = $this->_put('VRFY', $string))) { |
return $error; |
} |
if (PEAR::isError($error = $this->_parseResponse(250))) { |
return $error; |
} |
return true; |
} |
/** |
* Send the NOOP command. |
* |
* @return mixed Returns a PEAR_Error with an error message on any |
* kind of failure, or true on success. |
* @access public |
* @since 1.0 |
*/ |
function noop() |
{ |
if (PEAR::isError($error = $this->_put('NOOP'))) { |
return $error; |
} |
if (PEAR::isError($error = $this->_parseResponse(250))) { |
return $error; |
} |
return true; |
} |
/** |
* Backwards-compatibility method. identifySender()'s functionality is |
* now handled internally. |
* |
* @return boolean This method always return true. |
* |
* @access public |
* @since 1.0 |
*/ |
function identifySender() |
{ |
return true; |
} |
} |
?> |
/branches/livraison_menes/api/pear/Auth.php |
---|
New file |
0,0 → 1,869 |
<?php |
/* vim: set expandtab tabstop=4 shiftwidth=4: */ |
// +----------------------------------------------------------------------+ |
// | PHP Version 4 | |
// +----------------------------------------------------------------------+ |
// | Copyright (c) 1997-2003 The PHP Group | |
// +----------------------------------------------------------------------+ |
// | This source file is subject to version 2.02 of the PHP license, | |
// | that is bundled with this package in the file LICENSE, and is | |
// | available at through the world-wide-web at | |
// | http://www.php.net/license/2_02.txt. | |
// | If you did not receive a copy of the PHP license and are unable to | |
// | obtain it through the world-wide-web, please send a note to | |
// | license@php.net so we can mail you a copy immediately. | |
// +----------------------------------------------------------------------+ |
// | Authors: Martin Jansen <mj@php.net> | |
// +----------------------------------------------------------------------+ |
// |
// $Id: Auth.php,v 1.1 2005-03-30 08:50:19 jpm Exp $ |
// |
require_once 'PEAR.php'; |
define('AUTH_IDLED', -1); |
define('AUTH_EXPIRED', -2); |
define('AUTH_WRONG_LOGIN', -3); |
/** |
* PEAR::Auth |
* |
* The PEAR::Auth class provides methods for creating an |
* authentication system using PHP. |
* |
* @author Martin Jansen <mj@php.net> |
* @package Auth |
* @version $Revision: 1.1 $ |
*/ |
class Auth { |
/** |
* Auth lifetime in seconds |
* |
* If this variable is set to 0, auth never expires |
* |
* @var integer |
* @see setExpire(), checkAuth() |
*/ |
var $expire = 0; |
/** |
* Has the auth session expired? |
* |
* @var bool |
* @see checkAuth(), drawLogin() |
*/ |
var $expired = false; |
/** |
* Maximum time of idleness in seconds |
* |
* The difference to $expire is, that the idletime gets |
* refreshed each time, checkAuth() is called. If this |
* variable is set to 0, idle time is never checked. |
* |
* @var integer |
* @see setIdle(), checkAuth() |
*/ |
var $idle = 0; |
/** |
* Is the maximum idletime over? |
* |
* @var boolean |
* @see checkAuth(), drawLogin(); |
*/ |
var $idled = false; |
/** |
* Storage object |
* |
* @var object |
* @see Auth(), validateLogin() |
*/ |
var $storage = ''; |
/** |
* Function defined by the user, that creates the login screen |
* |
* @var string |
*/ |
var $loginFunction = ''; |
/** |
* Should the login form be displayed? |
* |
* @var bool |
* @see setShowlogin() |
*/ |
var $showLogin = true; |
/** |
* Current authentication status |
* |
* @var string |
*/ |
var $status = ''; |
/** |
* Username |
* |
* @var string |
*/ |
var $username = ''; |
/** |
* Password |
* |
* @var string |
*/ |
var $password = ''; |
/** |
* Login callback function name |
* |
* @var string |
* @see setLoginCallback() |
*/ |
var $loginCallback = ''; |
/** |
* Failed Login callback function name |
* |
* @var string |
* @see setLoginFailedCallback() |
*/ |
var $loginFailedCallback = ''; |
/** |
* Logout callback function name |
* |
* @var string |
* @see setLogoutCallback() |
*/ |
var $logoutCallback = ''; |
/** |
* Auth session-array name |
* |
* @var string |
*/ |
var $_sessionName = '_authsession'; |
/** |
* Package Version |
* |
* @var string |
*/ |
var $version = "1.2.3"; |
// {{{ Constructor |
/** |
* Constructor |
* |
* Set up the storage driver. |
* |
* @param string Type of the storage driver |
* @param mixed Additional options for the storage driver |
* (example: if you are using DB as the storage |
* driver, you have to pass the dsn string here) |
* |
* @param string Name of the function that creates the login form |
* @param boolean Should the login form be displayed if neccessary? |
* @return void |
*/ |
function Auth($storageDriver, $options = '', $loginFunction = '', $showLogin = true) |
{ |
if (!empty($options['sessionName'])) { |
$this->_sessionName = $options['sessionName']; |
unset($options['sessionName']); |
} |
if ($loginFunction != '' && is_callable($loginFunction)) { |
$this->loginFunction = $loginFunction; |
} |
if (is_bool($showLogin)) { |
$this->showLogin = $showLogin; |
} |
if (is_object($storageDriver)) { |
$this->storage =& $storageDriver; |
} else { |
$this->storage = $this->_factory($storageDriver, $options); |
} |
// Pass a reference to auth to the container, ugly but works |
// this is used by the DB container to use method setAuthData not staticaly. |
$this->storage->_auth_obj =& $this; |
} |
// }}} |
// {{{ _factory() |
/** |
* Return a storage driver based on $driver and $options |
* |
* @access private |
* @static |
* @param string $driver Type of storage class to return |
* @param string $options Optional parameters for the storage class |
* @return object Object Storage object |
*/ |
function _factory($driver, $options = '') |
{ |
$storage_path = 'Auth/Container/' . $driver . '.php'; |
$storage_class = 'Auth_Container_' . $driver; |
require_once $storage_path; |
return new $storage_class($options); |
} |
// }}} |
// {{{ assignData() |
/** |
* Assign data from login form to internal values |
* |
* This function takes the values for username and password |
* from $HTTP_POST_VARS and assigns them to internal variables. |
* If you wish to use another source apart from $HTTP_POST_VARS, |
* you have to derive this function. |
* |
* @access private |
* @global $HTTP_POST_VARS |
* @see Auth |
* @return void |
*/ |
function assignData() |
{ |
$post = &$this->_importGlobalVariable('post'); |
if (isset($post['username']) && $post['username'] != '') { |
$this->username = (get_magic_quotes_gpc() == 1 ? stripslashes($post['username']) : $post['username']); |
} |
if (isset($post['password']) && $post['password'] != '') { |
$this->password = (get_magic_quotes_gpc() == 1 ? stripslashes($post['password']) : $post['password'] ); |
} |
} |
// }}} |
// {{{ start() |
/** |
* Start new auth session |
* |
* @access public |
* @return void |
*/ |
function start() |
{ |
$this->assignData(); |
@session_start(); |
if (!$this->checkAuth()) { |
$this->login(); |
} |
} |
// }}} |
// {{{ login() |
/** |
* Login function |
* |
* @access private |
* @return void |
*/ |
function login() |
{ |
$login_ok = false; |
/** |
* When the user has already entered a username, |
* we have to validate it. |
*/ |
if (!empty($this->username)) { |
if (true === $this->storage->fetchData($this->username, $this->password)) { |
$login_ok = true; |
} else { |
if (is_callable($this->loginFailedCallback)) { |
call_user_func($this->loginFailedCallback,$this->username, $this); |
} |
} |
} |
if (!empty($this->username) && $login_ok) { |
$this->setAuth($this->username); |
if (is_callable($this->loginCallback)) { |
call_user_func($this->loginCallback,$this->username, $this); |
} |
} |
/** |
* If the login failed or the user entered no username, |
* output the login screen again. |
*/ |
if (!empty($this->username) && !$login_ok) { |
$this->status = AUTH_WRONG_LOGIN; |
} |
if ((empty($this->username) || !$login_ok) && $this->showLogin) { |
$this->drawLogin($this->storage->activeUser); |
return; |
} |
} |
// }}} |
// {{{ setExpire() |
/** |
* Set the maximum expire time |
* |
* @access public |
* @param integer time in seconds |
* @param bool add time to current expire time or not |
* @return void |
*/ |
function setExpire($time, $add = false) |
{ |
if ($add) { |
$this->expire += $time; |
} else { |
$this->expire = $time; |
} |
} |
// }}} |
// {{{ setIdle() |
/** |
* Set the maximum idle time |
* |
* @access public |
* @param integer time in seconds |
* @param bool add time to current maximum idle time or not |
* @return void |
*/ |
function setIdle($time, $add = false) |
{ |
if ($add) { |
$this->idle += $time; |
} else { |
$this->idle = $time; |
} |
} |
// }}} |
// {{{ setSessionname() |
/** |
* Set name of the session to a customized value. |
* |
* If you are using multiple instances of PEAR::Auth |
* on the same domain, you can change the name of |
* session per application via this function. |
* |
* @access public |
* @param string New name for the session |
* @return void |
*/ |
function setSessionname($name = 'PHPSESSID') |
{ |
@session_name($name); |
} |
// }}} |
// {{{ setShowLogin() |
/** |
* Should the login form be displayed if neccessary? |
* |
* @access public |
* @param bool show login form or not |
* @return void |
*/ |
function setShowLogin($showLogin = true) |
{ |
$this->showLogin = $showLogin; |
} |
/** |
* Register a callback function to be called on user login. |
* The function will receive two parameters, the username and a reference to the auth object. |
* |
* @access public |
* @param string callback function name |
* @return void |
* @see setLogoutCallback() |
*/ |
function setLoginCallback($loginCallback) |
{ |
$this->loginCallback = $loginCallback; |
} |
/** |
* Register a callback function to be called on failed user login. |
* The function will receive a single parameter, the username and a reference to the auth object. |
* |
* @access public |
* @param string callback function name |
* @return void |
*/ |
function setFailedLoginCallback($loginFailedCallback) |
{ |
$this->loginFailedCallback = $loginFailedCallback; |
} |
/** |
* Register a callback function to be called on user logout. |
* The function will receive three parameters, the username and a reference to the auth object. |
* |
* @access public |
* @param string callback function name |
* @return void |
* @see setLoginCallback() |
*/ |
function setLogoutCallback($logoutCallback) |
{ |
$this->logoutCallback = $logoutCallback; |
} |
// }}} |
// {{{ setAuthData() |
/** |
* Register additional information that is to be stored |
* in the session. |
* |
* @access public |
* @param string Name of the data field |
* @param mixed Value of the data field |
* @param boolean Should existing data be overwritten? (default |
* is true) |
* @return void |
*/ |
function setAuthData($name, $value, $overwrite = true) |
{ |
$session = &Auth::_importGlobalVariable('session'); |
if (!empty($session[$this->_sessionName]['data'][$name]) && $overwrite == false) { |
return; |
} |
$session[$this->_sessionName]['data'][$name] = $value; |
} |
// }}} |
// {{{ getAuthData() |
/** |
* Get additional information that is stored in the session. |
* |
* If no value for the first parameter is passed, the method will |
* return all data that is currently stored. |
* |
* @access public |
* @param string Name of the data field |
* @return mixed Value of the data field. |
*/ |
function getAuthData($name = null) |
{ |
$session = &Auth::_importGlobalVariable('session'); |
if(!isset($session[$this->_sessionName]['data'])){ |
return(null); |
} |
if (is_null($name)) { |
if(isset($session[$this->_sessionName]['data'])) { |
return $session[$this->_sessionName]['data']; |
} else { |
return null; |
} |
} |
if (isset($session[$this->_sessionName]['data'][$name])) { |
return $session[$this->_sessionName]['data'][$name]; |
} else { |
return null; |
} |
} |
// }}} |
// {{{ setAuth() |
/** |
* Register variable in a session telling that the user |
* has logged in successfully |
* |
* @access public |
* @param string Username |
* @return void |
*/ |
function setAuth($username) |
{ |
$session = &Auth::_importGlobalVariable('session'); |
if (!isset($session[$this->_sessionName]) && !isset($_SESSION)) { |
session_register($this->_sessionName); |
} |
if (!isset($session[$this->_sessionName]) || !is_array($session[$this->_sessionName])) { |
$session[$this->_sessionName] = array(); |
} |
if(!isset($session[$this->_sessionName]['data'])){ |
$session[$this->_sessionName]['data'] = array(); |
} |
$session[$this->_sessionName]['registered'] = true; |
$session[$this->_sessionName]['username'] = $username; |
$session[$this->_sessionName]['timestamp'] = time(); |
$session[$this->_sessionName]['idle'] = time(); |
} |
// }}} |
// {{{ checkAuth() |
/** |
* Checks if there is a session with valid auth information. |
* |
* @access private |
* @return boolean Whether or not the user is authenticated. |
*/ |
function checkAuth() |
{ |
$session = &$this->_importGlobalVariable('session'); |
if (isset($session[$this->_sessionName])) { |
// Check if authentication session is expired |
if ($this->expire > 0 && |
isset($session[$this->_sessionName]['timestamp']) && |
($session[$this->_sessionName]['timestamp'] + $this->expire) < time()) { |
$this->logout(); |
$this->expired = true; |
$this->status = AUTH_EXPIRED; |
return false; |
} |
// Check if maximum idle time is reached |
if ($this->idle > 0 && |
isset($session[$this->_sessionName]['idle']) && |
($session[$this->_sessionName]['idle'] + $this->idle) < time()) { |
$this->logout(); |
$this->idled = true; |
$this->status = AUTH_IDLED; |
return false; |
} |
if (isset($session[$this->_sessionName]['registered']) && |
isset($session[$this->_sessionName]['username']) && |
$session[$this->_sessionName]['registered'] == true && |
$session[$this->_sessionName]['username'] != '') { |
Auth::updateIdle(); |
return true; |
} |
} |
return false; |
} |
// }}} |
// {{{ getAuth() |
/** |
* Has the user been authenticated? |
* |
* @access public |
* @return bool True if the user is logged in, otherwise false. |
*/ |
function getAuth() |
{ |
$session = &$this->_importGlobalVariable('session'); |
if (!empty($session) && |
(isset($session[$this->_sessionName]['registered']) && |
$session[$this->_sessionName]['registered'] === true)) |
{ |
return true; |
} else { |
return false; |
} |
} |
// }}} |
// {{{ drawLogin() |
/** |
* Draw the login form |
* |
* Normally you will not use this output in your application, |
* because you can pass a different function name to the |
* constructor. For more information on this, please |
* consult the documentation. |
* |
* @access private |
* @param string Username if already entered |
* @return void |
*/ |
function drawLogin($username = '') |
{ |
if (is_callable($this->loginFunction)) { |
call_user_func($this->loginFunction, $username, $this->status, $this); |
} else { |
$server = &$this->_importGlobalVariable('server'); |
echo '<center>'."\n"; |
if (!empty($this->status) && $this->status == AUTH_EXPIRED) { |
echo '<i>Your session expired. Please login again!</i>'."\n"; |
} else if (!empty($this->status) && $this->status == AUTH_IDLED) { |
echo '<i>You have been idle for too long. Please login again!</i>'."\n"; |
} else if (!empty ($this->status) && $this->status == AUTH_WRONG_LOGIN) { |
echo '<i>Wrong login data!</i>'."\n"; |
} |
PEAR::raiseError('You are using the built-in login screen of PEAR::Auth.<br />See the <a href="http://pear.php.net/manual/">manual</a> for details on how to create your own login function.', null); |
echo '<form method="post" action="' . $server['PHP_SELF'] . '">'."\n"; |
echo '<table border="0" cellpadding="2" cellspacing="0" summary="login form">'."\n"; |
echo '<tr>'."\n"; |
echo ' <td colspan="2" bgcolor="#eeeeee"><b>Login:</b></td>'."\n"; |
echo '</tr>'."\n"; |
echo '<tr>'."\n"; |
echo ' <td>Username:</td>'."\n"; |
echo ' <td><input type="text" name="username" value="' . $username . '" /></td>'."\n"; |
echo '</tr>'."\n"; |
echo '<tr>'."\n"; |
echo ' <td>Password:</td>'."\n"; |
echo ' <td><input type="password" name="password" /></td>'."\n"; |
echo '</tr>'."\n"; |
echo '<tr>'."\n"; |
echo ' <td colspan="2" bgcolor="#eeeeee"><input type="submit" /></td>'."\n"; |
echo '</tr>'."\n"; |
echo '</table>'."\n"; |
echo '</form>'."\n"; |
echo '</center>'."\n\n"; |
} |
} |
// }}} |
// {{{ logout() |
/** |
* Logout function |
* |
* This function clears any auth tokens in the currently |
* active session and executes the logout callback function, |
* if any |
* |
* @access public |
* @return void |
*/ |
function logout() |
{ |
$session = &$this->_importGlobalVariable('session'); |
if (is_callable($this->logoutCallback)) { |
call_user_func($this->logoutCallback, $session[$this->_sessionName]['username'], $this); |
} |
$this->username = ''; |
$this->password = ''; |
$session[$this->_sessionName] = array(); |
if (isset($_SESSION)) { |
unset($session[$this->_sessionName]); |
} else { |
session_unregister($this->_sessionName); |
} |
} |
// }}} |
// {{{ updateIdle() |
/** |
* Update the idletime |
* |
* @access private |
* @return void |
*/ |
function updateIdle() |
{ |
$session = &$this->_importGlobalVariable('session'); |
$session[$this->_sessionName]['idle'] = time(); |
} |
// }}} |
// {{{ getUsername() |
/** |
* Get the username |
* |
* @access public |
* @return string |
*/ |
function getUsername() |
{ |
$session = &$this->_importGlobalVariable('session'); |
if (!isset($session[$this->_sessionName]['username'])) { |
return ''; |
} |
return $session[$this->_sessionName]['username']; |
} |
// }}} |
// {{{ getStatus() |
/** |
* Get the current status |
* |
* @access public |
* @return string |
*/ |
function getStatus() |
{ |
return $this->status; |
} |
// }}} |
// {{{ sessionValidThru() |
/** |
* Returns the time up to the session is valid |
* |
* @access public |
* @return integer |
*/ |
function sessionValidThru() |
{ |
$session = &$this->_importGlobalVariable('session'); |
if (!isset($session[$this->_sessionName]['idle'])) { |
return 0; |
} |
return ($session[$this->_sessionName]['idle'] + $this->idle); |
} |
// }}} |
// {{{ listUsers() |
/** |
* List all users that are currently available in the storage |
* container |
* |
* @access public |
* @return array |
*/ |
function listUsers() |
{ |
return $this->storage->listUsers(); |
} |
// }}} |
// {{{ addUser() |
/** |
* Add user to the storage container |
* |
* @access public |
* @param string Username |
* @param string Password |
* @param mixed Additional parameters |
* @return mixed True on success, PEAR error object on error |
* and AUTH_METHOD_NOT_SUPPORTED otherwise. |
*/ |
function addUser($username, $password, $additional = '') |
{ |
return $this->storage->addUser($username, $password, $additional); |
} |
// }}} |
// {{{ removeUser() |
/** |
* Remove user from the storage container |
* |
* @access public |
* @param string Username |
* @return mixed True on success, PEAR error object on error |
* and AUTH_METHOD_NOT_SUPPORTED otherwise. |
*/ |
function removeUser($username) |
{ |
return $this->storage->removeUser($username); |
} |
// }}} |
// {{{ _importGlobalVariable() |
/** |
* Import variables from special namespaces. |
* |
* @access private |
* @param string Type of variable (server, session, post) |
* @return array |
*/ |
function &_importGlobalVariable($variable) |
{ |
$var = null; |
switch (strtolower($variable)) { |
case 'server' : |
if (isset($_SERVER)) { |
$var = &$_SERVER; |
} else { |
$var = &$GLOBALS['HTTP_SERVER_VARS']; |
} |
break; |
case 'session' : |
if (isset($_SESSION)) { |
$var = &$_SESSION; |
} else { |
$var = &$GLOBALS['HTTP_SESSION_VARS']; |
} |
break; |
case 'post' : |
if (isset($_POST)) { |
$var = &$_POST; |
} else { |
$var = &$GLOBALS['HTTP_POST_VARS']; |
} |
break; |
case 'cookie' : |
if (isset($_COOKIE)) { |
$var = &$_COOKIE; |
} else { |
$var = &$GLOBALS['HTTP_COOKIE_VARS']; |
} |
break; |
case 'get' : |
if (isset($_GET)) { |
$var = &$_GET; |
} else { |
$var = &$GLOBALS['HTTP_GET_VARS']; |
} |
break; |
default: |
break; |
} |
return $var; |
} |
// }}} |
} |
?> |