1. Import
This commit is contained in:
874
html/illt/DB.php
Normal file
874
html/illt/DB.php
Normal file
@@ -0,0 +1,874 @@
|
||||
<?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: Stig Bakken <ssb@fast.no> |
|
||||
// | Tomas V.V.Cox <cox@idecnet.com> |
|
||||
// +----------------------------------------------------------------------+
|
||||
//
|
||||
// $Id: DB.php,v 1.86.2.2 2002/04/09 19:04:02 ssb Exp $
|
||||
//
|
||||
// Database independent query interface.
|
||||
//
|
||||
|
||||
require_once "PEAR.php";
|
||||
|
||||
/*
|
||||
* The method mapErrorCode in each DB_dbtype implementation maps
|
||||
* native error codes to one of these.
|
||||
*
|
||||
* If you add an error code here, make sure you also add a textual
|
||||
* version of it in DB::errorMessage().
|
||||
*/
|
||||
|
||||
define("DB_OK", 1);
|
||||
define("DB_ERROR", -1);
|
||||
define("DB_ERROR_SYNTAX", -2);
|
||||
define("DB_ERROR_CONSTRAINT", -3);
|
||||
define("DB_ERROR_NOT_FOUND", -4);
|
||||
define("DB_ERROR_ALREADY_EXISTS", -5);
|
||||
define("DB_ERROR_UNSUPPORTED", -6);
|
||||
define("DB_ERROR_MISMATCH", -7);
|
||||
define("DB_ERROR_INVALID", -8);
|
||||
define("DB_ERROR_NOT_CAPABLE", -9);
|
||||
define("DB_ERROR_TRUNCATED", -10);
|
||||
define("DB_ERROR_INVALID_NUMBER", -11);
|
||||
define("DB_ERROR_INVALID_DATE", -12);
|
||||
define("DB_ERROR_DIVZERO", -13);
|
||||
define("DB_ERROR_NODBSELECTED", -14);
|
||||
define("DB_ERROR_CANNOT_CREATE", -15);
|
||||
define("DB_ERROR_CANNOT_DELETE", -16);
|
||||
define("DB_ERROR_CANNOT_DROP", -17);
|
||||
define("DB_ERROR_NOSUCHTABLE", -18);
|
||||
define("DB_ERROR_NOSUCHFIELD", -19);
|
||||
define("DB_ERROR_NEED_MORE_DATA", -20);
|
||||
define("DB_ERROR_NOT_LOCKED", -21);
|
||||
define("DB_ERROR_VALUE_COUNT_ON_ROW", -22);
|
||||
define("DB_ERROR_INVALID_DSN", -23);
|
||||
define("DB_ERROR_CONNECT_FAILED", -24);
|
||||
define("DB_ERROR_EXTENSION_NOT_FOUND",-25);
|
||||
define("DB_ERROR_NOSUCHDB", -25);
|
||||
define("DB_ERROR_ACCESS_VIOLATION", -26);
|
||||
|
||||
/*
|
||||
* Warnings are not detected as errors by DB::isError(), and are not
|
||||
* fatal. You can detect whether an error is in fact a warning with
|
||||
* DB::isWarning().
|
||||
*/
|
||||
|
||||
define('DB_WARNING', -1000);
|
||||
define('DB_WARNING_READ_ONLY', -1001);
|
||||
|
||||
/*
|
||||
* These constants are used when storing information about prepared
|
||||
* statements (using the "prepare" method in DB_dbtype).
|
||||
*
|
||||
* The prepare/execute model in DB is mostly borrowed from the ODBC
|
||||
* extension, in a query the "?" character means a scalar parameter.
|
||||
* There are two extensions though, a "&" character means an opaque
|
||||
* parameter. An opaque parameter is simply a file name, the real
|
||||
* data are in that file (useful for putting uploaded files into your
|
||||
* database and such). The "!" char means a parameter that must be
|
||||
* left as it is.
|
||||
* They modify the quote behavoir:
|
||||
* DB_PARAM_SCALAR (?) => 'original string quoted'
|
||||
* DB_PARAM_OPAQUE (&) => 'string from file quoted'
|
||||
* DB_PARAM_MISC (!) => original string
|
||||
*/
|
||||
|
||||
define('DB_PARAM_SCALAR', 1);
|
||||
define('DB_PARAM_OPAQUE', 2);
|
||||
define('DB_PARAM_MISC', 3);
|
||||
|
||||
/*
|
||||
* These constants define different ways of returning binary data
|
||||
* from queries. Again, this model has been borrowed from the ODBC
|
||||
* extension.
|
||||
*
|
||||
* DB_BINMODE_PASSTHRU sends the data directly through to the browser
|
||||
* when data is fetched from the database.
|
||||
* DB_BINMODE_RETURN lets you return data as usual.
|
||||
* DB_BINMODE_CONVERT returns data as well, only it is converted to
|
||||
* hex format, for example the string "123" would become "313233".
|
||||
*/
|
||||
|
||||
define('DB_BINMODE_PASSTHRU', 1);
|
||||
define('DB_BINMODE_RETURN', 2);
|
||||
define('DB_BINMODE_CONVERT', 3);
|
||||
|
||||
/**
|
||||
* This is a special constant that tells DB the user hasn't specified
|
||||
* any particular get mode, so the default should be used.
|
||||
*/
|
||||
|
||||
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: normally the first level of arrays
|
||||
* is the row number, and the second level indexed by column number or name.
|
||||
* DB_FETCHMODE_FLIPPED switches this order, so the first level of arrays
|
||||
* is the column name, and the second level the row number.
|
||||
*/
|
||||
|
||||
define('DB_FETCHMODE_FLIPPED', 4);
|
||||
|
||||
/* for compatibility */
|
||||
|
||||
define('DB_GETMODE_ORDERED', DB_FETCHMODE_ORDERED);
|
||||
define('DB_GETMODE_ASSOC', DB_FETCHMODE_ASSOC);
|
||||
define('DB_GETMODE_FLIPPED', DB_FETCHMODE_FLIPPED);
|
||||
|
||||
/**
|
||||
* these are constants for the tableInfo-function
|
||||
* they are bitwised or'ed. so if there are more constants to be defined
|
||||
* in the future, adjust DB_TABLEINFO_FULL accordingly
|
||||
*/
|
||||
|
||||
define('DB_TABLEINFO_ORDER', 1);
|
||||
define('DB_TABLEINFO_ORDERTABLE', 2);
|
||||
define('DB_TABLEINFO_FULL', 3);
|
||||
|
||||
|
||||
/**
|
||||
* 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):
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
* @package DB
|
||||
* @author Stig Bakken <ssb@fast.no>
|
||||
* @since PHP 4.0
|
||||
*/
|
||||
|
||||
class DB
|
||||
{
|
||||
/**
|
||||
* Create a new DB connection object for the specified database
|
||||
* type
|
||||
*
|
||||
* @param string $type database type, for example "mysql"
|
||||
*
|
||||
* @return mixed a newly created DB object, or a DB error code on
|
||||
* error
|
||||
*
|
||||
* access public
|
||||
*/
|
||||
|
||||
function &factory($type)
|
||||
{
|
||||
@include_once("DB/${type}.php");
|
||||
|
||||
$classname = "DB_${type}";
|
||||
|
||||
if (!class_exists($classname)) {
|
||||
return PEAR::raiseError(null, DB_ERROR_NOT_FOUND,
|
||||
null, null, null, 'DB_Error', true);
|
||||
}
|
||||
|
||||
@$obj =& new $classname;
|
||||
|
||||
return $obj;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new DB connection object and connect to the specified
|
||||
* database
|
||||
*
|
||||
* @param mixed $dsn "data source name", see the DB::parseDSN
|
||||
* method for a description of the dsn format. Can also be
|
||||
* specified as an array of the format returned by DB::parseDSN.
|
||||
*
|
||||
* @param mixed $options An associative array of option names and
|
||||
* their values. For backwards compatibility, this parameter may
|
||||
* also be a boolean that tells whether the connection should be
|
||||
* persistent. See DB_common::setOption for more information on
|
||||
* connection options.
|
||||
*
|
||||
* @return mixed a newly created DB connection object, or a DB
|
||||
* error object on error
|
||||
*
|
||||
* @see DB::parseDSN
|
||||
* @see DB::isError
|
||||
* @see DB_common::setOption
|
||||
*/
|
||||
function &connect($dsn, $options = false)
|
||||
{
|
||||
if (is_array($dsn)) {
|
||||
$dsninfo = $dsn;
|
||||
} else {
|
||||
$dsninfo = DB::parseDSN($dsn);
|
||||
}
|
||||
$type = $dsninfo["phptype"];
|
||||
|
||||
if (is_array($options) && 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)) {
|
||||
return PEAR::raiseError(null, DB_ERROR_NOT_FOUND,
|
||||
null, null, null, 'DB_Error', true);
|
||||
}
|
||||
|
||||
@$obj =& new $classname;
|
||||
|
||||
if (is_array($options)) {
|
||||
foreach ($options as $option => $value) {
|
||||
$test = $obj->setOption($option, $value);
|
||||
if (DB::isError($test)) {
|
||||
return $test;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
$obj->setOption('persistent', $options);
|
||||
}
|
||||
$err = $obj->connect($dsninfo, $obj->getOption('persistent'));
|
||||
if (DB::isError($err)) {
|
||||
$err->addUserInfo($dsn);
|
||||
return $err;
|
||||
}
|
||||
|
||||
return $obj;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the DB API version
|
||||
*
|
||||
* @return int the DB API version number
|
||||
*
|
||||
* @access public
|
||||
*/
|
||||
function apiVersion()
|
||||
{
|
||||
return 2;
|
||||
}
|
||||
|
||||
/**
|
||||
* Tell whether a result code from a DB method is an error
|
||||
*
|
||||
* @param $value int result code
|
||||
*
|
||||
* @return bool whether $value is an error
|
||||
*
|
||||
* @access public
|
||||
*/
|
||||
function isError($value)
|
||||
{
|
||||
return (is_object($value) &&
|
||||
(get_class($value) == 'db_error' ||
|
||||
is_subclass_of($value, 'db_error')));
|
||||
}
|
||||
|
||||
/**
|
||||
* Tell whether a query is a data manipulation query (insert,
|
||||
* update or delete) or a data definition query (create, drop,
|
||||
* alter, grant, revoke).
|
||||
*
|
||||
* @access public
|
||||
*
|
||||
* @param string $query the query
|
||||
*
|
||||
* @return boolean whether $query is a data manipulation query
|
||||
*/
|
||||
function isManip($query)
|
||||
{
|
||||
$manips = 'INSERT|UPDATE|DELETE|'.'REPLACE|CREATE|DROP|'.
|
||||
'ALTER|GRANT|REVOKE|'.'LOCK|UNLOCK';
|
||||
if (preg_match('/^\s*"?('.$manips.')\s+/i', $query)) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Tell whether a result code from a DB method is a warning.
|
||||
* Warnings differ from errors in that they are generated by DB,
|
||||
* and are not fatal.
|
||||
*
|
||||
* @param mixed $value result value
|
||||
*
|
||||
* @return boolean whether $value is a warning
|
||||
*
|
||||
* @access public
|
||||
*/
|
||||
function isWarning($value)
|
||||
{
|
||||
return (is_object($value) &&
|
||||
(get_class($value) == "db_warning" ||
|
||||
is_subclass_of($value, "db_warning")));
|
||||
}
|
||||
|
||||
/**
|
||||
* Return a textual error message for a DB error code
|
||||
*
|
||||
* @param integer $value error code
|
||||
*
|
||||
* @return string 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_ALREADY_EXISTS => 'already exists',
|
||||
DB_ERROR_CANNOT_CREATE => 'can not create',
|
||||
DB_ERROR_CANNOT_DELETE => 'can not delete',
|
||||
DB_ERROR_CANNOT_DROP => 'can not drop',
|
||||
DB_ERROR_CONSTRAINT => 'constraint violation',
|
||||
DB_ERROR_DIVZERO => 'division by zero',
|
||||
DB_ERROR_INVALID => 'invalid',
|
||||
DB_ERROR_INVALID_DATE => 'invalid date or time',
|
||||
DB_ERROR_INVALID_NUMBER => 'invalid number',
|
||||
DB_ERROR_MISMATCH => 'mismatch',
|
||||
DB_ERROR_NODBSELECTED => 'no database selected',
|
||||
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_VALUE_COUNT_ON_ROW => 'value count on row',
|
||||
DB_ERROR_INVALID_DSN => 'invalid DSN',
|
||||
DB_ERROR_CONNECT_FAILED => 'connect failed',
|
||||
DB_OK => 'no error',
|
||||
DB_WARNING => 'unknown warning',
|
||||
DB_WARNING_READ_ONLY => 'read only',
|
||||
DB_ERROR_NEED_MORE_DATA => 'insufficient data supplied',
|
||||
DB_ERROR_EXTENSION_NOT_FOUND=> 'extension not found',
|
||||
DB_ERROR_NOSUCHDB => 'no such database',
|
||||
DB_ERROR_ACCESS_VIOLATION => 'insufficient permissions'
|
||||
);
|
||||
}
|
||||
|
||||
if (DB::isError($value)) {
|
||||
$value = $value->getCode();
|
||||
}
|
||||
|
||||
return isset($errorMessages[$value]) ? $errorMessages[$value] : $errorMessages[DB_ERROR];
|
||||
}
|
||||
|
||||
/**
|
||||
* Parse a data source name
|
||||
*
|
||||
* A array with the following keys will be returned:
|
||||
* 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
|
||||
*
|
||||
* The format of the supplied DSN is in its fullest form:
|
||||
*
|
||||
* phptype(dbsyntax)://username:password@protocol+hostspec/database
|
||||
*
|
||||
* Most variations are allowed:
|
||||
*
|
||||
* phptype://username:password@protocol+hostspec:110//usr/db_file.db
|
||||
* phptype://username:password@hostspec/database_name
|
||||
* phptype://username:password@hostspec
|
||||
* phptype://username@hostspec
|
||||
* phptype://hostspec/database
|
||||
* phptype://hostspec
|
||||
* phptype(dbsyntax)
|
||||
* phptype
|
||||
*
|
||||
* @param string $dsn Data Source Name to be parsed
|
||||
*
|
||||
* @return array an associative array
|
||||
*
|
||||
* @author Tomas V.V.Cox <cox@idecnet.com>
|
||||
*/
|
||||
function parseDSN($dsn)
|
||||
{
|
||||
if (is_array($dsn)) {
|
||||
return $dsn;
|
||||
}
|
||||
|
||||
$parsed = array(
|
||||
'phptype' => false,
|
||||
'dbsyntax' => false,
|
||||
'username' => false,
|
||||
'password' => false,
|
||||
'protocol' => false,
|
||||
'hostspec' => false,
|
||||
'port' => false,
|
||||
'socket' => false,
|
||||
'database' => false
|
||||
);
|
||||
|
||||
// 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'] = (empty($arr[2])) ? $arr[1] : $arr[2];
|
||||
} else {
|
||||
$parsed['phptype'] = $str;
|
||||
$parsed['dbsyntax'] = $str;
|
||||
}
|
||||
|
||||
if (empty($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'] = urldecode(substr($str, 0, $pos));
|
||||
$parsed['password'] = urldecode(substr($str, $pos + 1));
|
||||
} else {
|
||||
$parsed['username'] = urldecode($str);
|
||||
}
|
||||
}
|
||||
|
||||
// Find protocol and hostspec
|
||||
|
||||
// $dsn => proto(proto_opts)/database
|
||||
if (preg_match('|^(.+?)\((.*?)\)/?(.*?)$|', $dsn, $match)) {
|
||||
$proto = $match[1];
|
||||
$proto_opts = (!empty($match[2])) ? $match[2] : false;
|
||||
$dsn = $match[3];
|
||||
|
||||
// $dsn => protocol+hostspec/database (old format)
|
||||
} else {
|
||||
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 = urldecode($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 (!empty($dsn)) {
|
||||
// /database
|
||||
if (($pos = strpos($dsn, '?')) === false) {
|
||||
$parsed['database'] = $dsn;
|
||||
// /database?param1=value1¶m2=value2
|
||||
} else {
|
||||
$parsed['database'] = 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] = urldecode($value);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $parsed;
|
||||
}
|
||||
|
||||
/**
|
||||
* Load a PHP database extension if it is not loaded already.
|
||||
*
|
||||
* @access public
|
||||
*
|
||||
* @param string $name the base name of the extension (without the .so or
|
||||
* .dll suffix)
|
||||
*
|
||||
* @return boolean true if the extension was already or successfully
|
||||
* loaded, false if it could not be loaded
|
||||
*/
|
||||
function assertExtension($name)
|
||||
{
|
||||
if (!extension_loaded($name)) {
|
||||
$dlext = OS_WINDOWS ? '.dll' : '.so';
|
||||
@dl($name . $dlext);
|
||||
}
|
||||
return extension_loaded($name);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* DB_Error implements a class for reporting portable database error
|
||||
* messages.
|
||||
*
|
||||
* @package DB
|
||||
* @author Stig Bakken <ssb@fast.no>
|
||||
*/
|
||||
class DB_Error extends PEAR_Error
|
||||
{
|
||||
/**
|
||||
* DB_Error constructor.
|
||||
*
|
||||
* @param mixed $code DB error code, or string with error message.
|
||||
* @param integer $mode what "error mode" to operate in
|
||||
* @param integer $level what error level to use for $mode & PEAR_ERROR_TRIGGER
|
||||
* @param smixed $debuginfo additional debug info, such as the last query
|
||||
*
|
||||
* @access public
|
||||
*
|
||||
* @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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* DB_Warning implements a class for reporting portable database
|
||||
* warning messages.
|
||||
*
|
||||
* @package DB
|
||||
* @author Stig Bakken <ssb@fast.no>
|
||||
*/
|
||||
class DB_Warning extends PEAR_Error
|
||||
{
|
||||
/**
|
||||
* DB_Warning constructor.
|
||||
*
|
||||
* @param mixed $code DB error code, or string with error message.
|
||||
* @param integer $mode what "error mode" to operate in
|
||||
* @param integer $level what error level to use for $mode == PEAR_ERROR_TRIGGER
|
||||
* @param mmixed $debuginfo additional debug info, such as the last query
|
||||
*
|
||||
* @access public
|
||||
*
|
||||
* @see PEAR_Error
|
||||
*/
|
||||
|
||||
function DB_Warning($code = DB_WARNING, $mode = PEAR_ERROR_RETURN,
|
||||
$level = E_USER_NOTICE, $debuginfo = null)
|
||||
{
|
||||
if (is_int($code)) {
|
||||
$this->PEAR_Error('DB Warning: ' . DB::errorMessage($code), $code, $mode, $level, $debuginfo);
|
||||
} else {
|
||||
$this->PEAR_Error("DB Warning: $code", 0, $mode, $level, $debuginfo);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 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.
|
||||
*
|
||||
* @package DB
|
||||
* @author Stig Bakken <ssb@fast.no>
|
||||
*/
|
||||
|
||||
class DB_result
|
||||
{
|
||||
var $dbh;
|
||||
var $result;
|
||||
var $row_counter = null;
|
||||
/**
|
||||
* for limit queries, the row to start fetching
|
||||
* @var integer
|
||||
*/
|
||||
var $limit_from = null;
|
||||
|
||||
/**
|
||||
* for limit queries, the number of rows to fetch
|
||||
* @var integer
|
||||
*/
|
||||
var $limit_count = null;
|
||||
|
||||
/**
|
||||
* DB_result constructor.
|
||||
* @param resource $dbh DB object reference
|
||||
* @param resource $result result resource id
|
||||
*/
|
||||
|
||||
function DB_result(&$dbh, $result)
|
||||
{
|
||||
$this->dbh = &$dbh;
|
||||
$this->result = $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Fetch and return a row of data (it uses driver->fetchInto for that)
|
||||
* @param int $fetchmode format of fetched row
|
||||
* @param int $rownum the row number to fetch
|
||||
*
|
||||
* @return array a row of data, NULL on no more rows or PEAR_Error on error
|
||||
*
|
||||
* @access public
|
||||
*/
|
||||
function fetch_assoc($fetchmode = DB_FETCHMODE_DEFAULT, $rownum=null)
|
||||
{
|
||||
if ($fetchmode === DB_FETCHMODE_DEFAULT) {
|
||||
$fetchmode = $this->dbh->fetchmode;
|
||||
}
|
||||
if ($fetchmode === DB_FETCHMODE_OBJECT) {
|
||||
$fetchmode = DB_FETCHMODE_ASSOC;
|
||||
$object_class = $this->dbh->fetchmode_object_class;
|
||||
}
|
||||
if ($this->limit_from !== null) {
|
||||
if ($this->row_counter === null) {
|
||||
$this->row_counter = $this->limit_from;
|
||||
// For Interbase
|
||||
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))
|
||||
{
|
||||
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) {
|
||||
return $res;
|
||||
}
|
||||
if (isset($object_class)) {
|
||||
// default mode specified in DB_common::fetchmode_object_class property
|
||||
if ($object_class == 'stdClass') {
|
||||
$ret = (object) $arr;
|
||||
} else {
|
||||
$ret =& new $object_class($arr);
|
||||
}
|
||||
return $ret;
|
||||
}
|
||||
return $arr;
|
||||
}
|
||||
|
||||
/**
|
||||
* Fetch a row of data into an existing variable.
|
||||
*
|
||||
* @param mixed $arr reference to data containing the row
|
||||
* @param integer $fetchmode format of fetched row
|
||||
* @param integer $rownum the row number to fetch
|
||||
*
|
||||
* @return mixed DB_OK on success, NULL on no more rows or
|
||||
* a DB_Error object on error
|
||||
*
|
||||
* @access public
|
||||
*/
|
||||
function fetchInto(&$arr, $fetchmode = DB_FETCHMODE_DEFAULT, $rownum=null)
|
||||
{
|
||||
if ($fetchmode === DB_FETCHMODE_DEFAULT) {
|
||||
$fetchmode = $this->dbh->fetchmode;
|
||||
}
|
||||
if ($fetchmode === DB_FETCHMODE_OBJECT) {
|
||||
$fetchmode = DB_FETCHMODE_ASSOC;
|
||||
$object_class = $this->dbh->fetchmode_object_class;
|
||||
}
|
||||
if ($this->limit_from !== null) {
|
||||
if ($this->row_counter === null) {
|
||||
$this->row_counter = $this->limit_from;
|
||||
// For Interbase
|
||||
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))
|
||||
{
|
||||
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) && isset($object_class)) {
|
||||
// default mode specified in DB_common::fetchmode_object_class property
|
||||
if ($object_class == 'stdClass') {
|
||||
$arr = (object) $arr;
|
||||
} else {
|
||||
$arr = new $object_class($arr);
|
||||
}
|
||||
}
|
||||
return $res;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the the number of columns in a result set.
|
||||
*
|
||||
* @return int the number of columns, or a DB error
|
||||
*
|
||||
* @access public
|
||||
*/
|
||||
function numCols()
|
||||
{
|
||||
return $this->dbh->numCols($this->result);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the number of rows in a result set.
|
||||
*
|
||||
* @return int the number of rows, or a DB error
|
||||
*
|
||||
* @access public
|
||||
*/
|
||||
function numRows()
|
||||
{
|
||||
return $this->dbh->numRows($this->result);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the next result if a batch of queries was executed.
|
||||
*
|
||||
* @return bool true if a new result is available or false if not.
|
||||
*
|
||||
* @access public
|
||||
*/
|
||||
function nextResult()
|
||||
{
|
||||
return $this->dbh->nextResult($this->result);
|
||||
}
|
||||
|
||||
/**
|
||||
* Frees the resources allocated for this result set.
|
||||
* @return int error code
|
||||
*
|
||||
* @access public
|
||||
*/
|
||||
function free()
|
||||
{
|
||||
$err = $this->dbh->freeResult($this->result);
|
||||
if(DB::isError($err)) {
|
||||
return $err;
|
||||
}
|
||||
$this->result = false;
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated
|
||||
*/
|
||||
function tableInfo($mode = null)
|
||||
{
|
||||
return $this->dbh->tableInfo($this->result, $mode);
|
||||
}
|
||||
|
||||
/**
|
||||
* returns the actual rows number
|
||||
* @return integer
|
||||
*/
|
||||
function getRowCounter()
|
||||
{
|
||||
return $this->row_counter;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Pear DB Row Object
|
||||
* @see DB_common::setFetchMode()
|
||||
*/
|
||||
class DB_row
|
||||
{
|
||||
/**
|
||||
* constructor
|
||||
*
|
||||
* @param resource row data as array
|
||||
*/
|
||||
function DB_row(&$arr)
|
||||
{
|
||||
for (reset($arr); $key = key($arr); next($arr)) {
|
||||
$this->$key = &$arr[$key];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
?>
|
||||
90
html/illt/DB/IDEAS
Normal file
90
html/illt/DB/IDEAS
Normal file
@@ -0,0 +1,90 @@
|
||||
Abstracted Types (Stig)
|
||||
-----------------------
|
||||
|
||||
DB needs a set of types representing the most commonly used types in
|
||||
all backends. This type set could also be geared towards integration
|
||||
with things like XML-RPC/SOAP implementations, HTML form classes, etc.
|
||||
|
||||
Real Query Parser (Stig)
|
||||
------------------------
|
||||
|
||||
With a real query parser, DB can implement more of its portability
|
||||
based on the query, instead of having support functions for
|
||||
everything. One example would be LIMIT, another "INSERT
|
||||
... RETURNING".
|
||||
|
||||
Portable transactions (Stig)
|
||||
----------------------------
|
||||
|
||||
If DB can parse queries enough to determine what tables are affected
|
||||
by queries, it should be possible to make a replayable transaction
|
||||
log. GNOME uses an XML format for configuration data that lets you
|
||||
checkpoint state once in a while, and revert to that state later.
|
||||
With a similar approach for transactions in DB we can implement
|
||||
portable transactions and checkpointing even for the databases that
|
||||
don't support them.
|
||||
|
||||
|
||||
Error reporting clean-up/debug (Tomas)
|
||||
-------------------------------------
|
||||
Now each driver has its own raiseError method, common has a raiseError and
|
||||
DB has a DB_error class and its own isError() method. This error stuff
|
||||
overhead could be simplified with only one raiseError, droping the DB Error
|
||||
class and also the DB::isError() (use the PEAR.php ones instead).
|
||||
Other idea could be to add a system for allowing people access to all the
|
||||
queries sended by PEAR DB to the backend. Also a new PEAR_ERROR_DEBUG
|
||||
flag that automatically (show|triggers) debug info, perhaps
|
||||
with a new PEAR_(Warning|Debug) object.
|
||||
|
||||
Quote clean-up (Stig)
|
||||
---------------------
|
||||
1. Keep quote and quoteString, but move quoting of strings back into
|
||||
quoteString and make quote call it for strings.
|
||||
|
||||
2. Add an optional "operator" parameter to quote that is one of "=",
|
||||
"<", ">" or "<>" that will be inserted in front of the quoted value
|
||||
unless it is NULL, in which case it will be converted to "IS" (for
|
||||
"=") or "IS NOT" (for the others).
|
||||
|
||||
Auto free statements (Tomas)
|
||||
----------------------------
|
||||
By setting a param in query() or for the hole DB instance, PEAR DB
|
||||
could auto-free results in DB_result->fetch(Into|Row) when the driver
|
||||
returns false.
|
||||
|
||||
Datatypes in prepare syntax (Tomas)
|
||||
-----------------------------------
|
||||
Extend the actual prepare/execute placeholders to support data types, both
|
||||
to check the data introduced to the query and to "cast" the result
|
||||
to native php data types. Ex:
|
||||
|
||||
$sql = "INSERT INTO table VALUES ({{int(4)}}, {{bool}}, {{date('Y-m-d')}})";
|
||||
$row = $db->query($sql, array(8, 't', '2001-04-1'));
|
||||
|
||||
Format: {{<data_type>(<param1>,<param2>)}}
|
||||
|
||||
"param" could be the max lenght of the data, date formats, not_null
|
||||
checks or default values.
|
||||
|
||||
Other ideas could be:
|
||||
|
||||
1)
|
||||
$sql = "INSERT INTO table VALUES (?, ?, ?)";
|
||||
$sth = $db->prepare($sql, array('int(4)', 'bool', 'date');
|
||||
$res = $db->execute($sth, array($a, $b, $c);
|
||||
|
||||
2)
|
||||
$sql = "INSERT INTO table VALUES (?, ?, ?)";
|
||||
$params = array(
|
||||
0 => array($a, 'int(4)'),
|
||||
1 => array($b, 'bool')
|
||||
);
|
||||
$res = $db->query($sql, $params);
|
||||
|
||||
Auto connect feature (Tomas)
|
||||
----------------------------
|
||||
Add the ability to create for example a light and dump DB object which
|
||||
will only set up the connection when needed. With that people could
|
||||
create the DB object in a common prepend or default file without the
|
||||
need to waste system resources if the use of the database is finally
|
||||
not needed.
|
||||
15
html/illt/DB/MAINTAINERS
Normal file
15
html/illt/DB/MAINTAINERS
Normal file
@@ -0,0 +1,15 @@
|
||||
Maintainers for DB database backends/drivers:
|
||||
|
||||
ibase : Ludovico Magnocavallo <ludo@sumatrasolutions.com>
|
||||
msql :
|
||||
mssql : Frank M. Kromann <frank@frontbase.com>
|
||||
mysql : Stig Bakken <ssb@fast.no>
|
||||
oci8 : Tomas V.V.Cox <cox@idecnet.com>
|
||||
odbc : Tomas V.V.Cox <cox@idecnet.com>
|
||||
pgsql : Rui Hirokawa <rui_hirokawa@ybb.ne.jp>
|
||||
Stig Bakken <ssb@fast.no>
|
||||
sybase :
|
||||
ifx : Tomas V.V.Cox <cox@idecnet.com>
|
||||
fbsql : Frank M. Kromann <frank@frontbase.com>
|
||||
dbase : Tomas V.V.Cox <cox@idecnet.com>
|
||||
ldap : Ludovico Magnocavallo <ludo@sumatrasolutions.com>
|
||||
38
html/illt/DB/STATUS
Normal file
38
html/illt/DB/STATUS
Normal file
@@ -0,0 +1,38 @@
|
||||
DB driver feature matrix:
|
||||
|
||||
Symbols:
|
||||
"x" - implemented, but without tests
|
||||
"t" - implemented, but one or more tests fail
|
||||
"T" - implemented, passing all tests
|
||||
"e" - emulated, without tests
|
||||
"E" - emulated, passing all tests
|
||||
"n" - returns "not capable"
|
||||
"-" - no implementation of this feature
|
||||
|
||||
|
||||
fbsql ifx mssql oci8 pgsql
|
||||
FEATURE | ibase | msql | mysql | odbc | sybase
|
||||
simpleQuery x T x x x T T x T x
|
||||
numCols x T x x x T T x T x
|
||||
numRows x n n x x T E x T n
|
||||
errorNative x n x n n T x x T n
|
||||
prepare/execute e x e e e E T e E e
|
||||
sequences e T n n n E T n T n
|
||||
affectedRows x n x x n T T x T x
|
||||
fetch modes x T x x x T T x T x
|
||||
fetch row by number x n x x x x n x x x
|
||||
transactions x x n n x x x x x n
|
||||
auto-commit x x n n n n x x x n
|
||||
error mapping x x e - - T T x E -
|
||||
tableInfo x n n n x T n n x n
|
||||
|
||||
|
||||
Info returned by getListOf
|
||||
|
||||
fbsql ifx mssql oci8 pgsql
|
||||
TYPE | ibase | msql | mysql | odbc | sybase
|
||||
tables x - - - x x x - x x
|
||||
views - - - - x n - - x x
|
||||
users - - - - - x - - x -
|
||||
databases - - - - - x - - x -
|
||||
functions - - - - - - - - x -
|
||||
45
html/illt/DB/TESTERS
Normal file
45
html/illt/DB/TESTERS
Normal file
@@ -0,0 +1,45 @@
|
||||
How to run tests
|
||||
----------------
|
||||
|
||||
1) First you need the "run-tests.php" script located at the root
|
||||
directory of the PHP 4 source tar ball.
|
||||
|
||||
2) Download the lastest PEAR DB from CVS:
|
||||
|
||||
Where you want to place Pear files
|
||||
# cd /usr/local/lib
|
||||
Log to the repository (use "phpfi" as password):
|
||||
# cvs -d :pserver:cvsread@cvs.php.net:/repository login
|
||||
# cvs -d :pserver:cox@cvs.php.net:/repository co php4/run-tests.php
|
||||
# cvs -d :pserver:cvsread@cvs.php.net:/repository co php4/pear
|
||||
# cd php4
|
||||
# php -f run-tests.php -- <test file or directory>
|
||||
|
||||
<test file or directory> can be:
|
||||
|
||||
pear/DB/tests: Common PEAR DB tests
|
||||
pear/DB/tests/<backend>: Specific backend tests
|
||||
pear/DB/tests/driver: Common tests for all the drivers
|
||||
|
||||
|
||||
DB tester matrix
|
||||
----------------
|
||||
B - A - C - K - E - N - D - S
|
||||
TESTER ibase ifx msql mssql mysql oci8 odbc pgsql sybase fbsql
|
||||
John Horton - X - - - - - - - -
|
||||
Tim Zickus - - - - - X - - - -
|
||||
Tim Parkin - - - - - X - - - -
|
||||
Paul Gardiner - X - - - - - - - -
|
||||
Daniel, Adam - - - - - X - - - -
|
||||
szii@sziisoft.com - - - - - - X¹ - - -
|
||||
jmh3@linuxfreak.com - - - - - - - X - -
|
||||
Kevin Henrikson - - - - - X - - - -
|
||||
Stig Bakken - - - - X - - X - -
|
||||
Chuck Hagenbuch - - - X - - - - - -
|
||||
Ludovico Magnocavallo X - - - - - - - - -
|
||||
|
||||
MISSING TESTERS - - X - - - - - X X
|
||||
|
||||
Comments:
|
||||
|
||||
[1]: ODBC using IBM DB2
|
||||
1282
html/illt/DB/common.php
Normal file
1282
html/illt/DB/common.php
Normal file
File diff suppressed because it is too large
Load Diff
123
html/illt/DB/dbase.php
Normal file
123
html/illt/DB/dbase.php
Normal file
@@ -0,0 +1,123 @@
|
||||
<?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. |
|
||||
// +----------------------------------------------------------------------+
|
||||
// | Author: Tomas V.V.Cox <cox@idecnet.com> |
|
||||
// +----------------------------------------------------------------------+
|
||||
//
|
||||
// $Id: dbase.php,v 1.2 2002/02/28 08:27:08 sebastian Exp $
|
||||
//
|
||||
// Database independent query interface definition for PHP's dbase
|
||||
// extension.
|
||||
//
|
||||
// XXX legend:
|
||||
// You have to compile your PHP with the --enable-dbase option
|
||||
//
|
||||
|
||||
require_once "DB/common.php";
|
||||
|
||||
class DB_dbase extends DB_common
|
||||
{
|
||||
// {{{ properties
|
||||
|
||||
var $connection;
|
||||
var $phptype, $dbsyntax;
|
||||
var $prepare_tokens = array();
|
||||
var $prepare_types = array();
|
||||
var $transaction_opcount = 0;
|
||||
var $res_row = array();
|
||||
var $result = 0;
|
||||
|
||||
// }}}
|
||||
// {{{ constructor
|
||||
|
||||
/**
|
||||
* DB_mysql constructor.
|
||||
*
|
||||
* @access public
|
||||
*/
|
||||
|
||||
function DB_dbase()
|
||||
{
|
||||
$this->DB_common();
|
||||
$this->phptype = 'dbase';
|
||||
$this->dbsyntax = 'dbase';
|
||||
$this->features = array(
|
||||
'prepare' => false,
|
||||
'pconnect' => false,
|
||||
'transactions' => false,
|
||||
'limit' => false
|
||||
);
|
||||
$this->errorcode_map = array();
|
||||
}
|
||||
|
||||
function connect($dsninfo, $persistent = false)
|
||||
{
|
||||
if (!DB::assertExtension('dbase')) {
|
||||
return $this->raiseError(DB_ERROR_EXTENSION_NOT_FOUND);
|
||||
}
|
||||
$this->dsn = $dsninfo;
|
||||
ob_start();
|
||||
$conn = dbase_open($dsninfo['database'], 0);
|
||||
$error = ob_get_contents();
|
||||
ob_end_clean();
|
||||
if (!$conn) {
|
||||
return $this->raiseError(DB_ERROR_CONNECT_FAILED, null,
|
||||
null, null, strip_tags($error));
|
||||
}
|
||||
$this->connection = $conn;
|
||||
return DB_OK;
|
||||
}
|
||||
|
||||
function disconnect()
|
||||
{
|
||||
$ret = dbase_close($this->connection);
|
||||
$this->connection = null;
|
||||
return $ret;
|
||||
}
|
||||
|
||||
function &query($query = null)
|
||||
{
|
||||
// emulate result resources
|
||||
$this->res_row[$this->result] = 0;
|
||||
return new DB_result($this, $this->result++);
|
||||
}
|
||||
|
||||
function fetchInto($res, &$row, $fetchmode, $rownum = null)
|
||||
{
|
||||
if ($rownum === null) {
|
||||
$rownum = $this->res_row[$res]++;
|
||||
}
|
||||
if ($fetchmode & DB_FETCHMODE_ASSOC) {
|
||||
$row = @dbase_get_record_with_names($this->connection, $rownum);
|
||||
} else {
|
||||
$row = @dbase_get_record($this->connection, $rownum);
|
||||
}
|
||||
if (!$row) {
|
||||
return null;
|
||||
}
|
||||
return DB_OK;
|
||||
}
|
||||
|
||||
function numCols($foo)
|
||||
{
|
||||
return dbase_numfields($this->connection);
|
||||
}
|
||||
|
||||
function numRows($foo)
|
||||
{
|
||||
return dbase_numrecords($this->connection);
|
||||
}
|
||||
}
|
||||
?>
|
||||
618
html/illt/DB/fbsql.php
Normal file
618
html/illt/DB/fbsql.php
Normal file
@@ -0,0 +1,618 @@
|
||||
<?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. |
|
||||
// +----------------------------------------------------------------------+
|
||||
// | Author: Frank M. Kromann <frank@frontbase.com> |
|
||||
// +----------------------------------------------------------------------+
|
||||
//
|
||||
// $Id: fbsql.php,v 1.14 2002/02/28 08:27:08 sebastian Exp $
|
||||
//
|
||||
// Database independent query interface definition for PHP's FrontBase
|
||||
// extension.
|
||||
//
|
||||
|
||||
//
|
||||
// XXX legend:
|
||||
//
|
||||
// XXX ERRORMSG: The error message from the fbsql function should
|
||||
// be registered here.
|
||||
//
|
||||
|
||||
require_once "DB/common.php";
|
||||
|
||||
class DB_fbsql extends DB_common
|
||||
{
|
||||
// {{{ properties
|
||||
|
||||
var $connection;
|
||||
var $phptype, $dbsyntax;
|
||||
var $prepare_tokens = array();
|
||||
var $prepare_types = array();
|
||||
var $num_rows = array();
|
||||
var $fetchmode = DB_FETCHMODE_ORDERED; /* Default fetch mode */
|
||||
|
||||
// }}}
|
||||
// {{{ constructor
|
||||
|
||||
/**
|
||||
* DB_fbsql constructor.
|
||||
*
|
||||
* @access public
|
||||
*/
|
||||
|
||||
function DB_fbsql()
|
||||
{
|
||||
$this->DB_common();
|
||||
$this->phptype = 'fbsql';
|
||||
$this->dbsyntax = 'fbsql';
|
||||
$this->features = array(
|
||||
'prepare' => false,
|
||||
'pconnect' => true,
|
||||
'transactions' => true,
|
||||
'limit' => 'emulate'
|
||||
);
|
||||
$this->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,
|
||||
1046 => DB_ERROR_NODBSELECTED,
|
||||
1050 => DB_ERROR_ALREADY_EXISTS,
|
||||
1051 => DB_ERROR_NOSUCHTABLE,
|
||||
1054 => DB_ERROR_NOSUCHFIELD,
|
||||
1062 => DB_ERROR_ALREADY_EXISTS,
|
||||
1064 => DB_ERROR_SYNTAX,
|
||||
1100 => DB_ERROR_NOT_LOCKED,
|
||||
1136 => DB_ERROR_VALUE_COUNT_ON_ROW,
|
||||
1146 => DB_ERROR_NOSUCHTABLE,
|
||||
);
|
||||
}
|
||||
|
||||
// }}}
|
||||
|
||||
// {{{ connect()
|
||||
|
||||
/**
|
||||
* Connect to a database and log in as the specified user.
|
||||
*
|
||||
* @param $dsn the data source name (see DB::parseDSN for syntax)
|
||||
* @param $persistent (optional) whether the connection should
|
||||
* be persistent
|
||||
* @access public
|
||||
* @return int DB_OK on success, a DB error on failure
|
||||
*/
|
||||
|
||||
function connect($dsninfo, $persistent = false)
|
||||
{
|
||||
if (!DB::assertExtension('fbsql'))
|
||||
return $this->raiseError(DB_ERROR_EXTENSION_NOT_FOUND);
|
||||
|
||||
$this->dsn = $dsninfo;
|
||||
$dbhost = $dsninfo['hostspec'] ? $dsninfo['hostspec'] : 'localhost';
|
||||
$user = $dsninfo['username'];
|
||||
$pw = $dsninfo['password'];
|
||||
|
||||
$connect_function = $persistent ? 'fbsql_pconnect' : 'fbsql_connect';
|
||||
|
||||
ini_set('track_errors', true);
|
||||
if ($dbhost && $user && $pw) {
|
||||
$conn = @$connect_function($dbhost, $user, $pw);
|
||||
} elseif ($dbhost && $user) {
|
||||
$conn = @$connect_function($dbhost, $user);
|
||||
} elseif ($dbhost) {
|
||||
$conn = @$connect_function($dbhost);
|
||||
} else {
|
||||
$conn = false;
|
||||
}
|
||||
ini_restore("track_errors");
|
||||
if (empty($conn)) {
|
||||
if (empty($php_errormsg)) {
|
||||
return $this->raiseError(DB_ERROR_CONNECT_FAILED);
|
||||
} else {
|
||||
return $this->raiseError(DB_ERROR_CONNECT_FAILED, null, null,
|
||||
null, $php_errormsg);
|
||||
}
|
||||
}
|
||||
|
||||
if ($dsninfo['database']) {
|
||||
if (!fbsql_select_db($dsninfo['database'], $conn)) {
|
||||
return $this->fbsqlRaiseError();
|
||||
}
|
||||
}
|
||||
|
||||
$this->connection = $conn;
|
||||
return DB_OK;
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ disconnect()
|
||||
|
||||
/**
|
||||
* Log out and disconnect from the database.
|
||||
*
|
||||
* @access public
|
||||
*
|
||||
* @return bool TRUE on success, FALSE if not connected.
|
||||
*/
|
||||
function disconnect()
|
||||
{
|
||||
$ret = fbsql_close($this->connection);
|
||||
$this->connection = null;
|
||||
return $ret;
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ simpleQuery()
|
||||
|
||||
/**
|
||||
* Send a query to fbsql and return the results as a fbsql resource
|
||||
* identifier.
|
||||
*
|
||||
* @param the SQL query
|
||||
*
|
||||
* @access public
|
||||
*
|
||||
* @return mixed returns a valid fbsql result for successful SELECT
|
||||
* queries, DB_OK for other successful queries. A DB error is
|
||||
* returned 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;
|
||||
}
|
||||
$numrows = $this->numrows($result);
|
||||
if (is_object($numrows)) {
|
||||
return $numrows;
|
||||
}
|
||||
$this->num_rows[$result] = $numrows;
|
||||
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);
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ fetch_assoc()
|
||||
|
||||
/**
|
||||
* Fetch and return a row of data (it uses fetchInto for that)
|
||||
* @param $result fbsql result identifier
|
||||
* @param $fetchmode format of fetched row array
|
||||
* @param $rownum the absolute row number to fetch
|
||||
*
|
||||
* @return array a row of data, or false on error
|
||||
*/
|
||||
function fetch_assoc($result, $fetchmode = DB_FETCHMODE_DEFAULT, $rownum=null)
|
||||
{
|
||||
if ($fetchmode == DB_FETCHMODE_DEFAULT) {
|
||||
$fetchmode = $this->fetchmode;
|
||||
}
|
||||
$res = $this->fetchInto ($result, $arr, $fetchmode, $rownum);
|
||||
if ($res !== DB_OK) {
|
||||
return $res;
|
||||
}
|
||||
return $arr;
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ fetchInto()
|
||||
|
||||
/**
|
||||
* Fetch a row and insert the data into an existing array.
|
||||
*
|
||||
* @param $result fbsql result identifier
|
||||
* @param $arr (reference) array where data from the row is stored
|
||||
* @param $fetchmode how the array data should be indexed
|
||||
* @param $rownum the row number to fetch
|
||||
* @access public
|
||||
*
|
||||
* @return int DB_OK on success, a DB error on failure
|
||||
*/
|
||||
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);
|
||||
} else {
|
||||
$arr = @fbsql_fetch_row($result);
|
||||
}
|
||||
if (!$arr) {
|
||||
$errno = @fbsql_errno($this->connection);
|
||||
if (!$errno) {
|
||||
return NULL;
|
||||
}
|
||||
return $this->fbsqlRaiseError($errno);
|
||||
}
|
||||
return DB_OK;
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ freeResult()
|
||||
|
||||
/**
|
||||
* Free the internal resources associated with $result.
|
||||
*
|
||||
* @param $result fbsql result identifier or DB statement identifier
|
||||
*
|
||||
* @access public
|
||||
*
|
||||
* @return bool TRUE on success, FALSE if $result is invalid
|
||||
*/
|
||||
function freeResult($result)
|
||||
{
|
||||
if (is_resource($result)) {
|
||||
return fbsql_free_result($result);
|
||||
}
|
||||
|
||||
if (!isset($this->prepare_tokens[(int)$result])) {
|
||||
return false;
|
||||
}
|
||||
|
||||
unset($this->prepare_tokens[(int)$result]);
|
||||
unset($this->prepare_types[(int)$result]);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ autoCommit()
|
||||
|
||||
function autoCommit($onoff=false)
|
||||
{
|
||||
if ($onoff) {
|
||||
$this->query("SET COMMIT TRUE");
|
||||
} else {
|
||||
$this->query("SET COMMIT FALSE");
|
||||
}
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ commit()
|
||||
|
||||
function commit()
|
||||
{
|
||||
fbsql_commit();
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ rollback()
|
||||
|
||||
function rollback()
|
||||
{
|
||||
fbsql_rollback();
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ numCols()
|
||||
|
||||
/**
|
||||
* Get the number of columns in a result set.
|
||||
*
|
||||
* @param $result fbsql result identifier
|
||||
*
|
||||
* @access public
|
||||
*
|
||||
* @return int the number of columns per row in $result
|
||||
*/
|
||||
function numCols($result)
|
||||
{
|
||||
$cols = @fbsql_num_fields($result);
|
||||
|
||||
if (!$cols) {
|
||||
return $this->fbsqlRaiseError();
|
||||
}
|
||||
|
||||
return $cols;
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ numRows()
|
||||
|
||||
/**
|
||||
* Get the number of rows in a result set.
|
||||
*
|
||||
* @param $result fbsql result identifier
|
||||
*
|
||||
* @access public
|
||||
*
|
||||
* @return int the number of rows in $result
|
||||
*/
|
||||
function numRows($result)
|
||||
{
|
||||
$rows = @fbsql_num_rows($result);
|
||||
if ($rows === null) {
|
||||
return $this->fbsqlRaiseError();
|
||||
}
|
||||
return $rows;
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ affectedRows()
|
||||
|
||||
/**
|
||||
* Gets the number of rows affected by the data manipulation
|
||||
* query. For other queries, this function returns 0.
|
||||
*
|
||||
* @return number of rows affected by the last query
|
||||
*/
|
||||
|
||||
function affectedRows()
|
||||
{
|
||||
if (DB::isManip($this->last_query)) {
|
||||
$result = @fbsql_affected_rows($this->connection);
|
||||
} else {
|
||||
$result = 0;
|
||||
}
|
||||
return $result;
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ errorNative()
|
||||
|
||||
/**
|
||||
* Get the native error code of the last error (if any) that
|
||||
* occured on the current connection.
|
||||
*
|
||||
* @access public
|
||||
*
|
||||
* @return int native fbsql error code
|
||||
*/
|
||||
|
||||
function errorNative()
|
||||
{
|
||||
return fbsql_errno($this->connection);
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ nextId()
|
||||
|
||||
/**
|
||||
* Get the next value in a sequence. We emulate sequences
|
||||
* for fbsql. Will create the sequence if it does not exist.
|
||||
*
|
||||
* @access public
|
||||
*
|
||||
* @param $seq_name the name of the sequence
|
||||
*
|
||||
* @param $ondemand whether to create the sequence table on demand
|
||||
* (default is true)
|
||||
*
|
||||
* @return a sequence integer, or a DB error
|
||||
*/
|
||||
function nextId($seq_name, $ondemand = true)
|
||||
{
|
||||
$sqn = preg_replace('/[^a-z0-9_]/i', '_', $seq_name);
|
||||
$repeat = 0;
|
||||
do {
|
||||
$seqname = sprintf($this->getOption("seqname_format"), $sqn);
|
||||
$result = $this->query("INSERT INTO ${seqname} VALUES(NULL)");
|
||||
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 $result;
|
||||
}
|
||||
return fbsql_insert_id($this->connection);
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ createSequence()
|
||||
|
||||
function createSequence($seq_name)
|
||||
{
|
||||
$sqn = preg_replace('/[^a-z0-9_]/i', '_', $seq_name);
|
||||
$seqname = sprintf($this->getOption("seqname_format"), $sqn);
|
||||
return $this->query("CREATE TABLE ${seqname} ".
|
||||
'(id INTEGER UNSIGNED AUTO_INCREMENT NOT NULL,'.
|
||||
' PRIMARY KEY(id))');
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ dropSequence()
|
||||
|
||||
function dropSequence($seq_name)
|
||||
{
|
||||
$sqn = preg_replace('/[^a-z0-9_]/i', '_', $seq_name);
|
||||
$seqname = sprintf($this->getOption("seqname_format"), $sqn);
|
||||
return $this->query("DROP TABLE ${seqname} RESTRICT");
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ modifyQuery()
|
||||
|
||||
function modifyQuery($query)
|
||||
{
|
||||
if ($this->options['optimize'] == 'portability') {
|
||||
// "DELETE FROM table" gives 0 affected rows in fbsql.
|
||||
// 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;
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ fbsqlRaiseError()
|
||||
|
||||
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));
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ tableInfo()
|
||||
|
||||
function tableInfo($result, $mode = null) {
|
||||
$count = 0;
|
||||
$id = 0;
|
||||
$res = array();
|
||||
|
||||
/*
|
||||
* depending on $mode, metadata returns the following values:
|
||||
*
|
||||
* - mode is false (default):
|
||||
* $result[]:
|
||||
* [0]["table"] table name
|
||||
* [0]["name"] field name
|
||||
* [0]["type"] field type
|
||||
* [0]["len"] field length
|
||||
* [0]["flags"] field flags
|
||||
*
|
||||
* - mode is DB_TABLEINFO_ORDER
|
||||
* $result[]:
|
||||
* ["num_fields"] number of metadata records
|
||||
* [0]["table"] table name
|
||||
* [0]["name"] field name
|
||||
* [0]["type"] field type
|
||||
* [0]["len"] field length
|
||||
* [0]["flags"] field flags
|
||||
* ["order"][field name] index of field named "field name"
|
||||
* The last one is used, if you have a field name, but no index.
|
||||
* Test: if (isset($result['meta']['myfield'])) { ...
|
||||
*
|
||||
* - mode is DB_TABLEINFO_ORDERTABLE
|
||||
* the same as above. but additionally
|
||||
* ["ordertable"][table name][field name] index of field
|
||||
* named "field name"
|
||||
*
|
||||
* this is, because if you have fields from different
|
||||
* tables with the same field name * they override each
|
||||
* other with DB_TABLEINFO_ORDER
|
||||
*
|
||||
* you can combine DB_TABLEINFO_ORDER and
|
||||
* DB_TABLEINFO_ORDERTABLE with DB_TABLEINFO_ORDER |
|
||||
* DB_TABLEINFO_ORDERTABLE * or with DB_TABLEINFO_FULL
|
||||
*/
|
||||
|
||||
// if $result is a string, then we want information about a
|
||||
// table without a resultset
|
||||
if (is_string($result)) {
|
||||
$id = @fbsql_list_fields($this->dsn['database'],
|
||||
$result, $this->connection);
|
||||
if (empty($id)) {
|
||||
return $this->fbsqlRaiseError();
|
||||
}
|
||||
} else { // else we want information about a resultset
|
||||
$id = $result;
|
||||
if (empty($id)) {
|
||||
return $this->fbsqlRaiseError();
|
||||
}
|
||||
}
|
||||
|
||||
$count = @fbsql_num_fields($id);
|
||||
|
||||
// made this IF due to performance (one if is faster than $count if's)
|
||||
if (empty($mode)) {
|
||||
for ($i=0; $i<$count; $i++) {
|
||||
$res[$i]['table'] = @fbsql_field_table ($id, $i);
|
||||
$res[$i]['name'] = @fbsql_field_name ($id, $i);
|
||||
$res[$i]['type'] = @fbsql_field_type ($id, $i);
|
||||
$res[$i]['len'] = @fbsql_field_len ($id, $i);
|
||||
$res[$i]['flags'] = @fbsql_field_flags ($id, $i);
|
||||
}
|
||||
} else { // full
|
||||
$res["num_fields"]= $count;
|
||||
|
||||
for ($i=0; $i<$count; $i++) {
|
||||
$res[$i]['table'] = @fbsql_field_table ($id, $i);
|
||||
$res[$i]['name'] = @fbsql_field_name ($id, $i);
|
||||
$res[$i]['type'] = @fbsql_field_type ($id, $i);
|
||||
$res[$i]['len'] = @fbsql_field_len ($id, $i);
|
||||
$res[$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 (is_string($result)) {
|
||||
@fbsql_free_result($id);
|
||||
}
|
||||
return $res;
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ getSpecialQuery()
|
||||
|
||||
/**
|
||||
* Returns the query needed to get some backend info
|
||||
* @param string $type What kind of info you want to retrieve
|
||||
* @return string The SQL query string
|
||||
*/
|
||||
function getSpecialQuery($type)
|
||||
{
|
||||
switch ($type) {
|
||||
case 'tables':
|
||||
$sql = 'select "table_name" from information_schema.tables';
|
||||
break;
|
||||
default:
|
||||
return null;
|
||||
}
|
||||
return $sql;
|
||||
}
|
||||
|
||||
// }}}
|
||||
}
|
||||
|
||||
// TODO/wishlist:
|
||||
// longReadlen
|
||||
// binmode
|
||||
|
||||
?>
|
||||
592
html/illt/DB/ibase.php
Normal file
592
html/illt/DB/ibase.php
Normal file
@@ -0,0 +1,592 @@
|
||||
<?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. |
|
||||
// +----------------------------------------------------------------------+
|
||||
// | Author: Sterling Hughes <sterling@php.net> |
|
||||
// +----------------------------------------------------------------------+
|
||||
//
|
||||
// $Id: ibase.php,v 1.36.2.2 2002/04/09 19:04:13 ssb Exp $
|
||||
//
|
||||
// Database independent query interface definition for PHP's Interbase
|
||||
// extension.
|
||||
//
|
||||
|
||||
require_once 'DB/common.php';
|
||||
|
||||
class DB_ibase extends DB_common
|
||||
{
|
||||
var $connection;
|
||||
var $phptype, $dbsyntax;
|
||||
var $autocommit = 1;
|
||||
var $manip_query = array();
|
||||
|
||||
function DB_ibase()
|
||||
{
|
||||
$this->DB_common();
|
||||
$this->phptype = 'ibase';
|
||||
$this->dbsyntax = 'ibase';
|
||||
$this->features = array(
|
||||
'prepare' => true,
|
||||
'pconnect' => true,
|
||||
'transactions' => true,
|
||||
'limit' => false
|
||||
);
|
||||
// just a few of the tons of Interbase error codes listed in the
|
||||
// Language Reference section of the Interbase manual
|
||||
$this->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 => DB_ERROR_INVALID,
|
||||
-205 => DB_ERROR_NOSUCHFIELD,
|
||||
-206 => DB_ERROR_NOSUCHFIELD,
|
||||
-208 => DB_ERROR_INVALID,
|
||||
-219 => DB_ERROR_NOSUCHTABLE,
|
||||
-297 => DB_ERROR_CONSTRAINT,
|
||||
-530 => DB_ERROR_CONSTRAINT,
|
||||
-803 => DB_ERROR_CONSTRAINT,
|
||||
-551 => DB_ERROR_ACCESS_VIOLATION,
|
||||
-552 => DB_ERROR_ACCESS_VIOLATION,
|
||||
-922 => DB_ERROR_NOSUCHDB,
|
||||
-923 => DB_ERROR_CONNECT_FAILED,
|
||||
-924 => DB_ERROR_CONNECT_FAILED
|
||||
);
|
||||
}
|
||||
|
||||
function connect($dsninfo, $persistent = false)
|
||||
{
|
||||
if (!DB::assertExtension('interbase')) {
|
||||
return $this->raiseError(DB_ERROR_EXTENSION_NOT_FOUND);
|
||||
}
|
||||
$this->dsn = $dsninfo;
|
||||
$user = $dsninfo['username'];
|
||||
$pw = $dsninfo['password'];
|
||||
$dbhost = $dsninfo['hostspec'] ?
|
||||
($dsninfo['hostspec'] . ':/' . $dsninfo['database']) :
|
||||
$dsninfo['database'];
|
||||
|
||||
$connect_function = $persistent ? 'ibase_pconnect' : 'ibase_connect';
|
||||
|
||||
$params = array();
|
||||
$params[] = $dbhost;
|
||||
$params[] = !empty($user) ? $user : null;
|
||||
$params[] = !empty($pw) ? $pw : null;
|
||||
$params[] = isset($dsninfo['charset']) ? $dsninfo['charset'] : null;
|
||||
$params[] = isset($dsninfo['buffers']) ? $dsninfo['buffers'] : null;
|
||||
$params[] = isset($dsninfo['dialect']) ? $dsninfo['dialect'] : null;
|
||||
$params[] = isset($dsninfo['role']) ? $dsninfo['role'] : null;
|
||||
|
||||
/*
|
||||
if ($dbhost && $user && $pw) {
|
||||
$conn = $connect_function($dbhost, $user, $pw);
|
||||
} elseif ($dbhost && $user) {
|
||||
$conn = $connect_function($dbhost, $user);
|
||||
} elseif ($dbhost) {
|
||||
$conn = $connect_function($dbhost);
|
||||
} else {
|
||||
return $this->raiseError("no host, user or password");
|
||||
}
|
||||
*/
|
||||
$conn = @call_user_func_array($connect_function, $params);
|
||||
if (!$conn) {
|
||||
return $this->ibaseRaiseError(DB_ERROR_CONNECT_FAILED);
|
||||
}
|
||||
$this->connection = $conn;
|
||||
return DB_OK;
|
||||
}
|
||||
|
||||
function disconnect()
|
||||
{
|
||||
$ret = @ibase_close($this->connection);
|
||||
$this->connection = null;
|
||||
return $ret;
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
// Determine which queries that should return data, and which
|
||||
// should return an error code only.
|
||||
return DB::isManip($query) ? DB_OK : $result;
|
||||
}
|
||||
|
||||
// {{{ modifyLimitQuery()
|
||||
|
||||
/**
|
||||
* This method is used by backends to alter limited queries
|
||||
* Uses the new FIRST n SKIP n Firebird 1.0 syntax, so it is
|
||||
* only compatible with Firebird 1.x
|
||||
*
|
||||
* @param string $query query to modify
|
||||
* @param integer $from the row to start to fetching
|
||||
* @param integer $count the numbers of rows to fetch
|
||||
*
|
||||
* @return the new (modified) query
|
||||
* @author Ludovico Magnocavallo <ludo@sumatrasolutions.com>
|
||||
* @access private
|
||||
*/
|
||||
|
||||
function modifyLimitQuery($query, $from, $count)
|
||||
{
|
||||
if ($this->dsn['dbsyntax'] == 'firebird') {
|
||||
$from++; // SKIP starts from 1, ie SKIP 1 starts from the first record
|
||||
$query = preg_replace('/^\s*select\s(.*)$/is',
|
||||
"SELECT FIRST $count SKIP $from $1", $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;
|
||||
}
|
||||
|
||||
// }}}
|
||||
|
||||
function fetchInto($result, &$ar, $fetchmode, $rownum = null)
|
||||
{
|
||||
if ($rownum !== NULL) {
|
||||
return $this->ibaseRaiseError(DB_ERROR_NOT_CAPABLE);
|
||||
}
|
||||
if ($fetchmode & DB_FETCHMODE_ASSOC) {
|
||||
$ar = get_object_vars(ibase_fetch_object($result));
|
||||
if ($ar && $this->options['optimize'] == 'portability') {
|
||||
$ar = array_change_key_case($ar, CASE_LOWER);
|
||||
}
|
||||
} else {
|
||||
$ar = ibase_fetch_row($result);
|
||||
}
|
||||
if (!$ar) {
|
||||
if ($errmsg = ibase_errmsg()) {
|
||||
return $this->ibaseRaiseError(null, $errmsg);
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
return DB_OK;
|
||||
}
|
||||
|
||||
function freeResult()
|
||||
{
|
||||
if (is_resource($result)) {
|
||||
return ibase_free_result($result);
|
||||
}
|
||||
if (!isset($this->prepare_tokens[(int)$result])) {
|
||||
return false;
|
||||
}
|
||||
unset($this->prepare_tokens[(int)$result]);
|
||||
unset($this->prepare_types[(int)$result]);
|
||||
return true;
|
||||
}
|
||||
|
||||
function freeQuery($query)
|
||||
{
|
||||
ibase_free_query($query);
|
||||
return true;
|
||||
}
|
||||
|
||||
function numCols($result)
|
||||
{
|
||||
$cols = ibase_num_fields($result);
|
||||
if (!$cols) {
|
||||
return $this->ibaseRaiseError();
|
||||
}
|
||||
return $cols;
|
||||
}
|
||||
|
||||
function prepare($query)
|
||||
{
|
||||
$this->last_query = $query;
|
||||
$query = $this->modifyQuery($query);
|
||||
$stmt = ibase_prepare($query);
|
||||
$this->manip_query[(int)$stmt] = DB::isManip($query);
|
||||
return $stmt;
|
||||
}
|
||||
|
||||
function execute($stmt, $data = false)
|
||||
{
|
||||
$result = ibase_execute($stmt, $data);
|
||||
if (!$result) {
|
||||
return $this->ibaseRaiseError();
|
||||
}
|
||||
if ($this->autocommit) {
|
||||
ibase_commit($this->connection);
|
||||
}
|
||||
return DB::isManip($this->manip_query[(int)$stmt]) ? DB_OK : new DB_result($this, $result);
|
||||
}
|
||||
|
||||
function autoCommit($onoff = false)
|
||||
{
|
||||
$this->autocommit = $onoff ? 1 : 0;
|
||||
return DB_OK;
|
||||
}
|
||||
|
||||
function commit()
|
||||
{
|
||||
return ibase_commit($this->connection);
|
||||
}
|
||||
|
||||
function rollback($trans_number)
|
||||
{
|
||||
return ibase_rollback($this->connection, $trans_number);
|
||||
}
|
||||
|
||||
function transactionInit($trans_args = 0)
|
||||
{
|
||||
return $trans_args ? ibase_trans($trans_args, $this->connection) : ibase_trans();
|
||||
}
|
||||
|
||||
// {{{ nextId()
|
||||
/**
|
||||
* Get the next value in a sequence.
|
||||
*
|
||||
* If the sequence does not exist, it will be created,
|
||||
* unless $ondemand is false.
|
||||
*
|
||||
* @access public
|
||||
* @param string $seq_name the name of the sequence
|
||||
* @param bool $ondemand whether to create the sequence on demand
|
||||
* @return a sequence integer, or a DB error
|
||||
*/
|
||||
function nextId($seq_name, $ondemand = true)
|
||||
{
|
||||
$sqn = strtoupper(preg_replace('/[^a-z0-9_]/i', '_', $seq_name));
|
||||
$repeat = 0;
|
||||
do {
|
||||
$this->pushErrorHandling(PEAR_ERROR_RETURN);
|
||||
$result = $this->query("SELECT GEN_ID(${sqn}_SEQ, 1) FROM RDB\$GENERATORS"
|
||||
." WHERE RDB\$GENERATOR_NAME='${sqn}_SEQ'");
|
||||
$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 $result;
|
||||
}
|
||||
$arr = $result->fetch_assoc(DB_FETCHMODE_ORDERED);
|
||||
$result->free();
|
||||
return $arr[0];
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ createSequence()
|
||||
|
||||
/**
|
||||
* Create the sequence
|
||||
*
|
||||
* @param string $seq_name the name of the sequence
|
||||
* @return mixed DB_OK on success or DB error on error
|
||||
* @access public
|
||||
*/
|
||||
function createSequence($seq_name)
|
||||
{
|
||||
$sqn = strtoupper(preg_replace('/[^a-z0-9_]/i', '_', $seq_name));
|
||||
$this->pushErrorHandling(PEAR_ERROR_RETURN);
|
||||
$result = $this->query("CREATE GENERATOR ${sqn}_SEQ");
|
||||
$this->popErrorHandling();
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ dropSequence()
|
||||
|
||||
/**
|
||||
* Drop a sequence
|
||||
*
|
||||
* @param string $seq_name the name of the sequence
|
||||
* @return mixed DB_OK on success or DB error on error
|
||||
* @access public
|
||||
*/
|
||||
function dropSequence($seq_name)
|
||||
{
|
||||
$sqn = strtoupper(preg_replace('/[^a-z0-9_]/i', '_', $seq_name));
|
||||
return $this->query("DELETE FROM RDB\$GENERATORS WHERE RDB\$GENERATOR_NAME='${sqn}_SEQ'");
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ _ibaseFieldFlags()
|
||||
|
||||
/**
|
||||
* get the Flags of a Field
|
||||
*
|
||||
* @param string $field_name the name of the field
|
||||
* @param string $table_name the name of the table
|
||||
*
|
||||
* @return string The flags of the field ("primary_key", "unique_key", "not_null"
|
||||
* "default", "computed" and "blob" are supported)
|
||||
* @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 R.RDB$RELATION_NAME=\''.$table_name.'\'';
|
||||
$result = ibase_query($this->connection, $sql);
|
||||
if (empty($result)) {
|
||||
return $this->ibaseRaiseError();
|
||||
}
|
||||
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 R.RDB$RELATION_NAME=\''.$table_name.'\''
|
||||
.' AND R.RDB$FIELD_NAME=\''.$field_name.'\'';
|
||||
$result = ibase_query($this->connection, $sql);
|
||||
if (empty($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);
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ tableInfo()
|
||||
|
||||
/**
|
||||
* Returns information about a table or a result set
|
||||
*
|
||||
* NOTE: doesn't support 'flags'and 'table' if called from a db_result
|
||||
*
|
||||
* @param mixed $resource Interbase result identifier or table name
|
||||
* @param int $mode A valid tableInfo mode (DB_TABLEINFO_ORDERTABLE or
|
||||
* DB_TABLEINFO_ORDER)
|
||||
*
|
||||
* @return array An array with all the information
|
||||
*/
|
||||
function tableInfo($result, $mode = null)
|
||||
{
|
||||
$count = 0;
|
||||
$id = 0;
|
||||
$res = array();
|
||||
|
||||
/*
|
||||
* depending on $mode, metadata returns the following values:
|
||||
*
|
||||
* - mode is false (default):
|
||||
* $result[]:
|
||||
* [0]["table"] table name
|
||||
* [0]["name"] field name
|
||||
* [0]["type"] field type
|
||||
* [0]["len"] field length
|
||||
* [0]["flags"] field flags
|
||||
*
|
||||
* - mode is DB_TABLEINFO_ORDER
|
||||
* $result[]:
|
||||
* ["num_fields"] number of metadata records
|
||||
* [0]["table"] table name
|
||||
* [0]["name"] field name
|
||||
* [0]["type"] field type
|
||||
* [0]["len"] field length
|
||||
* [0]["flags"] field flags
|
||||
* ["order"][field name] index of field named "field name"
|
||||
* The last one is used, if you have a field name, but no index.
|
||||
* Test: if (isset($result['meta']['myfield'])) { ...
|
||||
*
|
||||
* - mode is DB_TABLEINFO_ORDERTABLE
|
||||
* the same as above. but additionally
|
||||
* ["ordertable"][table name][field name] index of field
|
||||
* named "field name"
|
||||
*
|
||||
* this is, because if you have fields from different
|
||||
* tables with the same field name * they override each
|
||||
* other with DB_TABLEINFO_ORDER
|
||||
*
|
||||
* you can combine DB_TABLEINFO_ORDER and
|
||||
* DB_TABLEINFO_ORDERTABLE with DB_TABLEINFO_ORDER |
|
||||
* DB_TABLEINFO_ORDERTABLE * or with DB_TABLEINFO_FULL
|
||||
*/
|
||||
|
||||
// if $result is a string, then we want information about a
|
||||
// table without a resultset
|
||||
|
||||
if (is_string($result)) {
|
||||
$id = ibase_query($this->connection,"SELECT * FROM $result");
|
||||
if (empty($id)) {
|
||||
return $this->ibaseRaiseError();
|
||||
}
|
||||
} else { // else we want information about a resultset
|
||||
$id = $result;
|
||||
if (empty($id)) {
|
||||
return $this->ibaseRaiseError();
|
||||
}
|
||||
}
|
||||
|
||||
$count = @ibase_num_fields($id);
|
||||
|
||||
// made this IF due to performance (one if is faster than $count if's)
|
||||
if (empty($mode)) {
|
||||
|
||||
for ($i=0; $i<$count; $i++) {
|
||||
$info = @ibase_field_info($id, $i);
|
||||
$res[$i]['table'] = (is_string($result)) ? $result : '';
|
||||
$res[$i]['name'] = $info['name'];
|
||||
$res[$i]['type'] = $info['type'];
|
||||
$res[$i]['len'] = $info['length'];
|
||||
$res[$i]['flags'] = (is_string($result)) ? $this->_ibaseFieldFlags($info['name'], $result) : '';
|
||||
}
|
||||
|
||||
} else { // full
|
||||
$res["num_fields"]= $count;
|
||||
|
||||
for ($i=0; $i<$count; $i++) {
|
||||
$info = @ibase_field_info($id, $i);
|
||||
$res[$i]['table'] = (is_string($result)) ? $result : '';
|
||||
$res[$i]['name'] = $info['name'];
|
||||
$res[$i]['type'] = $info['type'];
|
||||
$res[$i]['len'] = $info['length'];
|
||||
$res[$i]['flags'] = (is_string($result)) ? $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 (is_resource($id)) {
|
||||
ibase_free_result($id);
|
||||
}
|
||||
return $res;
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ getSpecialQuery()
|
||||
|
||||
/**
|
||||
* Returns the query needed to get some backend info
|
||||
* @param string $type What kind of info you want to retrieve
|
||||
* @return string The SQL query string
|
||||
*/
|
||||
function getSpecialQuery($type)
|
||||
{
|
||||
switch ($type) {
|
||||
case 'tables':
|
||||
default:
|
||||
return null;
|
||||
}
|
||||
return $sql;
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ ibaseRaiseError()
|
||||
|
||||
function ibaseRaiseError($errno = null, $errmsg = null)
|
||||
{
|
||||
if ($errmsg === null)
|
||||
$errmsg = ibase_errmsg();
|
||||
// memo for the interbase php module hackers: we need something similar
|
||||
// to mysql_errno() to retrieve error codes instead of this ugly hack
|
||||
if (preg_match('/^([^0-9\-]+)([0-9\-]+)\s+(.*)$/', $errmsg, $m)) {
|
||||
if ($errno === null) {
|
||||
$ibase_errno = (int)$m[2];
|
||||
// try to interpret Interbase error code (that's why we need ibase_errno()
|
||||
// in the interbase module to return the real error code)
|
||||
switch ($ibase_errno) {
|
||||
case -204:
|
||||
if (is_int(strpos($m[3], 'Table unknown'))) {
|
||||
$errno = DB_ERROR_NOSUCHTABLE;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
$errno = $this->errorCode($ibase_errno);
|
||||
}
|
||||
}
|
||||
$errmsg = $m[2] . ' ' . $m[3];
|
||||
}
|
||||
|
||||
return $this->raiseError($errno, null, null, $errmsg,
|
||||
$this->last_query);
|
||||
}
|
||||
|
||||
// }}}
|
||||
|
||||
}
|
||||
|
||||
/*
|
||||
* Local variables:
|
||||
* tab-width: 4
|
||||
* c-basic-offset: 4
|
||||
* End:
|
||||
*/
|
||||
|
||||
?>
|
||||
323
html/illt/DB/ifx.php
Normal file
323
html/illt/DB/ifx.php
Normal file
@@ -0,0 +1,323 @@
|
||||
<?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. |
|
||||
// +----------------------------------------------------------------------+
|
||||
// | Author: Tomas V.V.Cox <cox@idecnet.com> |
|
||||
// +----------------------------------------------------------------------+
|
||||
//
|
||||
// $Id: ifx.php,v 1.18 2002/02/28 08:27:09 sebastian Exp $
|
||||
//
|
||||
// Database independent query interface definition for PHP's Informix
|
||||
// extension.
|
||||
//
|
||||
|
||||
// Legend:
|
||||
// For more info on Informix errors see:
|
||||
// http://www.informix.com/answers/english/ierrors.htm
|
||||
//
|
||||
// TODO:
|
||||
// - set needed env Informix vars on connect
|
||||
// - implement native prepare/execute
|
||||
|
||||
require_once 'DB/common.php';
|
||||
|
||||
class DB_ifx extends DB_common
|
||||
{
|
||||
var $connection;
|
||||
var $affected = 0;
|
||||
var $dsn = array();
|
||||
var $fetchmode = DB_FETCHMODE_ORDERED; /* Default fetch mode */
|
||||
|
||||
function DB_ifx()
|
||||
{
|
||||
$this->phptype = 'ifx';
|
||||
$this->dbsyntax = 'ifx';
|
||||
$this->features = array(
|
||||
'prepare' => false,
|
||||
'pconnect' => true,
|
||||
'transactions' => false,
|
||||
'limit' => 'emulate'
|
||||
);
|
||||
$this->errorcode_map = array(
|
||||
'-201' => DB_ERROR_SYNTAX,
|
||||
'-206' => DB_ERROR_NOSUCHTABLE,
|
||||
'-217' => DB_ERROR_NOSUCHFIELD,
|
||||
'-329' => DB_ERROR_NODBSELECTED,
|
||||
'-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
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Connect to a database and log in as the specified user.
|
||||
*
|
||||
* @param $dsn the data source name (see DB::parseDSN for syntax)
|
||||
* @param $persistent (optional) whether the connection should
|
||||
* be persistent
|
||||
*
|
||||
* @return int DB_OK on success, a DB error code on failure
|
||||
*/
|
||||
function connect(&$dsninfo, $persistent = false)
|
||||
{
|
||||
if (!DB::assertExtension('informix'))
|
||||
return $this->raiseError(DB_ERROR_EXTENSION_NOT_FOUND);
|
||||
|
||||
$this->dsn = $dsninfo;
|
||||
$dbhost = $dsninfo['hostspec'] ? '@' . $dsninfo['hostspec'] : '';
|
||||
$dbname = $dsninfo['database'] ? $dsninfo['database'] . $dbhost : '';
|
||||
$user = $dsninfo['username'] ? $dsninfo['username'] : '';
|
||||
$pw = $dsninfo['password'] ? $dsninfo['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;
|
||||
}
|
||||
|
||||
/**
|
||||
* Log out and disconnect from the database.
|
||||
*
|
||||
* @return bool TRUE on success, FALSE if not connected.
|
||||
*/
|
||||
function disconnect()
|
||||
{
|
||||
$ret = @ifx_close($this->connection);
|
||||
$this->connection = null;
|
||||
return $ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* Send a query to Informix and return the results as a
|
||||
* Informix resource identifier.
|
||||
*
|
||||
* @param $query the SQL query
|
||||
*
|
||||
* @return int returns a valid Informix result for successful SELECT
|
||||
* queries, DB_OK for other successful queries. A DB error code
|
||||
* is returned on failure.
|
||||
*/
|
||||
function simpleQuery($query)
|
||||
{
|
||||
$this->last_query = $query;
|
||||
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 {
|
||||
$result = @ifx_query($query, $this->connection);
|
||||
}
|
||||
if (!$result) {
|
||||
return $this->ifxraiseError();
|
||||
}
|
||||
$this->affected = ifx_affected_rows ($result);
|
||||
// Determine which queries that should return data, and which
|
||||
// should return an error code only.
|
||||
if (preg_match('/(SELECT)/i', $query)) {
|
||||
return $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;
|
||||
}
|
||||
|
||||
// }}}
|
||||
|
||||
/**
|
||||
* Gets the number of rows affected by the last query.
|
||||
* if the last query was a select, returns an _estimate_ value.
|
||||
*
|
||||
* @return number of rows affected by the last query
|
||||
*/
|
||||
function affectedRows()
|
||||
{
|
||||
return $this->affected;
|
||||
}
|
||||
|
||||
/**
|
||||
* Fetch and return a row of data (it uses fetchInto for that)
|
||||
* @param $result Informix result identifier
|
||||
* @param $fetchmode format of fetched row array
|
||||
* @param $rownum the absolute row number to fetch
|
||||
*
|
||||
* @return array a row of data, or false on error
|
||||
*/
|
||||
function fetch_assoc($result, $fetchmode = DB_FETCHMODE_DEFAULT, $rownum=null)
|
||||
{
|
||||
if ($fetchmode == DB_FETCHMODE_DEFAULT) {
|
||||
$fetchmode = $this->fetchmode;
|
||||
}
|
||||
$res = $this->fetchInto ($result, $arr, $fetchmode, $rownum);
|
||||
if ($res !== DB_OK) {
|
||||
return $res;
|
||||
}
|
||||
return $arr;
|
||||
}
|
||||
|
||||
/**
|
||||
* Fetch a row and return as array.
|
||||
*
|
||||
* @param $result Informix result identifier
|
||||
* @param $row (reference) array where data from the row is stored
|
||||
* @param $fetchmode how the resulting array should be indexed
|
||||
* @param $rownum the row number to fetch
|
||||
*
|
||||
* @return int an array on success, a DB error code on failure, NULL
|
||||
* if there is no more data
|
||||
*/
|
||||
function fetchInto($result, &$row, $fetchmode, $rownum=null)
|
||||
{
|
||||
if (($rownum !== null) && ($rownum < 0)) {
|
||||
return null;
|
||||
}
|
||||
// if $rownum is null, fetch row will return the next row
|
||||
if (!$row = @ifx_fetch_row($result, $rownum)) {
|
||||
return null;
|
||||
}
|
||||
if ($fetchmode !== DB_FETCHMODE_ASSOC) {
|
||||
$i=0;
|
||||
$order = array();
|
||||
foreach ($row as $key => $val) {
|
||||
$order[$i++] = $val;
|
||||
}
|
||||
$row = $order;
|
||||
}
|
||||
return DB_OK;
|
||||
}
|
||||
|
||||
function numRows($result)
|
||||
{
|
||||
return $this->raiseError(DB_ERROR_NOT_CAPABLE);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the number of columns in a result set.
|
||||
*
|
||||
* @param $result Informix result identifier
|
||||
*
|
||||
* @return int the number of columns per row in $result
|
||||
*/
|
||||
function numCols($result)
|
||||
{
|
||||
if (!$cols = @ifx_num_fields($result)) {
|
||||
return $this->ifxraiseError();
|
||||
}
|
||||
return $cols;
|
||||
}
|
||||
|
||||
/**
|
||||
* Free the internal resources associated with $result.
|
||||
*
|
||||
* @param $result Informix result identifier
|
||||
*
|
||||
* @return bool TRUE on success, DB_error on error
|
||||
*/
|
||||
function freeResult($result)
|
||||
{
|
||||
if (is_resource($result)) {
|
||||
if (!@ifx_free_result($result)) {
|
||||
return $this->ifxraiseError();
|
||||
}
|
||||
return true;
|
||||
}
|
||||
if (!isset($this->prepare_tokens[(int)$result])) {
|
||||
return false;
|
||||
}
|
||||
unset($this->prepare_tokens[(int)$result]);
|
||||
unset($this->prepare_types[(int)$result]);
|
||||
return true;
|
||||
}
|
||||
|
||||
function ifxraiseError($errno = null)
|
||||
{
|
||||
if ($errno === null) {
|
||||
$errno = $this->errorCode(ifx_error());
|
||||
}
|
||||
|
||||
return $this->raiseError($errno, null, null, null,
|
||||
$this->errorNative());
|
||||
}
|
||||
|
||||
/**
|
||||
* Map native error codes to DB's portable ones. Requires that
|
||||
* the DB implementation's constructor fills in the $errorcode_map
|
||||
* property.
|
||||
*
|
||||
* @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;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the native error message of the last error (if any) that
|
||||
* occured on the current connection.
|
||||
*
|
||||
* @return int native Informix error code
|
||||
*/
|
||||
function errorNative()
|
||||
{
|
||||
return ifx_error() . ' ' . ifx_errormsg();
|
||||
}
|
||||
|
||||
// {{{ getSpecialQuery()
|
||||
|
||||
/**
|
||||
* Returns the query needed to get some backend info
|
||||
* @param string $type What kind of info you want to retrieve
|
||||
* @return string The SQL query string
|
||||
*/
|
||||
function getSpecialQuery($type)
|
||||
{
|
||||
switch ($type) {
|
||||
case 'tables':
|
||||
default:
|
||||
return null;
|
||||
}
|
||||
return $sql;
|
||||
}
|
||||
|
||||
// }}}
|
||||
}
|
||||
|
||||
?>
|
||||
210
html/illt/DB/msql.php
Normal file
210
html/illt/DB/msql.php
Normal file
@@ -0,0 +1,210 @@
|
||||
<?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. |
|
||||
// +----------------------------------------------------------------------+
|
||||
// | Author: Sterling Hughes <sterling@php.net> |
|
||||
// +----------------------------------------------------------------------+
|
||||
//
|
||||
// $Id: msql.php,v 1.25 2002/02/28 08:27:10 sebastian Exp $
|
||||
//
|
||||
// Database independent query interface definition for PHP's Mini-SQL
|
||||
// extension.
|
||||
//
|
||||
|
||||
require_once 'DB/common.php';
|
||||
|
||||
class DB_msql extends DB_common
|
||||
{
|
||||
var $connection;
|
||||
var $phptype, $dbsyntax;
|
||||
var $prepare_tokens = array();
|
||||
var $prepare_types = array();
|
||||
|
||||
function DB_msql()
|
||||
{
|
||||
$this->DB_common();
|
||||
$this->phptype = 'msql';
|
||||
$this->dbsyntax = 'msql';
|
||||
$this->features = array(
|
||||
'prepare' => false,
|
||||
'pconnect' => true,
|
||||
'transactions' => false,
|
||||
'limit' => 'emulate'
|
||||
);
|
||||
}
|
||||
|
||||
function connect($dsninfo, $persistent = false)
|
||||
{
|
||||
if (!DB::assertExtension('msql'))
|
||||
return $this->raiseError(DB_ERROR_EXTENSION_NOT_FOUND);
|
||||
|
||||
$this->dsn = $dsninfo;
|
||||
$user = $dsninfo['username'];
|
||||
$pw = $dsninfo['password'];
|
||||
$dbhost = $dsninfo['hostspec'] ? $dsninfo['hostspec'] : 'localhost';
|
||||
|
||||
$connect_function = $persistent ? 'msql_pconnect' : 'msql_connect';
|
||||
|
||||
if ($dbhost && $user && $pw) {
|
||||
$conn = $connect_function($dbhost, $user, $pw);
|
||||
} elseif ($dbhost && $user) {
|
||||
$conn = $connect_function($dbhost,$user);
|
||||
} else {
|
||||
$conn = $connect_function($dbhost);
|
||||
}
|
||||
if (!$conn) {
|
||||
$this->raiseError(DB_ERROR_CONNECT_FAILED);
|
||||
}
|
||||
if (!@msql_select_db($dsninfo['database'], $conn)){
|
||||
return $this->raiseError(DB_ERROR_NODBSELECTED);
|
||||
}
|
||||
$this->connection = $conn;
|
||||
return DB_OK;
|
||||
}
|
||||
|
||||
function disconnect()
|
||||
{
|
||||
$ret = @msql_close($this->connection);
|
||||
$this->connection = null;
|
||||
return $ret;
|
||||
}
|
||||
|
||||
function simpleQuery($query)
|
||||
{
|
||||
$this->last_query = $query;
|
||||
$query = $this->modifyQuery($query);
|
||||
$result = @msql_query($query, $this->connection);
|
||||
if (!$result) {
|
||||
return $this->raiseError();
|
||||
}
|
||||
// Determine which queries that should return data, and which
|
||||
// should return an error code only.
|
||||
return DB::isManip($query) ? DB_OK : $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;
|
||||
}
|
||||
|
||||
// }}}
|
||||
|
||||
function fetch_assoc($result, $fetchmode = DB_FETCHMODE_DEFAULT, $rownum=null)
|
||||
{
|
||||
if ($fetchmode == DB_FETCHMODE_DEFAULT) {
|
||||
$fetchmode = $this->fetchmode;
|
||||
}
|
||||
$res = $this->fetchInto ($result, $arr, $fetchmode, $rownum);
|
||||
if ($res !== DB_OK) {
|
||||
return $res;
|
||||
}
|
||||
return $arr;
|
||||
}
|
||||
|
||||
function fetchInto($result, &$ar, $fetchmode, $rownum=null)
|
||||
{
|
||||
if ($rownum !== null) {
|
||||
if (!@msql_data_seek($result, $rownum)) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
if ($fetchmode & DB_FETCHMODE_ASSOC) {
|
||||
$ar = @msql_fetch_array($result, MSQL_ASSOC);
|
||||
} else {
|
||||
$ar = @msql_fetch_row($result);
|
||||
}
|
||||
if (!$ar) {
|
||||
if ($error = msql_error()) {
|
||||
return $this->raiseError($error);
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
return DB_OK;
|
||||
}
|
||||
|
||||
function freeResult($result)
|
||||
{
|
||||
if (is_resource($result)) {
|
||||
return @msql_free_result($result);
|
||||
}
|
||||
if (!isset($this->prepare_tokens[$result])) {
|
||||
return false;
|
||||
}
|
||||
unset($this->prepare_tokens[$result]);
|
||||
unset($this->prepare_types[$result]);
|
||||
return true;
|
||||
}
|
||||
|
||||
function numCols($result)
|
||||
{
|
||||
$cols = @msql_num_fields($result);
|
||||
if (!$cols) {
|
||||
return $this->raiseError();
|
||||
}
|
||||
return $cols;
|
||||
}
|
||||
|
||||
function numRows($result)
|
||||
{
|
||||
$rows = @msql_num_rows($result);
|
||||
if (!$rows) {
|
||||
return $this->raiseError();
|
||||
}
|
||||
return $rows;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the number of rows affected by a query.
|
||||
*
|
||||
* @return number of rows affected by the last query
|
||||
*/
|
||||
|
||||
function affectedRows()
|
||||
{
|
||||
return @msql_affected_rows($this->connection);
|
||||
}
|
||||
|
||||
// {{{ getSpecialQuery()
|
||||
|
||||
/**
|
||||
* Returns the query needed to get some backend info
|
||||
* @param string $type What kind of info you want to retrieve
|
||||
* @return string The SQL query string
|
||||
*/
|
||||
function getSpecialQuery($type)
|
||||
{
|
||||
switch ($type) {
|
||||
case 'tables':
|
||||
default:
|
||||
return null;
|
||||
}
|
||||
return $sql;
|
||||
}
|
||||
|
||||
// }}}
|
||||
|
||||
}
|
||||
?>
|
||||
500
html/illt/DB/mssql.php
Normal file
500
html/illt/DB/mssql.php
Normal file
@@ -0,0 +1,500 @@
|
||||
<?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. |
|
||||
// +----------------------------------------------------------------------+
|
||||
// | Author: Sterling Hughes <sterling@php.net> |
|
||||
// +----------------------------------------------------------------------+
|
||||
//
|
||||
// $Id: mssql.php,v 1.40 2002/02/28 08:27:10 sebastian Exp $
|
||||
//
|
||||
// Database independent query interface definition for PHP's Microsoft SQL Server
|
||||
// extension.
|
||||
//
|
||||
|
||||
require_once 'DB/common.php';
|
||||
|
||||
class DB_mssql extends DB_common
|
||||
{
|
||||
var $connection;
|
||||
var $phptype, $dbsyntax;
|
||||
var $prepare_tokens = array();
|
||||
var $prepare_types = array();
|
||||
var $transaction_opcount = 0;
|
||||
var $autocommit = true;
|
||||
|
||||
function DB_mssql()
|
||||
{
|
||||
$this->DB_common();
|
||||
$this->phptype = 'mssql';
|
||||
$this->dbsyntax = 'mssql';
|
||||
$this->features = array(
|
||||
'prepare' => false,
|
||||
'pconnect' => true,
|
||||
'transactions' => true,
|
||||
'limit' => 'emulate'
|
||||
);
|
||||
// XXX Add here error codes ie: 'S100E' => DB_ERROR_SYNTAX
|
||||
$this->errorcode_map = array(
|
||||
|
||||
);
|
||||
}
|
||||
|
||||
function connect($dsninfo, $persistent = false)
|
||||
{
|
||||
if (!DB::assertExtension('mssql') && !DB::assertExtension('sybase')
|
||||
&& !DB::assertExtension('sybase_ct'))
|
||||
{
|
||||
return $this->raiseError(DB_ERROR_EXTENSION_NOT_FOUND);
|
||||
}
|
||||
$this->dsn = $dsninfo;
|
||||
$user = $dsninfo['username'];
|
||||
$pw = $dsninfo['password'];
|
||||
$dbhost = $dsninfo['hostspec'] ? $dsninfo['hostspec'] : 'localhost';
|
||||
|
||||
$connect_function = $persistent ? 'mssql_pconnect' : 'mssql_connect';
|
||||
|
||||
if ($dbhost && $user && $pw) {
|
||||
$conn = @$connect_function($dbhost, $user, $pw);
|
||||
} elseif ($dbhost && $user) {
|
||||
$conn = @$connect_function($dbhost, $user);
|
||||
} else {
|
||||
$conn = @$connect_function($dbhost);
|
||||
}
|
||||
if (!$conn) {
|
||||
return $this->raiseError(DB_ERROR_CONNECT_FAILED, null, null,
|
||||
null, mssql_get_last_message());
|
||||
}
|
||||
if ($dsninfo['database']) {
|
||||
if (!@mssql_select_db($dsninfo['database'], $conn)) {
|
||||
return $this->raiseError(DB_ERROR_NODBSELECTED, null, null,
|
||||
null, mssql_get_last_message());
|
||||
}
|
||||
}
|
||||
$this->connection = $conn;
|
||||
return DB_OK;
|
||||
}
|
||||
|
||||
function disconnect()
|
||||
{
|
||||
$ret = @mssql_close($this->connection);
|
||||
$this->connection = null;
|
||||
return $ret;
|
||||
}
|
||||
|
||||
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 = @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);
|
||||
}
|
||||
|
||||
// }}}
|
||||
|
||||
function &fetch_assoc($result, $fetchmode = DB_FETCHMODE_DEFAULT, $rownum=null)
|
||||
{
|
||||
if ($fetchmode == DB_FETCHMODE_DEFAULT) {
|
||||
$fetchmode = $this->fetchmode;
|
||||
}
|
||||
$res = $this->fetchInto ($result, $arr, $fetchmode, $rownum);
|
||||
if ($res !== DB_OK) {
|
||||
return $res;
|
||||
}
|
||||
return $arr;
|
||||
}
|
||||
|
||||
function fetchInto($result, &$ar, $fetchmode, $rownum=null)
|
||||
{
|
||||
if ($rownum !== null) {
|
||||
if (!@mssql_data_seek($result, $rownum)) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
if ($fetchmode & DB_FETCHMODE_ASSOC) {
|
||||
$ar = @mssql_fetch_array($result);
|
||||
} else {
|
||||
$ar = @mssql_fetch_row($result);
|
||||
}
|
||||
if (!$ar) {
|
||||
/* This throws informative error messages,
|
||||
don't use it for now
|
||||
if ($msg = mssql_get_last_message()) {
|
||||
return $this->raiseError($msg);
|
||||
}
|
||||
*/
|
||||
return null;
|
||||
}
|
||||
return DB_OK;
|
||||
}
|
||||
|
||||
function freeResult($result)
|
||||
{
|
||||
if (is_resource($result)) {
|
||||
return @mssql_free_result($result);
|
||||
}
|
||||
if (!isset($this->prepare_tokens[$result])) {
|
||||
return false;
|
||||
}
|
||||
unset($this->prepare_tokens[$result]);
|
||||
unset($this->prepare_types[$result]);
|
||||
return true;
|
||||
}
|
||||
|
||||
function numCols($result)
|
||||
{
|
||||
$cols = @mssql_num_fields($result);
|
||||
if (!$cols) {
|
||||
return $this->mssqlRaiseError();
|
||||
}
|
||||
return $cols;
|
||||
}
|
||||
|
||||
function numRows($result)
|
||||
{
|
||||
$rows = @mssql_num_rows($result);
|
||||
if ($rows === false) {
|
||||
return $this->mssqlRaiseError();
|
||||
}
|
||||
return $rows;
|
||||
}
|
||||
|
||||
/**
|
||||
* Enable/disable automatic commits
|
||||
*/
|
||||
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()
|
||||
|
||||
/**
|
||||
* Commit the current transaction.
|
||||
*/
|
||||
function commit()
|
||||
{
|
||||
if ($this->transaction_opcount > 0) {
|
||||
$result = @mssql_query('COMMIT TRAN', $this->connection);
|
||||
$this->transaction_opcount = 0;
|
||||
if (!$result) {
|
||||
return $this->mssqlRaiseError();
|
||||
}
|
||||
}
|
||||
return DB_OK;
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ rollback()
|
||||
|
||||
/**
|
||||
* Roll back (undo) the current transaction.
|
||||
*/
|
||||
function rollback()
|
||||
{
|
||||
if ($this->transaction_opcount > 0) {
|
||||
$result = @mssql_query('ROLLBACK TRAN', $this->connection);
|
||||
$this->transaction_opcount = 0;
|
||||
if (!$result) {
|
||||
return $this->mssqlRaiseError();
|
||||
}
|
||||
}
|
||||
return DB_OK;
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ affectedRows()
|
||||
|
||||
/**
|
||||
* Gets the number of rows affected by the last query.
|
||||
* if the last query was a select, returns 0.
|
||||
*
|
||||
* @return number of rows affected by the last query or DB_ERROR
|
||||
*/
|
||||
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()
|
||||
|
||||
/**
|
||||
* Get the next value in a sequence. We emulate sequences
|
||||
* for MSSQL. Will create the sequence if it does not exist.
|
||||
*
|
||||
* @access public
|
||||
*
|
||||
* @param $seq_name the name of the sequence
|
||||
*
|
||||
* @param $ondemand whether to create the sequence table on demand
|
||||
* (default is true)
|
||||
*
|
||||
* @return a sequence integer, or a DB error
|
||||
*/
|
||||
function nextId($seq_name, $ondemand = true)
|
||||
{
|
||||
$seqname = $this->getSequenceName($seq_name);
|
||||
$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 $result;
|
||||
}
|
||||
} else {
|
||||
$result = $this->query("SELECT @@IDENTITY FROM $seqname");
|
||||
$repeat = 0;
|
||||
}
|
||||
} while ($repeat);
|
||||
if (DB::isError($result)) {
|
||||
return $this->raiseError($result);
|
||||
}
|
||||
$result = $result->fetch_assoc(DB_FETCHMODE_ORDERED);
|
||||
return $result[0];
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ createSequence()
|
||||
|
||||
function createSequence($seq_name)
|
||||
{
|
||||
$seqname = $this->getSequenceName($seq_name);
|
||||
return $this->query("CREATE TABLE $seqname ".
|
||||
'([id] [int] IDENTITY (1, 1) NOT NULL ,' .
|
||||
'[vapor] [int] NULL)');
|
||||
}
|
||||
// }}}
|
||||
// {{{ dropSequence()
|
||||
|
||||
function dropSequence($seq_name)
|
||||
{
|
||||
$seqname = $this->getSequenceName($seq_name);
|
||||
return $this->query("DROP TABLE $seqname");
|
||||
}
|
||||
// }}}
|
||||
|
||||
function errorCode()
|
||||
{
|
||||
$this->pushErrorHandling(PEAR_ERROR_RETURN);
|
||||
$error_code = $this->getOne('select @@ERROR as ErrorCode');
|
||||
$this->popErrorHandling();
|
||||
// XXX Debug
|
||||
if (!isset($this->errorcode_map[$error_code])) {
|
||||
return DB_ERROR;
|
||||
}
|
||||
return $error_code;
|
||||
}
|
||||
|
||||
function mssqlRaiseError($code = null)
|
||||
{
|
||||
if ($code !== null) {
|
||||
$code = $this->errorCode();
|
||||
if (DB::isError($code)) {
|
||||
return $this->raiseError($code);
|
||||
}
|
||||
}
|
||||
return $this->raiseError($code, null, null, null,
|
||||
mssql_get_last_message());
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
* Returns information about a table or a result set
|
||||
*
|
||||
* NOTE: doesn't support table name and flags if called from a db_result
|
||||
*
|
||||
* @param mixed $resource SQL Server result identifier or table name
|
||||
* @param int $mode A valid tableInfo mode (DB_TABLEINFO_ORDERTABLE or
|
||||
* DB_TABLEINFO_ORDER)
|
||||
*
|
||||
* @return array An array with all the information
|
||||
*/
|
||||
|
||||
function tableInfo($result, $mode = null)
|
||||
{
|
||||
|
||||
$count = 0;
|
||||
$id = 0;
|
||||
$res = array();
|
||||
|
||||
/*
|
||||
* depending on $mode, metadata returns the following values:
|
||||
*
|
||||
* - mode is false (default):
|
||||
* $result[]:
|
||||
* [0]["table"] table name
|
||||
* [0]["name"] field name
|
||||
* [0]["type"] field type
|
||||
* [0]["len"] field length
|
||||
* [0]["flags"] field flags
|
||||
*
|
||||
* - mode is DB_TABLEINFO_ORDER
|
||||
* $result[]:
|
||||
* ["num_fields"] number of metadata records
|
||||
* [0]["table"] table name
|
||||
* [0]["name"] field name
|
||||
* [0]["type"] field type
|
||||
* [0]["len"] field length
|
||||
* [0]["flags"] field flags
|
||||
* ["order"][field name] index of field named "field name"
|
||||
* The last one is used, if you have a field name, but no index.
|
||||
* Test: if (isset($result['meta']['myfield'])) { ...
|
||||
*
|
||||
* - mode is DB_TABLEINFO_ORDERTABLE
|
||||
* the same as above. but additionally
|
||||
* ["ordertable"][table name][field name] index of field
|
||||
* named "field name"
|
||||
*
|
||||
* this is, because if you have fields from different
|
||||
* tables with the same field name * they override each
|
||||
* other with DB_TABLEINFO_ORDER
|
||||
*
|
||||
* you can combine DB_TABLEINFO_ORDER and
|
||||
* DB_TABLEINFO_ORDERTABLE with DB_TABLEINFO_ORDER |
|
||||
* DB_TABLEINFO_ORDERTABLE * or with DB_TABLEINFO_FULL
|
||||
*/
|
||||
|
||||
// if $result is a string, then we want information about a
|
||||
// table without a resultset
|
||||
|
||||
if (is_string($result)) {
|
||||
$id = mssql_query("SELECT * FROM $result", $this->connection);
|
||||
if (empty($id)) {
|
||||
return $this->mssqlRaiseError();
|
||||
}
|
||||
} else { // else we want information about a resultset
|
||||
$id = $result;
|
||||
if (empty($id)) {
|
||||
return $this->mssqlRaiseError();
|
||||
}
|
||||
}
|
||||
|
||||
$count = @mssql_num_fields($id);
|
||||
|
||||
// made this IF due to performance (one if is faster than $count if's)
|
||||
if (empty($mode)) {
|
||||
|
||||
for ($i=0; $i<$count; $i++) {
|
||||
$res[$i]['table'] = (is_string($result)) ? $result : '';
|
||||
$res[$i]['name'] = @mssql_field_name($id, $i);
|
||||
$res[$i]['type'] = @mssql_field_type($id, $i);
|
||||
$res[$i]['len'] = @mssql_field_length($id, $i);
|
||||
$res[$i]['flags'] = '';
|
||||
}
|
||||
|
||||
} else { // full
|
||||
$res['num_fields']= $count;
|
||||
|
||||
for ($i=0; $i<$count; $i++) {
|
||||
$res[$i]['table'] = (is_string($result)) ? $result : '';
|
||||
$res[$i]['name'] = @mssql_field_name($id, $i);
|
||||
$res[$i]['type'] = @mssql_field_type($id, $i);
|
||||
$res[$i]['len'] = @mssql_field_length($id, $i);
|
||||
$res[$i]['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 (is_string($result)) {
|
||||
@mssql_free_result($id);
|
||||
}
|
||||
return $res;
|
||||
}
|
||||
|
||||
// {{{ getSpecialQuery()
|
||||
|
||||
/**
|
||||
* Returns the query needed to get some backend info
|
||||
* @param string $type What kind of info you want to retrieve
|
||||
* @return string The SQL query string
|
||||
*/
|
||||
function getSpecialQuery($type)
|
||||
{
|
||||
switch ($type) {
|
||||
case 'tables':
|
||||
$sql = "select name from sysobjects where type = 'U' order by name";
|
||||
break;
|
||||
case 'views':
|
||||
$sql = "select name from sysobjects where type = 'V'";
|
||||
break;
|
||||
default:
|
||||
return null;
|
||||
}
|
||||
return $sql;
|
||||
}
|
||||
|
||||
// }}}
|
||||
|
||||
}
|
||||
?>
|
||||
847
html/illt/DB/mysql.php
Normal file
847
html/illt/DB/mysql.php
Normal file
@@ -0,0 +1,847 @@
|
||||
<?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. |
|
||||
// +----------------------------------------------------------------------+
|
||||
// | Author: Stig Bakken <ssb@fast.no> |
|
||||
// +----------------------------------------------------------------------+
|
||||
//
|
||||
// $Id: mysql.php,v 1.89.2.1 2002/04/09 19:04:14 ssb Exp $
|
||||
//
|
||||
// Database independent query interface definition for PHP's MySQL
|
||||
// extension.
|
||||
//
|
||||
|
||||
//
|
||||
// XXX legend:
|
||||
//
|
||||
// XXX ERRORMSG: The error message from the mysql function should
|
||||
// be registered here.
|
||||
//
|
||||
|
||||
require_once "DB/common.php";
|
||||
|
||||
class DB_mysql extends DB_common
|
||||
{
|
||||
// {{{ properties
|
||||
|
||||
var $connection;
|
||||
var $phptype, $dbsyntax;
|
||||
var $prepare_tokens = array();
|
||||
var $prepare_types = array();
|
||||
var $num_rows = array();
|
||||
var $transaction_opcount = 0;
|
||||
var $autocommit = true;
|
||||
var $fetchmode = DB_FETCHMODE_ORDERED; /* Default fetch mode */
|
||||
var $_db = false;
|
||||
|
||||
// }}}
|
||||
// {{{ constructor
|
||||
|
||||
/**
|
||||
* DB_mysql constructor.
|
||||
*
|
||||
* @access public
|
||||
*/
|
||||
|
||||
function DB_mysql()
|
||||
{
|
||||
$this->DB_common();
|
||||
$this->phptype = 'mysql';
|
||||
$this->dbsyntax = 'mysql';
|
||||
$this->features = array(
|
||||
'prepare' => false,
|
||||
'pconnect' => true,
|
||||
'transactions' => true,
|
||||
'limit' => 'alter'
|
||||
);
|
||||
$this->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,
|
||||
1046 => DB_ERROR_NODBSELECTED,
|
||||
1050 => DB_ERROR_ALREADY_EXISTS,
|
||||
1051 => DB_ERROR_NOSUCHTABLE,
|
||||
1054 => DB_ERROR_NOSUCHFIELD,
|
||||
1062 => DB_ERROR_ALREADY_EXISTS,
|
||||
1064 => DB_ERROR_SYNTAX,
|
||||
1100 => DB_ERROR_NOT_LOCKED,
|
||||
1136 => DB_ERROR_VALUE_COUNT_ON_ROW,
|
||||
1146 => DB_ERROR_NOSUCHTABLE,
|
||||
1048 => DB_ERROR_CONSTRAINT,
|
||||
);
|
||||
}
|
||||
|
||||
// }}}
|
||||
|
||||
// {{{ connect()
|
||||
|
||||
/**
|
||||
* Connect to a database and log in as the specified user.
|
||||
*
|
||||
* @param $dsn the data source name (see DB::parseDSN for syntax)
|
||||
* @param $persistent (optional) whether the connection should
|
||||
* be persistent
|
||||
* @access public
|
||||
* @return int DB_OK on success, a DB error on failure
|
||||
*/
|
||||
|
||||
function connect($dsninfo, $persistent = false)
|
||||
{
|
||||
if (!DB::assertExtension('mysql'))
|
||||
return $this->raiseError(DB_ERROR_EXTENSION_NOT_FOUND);
|
||||
|
||||
$this->dsn = $dsninfo;
|
||||
if (isset($dsninfo['protocol']) && $dsninfo['protocol'] == 'unix') {
|
||||
$dbhost = ':' . $dsninfo['socket'];
|
||||
} else {
|
||||
$dbhost = $dsninfo['hostspec'] ? $dsninfo['hostspec'] : 'localhost';
|
||||
if (!empty($dsninfo['port'])) {
|
||||
$dbhost .= ':' . $dsninfo['port'];
|
||||
}
|
||||
}
|
||||
$user = $dsninfo['username'];
|
||||
$pw = $dsninfo['password'];
|
||||
|
||||
$connect_function = $persistent ? 'mysql_pconnect' : 'mysql_connect';
|
||||
|
||||
@ini_set('track_errors', true);
|
||||
if ($dbhost && $user && $pw) {
|
||||
$conn = @$connect_function($dbhost, $user, $pw);
|
||||
} elseif ($dbhost && $user) {
|
||||
$conn = @$connect_function($dbhost, $user);
|
||||
} elseif ($dbhost) {
|
||||
$conn = @$connect_function($dbhost);
|
||||
} else {
|
||||
$conn = false;
|
||||
}
|
||||
@ini_restore('track_errors');
|
||||
if (empty($conn)) {
|
||||
if (($err = @mysql_error()) != '') {
|
||||
return $this->raiseError(DB_ERROR_CONNECT_FAILED, null, null,
|
||||
null, $err);
|
||||
} elseif (empty($php_errormsg)) {
|
||||
return $this->raiseError(DB_ERROR_CONNECT_FAILED);
|
||||
} else {
|
||||
return $this->raiseError(DB_ERROR_CONNECT_FAILED, null, null,
|
||||
null, $php_errormsg);
|
||||
}
|
||||
}
|
||||
|
||||
if ($dsninfo['database']) {
|
||||
if (!@mysql_select_db($dsninfo['database'], $conn)) {
|
||||
switch(mysql_errno($conn)) {
|
||||
case 1049:
|
||||
return $this->raiseError(DB_ERROR_NOSUCHDB, null, null,
|
||||
null, mysql_error($conn));
|
||||
break;
|
||||
case 1044:
|
||||
return $this->raiseError(DB_ERROR_ACCESS_VIOLATION, null, null,
|
||||
null, mysql_error($conn));
|
||||
break;
|
||||
default:
|
||||
return $this->raiseError(DB_ERROR, null, null,
|
||||
null, mysql_error($conn));
|
||||
break;
|
||||
|
||||
}
|
||||
}
|
||||
// fix to allow calls to different databases in the same script
|
||||
$this->_db = $dsninfo['database'];
|
||||
}
|
||||
|
||||
$this->connection = $conn;
|
||||
return DB_OK;
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ disconnect()
|
||||
|
||||
/**
|
||||
* Log out and disconnect from the database.
|
||||
*
|
||||
* @access public
|
||||
*
|
||||
* @return bool TRUE on success, FALSE if not connected.
|
||||
*/
|
||||
function disconnect()
|
||||
{
|
||||
$ret = mysql_close($this->connection);
|
||||
$this->connection = null;
|
||||
return $ret;
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ simpleQuery()
|
||||
|
||||
/**
|
||||
* Send a query to MySQL and return the results as a MySQL resource
|
||||
* identifier.
|
||||
*
|
||||
* @param the SQL query
|
||||
*
|
||||
* @access public
|
||||
*
|
||||
* @return mixed returns a valid MySQL result for successful SELECT
|
||||
* queries, DB_OK for other successful queries. A DB error is
|
||||
* returned on failure.
|
||||
*/
|
||||
function simpleQuery($query)
|
||||
{
|
||||
$ismanip = DB::isManip($query);
|
||||
$this->last_query = $query;
|
||||
$query = $this->modifyQuery($query);
|
||||
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++;
|
||||
}
|
||||
$result = @mysql_query($query, $this->connection);
|
||||
if (!$result) {
|
||||
return $this->mysqlRaiseError();
|
||||
}
|
||||
if (is_resource($result)) {
|
||||
$numrows = $this->numrows($result);
|
||||
if (is_object($numrows)) {
|
||||
return $numrows;
|
||||
}
|
||||
$this->num_rows[$result] = $numrows;
|
||||
return $result;
|
||||
}
|
||||
return DB_OK;
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ nextResult()
|
||||
|
||||
/**
|
||||
* Move the internal mysql 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;
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ fetch_assoc()
|
||||
|
||||
/**
|
||||
* Fetch and return a row of data (it uses fetchInto for that)
|
||||
* @param $result MySQL result identifier
|
||||
* @param $fetchmode format of fetched row array
|
||||
* @param $rownum the absolute row number to fetch
|
||||
*
|
||||
* @return array a row of data, or false on error
|
||||
*/
|
||||
function fetch_assoc($result, $fetchmode = DB_FETCHMODE_DEFAULT, $rownum=null)
|
||||
{
|
||||
if ($fetchmode == DB_FETCHMODE_DEFAULT) {
|
||||
$fetchmode = $this->fetchmode;
|
||||
}
|
||||
$res = $this->fetchInto ($result, $arr, $fetchmode, $rownum);
|
||||
if ($res !== DB_OK) {
|
||||
return $res;
|
||||
}
|
||||
return $arr;
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ fetchInto()
|
||||
|
||||
/**
|
||||
* Fetch a row and insert the data into an existing array.
|
||||
*
|
||||
* @param $result MySQL result identifier
|
||||
* @param $arr (reference) array where data from the row is stored
|
||||
* @param $fetchmode how the array data should be indexed
|
||||
* @param $rownum the row number to fetch
|
||||
* @access public
|
||||
*
|
||||
* @return int DB_OK on success, a DB error on failure
|
||||
*/
|
||||
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);
|
||||
} else {
|
||||
$arr = @mysql_fetch_row($result);
|
||||
}
|
||||
if (!$arr) {
|
||||
$errno = @mysql_errno($this->connection);
|
||||
if (!$errno) {
|
||||
return NULL;
|
||||
}
|
||||
return $this->mysqlRaiseError($errno);
|
||||
}
|
||||
return DB_OK;
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ freeResult()
|
||||
|
||||
/**
|
||||
* Free the internal resources associated with $result.
|
||||
*
|
||||
* @param $result MySQL result identifier or DB statement identifier
|
||||
*
|
||||
* @access public
|
||||
*
|
||||
* @return bool TRUE on success, FALSE if $result is invalid
|
||||
*/
|
||||
function freeResult($result)
|
||||
{
|
||||
if (is_resource($result)) {
|
||||
return mysql_free_result($result);
|
||||
}
|
||||
|
||||
$result = (int)$result; // $result is a prepared query handle
|
||||
if (!isset($this->prepare_tokens[$result])) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// [ssb]: WTF? unset($this->prepare_types[$result]) makes PHP
|
||||
// crash on my laptop (4.1.2 as well as 4.3.0-dev)
|
||||
|
||||
$copy = $this->prepare_types;
|
||||
unset($copy[$result]);
|
||||
$this->prepare_types = $copy;
|
||||
// unset($this->prepare_types[$result]);
|
||||
|
||||
$copy = $this->prepare_tokens;
|
||||
unset($copy[$result]);
|
||||
$this->prepare_tokens = $copy;
|
||||
// unset($this->prepare_tokens[$result]);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ numCols()
|
||||
|
||||
/**
|
||||
* Get the number of columns in a result set.
|
||||
*
|
||||
* @param $result MySQL result identifier
|
||||
*
|
||||
* @access public
|
||||
*
|
||||
* @return int the number of columns per row in $result
|
||||
*/
|
||||
function numCols($result)
|
||||
{
|
||||
$cols = @mysql_num_fields($result);
|
||||
|
||||
if (!$cols) {
|
||||
return $this->mysqlRaiseError();
|
||||
}
|
||||
|
||||
return $cols;
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ numRows()
|
||||
|
||||
/**
|
||||
* Get the number of rows in a result set.
|
||||
*
|
||||
* @param $result MySQL result identifier
|
||||
*
|
||||
* @access public
|
||||
*
|
||||
* @return int the number of rows in $result
|
||||
*/
|
||||
function numRows($result)
|
||||
{
|
||||
$rows = @mysql_num_rows($result);
|
||||
if ($rows === null) {
|
||||
return $this->mysqlRaiseError();
|
||||
}
|
||||
return $rows;
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ autoCommit()
|
||||
|
||||
/**
|
||||
* Enable/disable automatic commits
|
||||
*/
|
||||
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()
|
||||
|
||||
/**
|
||||
* Commit the current transaction.
|
||||
*/
|
||||
function commit()
|
||||
{
|
||||
if ($this->transaction_opcount > 0) {
|
||||
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()
|
||||
|
||||
/**
|
||||
* Roll back (undo) the current transaction.
|
||||
*/
|
||||
function rollback()
|
||||
{
|
||||
if ($this->transaction_opcount > 0) {
|
||||
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()
|
||||
|
||||
/**
|
||||
* Gets the number of rows affected by the data manipulation
|
||||
* query. For other queries, this function returns 0.
|
||||
*
|
||||
* @return number of rows affected by the last query
|
||||
*/
|
||||
|
||||
function affectedRows()
|
||||
{
|
||||
if (DB::isManip($this->last_query)) {
|
||||
$result = @mysql_affected_rows($this->connection);
|
||||
} else {
|
||||
$result = 0;
|
||||
}
|
||||
return $result;
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ errorNative()
|
||||
|
||||
/**
|
||||
* Get the native error code of the last error (if any) that
|
||||
* occured on the current connection.
|
||||
*
|
||||
* @access public
|
||||
*
|
||||
* @return int native MySQL error code
|
||||
*/
|
||||
|
||||
function errorNative()
|
||||
{
|
||||
return mysql_errno($this->connection);
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ nextId()
|
||||
|
||||
/**
|
||||
* Get the next value in a sequence. We emulate sequences
|
||||
* for MySQL. Will create the sequence if it does not exist.
|
||||
*
|
||||
* @access public
|
||||
*
|
||||
* @param string $seq_name the name of the sequence
|
||||
*
|
||||
* @param bool $ondemand whether to create the sequence table on demand
|
||||
* (default is true)
|
||||
*
|
||||
* @return mixed a sequence integer, or a DB error
|
||||
*/
|
||||
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
|
||||
// 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, bail with a DB_ERROR_NOT_LOCKED error
|
||||
return $this->mysqlRaiseError(DB_ERROR_NOT_LOCKED);
|
||||
}
|
||||
|
||||
// add the default value
|
||||
$result = $this->query("REPLACE INTO ${seqname} 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;
|
||||
|
||||
/** ONDEMAND TABLE CREATION **/
|
||||
} elseif ($ondemand && DB::isError($result) &&
|
||||
$result->getCode() == DB_ERROR_NOSUCHTABLE)
|
||||
{
|
||||
$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;
|
||||
}
|
||||
|
||||
/** BACKWARDS COMPAT **/
|
||||
} elseif (DB::isError($result) &&
|
||||
$result->getCode() == DB_ERROR_ALREADY_EXISTS)
|
||||
{
|
||||
// see _BCsequence() comment
|
||||
$result = $this->_BCsequence($seqname);
|
||||
if (DB::isError($result)) {
|
||||
return $this->raiseError($result);
|
||||
}
|
||||
$repeat = 1;
|
||||
}
|
||||
} while ($repeat);
|
||||
|
||||
return $this->raiseError($result);
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ createSequence()
|
||||
|
||||
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} VALUES(0)");
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ dropSequence()
|
||||
|
||||
function dropSequence($seq_name)
|
||||
{
|
||||
$seqname = $this->getSequenceName($seq_name);
|
||||
return $this->query("DROP TABLE ${seqname}");
|
||||
}
|
||||
|
||||
// }}}
|
||||
|
||||
/**
|
||||
* Bacwards Compatibility with old sequence emulation implementation
|
||||
* (clean up the dupes)
|
||||
* @param string $seqname The sequence name to clean up
|
||||
* @return mixed DB_Error or true
|
||||
*/
|
||||
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;
|
||||
}
|
||||
|
||||
// {{{ quote()
|
||||
/**
|
||||
* Quote the given string so it can be safely used within string delimiters
|
||||
* in a query.
|
||||
* @param $string mixed Data to be quoted
|
||||
* @return mixed "NULL" string, quoted string or original data
|
||||
*/
|
||||
function quote($str = null)
|
||||
{
|
||||
switch (strtolower(gettype($str))) {
|
||||
case 'null':
|
||||
return 'NULL';
|
||||
case 'integer':
|
||||
return $str;
|
||||
case 'string':
|
||||
default:
|
||||
return "'".mysql_escape_string($str)."'";
|
||||
}
|
||||
}
|
||||
// }}}
|
||||
// {{{ modifyQuery()
|
||||
|
||||
function modifyQuery($query, $subject = null)
|
||||
{
|
||||
if ($this->options['optimize'] == 'portability') {
|
||||
// "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()
|
||||
|
||||
function modifyLimitQuery($query, $from, $count)
|
||||
{
|
||||
$query = $query . " LIMIT $from, $count";
|
||||
return $query;
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ mysqlRaiseError()
|
||||
|
||||
function mysqlRaiseError($errno = null)
|
||||
{
|
||||
if ($errno === null) {
|
||||
$errno = $this->errorCode(mysql_errno($this->connection));
|
||||
}
|
||||
return $this->raiseError($errno, null, null, null,
|
||||
@mysql_errno($this->connection) . " ** " .
|
||||
@mysql_error($this->connection));
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ tableInfo()
|
||||
|
||||
function tableInfo($result, $mode = null) {
|
||||
$count = 0;
|
||||
$id = 0;
|
||||
$res = array();
|
||||
|
||||
/*
|
||||
* depending on $mode, metadata returns the following values:
|
||||
*
|
||||
* - mode is false (default):
|
||||
* $result[]:
|
||||
* [0]["table"] table name
|
||||
* [0]["name"] field name
|
||||
* [0]["type"] field type
|
||||
* [0]["len"] field length
|
||||
* [0]["flags"] field flags
|
||||
*
|
||||
* - mode is DB_TABLEINFO_ORDER
|
||||
* $result[]:
|
||||
* ["num_fields"] number of metadata records
|
||||
* [0]["table"] table name
|
||||
* [0]["name"] field name
|
||||
* [0]["type"] field type
|
||||
* [0]["len"] field length
|
||||
* [0]["flags"] field flags
|
||||
* ["order"][field name] index of field named "field name"
|
||||
* The last one is used, if you have a field name, but no index.
|
||||
* Test: if (isset($result['meta']['myfield'])) { ...
|
||||
*
|
||||
* - mode is DB_TABLEINFO_ORDERTABLE
|
||||
* the same as above. but additionally
|
||||
* ["ordertable"][table name][field name] index of field
|
||||
* named "field name"
|
||||
*
|
||||
* this is, because if you have fields from different
|
||||
* tables with the same field name * they override each
|
||||
* other with DB_TABLEINFO_ORDER
|
||||
*
|
||||
* you can combine DB_TABLEINFO_ORDER and
|
||||
* DB_TABLEINFO_ORDERTABLE with DB_TABLEINFO_ORDER |
|
||||
* DB_TABLEINFO_ORDERTABLE * or with DB_TABLEINFO_FULL
|
||||
*/
|
||||
|
||||
// if $result is a string, then we want information about a
|
||||
// table without a resultset
|
||||
if (is_string($result)) {
|
||||
$id = @mysql_list_fields($this->dsn['database'],
|
||||
$result, $this->connection);
|
||||
if (empty($id)) {
|
||||
return $this->mysqlRaiseError();
|
||||
}
|
||||
} else { // else we want information about a resultset
|
||||
$id = $result;
|
||||
if (empty($id)) {
|
||||
return $this->mysqlRaiseError();
|
||||
}
|
||||
}
|
||||
|
||||
$count = @mysql_num_fields($id);
|
||||
|
||||
// made this IF due to performance (one if is faster than $count if's)
|
||||
if (empty($mode)) {
|
||||
for ($i=0; $i<$count; $i++) {
|
||||
$res[$i]['table'] = @mysql_field_table ($id, $i);
|
||||
$res[$i]['name'] = @mysql_field_name ($id, $i);
|
||||
$res[$i]['type'] = @mysql_field_type ($id, $i);
|
||||
$res[$i]['len'] = @mysql_field_len ($id, $i);
|
||||
$res[$i]['flags'] = @mysql_field_flags ($id, $i);
|
||||
}
|
||||
} else { // full
|
||||
$res['num_fields']= $count;
|
||||
|
||||
for ($i=0; $i<$count; $i++) {
|
||||
$res[$i]['table'] = @mysql_field_table ($id, $i);
|
||||
$res[$i]['name'] = @mysql_field_name ($id, $i);
|
||||
$res[$i]['type'] = @mysql_field_type ($id, $i);
|
||||
$res[$i]['len'] = @mysql_field_len ($id, $i);
|
||||
$res[$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 (is_string($result)) {
|
||||
@mysql_free_result($id);
|
||||
}
|
||||
return $res;
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ getTablesQuery()
|
||||
|
||||
/**
|
||||
* Returns the query needed to get some backend info
|
||||
* @param string $type What kind of info you want to retrieve
|
||||
* @return string The SQL query string
|
||||
*/
|
||||
function getSpecialQuery($type)
|
||||
{
|
||||
switch ($type) {
|
||||
case 'tables':
|
||||
$sql = "SHOW TABLES";
|
||||
break;
|
||||
case 'views':
|
||||
return DB_ERROR_NOT_CAPABLE;
|
||||
case 'users':
|
||||
$sql = "select distinct User from user";
|
||||
if($this->dsn['database'] != 'mysql') {
|
||||
$dsn = $this->dsn;
|
||||
$dsn['database'] = 'mysql';
|
||||
if (DB::isError($db = DB::connect($dsn))) {
|
||||
return $db;
|
||||
}
|
||||
$sql = $db->getCol($sql);
|
||||
$db->disconnect();
|
||||
// XXX Fixme the mysql driver should take care of this
|
||||
if (!@mysql_select_db($this->dsn['database'], $this->connection)) {
|
||||
return $this->mysqlRaiseError(DB_ERROR_NODBSELECTED);
|
||||
}
|
||||
}
|
||||
return $sql;
|
||||
break;
|
||||
case 'databases':
|
||||
$sql = "SHOW DATABASES";
|
||||
break;
|
||||
default:
|
||||
return null;
|
||||
}
|
||||
return $sql;
|
||||
}
|
||||
|
||||
// }}}
|
||||
|
||||
// TODO/wishlist:
|
||||
// longReadlen
|
||||
// binmode
|
||||
}
|
||||
|
||||
?>
|
||||
664
html/illt/DB/oci8.php
Normal file
664
html/illt/DB/oci8.php
Normal file
@@ -0,0 +1,664 @@
|
||||
<?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. |
|
||||
// +----------------------------------------------------------------------+
|
||||
// | Author: James L. Pine <jlp@valinux.com> |
|
||||
// +----------------------------------------------------------------------+
|
||||
//
|
||||
// $Id: oci8.php,v 1.47.2.1 2002/04/09 19:04:15 ssb Exp $
|
||||
//
|
||||
// Database independent query interface definition for PHP's Oracle 8
|
||||
// call-interface extension.
|
||||
//
|
||||
|
||||
//
|
||||
// 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.
|
||||
//
|
||||
|
||||
|
||||
require_once 'DB/common.php';
|
||||
|
||||
class DB_oci8 extends DB_common
|
||||
{
|
||||
// {{{ properties
|
||||
|
||||
var $connection;
|
||||
var $phptype, $dbsyntax;
|
||||
var $manip_query = array();
|
||||
var $prepare_types = array();
|
||||
var $autoCommit = 1;
|
||||
var $last_stmt = false;
|
||||
|
||||
// }}}
|
||||
// {{{ constructor
|
||||
|
||||
function DB_oci8()
|
||||
{
|
||||
$this->DB_common();
|
||||
$this->phptype = 'oci8';
|
||||
$this->dbsyntax = 'oci8';
|
||||
$this->features = array(
|
||||
'prepare' => false,
|
||||
'pconnect' => true,
|
||||
'transactions' => true,
|
||||
'limit' => 'alter'
|
||||
);
|
||||
$this->errorcode_map = array(
|
||||
900 => DB_ERROR_SYNTAX,
|
||||
904 => DB_ERROR_NOSUCHFIELD,
|
||||
923 => DB_ERROR_SYNTAX,
|
||||
942 => DB_ERROR_NOSUCHTABLE,
|
||||
955 => DB_ERROR_ALREADY_EXISTS,
|
||||
1476 => DB_ERROR_DIVZERO,
|
||||
1722 => DB_ERROR_INVALID_NUMBER,
|
||||
2289 => DB_ERROR_NOSUCHTABLE,
|
||||
2291 => DB_ERROR_CONSTRAINT,
|
||||
2449 => DB_ERROR_CONSTRAINT,
|
||||
);
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ connect()
|
||||
|
||||
/**
|
||||
* Connect to a database and log in as the specified user.
|
||||
*
|
||||
* @param $dsn the data source name (see DB::parseDSN for syntax)
|
||||
* @param $persistent (optional) whether the connection should
|
||||
* be persistent
|
||||
*
|
||||
* @return int DB_OK on success, a DB error code on failure
|
||||
*/
|
||||
function connect($dsninfo, $persistent = false)
|
||||
{
|
||||
if (!DB::assertExtension('oci8')) {
|
||||
return $this->raiseError(DB_ERROR_EXTENSION_NOT_FOUND);
|
||||
}
|
||||
$this->dsn = $dsninfo;
|
||||
$user = $dsninfo['username'];
|
||||
$pw = $dsninfo['password'];
|
||||
$hostspec = $dsninfo['hostspec'];
|
||||
|
||||
$connect_function = $persistent ? 'OCIPLogon' : 'OCILogon';
|
||||
|
||||
if ($hostspec) {
|
||||
$conn = @$connect_function($user,$pw,$hostspec);
|
||||
} elseif ($user || $pw) {
|
||||
$conn = @$connect_function($user,$pw);
|
||||
} else {
|
||||
$conn = false;
|
||||
}
|
||||
if ($conn == false) {
|
||||
$error = OCIError();
|
||||
$error = (is_array($error)) ? $error['message'] : null;
|
||||
return $this->raiseError(DB_ERROR_CONNECT_FAILED, null, null,
|
||||
null, $error);
|
||||
}
|
||||
$this->connection = $conn;
|
||||
return DB_OK;
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ disconnect()
|
||||
|
||||
/**
|
||||
* Log out and disconnect from the database.
|
||||
*
|
||||
* @return bool TRUE on success, FALSE if not connected.
|
||||
*/
|
||||
function disconnect()
|
||||
{
|
||||
$ret = @OCILogOff($this->connection);
|
||||
$this->connection = null;
|
||||
return $ret;
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ simpleQuery()
|
||||
|
||||
/**
|
||||
* Send a query to oracle and return the results as an oci8 resource
|
||||
* identifier.
|
||||
*
|
||||
* @param $query the SQL query
|
||||
*
|
||||
* @return int returns a valid oci8 result for successful SELECT
|
||||
* queries, DB_OK for other successful queries. A DB error code
|
||||
* is returned on failure.
|
||||
*/
|
||||
function simpleQuery($query)
|
||||
{
|
||||
$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;
|
||||
// Determine which queries that should return data, and which
|
||||
// should return an error code only.
|
||||
return DB::isManip($query) ? DB_OK : $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;
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ fetch_assoc()
|
||||
|
||||
/**
|
||||
* Fetch a row and return as array.
|
||||
*
|
||||
* @param $result oci8 result identifier
|
||||
* @param $fetchmode how the resulting array should be indexed
|
||||
*
|
||||
* @return int an array on success, a DB error code on failure, NULL
|
||||
* if there is no more data
|
||||
*/
|
||||
function &fetch_assoc($result, $fetchmode = DB_FETCHMODE_DEFAULT)
|
||||
{
|
||||
if ($fetchmode == DB_FETCHMODE_DEFAULT) {
|
||||
$fetchmode = $this->fetchmode;
|
||||
}
|
||||
if ($fetchmode & DB_FETCHMODE_ASSOC) {
|
||||
$moredata = @OCIFetchInto($result, $row, OCI_ASSOC + OCI_RETURN_NULLS + OCI_RETURN_LOBS);
|
||||
} else {
|
||||
$moredata = @OCIFetchInto($result, $row, OCI_RETURN_NULLS + OCI_RETURN_LOBS);
|
||||
}
|
||||
if (!$moredata) {
|
||||
return NULL;
|
||||
}
|
||||
return $row;
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ fetchInto()
|
||||
|
||||
/**
|
||||
* Fetch a row and insert the data into an existing array.
|
||||
*
|
||||
* @param $result oci8 result identifier
|
||||
* @param $arr (reference) array where data from the row is stored
|
||||
* @param $fetchmode how the array data should be indexed
|
||||
* @param $rownum the row number to fetch (not yet supported)
|
||||
*
|
||||
* @return int DB_OK on success, a DB error code on failure
|
||||
*/
|
||||
function fetchInto($result, &$arr, $fetchmode = DB_FETCHMODE_DEFAULT, $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 ($moredata && $this->options['optimize'] == 'portability') {
|
||||
$arr = array_change_key_case($arr, CASE_LOWER);
|
||||
}
|
||||
} else {
|
||||
$moredata = @OCIFetchInto($result,$arr,OCI_RETURN_NULLS+OCI_RETURN_LOBS);
|
||||
}
|
||||
if (!$moredata) {
|
||||
return NULL;
|
||||
}
|
||||
return DB_OK;
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ freeResult()
|
||||
|
||||
/**
|
||||
* Free the internal resources associated with $result.
|
||||
*
|
||||
* @param $result oci8 result identifier or DB statement identifier
|
||||
*
|
||||
* @return bool TRUE on success, FALSE if $result is invalid
|
||||
*/
|
||||
function freeResult($result)
|
||||
{
|
||||
if (is_resource($result)) {
|
||||
return @OCIFreeStatement($result);
|
||||
}
|
||||
if (!isset($this->prepare_tokens[(int)$result])) {
|
||||
return false;
|
||||
}
|
||||
unset($this->prepare_tokens[(int)$result]);
|
||||
unset($this->prepare_types[(int)$result]);
|
||||
unset($this->manip_query[(int)$result]);
|
||||
return true;
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ numRows()
|
||||
|
||||
function numRows($result)
|
||||
{
|
||||
// emulate numRows for Oracle. yuck.
|
||||
if ($this->options['optimize'] == 'portability' &&
|
||||
$result === $this->last_stmt) {
|
||||
$countquery = preg_replace('/^\s*SELECT\s+(.*?)\s+FROM\s+/is',
|
||||
'SELECT COUNT(*) FROM ',
|
||||
$this->last_query);
|
||||
$save_query = $this->last_query;
|
||||
$save_stmt = $this->last_stmt;
|
||||
$count = $this->query($countquery);
|
||||
if (DB::isError($count) ||
|
||||
DB::isError($row = $count->fetch_assoc(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()
|
||||
|
||||
/**
|
||||
* Get the number of columns in a result set.
|
||||
*
|
||||
* @param $result oci8 result identifier
|
||||
*
|
||||
* @return int the number of columns per row in $result
|
||||
*/
|
||||
function numCols($result)
|
||||
{
|
||||
$cols = @OCINumCols($result);
|
||||
if (!$cols) {
|
||||
return $this->oci8RaiseError($result);
|
||||
}
|
||||
return $cols;
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ errorNative()
|
||||
|
||||
/**
|
||||
* Get the native error code of the last error (if any) that occured
|
||||
* on the current connection. This does not work, as OCIError does
|
||||
* not work unless given a statement. If OCIError does return
|
||||
* something, so will this.
|
||||
*
|
||||
* @return int native oci8 error code
|
||||
*/
|
||||
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;
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ prepare()
|
||||
|
||||
/**
|
||||
* Prepares a query for multiple execution with execute(). With
|
||||
* oci8, this is emulated.
|
||||
* @param $query query to be prepared
|
||||
*
|
||||
* @return DB statement resource
|
||||
*/
|
||||
function prepare($query)
|
||||
{
|
||||
$tokens = split('[\&\?]', $query);
|
||||
$token = 0;
|
||||
$types = array();
|
||||
for ($i = 0; $i < strlen($query); $i++) {
|
||||
switch ($query[$i]) {
|
||||
case '?':
|
||||
$types[$token++] = DB_PARAM_SCALAR;
|
||||
break;
|
||||
case '&':
|
||||
$types[$token++] = DB_PARAM_OPAQUE;
|
||||
break;
|
||||
}
|
||||
}
|
||||
$binds = sizeof($tokens) - 1;
|
||||
$newquery = '';
|
||||
for ($i = 0; $i < $binds; $i++) {
|
||||
$newquery .= $tokens[$i] . ":bind" . $i;
|
||||
}
|
||||
$newquery .= $tokens[$i];
|
||||
$this->last_query = $query;
|
||||
$newquery = $this->modifyQuery($newquery);
|
||||
$stmt = @OCIParse($this->connection, $newquery);
|
||||
$this->prepare_types[$stmt] = $types;
|
||||
$this->manip_query[(int)$stmt] = DB::isManip($query);
|
||||
return $stmt;
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ execute()
|
||||
|
||||
/**
|
||||
* Executes a DB statement prepared with prepare().
|
||||
*
|
||||
* @param $stmt a DB statement resource (returned from prepare())
|
||||
* @param $data data to be used in execution of the statement
|
||||
*
|
||||
* @return int returns an oci8 result resource for successful
|
||||
* SELECT queries, DB_OK for other successful queries. A DB error
|
||||
* code is returned on failure.
|
||||
*/
|
||||
function execute($stmt, $data = false)
|
||||
{
|
||||
$types=&$this->prepare_types[$stmt];
|
||||
if (($size = sizeof($types)) != sizeof($data)) {
|
||||
return $this->raiseError(DB_ERROR_MISMATCH);
|
||||
}
|
||||
for ($i = 0; $i < $size; $i++) {
|
||||
if (is_array($data)) {
|
||||
$pdata[$i] = &$data[$i];
|
||||
}
|
||||
else {
|
||||
$pdata[$i] = &$data;
|
||||
}
|
||||
if ($types[$i] == DB_PARAM_OPAQUE) {
|
||||
$fp = fopen($pdata[$i], "r");
|
||||
$pdata[$i] = '';
|
||||
if ($fp) {
|
||||
while (($buf = fread($fp, 4096)) != false) {
|
||||
$pdata[$i] .= $buf;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!@OCIBindByName($stmt, ":bind" . $i, $pdata[$i], -1)) {
|
||||
return $this->oci8RaiseError($stmt);
|
||||
}
|
||||
}
|
||||
if ($this->autoCommit) {
|
||||
$success = @OCIExecute($stmt, OCI_COMMIT_ON_SUCCESS);
|
||||
}
|
||||
else {
|
||||
$success = @OCIExecute($stmt, OCI_DEFAULT);
|
||||
}
|
||||
if (!$success) {
|
||||
return $this->oci8RaiseError($stmt);
|
||||
}
|
||||
$this->last_stmt = $stmt;
|
||||
if ($this->manip_query[(int)$stmt]) {
|
||||
return DB_OK;
|
||||
} else {
|
||||
return new DB_result($this, $stmt);
|
||||
}
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ autoCommit()
|
||||
|
||||
/**
|
||||
* Enable/disable automatic commits
|
||||
*
|
||||
* @param $onoff true/false whether to autocommit
|
||||
*/
|
||||
function autoCommit($onoff = false)
|
||||
{
|
||||
$this->autoCommit = (bool)$onoff;;
|
||||
return DB_OK;
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ commit()
|
||||
|
||||
/**
|
||||
* Commit transactions on the current connection
|
||||
*
|
||||
* @return DB_ERROR or DB_OK
|
||||
*/
|
||||
function commit()
|
||||
{
|
||||
$result = @OCICommit($this->connection);
|
||||
if (!$result) {
|
||||
return $this->oci8RaiseError();
|
||||
}
|
||||
return DB_OK;
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ rollback()
|
||||
|
||||
/**
|
||||
* Roll back all uncommitted transactions on the current connection.
|
||||
*
|
||||
* @return DB_ERROR or DB_OK
|
||||
*/
|
||||
function rollback()
|
||||
{
|
||||
$result = @OCIRollback($this->connection);
|
||||
if (!$result) {
|
||||
return $this->oci8RaiseError();
|
||||
}
|
||||
return DB_OK;
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ affectedRows()
|
||||
|
||||
/**
|
||||
* Gets the number of rows affected by the last query.
|
||||
* if the last query was a select, returns 0.
|
||||
*
|
||||
* @return number of rows affected by the last query or DB_ERROR
|
||||
*/
|
||||
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()
|
||||
|
||||
function modifyQuery($query)
|
||||
{
|
||||
// "SELECT 2+2" must be "SELECT 2+2 FROM dual" in Oracle
|
||||
if (preg_match('/^\s*SELECT/i', $query) &&
|
||||
!preg_match('/\sFROM\s/i', $query)) {
|
||||
$query .= " FROM dual";
|
||||
}
|
||||
return $query;
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ modifyLimitQuery()
|
||||
|
||||
/**
|
||||
* Emulate the row limit support altering the query
|
||||
*
|
||||
* @param string $query The query to treat
|
||||
* @param int $from The row to start to fetch from
|
||||
* @param int $count The offset
|
||||
* @return string The modified query
|
||||
*
|
||||
* @author Tomas V.V.Cox <cox@idecnet.com>
|
||||
*/
|
||||
function modifyLimitQuery($query, $from, $count)
|
||||
{
|
||||
// Let Oracle return the name of the columns instead of
|
||||
// coding a "home" SQL parser
|
||||
$q_fields = "SELECT * FROM ($query) WHERE NULL = NULL";
|
||||
if (!$result = OCIParse($this->connection, $q_fields)) {
|
||||
return $this->oci8RaiseError();
|
||||
}
|
||||
if (!OCIExecute($result, OCI_DEFAULT)) {
|
||||
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
|
||||
$from += 1; // in Oracle rownum starts at 1
|
||||
$query = "SELECT $fields FROM".
|
||||
" (SELECT rownum as linenum, $fields FROM".
|
||||
" ($query)".
|
||||
" WHERE rownum <= ". ($from + $count) .
|
||||
") WHERE linenum >= $from";
|
||||
return $query;
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ nextId()
|
||||
|
||||
/**
|
||||
* Get the next value in a sequence. We emulate sequences
|
||||
* for MySQL. Will create the sequence if it does not exist.
|
||||
*
|
||||
* @access public
|
||||
*
|
||||
* @param $seq_name the name of the sequence
|
||||
*
|
||||
* @param $ondemand whether to create the sequence table on demand
|
||||
* (default is true)
|
||||
*
|
||||
* @return a sequence integer, or a DB error
|
||||
*/
|
||||
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->fetch_assoc(DB_FETCHMODE_ORDERED);
|
||||
return $arr[0];
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ createSequence()
|
||||
|
||||
function createSequence($seq_name)
|
||||
{
|
||||
$seqname = $this->getSequenceName($seq_name);
|
||||
return $this->query("CREATE SEQUENCE ${seqname}");
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ dropSequence()
|
||||
|
||||
function dropSequence($seq_name)
|
||||
{
|
||||
$seqname = $this->getSequenceName($seq_name);
|
||||
return $this->query("DROP SEQUENCE ${seqname}");
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ oci8RaiseError()
|
||||
|
||||
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));
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ getSpecialQuery()
|
||||
|
||||
/**
|
||||
* Returns the query needed to get some backend info
|
||||
* @param string $type What kind of info you want to retrieve
|
||||
* @return string The SQL query string
|
||||
*/
|
||||
function getSpecialQuery($type)
|
||||
{
|
||||
switch ($type) {
|
||||
case 'tables':
|
||||
$sql = "SELECT table_name FROM user_tables";
|
||||
break;
|
||||
default:
|
||||
return null;
|
||||
}
|
||||
return $sql;
|
||||
}
|
||||
|
||||
// }}}
|
||||
|
||||
}
|
||||
// Local variables:
|
||||
// tab-width: 4
|
||||
// c-basic-offset: 4
|
||||
// End:
|
||||
?>
|
||||
484
html/illt/DB/odbc.php
Normal file
484
html/illt/DB/odbc.php
Normal file
@@ -0,0 +1,484 @@
|
||||
<?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. |
|
||||
// +----------------------------------------------------------------------+
|
||||
// | Author: Stig Bakken <ssb@fast.no> |
|
||||
// +----------------------------------------------------------------------+
|
||||
//
|
||||
// $Id: odbc.php,v 1.54 2002/02/28 08:27:11 sebastian Exp $
|
||||
//
|
||||
// Database independent query interface definition for PHP's ODBC
|
||||
// extension.
|
||||
//
|
||||
|
||||
//
|
||||
// XXX legend:
|
||||
// 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
|
||||
//
|
||||
// XXX ERRORMSG: The error message from the odbc function should
|
||||
// be registered here.
|
||||
//
|
||||
|
||||
require_once 'DB/common.php';
|
||||
|
||||
class DB_odbc extends DB_common
|
||||
{
|
||||
// {{{ properties
|
||||
|
||||
var $connection;
|
||||
var $phptype, $dbsyntax;
|
||||
var $row = array();
|
||||
|
||||
// }}}
|
||||
// {{{ constructor
|
||||
|
||||
function DB_odbc()
|
||||
{
|
||||
$this->DB_common();
|
||||
$this->phptype = 'odbc';
|
||||
$this->dbsyntax = 'sql92';
|
||||
$this->features = array(
|
||||
'prepare' => true,
|
||||
'pconnect' => true,
|
||||
'transactions' => false,
|
||||
'limit' => 'emulate'
|
||||
);
|
||||
$this->errorcode_map = array(
|
||||
'01004' => DB_ERROR_TRUNCATED,
|
||||
'07001' => DB_ERROR_MISMATCH,
|
||||
'21S01' => DB_ERROR_MISMATCH,
|
||||
'21S02' => DB_ERROR_MISMATCH,
|
||||
'22003' => DB_ERROR_INVALID_NUMBER,
|
||||
'22008' => DB_ERROR_INVALID_DATE,
|
||||
'22012' => DB_ERROR_DIVZERO,
|
||||
'23000' => DB_ERROR_CONSTRAINT,
|
||||
'24000' => DB_ERROR_INVALID,
|
||||
'34000' => DB_ERROR_INVALID,
|
||||
'37000' => DB_ERROR_SYNTAX,
|
||||
'42000' => DB_ERROR_SYNTAX,
|
||||
'IM001' => DB_ERROR_UNSUPPORTED,
|
||||
'S0000' => DB_ERROR_NOSUCHTABLE,
|
||||
'S0001' => DB_ERROR_NOT_FOUND,
|
||||
'S0002' => DB_ERROR_NOT_FOUND,
|
||||
'S0011' => DB_ERROR_ALREADY_EXISTS,
|
||||
'S0012' => DB_ERROR_NOT_FOUND,
|
||||
'S0021' => DB_ERROR_ALREADY_EXISTS,
|
||||
'S0022' => DB_ERROR_NOT_FOUND,
|
||||
'S1009' => DB_ERROR_INVALID,
|
||||
'S1090' => DB_ERROR_INVALID,
|
||||
'S1C00' => DB_ERROR_NOT_CAPABLE
|
||||
);
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ connect()
|
||||
|
||||
/**
|
||||
* Connect to a database and log in as the specified user.
|
||||
*
|
||||
* @param $dsn the data source name (see DB::parseDSN for syntax)
|
||||
* @param $persistent (optional) whether the connection should
|
||||
* be persistent
|
||||
*
|
||||
* @return int DB_OK on success, a DB error code on failure
|
||||
*/
|
||||
function connect($dsninfo, $persistent = false)
|
||||
{
|
||||
if (!DB::assertExtension('odbc'))
|
||||
return $this->raiseError(DB_ERROR_EXTENSION_NOT_FOUND);
|
||||
|
||||
$this->dsn = $dsninfo;
|
||||
if (!empty($dsninfo['dbsyntax'])) {
|
||||
$this->dbsyntax = $dsninfo['dbsyntax'];
|
||||
}
|
||||
switch ($this->dbsyntax) {
|
||||
case 'solid':
|
||||
$this->features = array(
|
||||
'prepare' => true,
|
||||
'pconnect' => true,
|
||||
'transactions' => true
|
||||
);
|
||||
$default_dsn = 'localhost';
|
||||
break;
|
||||
case 'navision':
|
||||
// the Navision driver doesn't support fetch row by number
|
||||
$this->features['limit'] = false;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
$dbhost = $dsninfo['hostspec'] ? $dsninfo['hostspec'] : 'localhost';
|
||||
$user = $dsninfo['username'];
|
||||
$pw = $dsninfo['password'];
|
||||
if ($this->provides('pconnect')) {
|
||||
$connect_function = $persistent ? 'odbc_pconnect' : 'odbc_connect';
|
||||
} else {
|
||||
$connect_function = 'odbc_connect';
|
||||
}
|
||||
$conn = @$connect_function($dbhost, $user, $pw);
|
||||
if (!is_resource($conn)) {
|
||||
return $this->raiseError(DB_ERROR_CONNECT_FAILED, null, null,
|
||||
null, $this->errorNative());
|
||||
}
|
||||
$this->connection = $conn;
|
||||
return DB_OK;
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ disconnect()
|
||||
|
||||
function disconnect()
|
||||
{
|
||||
$err = @odbc_close($this->connection);
|
||||
$this->connection = null;
|
||||
return $err;
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ simpleQuery()
|
||||
|
||||
/**
|
||||
* Send a query to ODBC and return the results as a ODBC resource
|
||||
* identifier.
|
||||
*
|
||||
* @param $query the SQL query
|
||||
*
|
||||
* @return int returns a valid ODBC result for successful SELECT
|
||||
* queries, DB_OK for other successful queries. A DB error code
|
||||
* is returned 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->manip_result = $result; // For affectedRows()
|
||||
return DB_OK;
|
||||
}
|
||||
$this->row[$result] = 0;
|
||||
$this->manip_result = 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);
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ fetch_assoc()
|
||||
|
||||
function fetch_assoc($result, $fetchmode = DB_FETCHMODE_DEFAULT, $rownum=null)
|
||||
{
|
||||
if ($fetchmode == DB_FETCHMODE_DEFAULT) {
|
||||
$fetchmode = $this->fetchmode;
|
||||
}
|
||||
$res = $this->fetchInto ($result, $arr, $fetchmode, $rownum);
|
||||
if ($res !== DB_OK) {
|
||||
return $res;
|
||||
}
|
||||
return $arr;
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ fetchInto()
|
||||
|
||||
function fetchInto($result, &$row, $fetchmode, $rownum=null)
|
||||
{
|
||||
$row = array();
|
||||
if ($rownum !== null) {
|
||||
$rownum++; // ODBC first row is 1
|
||||
if (!function_exists('version_compare') || version_compare(phpversion(), "4.0.5", "lt")) {
|
||||
$cols = odbc_fetch_into($result, $rownum, &$row);
|
||||
} else {
|
||||
$cols = odbc_fetch_into($result, $rownum, $row);
|
||||
}
|
||||
} else {
|
||||
if (!function_exists('version_compare') || version_compare(phpversion(), "4.0.5", "lt")) {
|
||||
$cols = odbc_fetch_into($result, &$row);
|
||||
} else {
|
||||
$cols = odbc_fetch_into($result, $row);
|
||||
}
|
||||
}
|
||||
|
||||
if (!$cols) {
|
||||
/* XXX FIXME: doesn't work with unixODBC and easysoft
|
||||
(get corrupted $errno values)
|
||||
if ($errno = odbc_error($this->connection)) {
|
||||
return $this->RaiseError($errno);
|
||||
}*/
|
||||
return null;
|
||||
}
|
||||
if ($fetchmode !== DB_FETCHMODE_ORDERED) {
|
||||
for ($i = 0; $i < count($row); $i++) {
|
||||
$colName = odbc_field_name($result, $i+1);
|
||||
$a[$colName] = $row[$i];
|
||||
}
|
||||
$row = $a;
|
||||
}
|
||||
return DB_OK;
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ freeResult()
|
||||
|
||||
function freeResult($result)
|
||||
{
|
||||
if (is_resource($result)) {
|
||||
// Always return true
|
||||
return odbc_free_result($result);
|
||||
}
|
||||
if (!isset($this->prepare_tokens[(int)$result])) {
|
||||
return false;
|
||||
}
|
||||
unset($this->prepare_tokens[(int)$result]);
|
||||
unset($this->prepare_types[(int)$result]);
|
||||
return true;
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ numCols()
|
||||
|
||||
function numCols($result)
|
||||
{
|
||||
$cols = @odbc_num_fields($result);
|
||||
if (!$cols) {
|
||||
return $this->odbcRaiseError();
|
||||
}
|
||||
return $cols;
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ affectedRows()
|
||||
|
||||
/**
|
||||
* Returns the number of rows affected by a manipulative query
|
||||
* (INSERT, DELETE, UPDATE)
|
||||
* @return mixed int affected rows, 0 when non manip queries or
|
||||
* DB error on error
|
||||
*/
|
||||
function affectedRows()
|
||||
{
|
||||
if (empty($this->manip_result)) { // In case of SELECT stms
|
||||
return 0;
|
||||
}
|
||||
$nrows = odbc_num_rows($this->manip_result);
|
||||
if ($nrows == -1) {
|
||||
return $this->odbcRaiseError();
|
||||
}
|
||||
return $nrows;
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ numRows()
|
||||
|
||||
/**
|
||||
* ODBC may or may not support counting rows in the result set of
|
||||
* SELECTs.
|
||||
*
|
||||
* @param $result the odbc result resource
|
||||
* @return the number of rows, or 0
|
||||
*/
|
||||
function numRows($result)
|
||||
{
|
||||
$nrows = odbc_num_rows($result);
|
||||
if ($nrows == -1) {
|
||||
return $this->odbcRaiseError(DB_ERROR_UNSUPPORTED);
|
||||
}
|
||||
return $nrows;
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ errorNative()
|
||||
|
||||
/**
|
||||
* Get the native error code of the last error (if any) that
|
||||
* occured on the current connection.
|
||||
*
|
||||
* @access public
|
||||
*
|
||||
* @return int ODBC error code
|
||||
*/
|
||||
|
||||
function errorNative()
|
||||
{
|
||||
if (!isset($this->connection) || !is_resource($this->connection)) {
|
||||
return odbc_error() . ' ' . odbc_errormsg();
|
||||
}
|
||||
return odbc_error($this->connection) . ' ' . odbc_errormsg($this->connection);
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ nextId()
|
||||
|
||||
/**
|
||||
* Get the next value in a sequence. We emulate sequences
|
||||
* for odbc. Will create the sequence if it does not exist.
|
||||
*
|
||||
* @access public
|
||||
*
|
||||
* @param $seq_name the name of the sequence
|
||||
*
|
||||
* @param $ondemand whether to create the sequence table on demand
|
||||
* (default is true)
|
||||
*
|
||||
* @return a sequence integer, or a DB error
|
||||
*/
|
||||
function nextId($seq_name, $ondemand = true)
|
||||
{
|
||||
$seqname = $this->getSequenceName($seq_name);
|
||||
$repeat = 0;
|
||||
do {
|
||||
$result = $this->query("update ${seqname} set id = id + 1");
|
||||
if ($ondemand && DB::isError($result) &&
|
||||
$result->getCode() == DB_ERROR_NOT_FOUND) {
|
||||
$repeat = 1;
|
||||
$result = $this->createSequence($seq_name);
|
||||
if (DB::isError($result)) {
|
||||
return $result;
|
||||
}
|
||||
$result = $this->query("insert into ${seqname} (id) values(0)");
|
||||
} else {
|
||||
$repeat = 0;
|
||||
}
|
||||
} while ($repeat);
|
||||
|
||||
if (DB::isError($result)) {
|
||||
return $result;
|
||||
}
|
||||
|
||||
$result = $this->query("select id from ${seqname}");
|
||||
if (DB::isError($result)) {
|
||||
return $result;
|
||||
}
|
||||
|
||||
$row = $result->fetch_assoc(DB_FETCHMODE_ASSOC);
|
||||
if (DB::isError($row || !$row)) {
|
||||
return $row;
|
||||
}
|
||||
|
||||
return $row['id'];
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ createSequence()
|
||||
|
||||
function createSequence($seq_name)
|
||||
{
|
||||
$seqname = $this->getSequenceName($seq_name);
|
||||
return $this->query("CREATE TABLE ${seqname} ".
|
||||
'(id bigint NOT NULL,'.
|
||||
' PRIMARY KEY(id))');
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ dropSequence()
|
||||
|
||||
function dropSequence($seq_name)
|
||||
{
|
||||
$seqname = $this->getSequenceName($seq_name);
|
||||
return $this->query("DROP TABLE ${seqname}");
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ autoCommit()
|
||||
|
||||
function autoCommit($onoff = false)
|
||||
{
|
||||
if (!@odbc_autocommit($this->connection, $onoff)) {
|
||||
return $this->odbcRaiseError();
|
||||
}
|
||||
return DB_OK;
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ commit()
|
||||
|
||||
function commit()
|
||||
{
|
||||
if (!@odbc_commit($this->connection)) {
|
||||
return $this->odbcRaiseError();
|
||||
}
|
||||
return DB_OK;
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ rollback()
|
||||
|
||||
function rollback()
|
||||
{
|
||||
if (!@odbc_rollback($this->connection)) {
|
||||
return $this->odbcRaiseError();
|
||||
}
|
||||
return DB_OK;
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ odbcRaiseError()
|
||||
|
||||
function odbcRaiseError($errno = null)
|
||||
{
|
||||
if ($errno === null) {
|
||||
$errno = $this->errorCode(odbc_error($this->connection));
|
||||
}
|
||||
return $this->raiseError($errno, null, null, null,
|
||||
$this->errorNative());
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ getSpecialQuery()
|
||||
|
||||
/**
|
||||
* Returns the query needed to get some backend info
|
||||
* @param string $type What kind of info you want to retrieve
|
||||
* @return string The SQL query string
|
||||
*/
|
||||
function getSpecialQuery($type)
|
||||
{
|
||||
switch ($type) {
|
||||
case 'tables':
|
||||
default:
|
||||
return null;
|
||||
}
|
||||
return $sql;
|
||||
}
|
||||
|
||||
// }}}
|
||||
|
||||
}
|
||||
|
||||
// Local variables:
|
||||
// tab-width: 4
|
||||
// c-basic-offset: 4
|
||||
// End:
|
||||
?>
|
||||
810
html/illt/DB/pgsql.php
Normal file
810
html/illt/DB/pgsql.php
Normal file
@@ -0,0 +1,810 @@
|
||||
<?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: Rui Hirokawa <rui_hirokawa@ybb.ne.jp> |
|
||||
// | Stig Bakken <ssb@fast.no> |
|
||||
// +----------------------------------------------------------------------+
|
||||
//
|
||||
// $Id: pgsql.php,v 1.65.2.3 2002/04/10 08:38:42 edink Exp $
|
||||
//
|
||||
// Database independent query interface definition for PHP's PostgreSQL
|
||||
// extension.
|
||||
//
|
||||
|
||||
//
|
||||
// XXX legend:
|
||||
//
|
||||
// XXX ERRORMSG: The error message from the pgsql function should
|
||||
// be registered here.
|
||||
//
|
||||
|
||||
require_once 'DB/common.php';
|
||||
|
||||
class DB_pgsql extends DB_common
|
||||
{
|
||||
// {{{ properties
|
||||
|
||||
var $connection;
|
||||
var $phptype, $dbsyntax;
|
||||
var $prepare_tokens = array();
|
||||
var $prepare_types = array();
|
||||
var $transaction_opcount = 0;
|
||||
var $dsn = array();
|
||||
var $row = array();
|
||||
var $num_rows = array();
|
||||
var $affected = 0;
|
||||
var $autocommit = true;
|
||||
var $fetchmode = DB_FETCHMODE_ORDERED;
|
||||
|
||||
// }}}
|
||||
// {{{ constructor
|
||||
|
||||
function DB_pgsql()
|
||||
{
|
||||
$this->DB_common();
|
||||
$this->phptype = 'pgsql';
|
||||
$this->dbsyntax = 'pgsql';
|
||||
$this->features = array(
|
||||
'prepare' => false,
|
||||
'pconnect' => true,
|
||||
'transactions' => true,
|
||||
'limit' => 'alter'
|
||||
);
|
||||
$this->errorcode_map = array(
|
||||
);
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ connect()
|
||||
|
||||
/**
|
||||
* Connect to a database and log in as the specified user.
|
||||
*
|
||||
* @param $dsn the data source name (see DB::parseDSN for syntax)
|
||||
* @param $persistent (optional) whether the connection should
|
||||
* be persistent
|
||||
*
|
||||
* @return int DB_OK on success, a DB error code on failure
|
||||
*/
|
||||
function connect($dsninfo, $persistent = false)
|
||||
{
|
||||
if (!DB::assertExtension('pgsql'))
|
||||
return $this->raiseError(DB_ERROR_EXTENSION_NOT_FOUND);
|
||||
|
||||
$this->dsn = $dsninfo;
|
||||
$protocol = (isset($dsninfo['protocol'])) ? $dsninfo['protocol'] : 'tcp';
|
||||
$connstr = '';
|
||||
|
||||
if ($protocol == 'tcp') {
|
||||
if ($dsninfo['hostspec']) {
|
||||
$connstr = 'host=' . $dsninfo['hostspec'];
|
||||
}
|
||||
if ($dsninfo['port']) {
|
||||
$connstr .= ' port=' . $dsninfo['port'];
|
||||
}
|
||||
}
|
||||
|
||||
if (isset($dsninfo['database'])) {
|
||||
$connstr .= ' dbname=' . $dsninfo['database'];
|
||||
}
|
||||
if (!empty($dsninfo['username'])) {
|
||||
$connstr .= ' user=' . $dsninfo['username'];
|
||||
}
|
||||
if (!empty($dsninfo['password'])) {
|
||||
$connstr .= ' password=' . $dsninfo['password'];
|
||||
}
|
||||
if (!empty($dsninfo['options'])) {
|
||||
$connstr .= ' options=' . $dsninfo['options'];
|
||||
}
|
||||
if (!empty($dsninfo['tty'])) {
|
||||
$connstr .= ' tty=' . $dsninfo['tty'];
|
||||
}
|
||||
|
||||
$connect_function = $persistent ? 'pg_pconnect' : 'pg_connect';
|
||||
// catch error
|
||||
ob_start();
|
||||
$conn = $connect_function($connstr);
|
||||
$error = ob_get_contents();
|
||||
ob_end_clean();
|
||||
if ($conn == false) {
|
||||
return $this->raiseError(DB_ERROR_CONNECT_FAILED, null,
|
||||
null, null, strip_tags($error));
|
||||
}
|
||||
$this->connection = $conn;
|
||||
return DB_OK;
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ disconnect()
|
||||
|
||||
/**
|
||||
* Log out and disconnect from the database.
|
||||
*
|
||||
* @return bool TRUE on success, FALSE if not connected.
|
||||
*/
|
||||
function disconnect()
|
||||
{
|
||||
$ret = @pg_close($this->connection); // XXX ERRORMSG
|
||||
$this->connection = null;
|
||||
return $ret;
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ simpleQuery()
|
||||
|
||||
/**
|
||||
* Send a query to PostgreSQL and return the results as a
|
||||
* PostgreSQL resource identifier.
|
||||
*
|
||||
* @param $query the SQL query
|
||||
*
|
||||
* @return int returns a valid PostgreSQL result for successful SELECT
|
||||
* queries, DB_OK for other successful queries. A DB error code
|
||||
* is returned 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_cmdtuples($result);
|
||||
return DB_OK;
|
||||
} elseif (preg_match('/^\s*\(?\s*SELECT\s+/si', $query) &&
|
||||
!preg_match('/^\s*\(?\s*SELECT\s+INTO\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[$result] = 0; // reset the row counter.
|
||||
$numrows = $this->numrows($result);
|
||||
if (is_object($numrows)) {
|
||||
return $numrows;
|
||||
}
|
||||
$this->num_rows[$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;
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ errorCode()
|
||||
|
||||
/**
|
||||
* Map native error codes to DB's portable ones. Requires that
|
||||
* the DB implementation's constructor fills in the $errorcode_map
|
||||
* property.
|
||||
*
|
||||
* @param $nativecode the native error code, as returned by the backend
|
||||
* database extension (string or integer)
|
||||
*
|
||||
* @return int a portable DB error code, or FALSE if this DB
|
||||
* implementation has no mapping for the given error code.
|
||||
*/
|
||||
|
||||
function errorCode($errormsg)
|
||||
{
|
||||
static $error_regexps;
|
||||
if (empty($error_regexps)) {
|
||||
$error_regexps = array(
|
||||
'/(Table does not exist\.|Relation [\"\'].*[\"\'] does not exist|sequence does not exist|class ".+" not found)$/' => DB_ERROR_NOSUCHTABLE,
|
||||
'/Relation [\"\'].*[\"\'] already exists|Cannot insert a duplicate key into (a )?unique index.*/' => DB_ERROR_ALREADY_EXISTS,
|
||||
'/divide by zero$/' => DB_ERROR_DIVZERO,
|
||||
'/pg_atoi: error in .*: can\'t parse /' => DB_ERROR_INVALID_NUMBER,
|
||||
'/ttribute [\"\'].*[\"\'] not found$|Relation [\"\'].*[\"\'] does not have attribute [\"\'].*[\"\']/' => DB_ERROR_NOSUCHFIELD,
|
||||
'/parser: parse error at or near \"/' => DB_ERROR_SYNTAX,
|
||||
'/referential integrity violation/' => DB_ERROR_CONSTRAINT
|
||||
);
|
||||
}
|
||||
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;
|
||||
}
|
||||
|
||||
// }}}
|
||||
/**
|
||||
* Fetch and return a row of data (it uses fetchInto for that)
|
||||
* @param $result PostgreSQL result identifier
|
||||
* @param $fetchmode format of fetched row array
|
||||
* @param $rownum the absolute row number to fetch
|
||||
*
|
||||
* @return array a row of data, or false on error
|
||||
*/
|
||||
function fetch_assoc($result, $fetchmode = DB_FETCHMODE_DEFAULT, $rownum=null)
|
||||
{
|
||||
if ($fetchmode == DB_FETCHMODE_DEFAULT) {
|
||||
$fetchmode = $this->fetchmode;
|
||||
}
|
||||
$res = $this->fetchInto ($result, $arr, $fetchmode, $rownum);
|
||||
if ($res !== DB_OK) {
|
||||
return $res;
|
||||
}
|
||||
return $arr;
|
||||
}
|
||||
|
||||
// {{{ fetchInto()
|
||||
|
||||
/**
|
||||
* Fetch a row and insert the data into an existing array.
|
||||
*
|
||||
* @param $result PostgreSQL result identifier
|
||||
* @param $row (reference) array where data from the row is stored
|
||||
* @param $fetchmode how the array data should be indexed
|
||||
* @param $rownum the row number to fetch
|
||||
*
|
||||
* @return int DB_OK on success, a DB error code on failure
|
||||
*/
|
||||
function fetchInto($result, &$row, $fetchmode, $rownum=null)
|
||||
{
|
||||
$rownum = ($rownum !== null) ? $rownum : $this->row[$result];
|
||||
if ($rownum >= $this->num_rows[$result]) {
|
||||
return null;
|
||||
}
|
||||
if ($fetchmode & DB_FETCHMODE_ASSOC) {
|
||||
$row = @pg_fetch_array($result, $rownum, PGSQL_ASSOC);
|
||||
} else {
|
||||
$row = @pg_fetch_row($result, $rownum);
|
||||
}
|
||||
if (!$row) {
|
||||
$err = pg_errormessage($this->connection);
|
||||
if (!$err) {
|
||||
return null;
|
||||
}
|
||||
return $this->pgsqlRaiseError();
|
||||
}
|
||||
$this->row[$result] = ++$rownum;
|
||||
return DB_OK;
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ freeResult()
|
||||
|
||||
/**
|
||||
* Free the internal resources associated with $result.
|
||||
*
|
||||
* @param $result int PostgreSQL result identifier or DB statement identifier
|
||||
*
|
||||
* @return bool TRUE on success, FALSE if $result is invalid
|
||||
*/
|
||||
function freeResult($result)
|
||||
{
|
||||
if (is_resource($result)) {
|
||||
return @pg_freeresult($result);
|
||||
}
|
||||
if (!isset($this->prepare_tokens[(int)$result])) {
|
||||
return false;
|
||||
}
|
||||
unset($this->prepare_tokens[(int)$result]);
|
||||
unset($this->prepare_types[(int)$result]);
|
||||
unset($this->row[(int)$result]);
|
||||
unset($this->num_rows[(int)$result]);
|
||||
$this->affected = 0;
|
||||
return true;
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ quote()
|
||||
/**
|
||||
* Quote the given string so it can be safely used within string delimiters
|
||||
* in a query.
|
||||
* @param $string mixed Data to be quoted
|
||||
* @return mixed "NULL" string, quoted string or original data
|
||||
*/
|
||||
function quote($str = null)
|
||||
{
|
||||
switch (strtolower(gettype($str))) {
|
||||
case 'null':
|
||||
return 'NULL';
|
||||
case 'integer':
|
||||
case 'double' :
|
||||
return $str;
|
||||
case 'string':
|
||||
default:
|
||||
$str = str_replace("'", "''", $str);
|
||||
//PostgreSQL treats a backslash as an escape character.
|
||||
$str = str_replace('\\', '\\\\', $str);
|
||||
return "'$str'";
|
||||
}
|
||||
}
|
||||
// }}}
|
||||
// {{{ numCols()
|
||||
|
||||
/**
|
||||
* Get the number of columns in a result set.
|
||||
*
|
||||
* @param $result resource PostgreSQL result identifier
|
||||
*
|
||||
* @return int the number of columns per row in $result
|
||||
*/
|
||||
function numCols($result)
|
||||
{
|
||||
$cols = @pg_numfields($result);
|
||||
if (!$cols) {
|
||||
return $this->pgsqlRaiseError();
|
||||
}
|
||||
return $cols;
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ numRows()
|
||||
|
||||
/**
|
||||
* Get the number of rows in a result set.
|
||||
*
|
||||
* @param $result resource PostgreSQL result identifier
|
||||
*
|
||||
* @return int the number of rows in $result
|
||||
*/
|
||||
function numRows($result)
|
||||
{
|
||||
$rows = @pg_numrows($result);
|
||||
if ($rows === null) {
|
||||
return $this->pgsqlRaiseError();
|
||||
}
|
||||
return $rows;
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ errorNative()
|
||||
|
||||
/**
|
||||
* Get the native error code of the last error (if any) that
|
||||
* occured on the current connection.
|
||||
*
|
||||
* @return int native PostgreSQL error code
|
||||
*/
|
||||
function errorNative()
|
||||
{
|
||||
return pg_errormessage($this->connection);
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ autoCommit()
|
||||
|
||||
/**
|
||||
* Enable/disable automatic commits
|
||||
*/
|
||||
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()
|
||||
|
||||
/**
|
||||
* Commit the current transaction.
|
||||
*/
|
||||
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()
|
||||
|
||||
/**
|
||||
* Roll back (undo) the current transaction.
|
||||
*/
|
||||
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()
|
||||
|
||||
/**
|
||||
* Gets the number of rows affected by the last query.
|
||||
* if the last query was a select, returns 0.
|
||||
*
|
||||
* @return int number of rows affected by the last query or DB_ERROR
|
||||
*/
|
||||
function affectedRows()
|
||||
{
|
||||
return $this->affected;
|
||||
}
|
||||
// }}}
|
||||
// {{{ nextId()
|
||||
|
||||
/**
|
||||
* Get the next value in a sequence.
|
||||
*
|
||||
* We are using native PostgreSQL sequences. If a sequence does
|
||||
* not exist, it will be created, unless $ondemand is false.
|
||||
*
|
||||
* @access public
|
||||
* @param string $seq_name the name of the sequence
|
||||
* @param bool $ondemand whether to create the sequence on demand
|
||||
* @return a sequence integer, or a DB error
|
||||
*/
|
||||
function nextId($seq_name, $ondemand = true)
|
||||
{
|
||||
$seqname = $this->getSequenceName($seq_name);
|
||||
$repeat = 0;
|
||||
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 = 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->fetch_assoc(DB_FETCHMODE_ORDERED);
|
||||
$result->free();
|
||||
return $arr[0];
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ createSequence()
|
||||
|
||||
/**
|
||||
* Create the sequence
|
||||
*
|
||||
* @param string $seq_name the name of the sequence
|
||||
* @return mixed DB_OK on success or DB error on error
|
||||
* @access public
|
||||
*/
|
||||
function createSequence($seq_name)
|
||||
{
|
||||
$seqname = $this->getSequenceName($seq_name);
|
||||
$this->pushErrorHandling(PEAR_ERROR_RETURN);
|
||||
$result = $this->query("CREATE SEQUENCE ${seqname}");
|
||||
$this->popErrorHandling();
|
||||
return $result;
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ dropSequence()
|
||||
|
||||
/**
|
||||
* Drop a sequence
|
||||
*
|
||||
* @param string $seq_name the name of the sequence
|
||||
* @return mixed DB_OK on success or DB error on error
|
||||
* @access public
|
||||
*/
|
||||
function dropSequence($seq_name)
|
||||
{
|
||||
$seqname = $this->getSequenceName($seq_name);
|
||||
return $this->query("DROP SEQUENCE ${seqname}");
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ modifyLimitQuery()
|
||||
|
||||
function modifyLimitQuery($query, $from, $count)
|
||||
{
|
||||
$query = $query . " LIMIT $count, $from";
|
||||
return $query;
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ pgsqlRaiseError()
|
||||
|
||||
function pgsqlRaiseError($errno = null)
|
||||
{
|
||||
$native = $this->errorNative();
|
||||
if ($errno === null) {
|
||||
$err = $this->errorCode($native);
|
||||
} else {
|
||||
$err = $errno;
|
||||
}
|
||||
return $this->raiseError($err, null, null, null, $native);
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ _pgFieldFlags()
|
||||
|
||||
/**
|
||||
* Flags of a Field
|
||||
*
|
||||
* @param int $resource PostgreSQL result identifier
|
||||
* @param int $num_field the field number
|
||||
*
|
||||
* @return string The flags of the field ("not_null", "default_xx", "primary_key",
|
||||
* "unique" and "multiple_key" are supported)
|
||||
* @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'");
|
||||
$row = pg_fetch_row($result, 0);
|
||||
$num = str_replace('\'', '', $row[0]);
|
||||
|
||||
$flags .= "default_$num ";
|
||||
}
|
||||
}
|
||||
$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') ? 'unique ' : '';
|
||||
$flags .= ($row[1] == 't') ? 'primary ' : '';
|
||||
if (count($keys) > 1)
|
||||
$flags .= 'multiple_key ';
|
||||
}
|
||||
}
|
||||
|
||||
return trim($flags);
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ tableInfo()
|
||||
|
||||
/**
|
||||
* Returns information about a table or a result set
|
||||
*
|
||||
* NOTE: doesn't support table name and flags if called from a db_result
|
||||
*
|
||||
* @param mixed $resource PostgreSQL result identifier or table name
|
||||
* @param int $mode A valid tableInfo mode (DB_TABLEINFO_ORDERTABLE or
|
||||
* DB_TABLEINFO_ORDER)
|
||||
*
|
||||
* @return array An array with all the information
|
||||
*/
|
||||
function tableInfo($result, $mode = null)
|
||||
{
|
||||
$count = 0;
|
||||
$id = 0;
|
||||
$res = array();
|
||||
|
||||
/*
|
||||
* depending on $mode, metadata returns the following values:
|
||||
*
|
||||
* - mode is false (default):
|
||||
* $result[]:
|
||||
* [0]["table"] table name
|
||||
* [0]["name"] field name
|
||||
* [0]["type"] field type
|
||||
* [0]["len"] field length
|
||||
* [0]["flags"] field flags
|
||||
*
|
||||
* - mode is DB_TABLEINFO_ORDER
|
||||
* $result[]:
|
||||
* ["num_fields"] number of metadata records
|
||||
* [0]["table"] table name
|
||||
* [0]["name"] field name
|
||||
* [0]["type"] field type
|
||||
* [0]["len"] field length
|
||||
* [0]["flags"] field flags
|
||||
* ["order"][field name] index of field named "field name"
|
||||
* The last one is used, if you have a field name, but no index.
|
||||
* Test: if (isset($result['meta']['myfield'])) { ...
|
||||
*
|
||||
* - mode is DB_TABLEINFO_ORDERTABLE
|
||||
* the same as above. but additionally
|
||||
* ["ordertable"][table name][field name] index of field
|
||||
* named "field name"
|
||||
*
|
||||
* this is, because if you have fields from different
|
||||
* tables with the same field name * they override each
|
||||
* other with DB_TABLEINFO_ORDER
|
||||
*
|
||||
* you can combine DB_TABLEINFO_ORDER and
|
||||
* DB_TABLEINFO_ORDERTABLE with DB_TABLEINFO_ORDER |
|
||||
* DB_TABLEINFO_ORDERTABLE * or with DB_TABLEINFO_FULL
|
||||
*/
|
||||
|
||||
// if $result is a string, then we want information about a
|
||||
// table without a resultset
|
||||
|
||||
if (is_string($result)) {
|
||||
$id = pg_exec($this->connection,"SELECT * FROM $result");
|
||||
if (empty($id)) {
|
||||
return $this->pgsqlRaiseError();
|
||||
}
|
||||
} else { // else we want information about a resultset
|
||||
$id = $result;
|
||||
if (empty($id)) {
|
||||
return $this->pgsqlRaiseError();
|
||||
}
|
||||
}
|
||||
|
||||
$count = @pg_numfields($id);
|
||||
|
||||
// made this IF due to performance (one if is faster than $count if's)
|
||||
if (empty($mode)) {
|
||||
|
||||
for ($i=0; $i<$count; $i++) {
|
||||
$res[$i]['table'] = (is_string($result)) ? $result : '';
|
||||
$res[$i]['name'] = @pg_fieldname ($id, $i);
|
||||
$res[$i]['type'] = @pg_fieldtype ($id, $i);
|
||||
$res[$i]['len'] = @pg_fieldsize ($id, $i);
|
||||
$res[$i]['flags'] = (is_string($result)) ? $this->_pgFieldflags($id, $i, $result) : '';
|
||||
}
|
||||
|
||||
} else { // full
|
||||
$res["num_fields"]= $count;
|
||||
|
||||
for ($i=0; $i<$count; $i++) {
|
||||
$res[$i]['table'] = (is_string($result)) ? $result : '';
|
||||
$res[$i]['name'] = @pg_fieldname ($id, $i);
|
||||
$res[$i]['type'] = @pg_fieldtype ($id, $i);
|
||||
$res[$i]['len'] = @pg_fieldsize ($id, $i);
|
||||
$res[$i]['flags'] = (is_string($result)) ? $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 (is_resource($id)) {
|
||||
@pg_freeresult($id);
|
||||
}
|
||||
return $res;
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ getTablesQuery()
|
||||
|
||||
/**
|
||||
* Returns the query needed to get some backend info
|
||||
* @param string $type What kind of info you want to retrieve
|
||||
* @return string The SQL query string
|
||||
*/
|
||||
function getSpecialQuery($type)
|
||||
{
|
||||
switch ($type) {
|
||||
case 'tables': {
|
||||
$sql = "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_'
|
||||
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_'";
|
||||
break;
|
||||
}
|
||||
case 'views': {
|
||||
// Table cols: viewname | viewowner | definition
|
||||
$sql = "SELECT viewname FROM pg_views";
|
||||
break;
|
||||
}
|
||||
case 'users': {
|
||||
// cols: usename |usesysid|usecreatedb|usetrace|usesuper|usecatupd|passwd |valuntil
|
||||
$sql = 'SELECT usename FROM pg_user';
|
||||
break;
|
||||
}
|
||||
case 'databases': {
|
||||
$sql = 'SELECT datname FROM pg_database';
|
||||
break;
|
||||
}
|
||||
case 'functions': {
|
||||
$sql = 'SELECT proname FROM pg_proc';
|
||||
break;
|
||||
}
|
||||
default:
|
||||
return null;
|
||||
}
|
||||
return $sql;
|
||||
}
|
||||
|
||||
// }}}
|
||||
|
||||
}
|
||||
|
||||
// Local variables:
|
||||
// tab-width: 4
|
||||
// c-basic-offset: 4
|
||||
// End:
|
||||
?>
|
||||
444
html/illt/DB/storage.php
Normal file
444
html/illt/DB/storage.php
Normal file
@@ -0,0 +1,444 @@
|
||||
<?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. |
|
||||
// +----------------------------------------------------------------------+
|
||||
// | Author: Stig Bakken <stig@php.net> |
|
||||
// +----------------------------------------------------------------------+
|
||||
//
|
||||
// $Id: storage.php,v 1.28 2002/02/28 08:27:11 sebastian Exp $
|
||||
//
|
||||
// DB_storage: a class that lets you return SQL data as objects that
|
||||
// can be manipulated and that updates the database accordingly.
|
||||
//
|
||||
|
||||
require_once "PEAR.php";
|
||||
require_once "DB.php";
|
||||
|
||||
/**
|
||||
* DB_storage provides an object interface to a table row. It lets
|
||||
* you add, delete and change rows without using SQL.
|
||||
*
|
||||
* @author Stig Bakken <stig@php.net>
|
||||
*
|
||||
* @package DB
|
||||
*/
|
||||
class DB_storage extends PEAR
|
||||
{
|
||||
/** 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
|
||||
*
|
||||
* @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;
|
||||
}
|
||||
|
||||
/**
|
||||
* 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;
|
||||
}
|
||||
|
||||
/**
|
||||
* 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)
|
||||
{
|
||||
$qval = $this->_dbh->quote($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->fetch_assoc(DB_FETCHMODE_ASSOC);
|
||||
if (DB::isError($row)) {
|
||||
return $row;
|
||||
}
|
||||
if (empty($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;
|
||||
}
|
||||
|
||||
/**
|
||||
* 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);
|
||||
}
|
||||
|
||||
/**
|
||||
* Output a simple description of this DB_storage object.
|
||||
* @return string object description
|
||||
*/
|
||||
function toString()
|
||||
{
|
||||
$info = 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 the contents of this object to "standard output".
|
||||
*/
|
||||
function dump()
|
||||
{
|
||||
reset($this->_properties);
|
||||
while (list($prop, $foo) = each($this->_properties)) {
|
||||
print "$prop = ";
|
||||
print htmlentities($this->$prop);
|
||||
print "<BR>\n";
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 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 = get_class($this);
|
||||
$obj = new $classname($table);
|
||||
reset($data);
|
||||
while (list($name, $value) = each($data)) {
|
||||
$obj->_properties[$name] = true;
|
||||
$obj->$name = &$value;
|
||||
}
|
||||
return $obj;
|
||||
}
|
||||
|
||||
/**
|
||||
* 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;
|
||||
}
|
||||
*/
|
||||
|
||||
/**
|
||||
* 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;
|
||||
@$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);
|
||||
}
|
||||
|
||||
/**
|
||||
* 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;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Destructor, calls DB_storage::store() if there are changes
|
||||
* that are to be kept.
|
||||
*/
|
||||
function _DB_storage()
|
||||
{
|
||||
if (empty($this->_discard) && sizeof($this->_changes)) {
|
||||
$this->store();
|
||||
}
|
||||
$this->_properties = array();
|
||||
$this->_changes = array();
|
||||
$this->_table = null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Stores changes to this object in the database.
|
||||
*
|
||||
* @return DB_OK or a DB error
|
||||
*/
|
||||
function store()
|
||||
{
|
||||
while (list($name, $changed) = each($this->_changes)) {
|
||||
$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 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;
|
||||
}
|
||||
}
|
||||
|
||||
?>
|
||||
251
html/illt/DB/sybase.php
Normal file
251
html/illt/DB/sybase.php
Normal file
@@ -0,0 +1,251 @@
|
||||
<?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. |
|
||||
// +----------------------------------------------------------------------+
|
||||
// | Author: Sterling Hughes <sterling@php.net> |
|
||||
// +----------------------------------------------------------------------+
|
||||
//
|
||||
// $Id: sybase.php,v 1.30 2002/02/28 08:27:11 sebastian Exp $
|
||||
//
|
||||
// Database independent query interface definition for PHP's Sybase
|
||||
// extension.
|
||||
//
|
||||
|
||||
require_once 'DB/common.php';
|
||||
|
||||
class DB_sybase extends DB_common
|
||||
{
|
||||
// {{{ properties
|
||||
|
||||
var $connection;
|
||||
var $phptype, $dbsyntax;
|
||||
var $prepare_tokens = array();
|
||||
var $prepare_types = array();
|
||||
|
||||
// }}}
|
||||
// {{{ constructor
|
||||
|
||||
function DB_sybase()
|
||||
{
|
||||
$this->DB_common();
|
||||
$this->phptype = 'sybase';
|
||||
$this->dbsyntax = 'sybase';
|
||||
$this->features = array(
|
||||
'prepare' => false,
|
||||
'pconnect' => true,
|
||||
'transactions' => false,
|
||||
'limit' => 'emulate'
|
||||
);
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ connect()
|
||||
|
||||
function connect($dsninfo, $persistent = false)
|
||||
{
|
||||
if (!DB::assertExtension('sybase') && !DB::assertExtension('sybase_ct'))
|
||||
return $this->raiseError(DB_ERROR_EXTENSION_NOT_FOUND);
|
||||
|
||||
$this->dsn = $dsninfo;
|
||||
$user = $dsninfo['username'];
|
||||
$pw = $dsninfo['password'];
|
||||
|
||||
$dbhost = $dsninfo['hostspec'] ? $dsninfo['hostspec'] : 'localhost';
|
||||
$connect_function = $persistent ? 'sybase_pconnect' : 'sybase_connect';
|
||||
|
||||
if ($dbhost && $user && $pw) {
|
||||
$conn = $connect_function($dbhost, $user, $pw);
|
||||
} elseif ($dbhost && $user) {
|
||||
$conn = $connect_function($dbhost, $user);
|
||||
} elseif ($dbhost) {
|
||||
$conn = $connect_function($dbhost);
|
||||
} else {
|
||||
$conn = $connect_function();
|
||||
}
|
||||
|
||||
if (!$conn) {
|
||||
return $this->raiseError(DB_ERROR_CONNECT_FAILED);
|
||||
}
|
||||
|
||||
if ($dsninfo['database']) {
|
||||
if (!@sybase_select_db($dsninfo['database'], $conn)) {
|
||||
return $this->raiseError(DB_ERROR_NODBSELECTED);
|
||||
}
|
||||
}
|
||||
$this->connection = $conn;
|
||||
return DB_OK;
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ disconnect()
|
||||
|
||||
function disconnect()
|
||||
{
|
||||
$ret = @sybase_close($this->connection);
|
||||
$this->connection = null;
|
||||
return $ret;
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ simpleQuery()
|
||||
|
||||
function simpleQuery($query)
|
||||
{
|
||||
$this->last_query = $query;
|
||||
$query = $this->modifyQuery($query);
|
||||
$result = @sybase_query($query, $this->connection);
|
||||
if (!$result) {
|
||||
return $this->raiseError();
|
||||
}
|
||||
// Determine which queries that should return data, and which
|
||||
// should return an error code only.
|
||||
return DB::isManip($query) ? DB_OK : $result;
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ nextResult()
|
||||
|
||||
/**
|
||||
* Move the internal sybase 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;
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ fetch_assoc()
|
||||
function &fetch_assoc($result, $fetchmode = DB_FETCHMODE_DEFAULT, $rownum=null)
|
||||
{
|
||||
if ($fetchmode == DB_FETCHMODE_DEFAULT) {
|
||||
$fetchmode = $this->fetchmode;
|
||||
}
|
||||
$res = $this->fetchInto ($result, $arr, $fetchmode, $rownum);
|
||||
if ($res !== DB_OK) {
|
||||
return $res;
|
||||
}
|
||||
return $arr;
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ fetchInto()
|
||||
|
||||
function fetchInto($result, &$ar, $fetchmode, $rownum=null)
|
||||
{
|
||||
if ($rownum !== null) {
|
||||
if (!sybase_data_seek($result, $rownum)) {
|
||||
return $this->raiseError();
|
||||
}
|
||||
}
|
||||
$ar = ($fetchmode & DB_FETCHMODE_ASSOC) ? @sybase_fetch_array($result) : @sybase_fetch_row($result);
|
||||
if (!$ar) {
|
||||
// reported not work as seems that sybase_get_last_message()
|
||||
// always return a message here
|
||||
//if ($errmsg = sybase_get_last_message()) {
|
||||
// return $this->raiseError($errmsg);
|
||||
//} else {
|
||||
return null;
|
||||
//}
|
||||
}
|
||||
return DB_OK;
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ freeResult()
|
||||
|
||||
function freeResult($result)
|
||||
{
|
||||
if (is_resource($result)) {
|
||||
return @sybase_free_result($result);
|
||||
}
|
||||
if (!isset($this->prepare_tokens[(int)$result])) {
|
||||
return false;
|
||||
}
|
||||
unset($this->prepare_tokens[(int)$result]);
|
||||
unset($this->prepare_types[(int)$result]);
|
||||
return true;
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ numCols()
|
||||
|
||||
function numCols($result)
|
||||
{
|
||||
$cols = @sybase_num_fields($result);
|
||||
if (!$cols) {
|
||||
return $this->raiseError();
|
||||
}
|
||||
return $cols;
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ affectedRows()
|
||||
|
||||
/**
|
||||
* Gets the number of rows affected by the data manipulation
|
||||
* query. For other queries, this function returns 0.
|
||||
*
|
||||
* @return number of rows affected by the last query
|
||||
*/
|
||||
|
||||
function affectedRows()
|
||||
{
|
||||
if (DB::isManip($this->last_query)) {
|
||||
$result = @sybase_affected_rows($this->connection);
|
||||
} else {
|
||||
$result = 0;
|
||||
}
|
||||
return $result;
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ getSpecialQuery()
|
||||
|
||||
/**
|
||||
* Returns the query needed to get some backend info
|
||||
* @param string $type What kind of info you want to retrieve
|
||||
* @return string The SQL query string
|
||||
*/
|
||||
function getSpecialQuery($type)
|
||||
{
|
||||
switch ($type) {
|
||||
case 'tables':
|
||||
$sql = "select name from sysobjects where type = 'U' order by name";
|
||||
break;
|
||||
case 'views':
|
||||
$sql = "select name from sysobjects where type = 'V'";
|
||||
break;
|
||||
default:
|
||||
return null;
|
||||
}
|
||||
return $sql;
|
||||
}
|
||||
|
||||
// }}}
|
||||
|
||||
}
|
||||
|
||||
/*
|
||||
* Local variables:
|
||||
* tab-width: 4
|
||||
* c-basic-offset: 4
|
||||
* End:
|
||||
*/
|
||||
?>
|
||||
351
html/illt/HTML/Common.php
Normal file
351
html/illt/HTML/Common.php
Normal file
@@ -0,0 +1,351 @@
|
||||
<?php
|
||||
/* vim: set expandtab tabstop=4 shiftwidth=4: */
|
||||
// +----------------------------------------------------------------------+
|
||||
// | PHP Version 4 |
|
||||
// +----------------------------------------------------------------------+
|
||||
// | 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. |
|
||||
// +----------------------------------------------------------------------+
|
||||
// | Author: Adam Daniel <adaniel1@eesus.jnj.com> |
|
||||
// +----------------------------------------------------------------------+
|
||||
//
|
||||
// $Id: Common.php,v 1.14.2.1 2002/04/09 19:04:19 ssb Exp $
|
||||
|
||||
/**
|
||||
* Base class for all HTML classes
|
||||
*
|
||||
* @author Adam Daniel <adaniel1@eesus.jnj.com>
|
||||
* @version 1.6
|
||||
* @since PHP 4.0.3pl1
|
||||
* @abstract
|
||||
*/
|
||||
class HTML_Common {
|
||||
|
||||
/**
|
||||
* Associative array of table attributes
|
||||
* @var array
|
||||
* @access private
|
||||
*/
|
||||
var $_attributes = array();
|
||||
|
||||
/**
|
||||
* Tab offset of the table
|
||||
* @var int
|
||||
* @access private
|
||||
*/
|
||||
var $_tabOffset = 0;
|
||||
|
||||
/**
|
||||
* HTML comment on the object
|
||||
* @var string
|
||||
* @since 1.5
|
||||
* @access private
|
||||
*/
|
||||
var $_comment = "";
|
||||
|
||||
/**
|
||||
* Class constructor
|
||||
* @param mixed $attributes Associative array of table tag attributes
|
||||
* or HTML attributes name="value" pairs
|
||||
* @access public
|
||||
*/
|
||||
function HTML_Common($attributes=null, $tabOffset=0)
|
||||
{
|
||||
$this->setTabOffset($tabOffset);
|
||||
$this->setAttributes($attributes);
|
||||
} // end constructor
|
||||
|
||||
/**
|
||||
* Returns the current API version
|
||||
* @access public
|
||||
* @returns double
|
||||
*/
|
||||
function apiVersion()
|
||||
{
|
||||
return 1.6;
|
||||
} // end func apiVersion
|
||||
|
||||
/**
|
||||
* Returns a string of \t for the tabOffset property
|
||||
* @access private
|
||||
*/
|
||||
function _getTabs()
|
||||
{
|
||||
return $this->_tabOffset > 0 ? str_repeat("\t", $this->_tabOffset) : "";
|
||||
} // end func _getTabs
|
||||
|
||||
/**
|
||||
* Returns an HTML formatted attribute string
|
||||
* @param array $attributes
|
||||
* @return string
|
||||
* @access private
|
||||
*/
|
||||
function _getAttrString($attributes)
|
||||
{
|
||||
$strAttr = '';
|
||||
if (is_array($attributes)) {
|
||||
while (list($key, $value) = each($attributes)) {
|
||||
if (is_int($key)) {
|
||||
$strAttr .= ' ' . strtolower($value) . '="' . strtolower($value) . '"';
|
||||
} else {
|
||||
$strAttr .= ' ' . strtolower($key) . '="' . htmlspecialchars($value) . '"';
|
||||
}
|
||||
}
|
||||
}
|
||||
return $strAttr;
|
||||
} // end func _getAttrString
|
||||
|
||||
/**
|
||||
* Returns a valid atrributes array from either a string or array
|
||||
* @param mixed $attributes Either a typical HTML attribute string or an associative array
|
||||
* @access private
|
||||
*/
|
||||
function _parseAttributes($attributes)
|
||||
{
|
||||
if (is_array($attributes)) {
|
||||
return $attributes;
|
||||
} elseif (is_string($attributes)) {
|
||||
$preg = "/(([A-Za-z_:]|[^\\x00-\\x7F])([A-Za-z0-9_:.-]|[^\\x00-\\x7F])*)" .
|
||||
"([ \\n\\t\\r]+)?(=([ \\n\\t\\r]+)?(\"[^\"]*\"|'[^']*'|[^ \\n\\t\\r]*))?/";
|
||||
if (preg_match_all($preg, $attributes, $regs)) {
|
||||
$valCounter = 0;
|
||||
for ($counter=0; $counter<count($regs[1]); $counter++) {
|
||||
$name = $regs[1][$counter];
|
||||
$check = $regs[0][$counter];
|
||||
$value = $regs[7][$valCounter];
|
||||
if (trim($name) == trim($check)) {
|
||||
$arrAttr[] = strtoupper(trim($name));
|
||||
} else {
|
||||
if (substr($value, 0, 1) == "\"" || substr($value, 0, 1) == "'") {
|
||||
$value = substr($value, 1, -1);
|
||||
}
|
||||
$arrAttr[strtolower(trim($name))] = trim($value);
|
||||
$valCounter++;
|
||||
}
|
||||
}
|
||||
return $arrAttr;
|
||||
}
|
||||
}
|
||||
} // end func _parseAttributes
|
||||
|
||||
/**
|
||||
* Returns the array key for the given non-name-value pair attribute
|
||||
*
|
||||
* @param string $attr Attribute
|
||||
* @param array $attributes Array of attribute
|
||||
* @since 1.0
|
||||
* @access public
|
||||
* @return void
|
||||
* @throws
|
||||
*/
|
||||
function _getAttrKey($attr, $attributes)
|
||||
{
|
||||
if (is_array($attributes)) {
|
||||
$keys = array_keys($attributes);
|
||||
for ($counter=0; $counter < count($keys); $counter++) {
|
||||
$key = $keys[$counter];
|
||||
$value = $attributes[$key];
|
||||
if (strtoupper($value) == strtoupper($attr) && is_int($key)) {
|
||||
return $key;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
} //end func _getAttrKey
|
||||
|
||||
/**
|
||||
* Updates the attributes in $attr1 with the values in $attr2 without changing the other existing attributes
|
||||
* @param array $attr1 Original attributes array
|
||||
* @param array $attr2 New attributes array
|
||||
* @access private
|
||||
* @return array
|
||||
*/
|
||||
function _updateAttrArray(&$attr1, $attr2)
|
||||
{
|
||||
if (!is_array($attr2)) {
|
||||
return false;
|
||||
}
|
||||
while (list($key, $value) = each($attr2)) {
|
||||
if (!is_int($key)) {
|
||||
$attr1[$key] = $value;
|
||||
} else {
|
||||
$key = $this->_getAttrKey($value, $attr1);
|
||||
if (isset($key)) {
|
||||
$attr1[$key] = $value;
|
||||
} else {
|
||||
if (is_array($attr1)) {
|
||||
array_unshift($attr1, $value);
|
||||
} else {
|
||||
$attr1[] = $value;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
} // end func _updateAtrrArray
|
||||
|
||||
/**
|
||||
* Removes the given attribute from the given array
|
||||
*
|
||||
* @param string $attr Attribute name
|
||||
* @param array $attributes Attribute array
|
||||
* @since 1.4
|
||||
* @access public
|
||||
* @return void
|
||||
* @throws
|
||||
*/
|
||||
function _removeAttr($attr, &$attributes)
|
||||
{
|
||||
if (in_array(strtolower($attr), array_keys($attributes))) {
|
||||
unset($attributes[$attr]);
|
||||
} else {
|
||||
unset($attributes[$this->_getAttrKey($attr, $attributes)]);
|
||||
}
|
||||
} //end func _removeAttr
|
||||
|
||||
/**
|
||||
* Returns the value of the given attribute
|
||||
*
|
||||
* @param string $attr Attribute name
|
||||
* @since 1.5
|
||||
* @access public
|
||||
* @return void
|
||||
* @throws
|
||||
*/
|
||||
function getAttribute($attr)
|
||||
{
|
||||
$attr = strtolower($attr);
|
||||
if (is_array($this->_attributes) && isset($this->_attributes[$attr])) {
|
||||
return $this->_attributes[$attr];
|
||||
}
|
||||
return;
|
||||
} //end func getAttribute
|
||||
|
||||
/**
|
||||
* Sets the HTML attributes
|
||||
* @param mixed $attributes Either a typical HTML attribute string or an associative array
|
||||
* @access public
|
||||
*/
|
||||
function setAttributes($attributes)
|
||||
{
|
||||
$this->_attributes = $this->_parseAttributes($attributes);
|
||||
} // end func _setAttributes
|
||||
|
||||
/**
|
||||
* Returns an assoc array of attributes
|
||||
*
|
||||
* @since 1.6
|
||||
* @access public
|
||||
* @return void
|
||||
* @throws
|
||||
*/
|
||||
function getAttributes()
|
||||
{
|
||||
return $this->_attributes;
|
||||
} //end func getAttributes
|
||||
|
||||
/**
|
||||
* Updates the passed attributes without changing the other existing attributes
|
||||
* @param mixed $attributes Either a typical HTML attribute string or an associative array
|
||||
* @access public
|
||||
*/
|
||||
function updateAttributes($attributes)
|
||||
{
|
||||
$attributes = $this->_parseAttributes($attributes);
|
||||
$this->_updateAttrArray($this->_attributes, $attributes);
|
||||
} // end func updateAttributes
|
||||
|
||||
/**
|
||||
* Removes an attribute from
|
||||
*
|
||||
* @param string $attr Attribute name
|
||||
* @since 1.4
|
||||
* @access public
|
||||
* @return void
|
||||
* @throws
|
||||
*/
|
||||
function removeAttribute($attr)
|
||||
{
|
||||
$this->_removeAttr($attr, $this->_attributes);
|
||||
} //end func removeAttribute
|
||||
|
||||
/**
|
||||
* Sets the tab offset
|
||||
* @param int $offset
|
||||
* @access public
|
||||
*/
|
||||
function setTabOffset($offset)
|
||||
{
|
||||
$this->_tabOffset = $offset;
|
||||
} // end func setTabOffset
|
||||
|
||||
/**
|
||||
* Returns the tabOffset
|
||||
*
|
||||
* @since 1.5
|
||||
* @access public
|
||||
* @return void
|
||||
* @throws
|
||||
*/
|
||||
function getTabOffset()
|
||||
{
|
||||
return $this->_tabOffset;
|
||||
} //end func getTabOffset
|
||||
|
||||
/**
|
||||
* Sets the HTML comment to be displayed at the beginning of the HTML string
|
||||
*
|
||||
* @param string
|
||||
* @since 1.4
|
||||
* @access public
|
||||
* @return void
|
||||
* @throws
|
||||
*/
|
||||
function setComment($comment)
|
||||
{
|
||||
$this->_comment = $comment;
|
||||
} // end func setHtmlComment
|
||||
|
||||
/**
|
||||
* Returns the HTML comment
|
||||
*
|
||||
* @since 1.5
|
||||
* @access public
|
||||
* @return void
|
||||
* @throws
|
||||
*/
|
||||
function getComment()
|
||||
{
|
||||
return $this->_comment;
|
||||
} //end func getComment
|
||||
|
||||
/**
|
||||
* Abstract method. Must be extended to return the objects HTML
|
||||
*
|
||||
* @access public
|
||||
* @return string
|
||||
* @abstract
|
||||
*/
|
||||
function toHtml()
|
||||
{
|
||||
return "";
|
||||
} // end func toHtml
|
||||
|
||||
/**
|
||||
* Displays the HTML to the screen
|
||||
*
|
||||
* @access public
|
||||
*/
|
||||
function display()
|
||||
{
|
||||
print $this->toHtml();
|
||||
} // end func display
|
||||
|
||||
} // end class HTML_Common
|
||||
?>
|
||||
792
html/illt/HTML/IT.php
Normal file
792
html/illt/HTML/IT.php
Normal file
@@ -0,0 +1,792 @@
|
||||
<?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. |
|
||||
// +----------------------------------------------------------------------+
|
||||
// | Author: Ulf Wendel <ulf.wendel@phpdoc.de> |
|
||||
// +----------------------------------------------------------------------+
|
||||
//
|
||||
// $Id: IT.php,v 1.13 2002/02/28 08:27:13 sebastian Exp $
|
||||
//
|
||||
|
||||
require_once('HTML/IT_Error.php');
|
||||
|
||||
/**
|
||||
* 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 IntegratedTemplate( [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: IT.php,v 1.13 2002/02/28 08:27:13 sebastian Exp $
|
||||
* @access public
|
||||
* @package IX[X]
|
||||
*/
|
||||
class IntegratedTemplate {
|
||||
|
||||
/**
|
||||
* 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 this
|
||||
* you 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();
|
||||
|
||||
/**
|
||||
* 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 IntegratedTemplate(), 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 = "";
|
||||
|
||||
/**
|
||||
* 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 IntegratedTemplate($root = "") {
|
||||
|
||||
$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
|
||||
|
||||
/**
|
||||
* 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 IT_Error
|
||||
* @access public
|
||||
* @see show()
|
||||
*/
|
||||
function get($block = "__global__") {
|
||||
|
||||
if ("__global__" == $block && !$this->flagGlobalParsed)
|
||||
$this->parse("__global__");
|
||||
|
||||
if (!isset($this->blocklist[$block])) {
|
||||
new IT_Error("The block '$block' was not found in the template.", __FILE__, __LINE__);
|
||||
return "";
|
||||
}
|
||||
|
||||
if ($this->clearCache) {
|
||||
|
||||
$data = (isset($this->blockdata[$block])) ? $this->blockdata[$block] : "";
|
||||
unset($this->blockdata[$block]);
|
||||
return $data;
|
||||
|
||||
} else {
|
||||
|
||||
return (isset($this->blockdata[$block])) ? $this->blockdata[$block] : "";
|
||||
|
||||
}
|
||||
|
||||
} // end func get()
|
||||
|
||||
/**
|
||||
* Parses the given block.
|
||||
*
|
||||
* @param string name of the block to be parsed
|
||||
* @access public
|
||||
* @see parseCurrentBlock()
|
||||
* @throws IT_Error
|
||||
*/
|
||||
function parse($block = "__global__", $flag_recursion = false) {
|
||||
|
||||
if (!isset($this->blocklist[$block])) {
|
||||
return new IT_Error("The block '$block' was not found in the template.", __FILE__, __LINE__);
|
||||
return false;
|
||||
}
|
||||
|
||||
if ("__global__" == $block)
|
||||
$this->flagGlobalParsed = true;
|
||||
|
||||
$regs = array();
|
||||
$values = array();
|
||||
|
||||
if ($this->clearCacheOnParse) {
|
||||
|
||||
foreach ($this->variableCache as $name => $value) {
|
||||
$regs[] = "@" . $this->openingDelimiter . $name . $this->closingDelimiter . "@";
|
||||
$values[] = $value;
|
||||
}
|
||||
$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]);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
$outer = (0 == count($regs)) ? $this->blocklist[$block] : preg_replace($regs, $values, $this->blocklist[$block]);
|
||||
$empty = (0 == count($values)) ? true : 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 ($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 IT_Error
|
||||
* @access public
|
||||
*/
|
||||
function setCurrentBlock($block = "__global__") {
|
||||
|
||||
if (!isset($this->blocklist[$block]))
|
||||
return new IT_Error("Can't find the block '$block' in the template.", __FILE__, __LINE__);
|
||||
|
||||
$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 IT_Error
|
||||
* @access public
|
||||
* @see $removeEmptyBlocks
|
||||
*/
|
||||
function touchBlock($block) {
|
||||
|
||||
if (!isset($this->blocklist[$block]))
|
||||
return new IT_Error("Can't find the block '$block' in the template.", __FILE__, __LINE__);
|
||||
|
||||
$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 $this->setTemplate($template, $removeUnknownVariables, $removeEmptyBlocks);
|
||||
} // 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 (0 != count($regs[1])) {
|
||||
|
||||
foreach ($regs[1] as $k => $var)
|
||||
$this->blockvariables[$name][$var] = true;
|
||||
|
||||
} else {
|
||||
|
||||
$this->blockvariables[$name] = array();
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
} // end func buildBlockvariablelist
|
||||
|
||||
/**
|
||||
* Returns a list of all
|
||||
*/
|
||||
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])) {
|
||||
new IT_Error("The name of a block must be unique within a template. Found '$blockname' twice. Unpredictable results may appear.", __FILE__, __LINE__);
|
||||
$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"))) {
|
||||
new IT_Error("Can't read '$filename'.", __FILE__, __LINE__);
|
||||
return "";
|
||||
}
|
||||
|
||||
$content = fread($fh, filesize($filename));
|
||||
fclose($fh);
|
||||
|
||||
return preg_replace("#<!-- INCLUDE (.*) -->#ime", "\$this->getFile('\\1')", $content);
|
||||
} // end func getFile
|
||||
|
||||
} // end class IntegratedTemplate
|
||||
?>
|
||||
51
html/illt/HTML/IT_Error.php
Normal file
51
html/illt/HTML/IT_Error.php
Normal file
@@ -0,0 +1,51 @@
|
||||
<?php
|
||||
// +----------------------------------------------------------------------+
|
||||
// | PHP Version 4 |
|
||||
// +----------------------------------------------------------------------+
|
||||
// | 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. |
|
||||
// +----------------------------------------------------------------------+
|
||||
// | Author: Ulf Wendel <ulf.wendel@phpdoc.de> |
|
||||
// +----------------------------------------------------------------------+
|
||||
//
|
||||
// $Id: IT_Error.php,v 1.4 2002/02/28 08:27:13 sebastian Exp $
|
||||
|
||||
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
|
||||
?>
|
||||
631
html/illt/HTML/Table.php
Normal file
631
html/illt/HTML/Table.php
Normal file
@@ -0,0 +1,631 @@
|
||||
<?php
|
||||
/* vim: set expandtab tabstop=4 shiftwidth=4: */
|
||||
// +----------------------------------------------------------------------+
|
||||
// | PHP Version 4 |
|
||||
// +----------------------------------------------------------------------+
|
||||
// | 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: Table.php,v 1.14 2002/01/31 13:01:52 mansion Exp $
|
||||
|
||||
require_once "PEAR.php";
|
||||
require_once "HTML/Common.php";
|
||||
|
||||
/**
|
||||
* Builds an HTML table
|
||||
*
|
||||
* @author Adam Daniel <adaniel1@eesus.jnj.com>
|
||||
* @author Bertrand Mansion <bmansion@mamasam.com>
|
||||
* @version 1.6
|
||||
* @since PHP 4.0.3pl1
|
||||
*/
|
||||
class HTML_Table extends HTML_Common {
|
||||
|
||||
/**
|
||||
* Automatically adds a new row or column if a given row or column index does not exist
|
||||
*
|
||||
* @var bool
|
||||
* @access private
|
||||
*/
|
||||
var $_autoGrow = true;
|
||||
|
||||
/**
|
||||
* Value to insert into empty cells
|
||||
*
|
||||
* @var string
|
||||
* @access private
|
||||
*/
|
||||
var $_autoFill = " ";
|
||||
|
||||
/**
|
||||
* Array containing the table structure
|
||||
*
|
||||
* @var array
|
||||
* @access private
|
||||
*/
|
||||
var $_structure = array();
|
||||
|
||||
/**
|
||||
* Number of rows composing in the table
|
||||
*
|
||||
* @var int
|
||||
* @access private
|
||||
*/
|
||||
var $_rows = 0;
|
||||
|
||||
/**
|
||||
* Number of column composing the table
|
||||
*
|
||||
* @var int
|
||||
* @access private
|
||||
*/
|
||||
var $_cols = 0;
|
||||
|
||||
/**
|
||||
* Tracks the level of nested tables
|
||||
*
|
||||
* @var int
|
||||
* @since 1.5
|
||||
* @access private
|
||||
*/
|
||||
var $_nestLevel = 0;
|
||||
|
||||
/**
|
||||
* Class constructor
|
||||
*
|
||||
* @param array $attributes Associative array of table tag attributes
|
||||
* @param int $tabOffset
|
||||
* @access public
|
||||
*/
|
||||
function HTML_Table($attributes = null, $tabOffset = 0)
|
||||
{
|
||||
$commonVersion = 1.3;
|
||||
if (HTML_Common::apiVersion() < $commonVersion) {
|
||||
return new PEAR_Error("HTML_Table version " . $this->apiVersion() . " requires " .
|
||||
"HTML_Common version $commonVersion or greater.", 0, PEAR_ERROR_TRIGGER);
|
||||
}
|
||||
HTML_Common::HTML_Common($attributes, $tabOffset);
|
||||
} // end constructor
|
||||
|
||||
/**
|
||||
* Returns the API version
|
||||
*
|
||||
* @access public
|
||||
* @return double
|
||||
*/
|
||||
function apiVersion()
|
||||
{
|
||||
return 1.6;
|
||||
} // end func apiVersion
|
||||
|
||||
/**
|
||||
* Sets the table caption
|
||||
*
|
||||
* @param string $caption
|
||||
* @param mixed $attributes Associative array or string of table row attributes
|
||||
* @access public
|
||||
*/
|
||||
function setCaption($caption, $attributes = null)
|
||||
{
|
||||
$attributes = $this->_parseAttributes($attributes);
|
||||
$this->_structure["caption"] = array("attr" => $attributes, "contents" => $caption);
|
||||
} // end func setCaption
|
||||
|
||||
/**
|
||||
* Sets the autoFill value
|
||||
*
|
||||
* @param mixed $fill
|
||||
* @access public
|
||||
*/
|
||||
function setAutoFill($fill)
|
||||
{
|
||||
$this->_autoFill = $fill;
|
||||
} // end func setAutoFill
|
||||
|
||||
/**
|
||||
* Returns the autoFill value
|
||||
*
|
||||
* @access public
|
||||
* @return mixed
|
||||
*/
|
||||
function getAutoFill()
|
||||
{
|
||||
return $this->_autoFill;
|
||||
} // end func getAutoFill
|
||||
|
||||
/**
|
||||
* Sets the autoGrow value
|
||||
*
|
||||
* @param bool $fill
|
||||
* @access public
|
||||
*/
|
||||
function setAutoGrow($grow)
|
||||
{
|
||||
$this->_autoGrow = $grow;
|
||||
} // end func setAutoGrow
|
||||
|
||||
/**
|
||||
* Returns the autoGrow value
|
||||
*
|
||||
* @access public
|
||||
* @return mixed
|
||||
*/
|
||||
function getAutoGrow()
|
||||
{
|
||||
return $this->_autoGrow;
|
||||
} // end func getAutoGrow
|
||||
|
||||
/**
|
||||
* Sets the number of rows in the table
|
||||
*
|
||||
* @param int $rows
|
||||
* @access public
|
||||
*/
|
||||
function setRowCount($rows)
|
||||
{
|
||||
$this->_rows = $rows;
|
||||
} // end func setRowCount
|
||||
|
||||
/**
|
||||
* Sets the number of columns in the table
|
||||
*
|
||||
* @param int $cols
|
||||
* @access public
|
||||
*/
|
||||
function setColCount($cols)
|
||||
{
|
||||
$this->_cols = $cols;
|
||||
} // end func setColCount
|
||||
|
||||
/**
|
||||
* Returns the number of rows in the table
|
||||
*
|
||||
* @access public
|
||||
* @return int
|
||||
*/
|
||||
function getRowCount()
|
||||
{
|
||||
return $this->_rows;
|
||||
} // end func getRowCount
|
||||
|
||||
/**
|
||||
* Sets the number of columns in the table
|
||||
*
|
||||
* @access public
|
||||
* @return int
|
||||
*/
|
||||
function getColCount()
|
||||
{
|
||||
return $this->_cols;
|
||||
} // end func getColCount
|
||||
|
||||
/**
|
||||
* Sets a rows type 'TH' or 'TD'
|
||||
*
|
||||
* @param int $row Row index
|
||||
* @param string $type 'TH' or 'TD'
|
||||
* @access public
|
||||
*/
|
||||
|
||||
function setRowType($row, $type)
|
||||
{
|
||||
for ($counter = 0; $counter < $this->_cols; $counter++) {
|
||||
$this->_structure[$row][$counter]["type"] = $type;
|
||||
}
|
||||
} // end func setRowType
|
||||
|
||||
/**
|
||||
* Sets a columns type 'TH' or 'TD'
|
||||
*
|
||||
* @param int $col Column index
|
||||
* @param string $type 'TH' or 'TD'
|
||||
* @access public
|
||||
*/
|
||||
function setColType($col, $type)
|
||||
{
|
||||
for ($counter = 0; $counter < $this->_rows; $counter++) {
|
||||
$this->_structure[$counter][$col]["type"] = $type;
|
||||
}
|
||||
} // end func setColType
|
||||
|
||||
/**
|
||||
* Sets the cell attributes for an existing cell.
|
||||
*
|
||||
* If the given indices do not exist and autoGrow is true then the given
|
||||
* row and/or col is automatically added. If autoGrow is false then an
|
||||
* error is returned.
|
||||
*
|
||||
* @param int $row Row index
|
||||
* @param int $col Column index
|
||||
* @param mixed $attributes Associative array or string of table row attributes
|
||||
* @access public
|
||||
* @throws PEAR_Error
|
||||
*/
|
||||
function setCellAttributes($row, $col, $attributes)
|
||||
{
|
||||
if (isset($this->_structure[$row][$col]) && $this->_structure[$row][$col] == "__SPANNED__") return;
|
||||
$attributes = $this->_parseAttributes($attributes);
|
||||
$err = $this->_adjustEnds($row, $col, 'setCellAttributes', $attributes);
|
||||
if (PEAR::isError($err)) {
|
||||
return $err;
|
||||
}
|
||||
$this->_structure[$row][$col]["attr"] = $attributes;
|
||||
$this->_updateSpanGrid($row, $col);
|
||||
} // end func setCellAttributes
|
||||
|
||||
/**
|
||||
* Updates the cell attributes passed but leaves other existing attributes in tact
|
||||
*
|
||||
* @param int $row Row index
|
||||
* @param int $col Column index
|
||||
* @param mixed $attributes Associative array or string of table row attributes
|
||||
* @access public
|
||||
*/
|
||||
function updateCellAttributes($row, $col, $attributes)
|
||||
{
|
||||
if (isset($this->_structure[$row][$col]) && $this->_structure[$row][$col] == "__SPANNED__") return;
|
||||
$attributes = $this->_parseAttributes($attributes);
|
||||
$err = $this->_adjustEnds($row, $col, 'updateCellAttributes', $attributes);
|
||||
if (PEAR::isError($err)) {
|
||||
return $err;
|
||||
}
|
||||
$this->_updateAttrArray($this->_structure[$row][$col]["attr"], $attributes);
|
||||
$this->_updateSpanGrid($row, $col);
|
||||
} // end func updateCellAttributes
|
||||
|
||||
/**
|
||||
* Sets the cell contents for an existing cell
|
||||
*
|
||||
* If the given indices do not exist and autoGrow is true then the given
|
||||
* row and/or col is automatically added. If autoGrow is false then an
|
||||
* error is returned.
|
||||
*
|
||||
* @param int $row Row index
|
||||
* @param int $col Column index
|
||||
* @param mixed $contents May contain html or any object with a toHTML method
|
||||
* @param string $type (optional) Cell type either 'TH' or 'TD'
|
||||
* @access public
|
||||
* @throws PEAR_Error
|
||||
*/
|
||||
function setCellContents($row, $col, $contents, $type = 'TD')
|
||||
{
|
||||
if(isset($this->_structure[$row][$col]) && $this->_structure[$row][$col] == "__SPANNED__") return;
|
||||
$err = $this->_adjustEnds($row, $col, 'setCellContents');
|
||||
if (PEAR::isError($err)) {
|
||||
return $err;
|
||||
}
|
||||
$this->_structure[$row][$col]["contents"] = $contents;
|
||||
$this->_structure[$row][$col]["type"] = $type;
|
||||
} // end func setCellContents
|
||||
|
||||
/**
|
||||
* Returns the cell contents for an existing cell
|
||||
*
|
||||
* @param int $row Row index
|
||||
* @param int $col Column index
|
||||
* @access public
|
||||
* @return mixed
|
||||
*/
|
||||
function getCellContents($row, $col)
|
||||
{
|
||||
if (isset($this->_structure[$row][$col]) && $this->_structure[$row][$col] == "__SPANNED__") return;
|
||||
return $this->_structure[$row][$col]["contents"];
|
||||
} // end func getCellContents
|
||||
|
||||
/**
|
||||
* Sets the contents of a header cell
|
||||
*
|
||||
* @param int $row
|
||||
* @param int $col
|
||||
* @param mixed $contents
|
||||
* @access public
|
||||
*/
|
||||
function setHeaderContents($row, $col, $contents)
|
||||
{
|
||||
$this->setCellContents($row, $col, $contents, 'TH');
|
||||
} // end func setHeaderContents
|
||||
|
||||
/**
|
||||
* Adds a table row and returns the row identifier
|
||||
*
|
||||
* @param array $contents (optional) Must be a indexed array of valid cell contents
|
||||
* @param mixed $attributes (optional) Associative array or string of table row attributes
|
||||
* @param string $type (optional) Cell type either 'TH' or 'TD'
|
||||
* @return int
|
||||
* @access public
|
||||
*/
|
||||
function addRow($contents = null, $attributes = null, $type = 'TD')
|
||||
{
|
||||
if (isset($contents) && !is_array($contents)) {
|
||||
return new PEAR_Error("First parameter to HTML_Table::addRow must be an array");
|
||||
}
|
||||
$row = $this->_rows++;
|
||||
for ($counter = 0; $counter < count($contents); $counter++) {
|
||||
if ($type == 'TD') {
|
||||
$this->setCellContents($row, $counter, $contents[$counter]);
|
||||
} elseif ($type == 'TH') {
|
||||
$this->setHeaderContents($row, $counter, $contents[$counter]);
|
||||
}
|
||||
}
|
||||
$this->setRowAttributes($row, $attributes);
|
||||
return $row;
|
||||
} // end func addRow
|
||||
|
||||
/**
|
||||
* Sets the row attributes for an existing row
|
||||
*
|
||||
* @param int $row Row index
|
||||
* @param mixed $attributes Associative array or string of table row attributes
|
||||
* @access public
|
||||
*/
|
||||
function setRowAttributes($row, $attributes)
|
||||
{
|
||||
for ($i = 0; $i < $this->_cols; $i++) {
|
||||
$this->setCellAttributes($row, $i, $attributes);
|
||||
}
|
||||
} // end func setRowAttributes
|
||||
|
||||
/**
|
||||
* Updates the row attributes for an existing row
|
||||
*
|
||||
* @param int $row Row index
|
||||
* @param mixed $attributes Associative array or string of table row attributes
|
||||
* @access public
|
||||
*/
|
||||
function updateRowAttributes($row, $attributes = null)
|
||||
{
|
||||
for ($i = 0; $i < $this->_cols; $i++) {
|
||||
$this->updateCellAttributes($row, $i, $attributes);
|
||||
}
|
||||
} // end func updateRowAttributes
|
||||
|
||||
/**
|
||||
* Alternates the row attributes starting at $start
|
||||
*
|
||||
* @param int $start Row index of row in which alternating begins
|
||||
* @param mixed $attributes1 Associative array or string of table row attributes
|
||||
* @param mixed $attribute2 Associative array or string of table row attributes
|
||||
* @access public
|
||||
*/
|
||||
function altRowAttributes($start, $attributes1, $attributes2)
|
||||
{
|
||||
for ($row = $start ; $row < $this->_rows ; $row++) {
|
||||
$attributes = ( ($row+$start)%2 == 0 ) ? $attributes1 : $attributes2;
|
||||
$this->updateRowAttributes($row, $attributes);
|
||||
}
|
||||
} // end func altRowAttributes
|
||||
|
||||
/**
|
||||
* Adds a table column and returns the column identifier
|
||||
*
|
||||
* @param array $contents (optional) Must be a indexed array of valid cell contents
|
||||
* @param mixed $attributes (optional) Associative array or string of table row attributes
|
||||
* @param string $type (optional) Cell type either 'TH' or 'TD'
|
||||
* @return int
|
||||
* @access public
|
||||
*/
|
||||
function addCol($contents = null, $attributes = null, $type = 'TD')
|
||||
{
|
||||
if (isset($contents) && !is_array($contents)) {
|
||||
return new PEAR_Error("First parameter to HTML_Table::addCol must be an array");
|
||||
}
|
||||
$col = $this->_cols++;
|
||||
for ($counter = 0; $counter < count($contents); $counter++) {
|
||||
$this->setCellContents($counter, $col, $contents[$counter], $type);
|
||||
}
|
||||
$this->setColAttributes($col, $attributes);
|
||||
return $col;
|
||||
} // end func addCol
|
||||
|
||||
/**
|
||||
* Sets the column attributes for an existing column
|
||||
*
|
||||
* @param int $col Column index
|
||||
* @param mixed $attributes (optional) Associative array or string of table row attributes
|
||||
* @access public
|
||||
*/
|
||||
function setColAttributes($col, $attributes = null)
|
||||
{
|
||||
for ($i = 0; $i < $this->_rows; $i++) {
|
||||
$this->setCellAttributes($i,$col,$attributes);
|
||||
}
|
||||
} // end func setColAttributes
|
||||
|
||||
/**
|
||||
* Updates the column attributes for an existing column
|
||||
*
|
||||
* @param int $col Column index
|
||||
* @param mixed $attributes (optional) Associative array or string of table row attributes
|
||||
* @access public
|
||||
*/
|
||||
function updateColAttributes($col, $attributes = null)
|
||||
{
|
||||
for ($i = 0; $i < $this->_rows; $i++) {
|
||||
$this->updateCellAttributes($i, $col, $attributes);
|
||||
}
|
||||
} // end func updateColAttributes
|
||||
|
||||
/**
|
||||
* Sets the attributes for all cells
|
||||
*
|
||||
* @param mixed $attributes (optional) Associative array or string of table row attributes
|
||||
* @since 1.6
|
||||
* @access public
|
||||
*/
|
||||
function setAllAttributes($attributes = null)
|
||||
{
|
||||
for ($i = 0; $i < $this->_rows; $i++) {
|
||||
$this->setRowAttributes($i, $attributes);
|
||||
}
|
||||
} // end func setAllAttributes
|
||||
|
||||
/**
|
||||
* Updates the attributes for all cells
|
||||
*
|
||||
* @param mixed $attributes (optional) Associative array or string of table row attributes
|
||||
* @since 1.6
|
||||
* @access public
|
||||
*/
|
||||
function updateAllAttributes($attributes = null)
|
||||
{
|
||||
for ($i = 0; $i < $this->_rows; $i++) {
|
||||
$this->updateRowAttributes($i, $attributes);
|
||||
}
|
||||
} // end func updateAllAttributes
|
||||
|
||||
/**
|
||||
* Returns the table structure as HTML
|
||||
*
|
||||
* @access public
|
||||
* @return string
|
||||
*/
|
||||
function toHtml()
|
||||
{
|
||||
$tabs = $this->_getTabs();
|
||||
$strHtml =
|
||||
"\n" . $tabs . "<!-- BEGIN TABLE LEVEL: $this->_nestLevel -->\n";
|
||||
if ($this->_comment) {
|
||||
$strHtml .= $tabs . "<!-- $this->_comment -->\n";
|
||||
}
|
||||
$strHtml .=
|
||||
$tabs . "<table" . $this->_getAttrString($this->_attributes) . ">\n";
|
||||
if (!empty($this->_structure["caption"])) {
|
||||
$attr = $this->_structure["caption"]["attr"];
|
||||
$contents = $this->_structure["caption"]["contents"];
|
||||
$strHtml .= $tabs . "\t<caption" . $this->_getAttrString($attr) . ">";
|
||||
if (is_array($contents)) $contents = implode(", ", $contents);
|
||||
$strHtml .= $contents;
|
||||
$strHtml .= "</caption>\n";
|
||||
}
|
||||
for ($i = 0 ; $i < $this->_rows ; $i++) {
|
||||
$strHtml .= $tabs ."\t<tr>\n";
|
||||
for ($j = 0 ; $j < $this->_cols ; $j++) {
|
||||
if (isset($this -> _structure[$i][$j]) && $this->_structure[$i][$j] == "__SPANNED__") {
|
||||
$strHtml .= $tabs ."\t\t<!-- span -->\n";
|
||||
continue;
|
||||
}
|
||||
if (isset($this->_structure[$i][$j]["type"])) {
|
||||
$type = (strtoupper($this->_structure[$i][$j]["type"]) == "TH" ? "th" : "td");
|
||||
} else {
|
||||
$type = "td";
|
||||
}
|
||||
if (isset($this->_structure[$i][$j]["attr"])) {
|
||||
$attr = $this->_structure[$i][$j]["attr"];
|
||||
} else {
|
||||
$attr = "";
|
||||
}
|
||||
if (isset($this->_structure[$i][$j]["contents"])) {
|
||||
$contents = $this->_structure[$i][$j]["contents"];
|
||||
} else {
|
||||
$contents = "";
|
||||
}
|
||||
$flagCloseTable = false;
|
||||
$strHtml .= $tabs . "\t\t<$type" . $this->_getAttrString($attr) . ">";
|
||||
if (is_object($contents)) {
|
||||
if (is_subclass_of($contents, "html_common")) {
|
||||
$contents->setTabOffset($this->_tabOffset + 3);
|
||||
$contents->_nestLevel = $this->_nestLevel + 1;
|
||||
$flagCloseTable = true;
|
||||
}
|
||||
if (method_exists($contents, "toHtml")) {
|
||||
$contents = $contents->toHtml();
|
||||
} elseif (method_exists($contents, "toString")) {
|
||||
$contents = $contents->toString();
|
||||
}
|
||||
}
|
||||
if (is_array($contents))
|
||||
$contents = implode(", ",$contents);
|
||||
if (isset($this->_autoFill) && $contents == "")
|
||||
$contents = $this->_autoFill;
|
||||
$strHtml .= $contents;
|
||||
$strHtml .= (isset($flagCloseTable)) ? "\t\t" : '';
|
||||
$strHtml .= "</$type>\n";
|
||||
}
|
||||
$strHtml .= $tabs ."\t</tr>\n";
|
||||
}
|
||||
$strHtml .=
|
||||
$tabs . "</table>\n". $tabs . "<!-- END TABLE LEVEL: $this->_nestLevel -->\n";
|
||||
return $strHtml;
|
||||
} // end func toHtml
|
||||
|
||||
/**
|
||||
* Checks if rows or columns are spanned
|
||||
*
|
||||
* @param int $row Row index
|
||||
* @param int $col Column index
|
||||
* @access private
|
||||
*/
|
||||
function _updateSpanGrid($row, $col)
|
||||
{
|
||||
if (isset($this->_structure[$row][$col]["attr"]["colspan"])) {
|
||||
$colspan = $this->_structure[$row][$col]["attr"]["colspan"];
|
||||
}
|
||||
if (isset($this->_structure[$row][$col]["attr"]["rowspan"])) {
|
||||
$rowspan = $this->_structure[$row][$col]["attr"]["rowspan"];
|
||||
}
|
||||
if (isset($colspan)) {
|
||||
for ($j = $col+1; (($j < $this->_cols) && ($j <= ($col + $colspan - 1))); $j++) {
|
||||
$this->_structure[$row][$j] = "__SPANNED__";
|
||||
}
|
||||
}
|
||||
if (isset($rowspan)) {
|
||||
for ($i = $row+1; (($i < $this->_rows) && ($i <= ($row + $rowspan - 1))); $i++) {
|
||||
$this->_structure[$i][$col] = "__SPANNED__";
|
||||
}
|
||||
}
|
||||
if (isset($colspan) && isset($rowspan)) {
|
||||
for ($i = $row+1; (($i < $this->_rows) && ($i <= ($row + $rowspan - 1))); $i++) {
|
||||
for ($j = $col+1; (($j <= $this->_cols) && ($j <= ($col + $colspan - 1))); $j++) {
|
||||
$this->_structure[$i][$j] = "__SPANNED__";
|
||||
}
|
||||
}
|
||||
}
|
||||
} // end func _updateSpanGrid
|
||||
|
||||
/**
|
||||
* Adjusts ends (total number of rows and columns)
|
||||
*
|
||||
* @param int $row Row index
|
||||
* @param int $col Column index
|
||||
* @param string $method Method name of caller
|
||||
* Used to populate PEAR_Error if thrown.
|
||||
* @param array $attributes Assoc array of attributes
|
||||
* Default is an empty array.
|
||||
* @access private
|
||||
* @throws PEAR_Error
|
||||
*/
|
||||
function _adjustEnds($row, $col, $method, $attributes = array())
|
||||
{
|
||||
$colspan = isset($attributes['colspan']) ? $attributes['colspan'] : 1;
|
||||
$rowspan = isset($attributes['rowspan']) ? $attributes['rowspan'] : 1;
|
||||
if (($row + $rowspan - 1) >= $this->_rows) {
|
||||
if ($this->_autoGrow) {
|
||||
$this->_rows = $row + $rowspan;
|
||||
} else {
|
||||
return new PEAR_Error('Invalid table row reference[' .
|
||||
$row . '] in HTML_Table::' . $method);
|
||||
}
|
||||
}
|
||||
if (($col + $colspan - 1) >= $this->_cols) {
|
||||
if ($this->_autoGrow) {
|
||||
$this->_cols = $col + $colspan;
|
||||
} else {
|
||||
return new PEAR_Error('Invalid table column reference[' .
|
||||
$col . '] in HTML_Table::' . $method);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
} // end class HTML_Table
|
||||
?>
|
||||
186
html/illt/Mail.php
Normal file
186
html/illt/Mail.php
Normal file
@@ -0,0 +1,186 @@
|
||||
<?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. |
|
||||
// +----------------------------------------------------------------------+
|
||||
// | Author: Chuck Hagenbuch <chuck@horde.org> |
|
||||
// +----------------------------------------------------------------------+
|
||||
//
|
||||
// $Id: Mail.php,v 1.17 2002/02/28 08:27:05 sebastian 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.17 $
|
||||
* @package Mail
|
||||
*/
|
||||
class Mail extends PEAR
|
||||
{
|
||||
/**
|
||||
* 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)) {
|
||||
return new $class($params);
|
||||
} 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)
|
||||
{
|
||||
// Look out for the From: value to use along the way.
|
||||
$text_headers = ''; // text representation of headers
|
||||
$from = null;
|
||||
|
||||
foreach ($headers as $key => $val) {
|
||||
if ($key == 'From') {
|
||||
include_once 'Mail/RFC822.php';
|
||||
|
||||
$from_arr = Mail_RFC822::parseAddressList($val, 'localhost', false);
|
||||
$from = $from_arr[0]->mailbox . '@' . $from_arr[0]->host;
|
||||
if (strstr($from, ' ')) {
|
||||
// Reject outright envelope From addresses with spaces.
|
||||
return false;
|
||||
}
|
||||
$text_headers .= $key . ': ' . $val . "\n";
|
||||
} else if ($key == 'Received') {
|
||||
// put Received: headers at the top, since Receieved:
|
||||
// after Subject: in the header order is somtimes used
|
||||
// as a spam trap.
|
||||
$text_headers = $key . ': ' . $val . "\n" . $text_headers;
|
||||
} else {
|
||||
$text_headers .= $key . ': ' . $val . "\n";
|
||||
}
|
||||
}
|
||||
|
||||
return array($from, $text_headers);
|
||||
}
|
||||
|
||||
/**
|
||||
* 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;
|
||||
}
|
||||
|
||||
}
|
||||
?>
|
||||
868
html/illt/Mail/RFC822.php
Normal file
868
html/illt/Mail/RFC822.php
Normal file
@@ -0,0 +1,868 @@
|
||||
<?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: Richard Heyes <richard@phpguru.org> |
|
||||
// | Chuck Hagenbuch <chuck@horde.org> |
|
||||
// +----------------------------------------------------------------------+
|
||||
|
||||
require_once ('PEAR.php');
|
||||
|
||||
/**
|
||||
* 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 Heyes" <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.18.2.1 $
|
||||
* @package Mail
|
||||
*/
|
||||
|
||||
class Mail_RFC822 extends PEAR{
|
||||
|
||||
/**
|
||||
* 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->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;
|
||||
|
||||
while ($this->address = $this->_splitAddresses($this->address)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if ($this->address === false || isset($this->error)) {
|
||||
return $this->raiseError($this->error);
|
||||
}
|
||||
|
||||
// Reset timer since large amounts of addresses can take a long time to
|
||||
// get here
|
||||
set_time_limit(30);
|
||||
|
||||
// Loop through all the addresses
|
||||
for ($i = 0; $i < count($this->addresses); $i++){
|
||||
|
||||
if (($return = $this->_validateAddress($this->addresses[$i])) === false
|
||||
|| isset($this->error)) {
|
||||
return $this->raiseError($this->error);
|
||||
}
|
||||
|
||||
if (!$this->nestGroups) {
|
||||
$this->structure = array_merge($this->structure, $return);
|
||||
} else {
|
||||
$this->structure[] = $return;
|
||||
}
|
||||
}
|
||||
|
||||
return $this->structure;
|
||||
}
|
||||
|
||||
/**
|
||||
* Splits an address into seperate addresses.
|
||||
*
|
||||
* @access private
|
||||
* @param string $address The addresses to split.
|
||||
* @return boolean Success or failure.
|
||||
*/
|
||||
function _splitAddresses($address)
|
||||
{
|
||||
|
||||
if (!empty($this->limit) AND 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;
|
||||
|
||||
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 (!isset($addresses)){
|
||||
$this->error = 'Empty group.';
|
||||
return false;
|
||||
}
|
||||
|
||||
for ($i = 0; $i < count($addresses); $i++) {
|
||||
$addresses[$i] = trim($addresses[$i]);
|
||||
}
|
||||
|
||||
// Validate each mailbox.
|
||||
// Format could be one of: name <geezer@domain.com>
|
||||
// geezer@domain.com
|
||||
// geezer
|
||||
// ... or any other format valid by RFC 822.
|
||||
array_walk($addresses, array($this, 'validateMailbox'));
|
||||
|
||||
// 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);
|
||||
}
|
||||
|
||||
for ($i = 0; $i < count($phrase_parts); $i++) {
|
||||
// If quoted string:
|
||||
if (substr($phrase_parts[$i], 0, 1) == '"') {
|
||||
if (!$this->_validateQuotedString($phrase_parts[$i]))
|
||||
return false;
|
||||
continue;
|
||||
}
|
||||
|
||||
// Otherwise it's an atom:
|
||||
if (!$this->_validateAtom($phrase_parts[$i])) 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.
|
||||
return !(preg_match('/(.)[\x0D\\\\"]/', $qstring, $matches) && $matches[1] != '\\');
|
||||
}
|
||||
|
||||
/**
|
||||
* 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 = '';
|
||||
|
||||
// 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;
|
||||
}
|
||||
}
|
||||
|
||||
for($i=0; $i<count(@$comments); $i++){
|
||||
$mailbox = str_replace('('.$comments[$i].')', '', $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));
|
||||
|
||||
for ($i = 0; $i < count($domains); $i++) {
|
||||
$domains[$i] = str_replace('@', '', trim($domains[$i]));
|
||||
if (!$this->_validateDomain($domains[$i])) 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);
|
||||
}
|
||||
|
||||
for ($i = 0; $i < count($sub_domains); $i++) {
|
||||
if (!$this->_validateSubdomain(trim($sub_domains[$i])))
|
||||
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);
|
||||
|
||||
// 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.
|
||||
for ($i = 0; $i < count($words); $i++) {
|
||||
if ($this->_validatePhrase(trim($words[$i])) === 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));
|
||||
}
|
||||
}
|
||||
?>
|
||||
77
html/illt/Mail/mail.php
Normal file
77
html/illt/Mail/mail.php
Normal file
@@ -0,0 +1,77 @@
|
||||
<?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. |
|
||||
// +----------------------------------------------------------------------+
|
||||
// | Author: Chuck Hagenbuch <chuck@horde.org> |
|
||||
// +----------------------------------------------------------------------+
|
||||
//
|
||||
// $Id: mail.php,v 1.4 2002/02/28 08:27:14 sebastian Exp $
|
||||
|
||||
require_once ('Mail.php');
|
||||
|
||||
/**
|
||||
* internal PHP-mail() implementation of the PEAR Mail:: interface.
|
||||
* @access public
|
||||
* @package Mail
|
||||
* @version $Revision: 1.4 $
|
||||
*/
|
||||
|
||||
class Mail_mail extends Mail {
|
||||
/**
|
||||
* 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.
|
||||
list(,$text_headers) = Mail::prepareHeaders($headers);
|
||||
|
||||
return mail($recipients, $subject, $body, $text_headers);
|
||||
}
|
||||
|
||||
}
|
||||
142
html/illt/Mail/smtp.php
Normal file
142
html/illt/Mail/smtp.php
Normal file
@@ -0,0 +1,142 @@
|
||||
<?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. |
|
||||
// +----------------------------------------------------------------------+
|
||||
// | Author: Chuck Hagenbuch <chuck@horde.org> |
|
||||
// +----------------------------------------------------------------------+
|
||||
|
||||
require_once 'Mail.php';
|
||||
|
||||
/**
|
||||
* SMTP implementation of the PEAR Mail:: interface. Requires the PEAR
|
||||
* Net_SMTP:: class.
|
||||
* @access public
|
||||
* @package Mail
|
||||
* @version $Revision: 1.11 $
|
||||
*/
|
||||
class Mail_smtp extends Mail {
|
||||
|
||||
/**
|
||||
* The SMTP host to connect to.
|
||||
* @var string
|
||||
*/
|
||||
var $host = 'localhost';
|
||||
|
||||
/**
|
||||
* The port the SMTP server is on.
|
||||
* @var integer
|
||||
*/
|
||||
var $port = 25;
|
||||
|
||||
/**
|
||||
* Whether or not to attempt to authenticate to the SMTP server.
|
||||
* @var boolean
|
||||
*/
|
||||
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 = '';
|
||||
|
||||
/**
|
||||
* 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 Whether or not to use SMTP auth. Defaults to false.
|
||||
* username The username to use for SMTP auth. No default.
|
||||
* password The password to use for SMTP auth. No default.
|
||||
*
|
||||
* 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'];
|
||||
}
|
||||
|
||||
/**
|
||||
* 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 (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)
|
||||
{
|
||||
include_once 'Net/SMTP.php';
|
||||
|
||||
if (!($smtp = new Net_SMTP($this->host, $this->port))) { return new PEAR_Error('unable to instantiate Net_SMTP object'); }
|
||||
if (PEAR::isError($smtp->connect())) { return new PEAR_Error('unable to connect to smtp server ' . $this->host . ':' . $this->port); }
|
||||
|
||||
if ($this->auth) {
|
||||
if (PEAR::isError($smtp->auth($this->username, $this->password))) { return new PEAR_Error('unable to authenticate to smtp server'); }
|
||||
if (PEAR::isError($smtp->identifySender())) { return new PEAR_Error('unable to identify smtp server'); }
|
||||
}
|
||||
|
||||
list($from, $text_headers) = $this->prepareHeaders($headers);
|
||||
if (!isset($from)) {
|
||||
return new PEAR_Error('No from address given');
|
||||
}
|
||||
|
||||
if (PEAR::isError($smtp->mailFrom($from))) { return new PEAR_Error('unable to set sender to [' . $from . ']'); }
|
||||
|
||||
$recipients = $this->parseRecipients($recipients);
|
||||
foreach($recipients as $recipient) {
|
||||
if (PEAR::isError($res = $smtp->rcptTo($recipient))) { return new PEAR_Error('unable to add recipient [' . $recipient . ']: ' . $res->getMessage()); }
|
||||
}
|
||||
|
||||
if (PEAR::isError($smtp->data($text_headers . "\n" . $body))) { return new PEAR_Error('unable to send data'); }
|
||||
|
||||
$smtp->disconnect();
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
||||
?>
|
||||
391
html/illt/Net/Curl.php
Normal file
391
html/illt/Net/Curl.php
Normal file
@@ -0,0 +1,391 @@
|
||||
<?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. |
|
||||
// +----------------------------------------------------------------------+
|
||||
// | Author: Sterling Hughes <sterling@php.net> |
|
||||
// +----------------------------------------------------------------------+
|
||||
//
|
||||
// $Id: Curl.php,v 1.9 2002/02/28 08:27:14 sebastian Exp $
|
||||
//
|
||||
// A nice friendly OO interface for CURL
|
||||
//
|
||||
require_once('PEAR.php');
|
||||
|
||||
class Net_Curl extends PEAR
|
||||
{
|
||||
// {{{ Public Properties
|
||||
|
||||
/**
|
||||
* The URL for cURL to work with
|
||||
*
|
||||
* @var string $url
|
||||
* @access public
|
||||
*/
|
||||
var $url;
|
||||
|
||||
/**
|
||||
* The SSL version for the transfer
|
||||
*
|
||||
* @var integer $sslVersion
|
||||
* @access public
|
||||
*/
|
||||
var $sslVersion;
|
||||
|
||||
/**
|
||||
* The filename of the SSL certificate
|
||||
*
|
||||
* @var string $sslCert
|
||||
* @access public
|
||||
*/
|
||||
var $sslCert;
|
||||
|
||||
/**
|
||||
* The password corresponding to the certificate
|
||||
* in the $sslCert property
|
||||
*
|
||||
* @var string $sslCertPasswd
|
||||
* @access public
|
||||
*/
|
||||
var $sslCertPasswd;
|
||||
|
||||
/**
|
||||
* User Agent string when making an HTTP request
|
||||
*
|
||||
* @var string $userAgent
|
||||
* @access public
|
||||
*/
|
||||
var $userAgent;
|
||||
|
||||
/**
|
||||
* Whether or not to include the header in the results
|
||||
* of the CURL transfer
|
||||
*
|
||||
* @var boolean $header
|
||||
*/
|
||||
var $header = 0;
|
||||
|
||||
/**
|
||||
* Whether or not to output debug information while executing a
|
||||
* curl transfer
|
||||
*
|
||||
* @var boolean $verbose
|
||||
* @access public
|
||||
*/
|
||||
var $verbose = 0;
|
||||
|
||||
/**
|
||||
* Whether or not to display a progress meter for the current transfer
|
||||
*
|
||||
* @var boolean $progress
|
||||
* @access public
|
||||
*/
|
||||
var $progress = 0;
|
||||
|
||||
/**
|
||||
* Whether or not to suppress error messages
|
||||
*
|
||||
* @var boolean $mute
|
||||
* @access public
|
||||
*/
|
||||
var $mute = 1;
|
||||
|
||||
/**
|
||||
* Whether or not to follow HTTP Location headers.
|
||||
*
|
||||
* @var boolean $follow_location
|
||||
* @access public
|
||||
*/
|
||||
var $follow_location = 1;
|
||||
|
||||
/**
|
||||
* Time allowed for current transfer, in seconds. 0 means no limit
|
||||
*
|
||||
* @var int $timeout
|
||||
* @access public
|
||||
*/
|
||||
var $timeout = 0;
|
||||
|
||||
/**
|
||||
* Whether or not to return the results of the
|
||||
* current transfer
|
||||
*
|
||||
* @var boolean $return_transfer
|
||||
* @access public
|
||||
*/
|
||||
var $return_transfer = 1;
|
||||
|
||||
/**
|
||||
* The type of transfer to perform
|
||||
*
|
||||
* @var string $type
|
||||
* @access public
|
||||
*/
|
||||
var $type;
|
||||
|
||||
/**
|
||||
* The file to upload
|
||||
*
|
||||
* @var string $file
|
||||
* @access public
|
||||
*/
|
||||
var $file;
|
||||
|
||||
/**
|
||||
* The file size of the file pointed to by the $file
|
||||
* property
|
||||
*
|
||||
* @var integer $file_size
|
||||
* @access public
|
||||
*/
|
||||
var $file_size;
|
||||
|
||||
/**
|
||||
* The cookies to send to the remote site
|
||||
*
|
||||
* @var array $cookies
|
||||
* @access public
|
||||
*/
|
||||
var $cookies;
|
||||
|
||||
/**
|
||||
* The fields to send in a 'POST' request
|
||||
*
|
||||
* @var array $fields
|
||||
* @access public
|
||||
*/
|
||||
var $fields;
|
||||
|
||||
/**
|
||||
* The proxy server to go through
|
||||
*
|
||||
* @var string $proxy
|
||||
* @access public
|
||||
*/
|
||||
var $proxy;
|
||||
|
||||
/**
|
||||
* The username for the Proxy server
|
||||
*
|
||||
* @var string $proxyUser
|
||||
* @access public
|
||||
*/
|
||||
var $proxyUser;
|
||||
|
||||
/**
|
||||
* The password for the Proxy server
|
||||
*
|
||||
* @var string $proxyPassword
|
||||
* @access public
|
||||
*/
|
||||
var $proxyPassword;
|
||||
|
||||
// }}}
|
||||
// {{{ Private Properties
|
||||
|
||||
/**
|
||||
* The current curl handle
|
||||
*
|
||||
* @var resource $_ch
|
||||
* @access public
|
||||
*/
|
||||
var $_ch;
|
||||
|
||||
// }}}
|
||||
// {{{ Net_Curl()
|
||||
|
||||
/**
|
||||
* The Net_Curl constructor, called when a new Net_Curl object
|
||||
* is initialized
|
||||
*
|
||||
* @param string [$url] The URL to fetch (can be set
|
||||
* using the $url property as well)
|
||||
*
|
||||
* @return object Net_Curl $obj A new Net_Curl object
|
||||
*
|
||||
* @access public
|
||||
* @author Sterling Hughes <sterling@php.net>
|
||||
* @since PHP 4.0.5
|
||||
*/
|
||||
function Net_Curl($url = "")
|
||||
{
|
||||
if ($url) {
|
||||
$this->url = $url;
|
||||
}
|
||||
|
||||
$ch = curl_init();
|
||||
if (!$ch) {
|
||||
$this = new PEAR_Error("Couldn't initialize a new curl handle");
|
||||
}
|
||||
|
||||
$this->_ch = $ch;
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ execute()
|
||||
|
||||
/**
|
||||
* Executes a prepared CURL transfer
|
||||
*
|
||||
* @access public
|
||||
* @author Sterling Hughes <sterling@php.net>
|
||||
* @since PHP 4.0.5
|
||||
*/
|
||||
function execute()
|
||||
{
|
||||
$ch = &$this->_ch;
|
||||
$ret = true;
|
||||
|
||||
// Basic stuff
|
||||
|
||||
$ret = curl_setopt($ch, CURLOPT_URL, $this->url);
|
||||
$ret = curl_setopt($ch, CURLOPT_HEADER, $this->header);
|
||||
|
||||
// Whether or not to return the transfer contents
|
||||
if ($this->return_transfer && !isset($this->file)) {
|
||||
$ret = curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
|
||||
}
|
||||
|
||||
// SSL Checks
|
||||
|
||||
if (isset($this->sslVersion)) {
|
||||
$ret = curl_setopt($ch, CURLOPT_SSLVERSION, $this->sslVersion);
|
||||
}
|
||||
|
||||
if (isset($this->sslCert)) {
|
||||
$ret = curl_setopt($ch, CURLOPT_SSLCERT, $this->sslCert);
|
||||
}
|
||||
|
||||
if (isset($this->sslCertPasswd)) {
|
||||
$ret = curl_setopt($ch, CURLOPT_SSLCERTPASSWD, $this->sslCertPasswd);
|
||||
}
|
||||
|
||||
// Proxy Related checks
|
||||
|
||||
if (isset($this->proxy)) {
|
||||
$ret = curl_setopt($ch, CURLOPT_PROXY, $this->proxy);
|
||||
}
|
||||
|
||||
if (isset($this->proxyUser) || isset($this->proxyPassword)) {
|
||||
$proxyString = $this->proxyUser . ":" . $this->proxyPassword;
|
||||
|
||||
$ret = curl_setopt($ch, CURLOPT_PROXYUSERPWD, $proxyString);
|
||||
}
|
||||
|
||||
|
||||
// Transfer type
|
||||
|
||||
if (isset($this->type)) {
|
||||
switch (strtolower($this->type)) {
|
||||
case 'post':
|
||||
$ret = curl_setopt($ch, CURLOPT_POST, 1);
|
||||
break;
|
||||
case 'put':
|
||||
$ret = curl_setopt($ch, CURLOPT_PUT, 1);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Transfer upload, etc. related
|
||||
|
||||
if (isset($this->file)) {
|
||||
if (!isset($this->file_size)) {
|
||||
$this->file_size = filesize($this->file);
|
||||
}
|
||||
|
||||
$ret = curl_setopt($ch, CURLOPT_INFILE, $this->file);
|
||||
$ret = curl_setopt($ch, CURLOPT_INFILESIZE, $this->file_size);
|
||||
}
|
||||
|
||||
if (isset($this->fields)) {
|
||||
if (!isset($this->type)) {
|
||||
$this->type = 'post';
|
||||
$ret = curl_setopt($ch, CURLOPT_POST, 1);
|
||||
}
|
||||
|
||||
$ret = curl_setopt($ch, CURLOPT_POSTFIELDS, $this->fields);
|
||||
}
|
||||
|
||||
|
||||
// Error related
|
||||
|
||||
if ($this->progress) {
|
||||
$ret = curl_setopt($ch, CURLOPT_PROGRESS, 1);
|
||||
}
|
||||
|
||||
if ($this->verbose) {
|
||||
$ret = curl_setopt($ch, CURLOPT_VERBOSE, 1);
|
||||
}
|
||||
|
||||
if (!$this->mute) {
|
||||
$ret = curl_setopt($ch, CURLOPT_MUTE, 0);
|
||||
}
|
||||
|
||||
// Other stuff
|
||||
|
||||
$ret = curl_setopt($ch, CURLOPT_FOLLOWLOCATION, $this->follow_location);
|
||||
|
||||
if ($this->timeout) {
|
||||
$ret = curl_setopt($ch, CURLOPT_TIMEOUT, $this->timeout);
|
||||
}
|
||||
|
||||
if (isset($this->userAgent)) {
|
||||
$ret = curl_setopt($ch, CURLOPT_USERAGENT, $this->userAgent);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
// Cookies and the such
|
||||
|
||||
if (isset($this->cookies)) {
|
||||
foreach ($this->cookies as $name => $value) {
|
||||
$cookie_data .= urlencode($name) . ": " . urlencode($value) . ";";
|
||||
}
|
||||
|
||||
$ret = curl_setopt($ch, CURLOPT_COOKIE, $cookie_data);
|
||||
}
|
||||
|
||||
$ret = curl_exec($ch);
|
||||
if (!$ret) {
|
||||
$errObj = new PEAR_Error(curl_error($ch), curl_errno($ch));
|
||||
return($errObj);
|
||||
}
|
||||
|
||||
return($ret);
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ close()
|
||||
|
||||
/**
|
||||
* Closes the curl transfer and finishes the object (kinda ;)
|
||||
*
|
||||
* @access public
|
||||
* @author Sterling Hughes <sterling@php.net>
|
||||
* @since PHP 4.0.5
|
||||
*/
|
||||
function close()
|
||||
{
|
||||
if ($this->_ch) {
|
||||
curl_close($this->_ch);
|
||||
}
|
||||
}
|
||||
|
||||
// }}}
|
||||
}
|
||||
|
||||
// }}}
|
||||
|
||||
?>
|
||||
448
html/illt/Net/Dig.php
Normal file
448
html/illt/Net/Dig.php
Normal file
@@ -0,0 +1,448 @@
|
||||
<?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. |
|
||||
// +----------------------------------------------------------------------+
|
||||
// | Author: Colin Viebrock <colin@easyDNS.com> |
|
||||
// +----------------------------------------------------------------------+
|
||||
//
|
||||
// $Id: Dig.php,v 1.4 2002/02/28 08:27:15 sebastian Exp $
|
||||
//
|
||||
// A nice friendly OO interface to dig
|
||||
//
|
||||
require_once('PEAR.php');
|
||||
|
||||
class Net_Dig extends PEAR
|
||||
{
|
||||
// {{{ Public Properties
|
||||
|
||||
/**
|
||||
* The address to dig
|
||||
*
|
||||
* @var string $address
|
||||
* @access public
|
||||
*/
|
||||
var $address;
|
||||
|
||||
/**
|
||||
* The server to use for digging
|
||||
*
|
||||
* @var string $server
|
||||
* @access public
|
||||
*/
|
||||
var $server;
|
||||
|
||||
/**
|
||||
* The type of DNS records to dig for
|
||||
*
|
||||
* @var string $query_type
|
||||
* @access public
|
||||
*/
|
||||
var $query_type;
|
||||
|
||||
/**
|
||||
* The last system command executed (for debugging)
|
||||
*
|
||||
* @var string $cmd
|
||||
* @access public
|
||||
*/
|
||||
var $cmd;
|
||||
|
||||
/**
|
||||
* The raw output of the system command (for debugging)
|
||||
*
|
||||
* @var string $raw_data
|
||||
* @access public
|
||||
*/
|
||||
var $raw_data;
|
||||
|
||||
/**
|
||||
* The location of the system dig program
|
||||
*
|
||||
* @var string $dig_prg
|
||||
* @access public
|
||||
*/
|
||||
var $dig_prog;
|
||||
|
||||
/**
|
||||
* The parsed result of the last dig
|
||||
*
|
||||
* @var string $result
|
||||
* @access public
|
||||
*/
|
||||
var $result;
|
||||
|
||||
// }}}
|
||||
|
||||
|
||||
// {{{ Net_Dig()
|
||||
|
||||
/**
|
||||
* The Net_Dig constructor
|
||||
* Called when a new Net_Dig object is initialized
|
||||
*
|
||||
* @param string [$address] The address to dig (can be set
|
||||
* using the $address property as well)
|
||||
*
|
||||
* @param string [$server] The server to dig at (can be set
|
||||
* using the $server property as well)
|
||||
*
|
||||
* @return object Net_Dig $obj A new Net_Dig object
|
||||
*
|
||||
* @access public
|
||||
* @author Colin Viebrock <colin@easyDNS.com>
|
||||
* @since PHP 4.0.5
|
||||
*/
|
||||
function Net_Dig($address = false, $server = false )
|
||||
{
|
||||
|
||||
$this->address = $address;
|
||||
$this->server = $server;
|
||||
$this->query_type = false;
|
||||
|
||||
$this->cmd = '';
|
||||
$this->raw_data = '';
|
||||
|
||||
$this->result = false;
|
||||
|
||||
$this->dig_prog = trim(`which dig`);
|
||||
if (!$this->dig_prog) {
|
||||
$this = new PEAR_Error("Couldn't find system dig program");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// }}}
|
||||
|
||||
|
||||
|
||||
// {{{ dig()
|
||||
|
||||
/**
|
||||
* Does a dig of the given address (or $this->address)
|
||||
*
|
||||
* @param string [$address] The address to dig (can be set
|
||||
* using the $address property as well)
|
||||
*
|
||||
* @return object Net_Dig_result $obj A new Net_Dig_result object
|
||||
*
|
||||
* @access public
|
||||
* @author Colin Viebrock <colin@easyDNS.com>
|
||||
* @since PHP 4.0.5
|
||||
*/
|
||||
function dig($address=false)
|
||||
{
|
||||
|
||||
if ($address) {
|
||||
$this->address = $address;
|
||||
}
|
||||
|
||||
if (!$this->address) {
|
||||
return new PEAR_Error("No address specified");
|
||||
}
|
||||
|
||||
if (!$this->_validate_type()) {
|
||||
return new PEAR_Error($this->query_type." is an invalid query type");
|
||||
}
|
||||
|
||||
$cmd = escapeshellcmd(
|
||||
sprintf("%s %s %s %s",
|
||||
$this->dig_prog,
|
||||
($this->server ? '@'.$this->server : ''),
|
||||
$this->address,
|
||||
($this->query_type ? $this->query_type : '' )
|
||||
)
|
||||
);
|
||||
|
||||
$this->cmd = $cmd;
|
||||
|
||||
|
||||
$this->raw_data = `$cmd`;
|
||||
$this->raw_data = trim( $this->raw_data );
|
||||
|
||||
return $this->_parse_data();
|
||||
|
||||
}
|
||||
|
||||
// }}}
|
||||
|
||||
|
||||
// {{{ _validate_type()
|
||||
|
||||
/**
|
||||
* Validates the value of $this->query_type
|
||||
*
|
||||
* @return boolean $return True if $this->query_type is a
|
||||
* valid dig query, otherwise false
|
||||
*
|
||||
* @access private
|
||||
* @author Colin Viebrock <colin@easyDNS.com>
|
||||
* @since PHP 4.0.5
|
||||
*/
|
||||
function _validate_type()
|
||||
{
|
||||
$return = true;
|
||||
if ($this->query_type) {
|
||||
$this->query_type = strtolower($this->query_type);
|
||||
switch ($this->query_type) {
|
||||
case 'a':
|
||||
case 'any':
|
||||
case 'mx':
|
||||
case 'ns':
|
||||
case 'soa':
|
||||
case 'hinfo':
|
||||
case 'axfr':
|
||||
case 'txt':
|
||||
break;
|
||||
default:
|
||||
$return = false;
|
||||
}
|
||||
}
|
||||
return $return;
|
||||
}
|
||||
|
||||
// }}}
|
||||
|
||||
|
||||
|
||||
// {{{ _parse_data()
|
||||
|
||||
/**
|
||||
* Parses the raw data in $this->raw_data
|
||||
*
|
||||
* @return obj Net_Dig_result $return A Net_Dig_result object
|
||||
*
|
||||
* @access private
|
||||
* @author Colin Viebrock <colin@easyDNS.com>
|
||||
* @since PHP 4.0.5
|
||||
*/
|
||||
function _parse_data()
|
||||
{
|
||||
|
||||
if (!$this->raw_data) {
|
||||
return new PEAR_Error("No raw data to parse");
|
||||
}
|
||||
|
||||
$regex = '/' .
|
||||
'^;(.*?)' .
|
||||
';; QUESTION SECTION\:(.*?)' .
|
||||
'(;; ANSWER SECTION\:(.*?))?' .
|
||||
'(;; AUTHORITY SECTION\:(.*?))?' .
|
||||
'(;; ADDITIONAL SECTION\:(.*?))?' .
|
||||
'(;;.*)' .
|
||||
'/ims';
|
||||
|
||||
if (preg_match($regex, $this->raw_data, $matches)) {
|
||||
|
||||
$result = new Net_Dig_result;
|
||||
|
||||
/* Start parsing the data */
|
||||
|
||||
|
||||
/* the header ... */
|
||||
|
||||
|
||||
$temp = explode("\n", trim($matches[1]));
|
||||
if (preg_match('/DiG (.*?) /i', $temp[0], $m)) {
|
||||
$result->dig_version = trim($m[1]);
|
||||
}
|
||||
if (preg_match('/status: (.*?), id: (.*?)$/i', $temp[3], $m)) {
|
||||
$result->status = trim($m[1]);
|
||||
$result->id = trim($m[2]);
|
||||
}
|
||||
|
||||
if (preg_match('/flags: (.*?); query: (.*?), answer: (.*?), authority: (.*?), additional: (.*?)$/i', $temp[4], $m)) {
|
||||
$result->flags = trim($m[1]);
|
||||
$result->query_count = (int)trim($m[2]);
|
||||
$result->answer_count = (int)trim($m[3]);
|
||||
$result->authority_count = (int)trim($m[4]);
|
||||
$result->additional_count = (int)trim($m[5]);
|
||||
}
|
||||
|
||||
|
||||
/* query section */
|
||||
|
||||
$line = trim(preg_replace('/^(;*)/', '', trim($matches[2])));
|
||||
list($host, $class, $type) = preg_split('/[\s]+/', $line, 3);
|
||||
$result->query[] = new Net_Dig_resource($host, false, $class, $type, false);
|
||||
|
||||
|
||||
/* answer section */
|
||||
|
||||
$temp = trim($matches[4]);
|
||||
if ($temp) {
|
||||
$temp = explode("\n", $temp);
|
||||
if (count($temp)) {
|
||||
foreach($temp as $line) {
|
||||
$result->answer[] = $this->_parse_resource($line);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* authority section */
|
||||
|
||||
$temp = trim($matches[6]);
|
||||
if ($temp) {
|
||||
$temp = explode("\n", $temp);
|
||||
if (count($temp)) {
|
||||
foreach($temp as $line) {
|
||||
$result->authority[] = $this->_parse_resource($line);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* additional section */
|
||||
|
||||
$temp = trim($matches[8]);
|
||||
if ($temp) {
|
||||
$temp = explode("\n", $temp);
|
||||
if (count($temp)) {
|
||||
foreach($temp as $line) {
|
||||
$result->additional[] = $this->_parse_resource($line);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* footer */
|
||||
|
||||
$temp = explode("\n", trim($matches[9]));
|
||||
if (preg_match('/query time: (.*?)$/i', $temp[0], $m)) {
|
||||
$result->query_time = trim($m[1]);
|
||||
}
|
||||
if (preg_match('/server: (.*?)#(.*?)\(/i', $temp[1], $m)) {
|
||||
$result->dig_server = trim($m[1]);
|
||||
$result->dig_port = trim($m[2]);
|
||||
}
|
||||
|
||||
/* done */
|
||||
|
||||
$result->consistency_check = (
|
||||
(count($result->query) == $result->query_count) &&
|
||||
(count($result->answer) == $result->answer_count) &&
|
||||
(count($result->authority) == $result->authority_count) &&
|
||||
(count($result->additional) == $result->additional_count)
|
||||
);
|
||||
|
||||
return $result;
|
||||
|
||||
}
|
||||
|
||||
return new PEAR_Error("Can't parse raw data");
|
||||
}
|
||||
|
||||
// }}}
|
||||
|
||||
|
||||
// {{{ _parse_resource()
|
||||
|
||||
/**
|
||||
* Parses a resource record line
|
||||
*
|
||||
* @param string $line The line to parse
|
||||
*
|
||||
* @return obj Net_Dig_resource $return A Net_Dig_resource object
|
||||
*
|
||||
* @access private
|
||||
* @author Colin Viebrock <colin@easyDNS.com>
|
||||
* @since PHP 4.0.5
|
||||
*/
|
||||
function _parse_resource($line)
|
||||
{
|
||||
|
||||
/* trim and remove leading ;, if present */
|
||||
|
||||
$line = trim(preg_replace('/^(;*)/', '', trim($line)));
|
||||
|
||||
if ($line) {
|
||||
list($host, $ttl, $class, $type, $data) = preg_split('/[\s]+/', $line, 5);
|
||||
return new Net_Dig_resource($host, $ttl, $class, $type, $data);
|
||||
}
|
||||
|
||||
return false;
|
||||
|
||||
}
|
||||
|
||||
// }}}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
class Net_Dig_result {
|
||||
|
||||
// {{{ Public Properties
|
||||
|
||||
var $status;
|
||||
var $id;
|
||||
var $flags;
|
||||
var $query_count;
|
||||
var $answer_count;
|
||||
var $authority_count;
|
||||
var $additional_count;
|
||||
|
||||
var $dig_version;
|
||||
var $dig_server;
|
||||
var $dig_port;
|
||||
|
||||
var $query;
|
||||
var $answer;
|
||||
var $authority;
|
||||
var $additional;
|
||||
|
||||
var $consistency_check;
|
||||
|
||||
function Net_Dig_result() {
|
||||
$this->status = false;
|
||||
$this->id = false;
|
||||
$this->flags = false;
|
||||
$this->query_count = false;
|
||||
$this->answer_count = false;
|
||||
$this->authority_count = false;
|
||||
$this->additional_count = false;
|
||||
|
||||
$this->dig_version = false;
|
||||
$this->dig_server = false;
|
||||
$this->dig_port = false;
|
||||
|
||||
$this->query = array();
|
||||
$this->answer = array();
|
||||
$this->authority = array();
|
||||
$this->additional = array();
|
||||
|
||||
$this->consistency_check = false;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
class Net_Dig_resource {
|
||||
|
||||
var $host;
|
||||
var $ttl;
|
||||
var $class;
|
||||
var $type;
|
||||
var $data;
|
||||
|
||||
function Net_Dig_resource($host=false, $ttl=false, $class=false, $type=false, $data=false) {
|
||||
$this->host = $host;
|
||||
$this->ttl = $ttl;
|
||||
$this->class = $class;
|
||||
$this->type = $type;
|
||||
$this->data = $data;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
?>
|
||||
400
html/illt/Net/SMTP.php
Normal file
400
html/illt/Net/SMTP.php
Normal file
@@ -0,0 +1,400 @@
|
||||
<?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. |
|
||||
// +----------------------------------------------------------------------+
|
||||
// | Author: Chuck Hagenbuch <chuck@horde.org> |
|
||||
// +----------------------------------------------------------------------+
|
||||
|
||||
require_once 'PEAR.php';
|
||||
|
||||
/**
|
||||
* Provides an implementation of the SMTP protocol using PEAR's
|
||||
* Net_Socket:: class.
|
||||
*/
|
||||
class Net_SMTP extends PEAR {
|
||||
|
||||
/**
|
||||
* The server to connect to.
|
||||
* @var string
|
||||
*/
|
||||
var $host = 'localhost';
|
||||
|
||||
/**
|
||||
* The port to connect to.
|
||||
* @var int
|
||||
*/
|
||||
var $port = 25;
|
||||
|
||||
/**
|
||||
* The value to give when sending EHLO or HELO.
|
||||
* @var string
|
||||
*/
|
||||
var $localhost = 'localhost';
|
||||
|
||||
/**
|
||||
* The socket resource being used to connect to the SMTP server.
|
||||
* @var resource
|
||||
*/
|
||||
var $socket;
|
||||
|
||||
/**
|
||||
* The most recent reply code
|
||||
* @var int
|
||||
*/
|
||||
var $code;
|
||||
|
||||
/**
|
||||
* Stores detected features of the SMTP server.
|
||||
* @var array
|
||||
*/
|
||||
var $esmtp;
|
||||
|
||||
/**
|
||||
* The last line read from the server.
|
||||
* @var string
|
||||
*/
|
||||
var $lastline;
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
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;
|
||||
}
|
||||
|
||||
/**
|
||||
* Attempt to connect to the SMTP server.
|
||||
*
|
||||
* @return mixed Returns a PEAR_Error with an error message on any
|
||||
* kind of failure, or true on success.
|
||||
* @access public
|
||||
*/
|
||||
function connect() {
|
||||
include_once 'Net/Socket.php';
|
||||
|
||||
if (PEAR::isError($this->socket = new Net_Socket())) { return new PEAR_Error('unable to create a socket object'); }
|
||||
if (PEAR::isError($this->socket->connect($this->host, $this->port))) { return new PEAR_Error('unable to open socket'); }
|
||||
|
||||
if (PEAR::isError($this->validateResponse('220'))) { return new PEAR_Error('smtp server not 220 ready'); }
|
||||
if (!$this->identifySender()) { return new PEAR_Error('unable to identify smtp server'); }
|
||||
|
||||
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
|
||||
*/
|
||||
function disconnect() {
|
||||
if (PEAR::isError($this->socket->write("QUIT\r\n"))) { return new PEAR_Error('write to socket failed'); }
|
||||
if (!$this->validateResponse('221')) { return new PEAR_Error('221 Bye not received'); }
|
||||
if (PEAR::isError($this->socket->disconnect())) { return new PEAR_Error('socket disconnect failed'); }
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Attempt to do SMTP authentication.
|
||||
*
|
||||
* @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 public
|
||||
*/
|
||||
function auth($uid, $pwd) {
|
||||
/* Note: not currently checking if AUTH LOGIN is allowed */
|
||||
/* Note: only allows one authentication mechanism */
|
||||
|
||||
if (!isset($this->esmtp['AUTH'])) { return new PEAR_Error('auth not supported'); }
|
||||
|
||||
if (PEAR::isError($this->socket->write("AUTH LOGIN\r\n"))) { return new PEAR_Error('write to socket failed'); }
|
||||
if (!$this->validateResponse('334')) { return new PEAR_Error('AUTH LOGIN not recognized'); }
|
||||
|
||||
if (PEAR::isError($this->socket->write(base64_encode($uid) . "\n"))) { return new PEAR_Error('write to socket failed'); }
|
||||
if (!$this->validateResponse('334')) { return new PEAR_Error('354 not received'); }
|
||||
|
||||
if (PEAR::isError($this->socket->write(base64_encode($pwd) . "\n"))) { return new PEAR_Error('write to socket failed'); }
|
||||
if (!$this->validateResponse('235')) { return new PEAR_Error('235 not received'); }
|
||||
|
||||
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
|
||||
*/
|
||||
function helo($domain) {
|
||||
if (PEAR::isError($this->socket->write("HELO $domain\r\n"))) { return new PEAR_Error('write to socket failed'); }
|
||||
if (!($this->validateResponse('250'))) { return new PEAR_Error('250 OK not received'); }
|
||||
|
||||
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
|
||||
*/
|
||||
function mailFrom($reverse_path) {
|
||||
if (PEAR::isError($this->socket->write("MAIL FROM:<$reverse_path>\r\n"))) { return new PEAR_Error('write to socket failed'); }
|
||||
if (!($this->validateResponse('250'))) { return new PEAR_Error('250 OK not received'); }
|
||||
|
||||
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
|
||||
*/
|
||||
function rcptTo($forward_path) {
|
||||
/* Note: 251 is also a valid response code */
|
||||
|
||||
if (PEAR::isError($this->socket->write("RCPT TO: <$forward_path>\r\n"))) { return new PEAR_Error('write to socket failed'); }
|
||||
if (!($this->validateResponse('250'))) { return new PEAR_Error($this->lastline); }
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* 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
|
||||
*/
|
||||
function data($data) {
|
||||
$data = preg_replace("/([^\r]{1})\n/", "\\1\r\n", $data);
|
||||
$data = preg_replace("/\n\n/", "\n\r\n", $data);
|
||||
$data = preg_replace("/\n\./", "\n..", $data);
|
||||
|
||||
if (PEAR::isError($this->socket->write("DATA\r\n"))) { return new PEAR_Error('write to socket failed'); }
|
||||
if (!($this->validateResponse('354'))) { return new PEAR_Error('354 not received'); }
|
||||
if (PEAR::isError($this->socket->write($data . "\r\n.\r\n"))) { return new PEAR_Error('write to socket failed'); }
|
||||
if (!($this->validateResponse('250'))) { return new PEAR_Error('250 OK not received'); }
|
||||
|
||||
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
|
||||
*/
|
||||
function send_from($reverse_path) {
|
||||
if (PEAR::isError($this->socket->write("SEND FROM:<$reverse_path>\r\n"))) { return new PEAR_Error('write to socket failed'); }
|
||||
if (!($this->validateResponse('250'))) { return new PEAR_Error('250 OK not received'); }
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* 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
|
||||
*/
|
||||
function soml_from($reverse_path) {
|
||||
if (PEAR::isError($this->socket->write("SOML FROM:<$reverse_path>\r\n"))) { return new PEAR_Error('write to socket failed'); }
|
||||
if (!($this->validateResponse('250'))) { return new PEAR_Error('250 OK not received'); }
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* 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
|
||||
*/
|
||||
function saml_from($reverse_path) {
|
||||
if (PEAR::isError($this->socket->write("SAML FROM:<$reverse_path>\r\n"))) { return new PEAR_Error('write to socket failed'); }
|
||||
if (!($this->validateResponse('250'))) { return new PEAR_Error('250 OK not received'); }
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* 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
|
||||
*/
|
||||
function rset() {
|
||||
if (PEAR::isError($this->socket->write("RSET\r\n"))) { return new PEAR_Error('write to socket failed'); }
|
||||
if (!($this->validateResponse('250'))) { return new PEAR_Error('250 OK not received'); }
|
||||
|
||||
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
|
||||
*/
|
||||
function vrfy($string) {
|
||||
/* Note: 251 is also a valid response code */
|
||||
if (PEAR::isError($this->socket->write("VRFY $string\r\n"))) { return new PEAR_Error('write to socket failed'); }
|
||||
if (!($this->validateResponse('250'))) { return new PEAR_Error('250 OK not received'); }
|
||||
|
||||
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
|
||||
*/
|
||||
function noop() {
|
||||
if (PEAR::isError($this->socket->write("NOOP\r\n"))) { return new PEAR_Error('write to socket failed'); }
|
||||
if (!($this->validateResponse('250'))) { return new PEAR_Error('250 OK not received'); }
|
||||
|
||||
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
|
||||
*/
|
||||
function identifySender() {
|
||||
if (PEAR::isError($this->socket->write("EHLO $this->localhost\r\n"))) { return new PEAR_Error('write to socket failed'); }
|
||||
|
||||
$extensions = array();
|
||||
if (!($this->validateAndParseResponse('250', $extensions))) {
|
||||
if (PEAR::isError($this->socket->write("HELO $this->localhost\r\n"))) { return new PEAR_Error('write to socket failed'); }
|
||||
if (!($this->validateResponse('250'))) { return new PEAR_Error('HELO not accepted', $this->code); }
|
||||
return true;
|
||||
}
|
||||
|
||||
for ($i = 0; $i < count($extensions); $i++) {
|
||||
$verb = strtok($extensions[$i], ' ');
|
||||
$arguments = substr($extensions[$i], strlen($verb) + 1, strlen($extensions[$i]) - strlen($verb) - 2);
|
||||
$this->esmtp[$verb] = $arguments;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Read a response from the server and see if the response code
|
||||
* matches what we are expecting.
|
||||
*
|
||||
* @param int The response code we are expecting.
|
||||
*
|
||||
* @return boolean True if we get what we expect, false otherwise.
|
||||
* @access private
|
||||
*/
|
||||
function validateResponse($code) {
|
||||
while ($this->lastline = $this->socket->readLine()) {
|
||||
$reply_code = strtok($this->lastline, ' ');
|
||||
if (!(strcmp($code, $reply_code))) {
|
||||
$this->code = $reply_code;
|
||||
return true;
|
||||
} else {
|
||||
$reply_code = strtok($this->lastline, '-');
|
||||
if (strcmp($code, $reply_code)) {
|
||||
$this->code = $reply_code;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Read a response from the server and see if the response code
|
||||
* matches what we are expecting. Also save the rest of the
|
||||
* response in the array passed by reference as the second
|
||||
* argument.
|
||||
*
|
||||
* @param int The response code we are expecting.
|
||||
* @param array An array to dump the rest of the response into.
|
||||
*
|
||||
* @return boolean True if we get what we expect, false otherwise.
|
||||
* @access private
|
||||
*/
|
||||
function validateAndParseResponse($code, &$arguments) {
|
||||
$arguments = array();
|
||||
|
||||
while ($this->lastline = $this->socket->readLine()) {
|
||||
$reply_code = strtok($this->lastline, ' ');
|
||||
if (!(strcmp($code, $reply_code))) {
|
||||
$arguments[] = substr($this->lastline, strlen($code) + 1, strlen($this->lastline) - strlen($code) - 1);
|
||||
$this->code = $reply_code;
|
||||
return true;
|
||||
} else {
|
||||
$reply_code = strtok($this->lastline, '-');
|
||||
if (strcmp($code, $reply_code)) {
|
||||
$this->code = $reply_code;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
$arguments[] = substr($this->lastline, strlen($code) + 1, strlen($this->lastline) - strlen($code) - 1);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
||||
?>
|
||||
456
html/illt/Net/Socket.php
Normal file
456
html/illt/Net/Socket.php
Normal file
@@ -0,0 +1,456 @@
|
||||
<?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.9 2004/04/26 23:02:41 chagenbu Exp $
|
||||
//
|
||||
|
||||
require_once 'PEAR.php';
|
||||
|
||||
/**
|
||||
* Generalized Socket class. More docs to be written.
|
||||
*
|
||||
* @version 1.0
|
||||
* @author Stig Bakken <ssb@php.net>
|
||||
* @author Chuck Hagenbuch <chuck@horde.org>
|
||||
*/
|
||||
class Net_Socket extends PEAR {
|
||||
// {{{ properties
|
||||
|
||||
/** Socket file pointer. */
|
||||
var $fp = null;
|
||||
|
||||
/** Whether the socket is blocking. */
|
||||
var $blocking = true;
|
||||
|
||||
/** Whether the socket is persistent. */
|
||||
var $persistent = false;
|
||||
|
||||
/** The IP address to connect to. */
|
||||
var $addr = '';
|
||||
|
||||
/** The port number to connect to. */
|
||||
var $port = 0;
|
||||
|
||||
/** Number of seconds to wait on socket connections before
|
||||
assuming there's no more data. */
|
||||
var $timeout = false;
|
||||
|
||||
/** Number of bytes to read at a time in readLine() and
|
||||
readAll(). */
|
||||
var $lineLength = 2048;
|
||||
// }}}
|
||||
|
||||
// {{{ constructor
|
||||
/**
|
||||
* Constructs a new Net_Socket object.
|
||||
*
|
||||
* @access public
|
||||
*/
|
||||
function Net_Socket()
|
||||
{
|
||||
$this->PEAR();
|
||||
}
|
||||
// }}}
|
||||
|
||||
// {{{ connect()
|
||||
/**
|
||||
* Connect to the specified port. If called when the socket is
|
||||
* already connected, it disconnects and connects again.
|
||||
*
|
||||
* @param $addr string IP address or host name
|
||||
* @param $port int TCP port number
|
||||
* @param $persistent bool (optional) whether the connection is
|
||||
* persistent (kept open between requests by the web server)
|
||||
* @param $timeout int (optional) how long to wait for data
|
||||
* @param $options array see options for stream_context_create
|
||||
* @access public
|
||||
* @return mixed true on success or error object
|
||||
*/
|
||||
function connect($addr, $port, $persistent = null, $timeout = null, $options = null)
|
||||
{
|
||||
if (is_resource($this->fp)) {
|
||||
@fclose($this->fp);
|
||||
$this->fp = null;
|
||||
}
|
||||
|
||||
if (strspn($addr, '.0123456789') == strlen($addr)) {
|
||||
$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);
|
||||
}
|
||||
// }}}
|
||||
|
||||
// {{{ disconnect()
|
||||
/**
|
||||
* 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)) {
|
||||
fclose($this->fp);
|
||||
$this->fp = null;
|
||||
return true;
|
||||
}
|
||||
return $this->raiseError("not connected");
|
||||
}
|
||||
// }}}
|
||||
|
||||
// {{{ isBlocking()
|
||||
/**
|
||||
* Find out if the socket is in blocking mode.
|
||||
*
|
||||
* @access public
|
||||
* @return bool the current blocking mode.
|
||||
*/
|
||||
function isBlocking()
|
||||
{
|
||||
return $this->blocking;
|
||||
}
|
||||
// }}}
|
||||
|
||||
// {{{ setBlocking()
|
||||
/**
|
||||
* 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 $mode bool 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)) {
|
||||
$this->blocking = $mode;
|
||||
socket_set_blocking($this->fp, $this->blocking);
|
||||
return true;
|
||||
}
|
||||
return $this->raiseError("not connected");
|
||||
}
|
||||
// }}}
|
||||
|
||||
// {{{ setTimeout()
|
||||
/**
|
||||
* Sets the timeout value on socket descriptor,
|
||||
* expressed in the sum of seconds and microseconds
|
||||
*
|
||||
* @param $seconds int seconds
|
||||
* @param $microseconds int microseconds
|
||||
* @access public
|
||||
* @return mixed true on success or an error object otherwise
|
||||
*/
|
||||
function setTimeout($seconds, $microseconds)
|
||||
{
|
||||
if (is_resource($this->fp)) {
|
||||
socket_set_timeout($this->fp, $seconds, $microseconds);
|
||||
return true;
|
||||
}
|
||||
return $this->raiseError("not connected");
|
||||
}
|
||||
// }}}
|
||||
|
||||
// {{{ getStatus()
|
||||
/**
|
||||
* 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 socket_get_status($this->fp);
|
||||
}
|
||||
return $this->raiseError("not connected");
|
||||
}
|
||||
// }}}
|
||||
|
||||
// {{{ gets()
|
||||
/**
|
||||
* 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 fgets($this->fp, $size);
|
||||
}
|
||||
return $this->raiseError("not connected");
|
||||
}
|
||||
// }}}
|
||||
|
||||
// {{{ read()
|
||||
/**
|
||||
* 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 $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 fread($this->fp, $size);
|
||||
}
|
||||
return $this->raiseError("not connected");
|
||||
}
|
||||
// }}}
|
||||
|
||||
// {{{ write()
|
||||
/**
|
||||
* Write a specified amount of data.
|
||||
*
|
||||
* @access public
|
||||
* @return mixed true on success or an error object otherwise
|
||||
*/
|
||||
function write($data)
|
||||
{
|
||||
if (is_resource($this->fp)) {
|
||||
return fwrite($this->fp, $data);
|
||||
}
|
||||
return $this->raiseError("not connected");
|
||||
}
|
||||
// }}}
|
||||
|
||||
// {{{ writeLine()
|
||||
/**
|
||||
* 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->write($data . "\r\n");
|
||||
}
|
||||
return $this->raiseError("not connected");
|
||||
}
|
||||
// }}}
|
||||
|
||||
// {{{ eof()
|
||||
/**
|
||||
* Tests for end-of-file on a socket descriptor
|
||||
*
|
||||
* @access public
|
||||
* @return bool
|
||||
*/
|
||||
function eof()
|
||||
{
|
||||
return (is_resource($this->fp) && feof($this->fp));
|
||||
}
|
||||
// }}}
|
||||
|
||||
// {{{ readByte()
|
||||
/**
|
||||
* 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 ord($this->read(1));
|
||||
}
|
||||
return $this->raiseError("not connected");
|
||||
}
|
||||
// }}}
|
||||
|
||||
// {{{ readWord()
|
||||
/**
|
||||
* 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)) {
|
||||
$buf = $this->read(2);
|
||||
return (ord($buf[0]) + (ord($buf[1]) << 8));
|
||||
}
|
||||
return $this->raiseError("not connected");
|
||||
}
|
||||
// }}}
|
||||
|
||||
// {{{ readInt()
|
||||
/**
|
||||
* Reads an int of data
|
||||
*
|
||||
* @access public
|
||||
* @return 1 int of data from the socket, or a PEAR_Error if
|
||||
* not connected.
|
||||
*/
|
||||
function readInt()
|
||||
{
|
||||
if (is_resource($this->fp)) {
|
||||
$buf = $this->read(4);
|
||||
return (ord($buf[0]) + (ord($buf[1]) << 8) +
|
||||
(ord($buf[2]) << 16) + (ord($buf[3]) << 24));
|
||||
}
|
||||
return $this->raiseError("not connected");
|
||||
}
|
||||
// }}}
|
||||
|
||||
// {{{ readString()
|
||||
/**
|
||||
* Reads a zeroterminated string of data
|
||||
*
|
||||
* @access public
|
||||
* @return string, or a PEAR_Error if
|
||||
* not connected.
|
||||
*/
|
||||
function readString()
|
||||
{
|
||||
if (is_resource($this->fp)) {
|
||||
$string = '';
|
||||
while (($char = $this->read(1)) != "\x00") {
|
||||
$string .= $char;
|
||||
}
|
||||
return $string;
|
||||
}
|
||||
return $this->raiseError("not connected");
|
||||
}
|
||||
// }}}
|
||||
|
||||
// {{{ readIPAddress()
|
||||
/**
|
||||
* 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)) {
|
||||
$buf = $this->read(4);
|
||||
return sprintf("%s.%s.%s.%s", ord($buf[0]), ord($buf[1]),
|
||||
ord($buf[2]), ord($buf[3]));
|
||||
}
|
||||
return $this->raiseError("not connected");
|
||||
}
|
||||
// }}}
|
||||
|
||||
// {{{ readLine()
|
||||
/**
|
||||
* 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)) {
|
||||
$line = '';
|
||||
$timeout = time() + $this->timeout;
|
||||
while (!$this->eof() && (!$this->timeout || time() < $timeout)) {
|
||||
$line .= $this->gets($this->lineLength);
|
||||
if (substr($line, -2) == "\r\n" ||
|
||||
substr($line, -1) == "\n") {
|
||||
return rtrim($line, "\r\n");
|
||||
}
|
||||
}
|
||||
return $line;
|
||||
}
|
||||
return $this->raiseError("not connected");
|
||||
}
|
||||
// }}}
|
||||
|
||||
// {{{ readAll()
|
||||
/**
|
||||
* Read until the socket closes. THIS FUNCTION WILL NOT EXIT if the
|
||||
* socket is in blocking mode until the socket closes.
|
||||
*
|
||||
* @access public
|
||||
* @return All data until the socket closes, or a PEAR_Error if
|
||||
* not connected.
|
||||
*/
|
||||
function readAll()
|
||||
{
|
||||
if (is_resource($this->fp)) {
|
||||
$data = '';
|
||||
while (!$this->eof())
|
||||
$data .= $this->read($this->lineLength);
|
||||
return $data;
|
||||
}
|
||||
return $this->raiseError("not connected");
|
||||
}
|
||||
// }}}
|
||||
|
||||
}
|
||||
793
html/illt/PEAR.php
Normal file
793
html/illt/PEAR.php
Normal file
@@ -0,0 +1,793 @@
|
||||
<?php
|
||||
//
|
||||
// +----------------------------------------------------------------------+
|
||||
// | PHP Version 4 |
|
||||
// +----------------------------------------------------------------------+
|
||||
// | Copyright (c) 1997-2002 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: Sterling Hughes <sterling@php.net> |
|
||||
// | Stig Bakken <ssb@fast.no> |
|
||||
// | Tomas V.V.Cox <cox@idecnet.com> |
|
||||
// +----------------------------------------------------------------------+
|
||||
//
|
||||
// $Id: PEAR.php,v 1.32.2.2 2002/04/09 19:04:07 ssb 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);
|
||||
|
||||
if (substr(PHP_OS, 0, 3) == 'WIN') {
|
||||
define('OS_WINDOWS', true);
|
||||
define('OS_UNIX', false);
|
||||
define('PEAR_OS', 'Windows');
|
||||
} else {
|
||||
define('OS_WINDOWS', false);
|
||||
define('OS_UNIX', true);
|
||||
define('PEAR_OS', 'Unix'); // blatant assumption
|
||||
}
|
||||
|
||||
$GLOBALS['_PEAR_default_error_mode'] = PEAR_ERROR_RETURN;
|
||||
$GLOBALS['_PEAR_default_error_options'] = E_USER_NOTICE;
|
||||
$GLOBALS['_PEAR_default_error_callback'] = '';
|
||||
$GLOBALS['_PEAR_destructor_object_list'] = array();
|
||||
|
||||
//
|
||||
// Tests needed: - PEAR inheritance
|
||||
//
|
||||
|
||||
/**
|
||||
* 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.
|
||||
*
|
||||
* @since PHP 4.0.2
|
||||
* @author Stig Bakken <ssb@fast.no>
|
||||
*/
|
||||
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 (optional) which class to use for error objects,
|
||||
* defaults to PEAR_Error.
|
||||
* @access public
|
||||
* @return void
|
||||
*/
|
||||
function PEAR($error_class = null)
|
||||
{
|
||||
$classname = get_class($this);
|
||||
if ($this->_debug) {
|
||||
print "PEAR constructor called, class=$classname\n";
|
||||
}
|
||||
if ($error_class !== null) {
|
||||
$this->_error_class = $error_class;
|
||||
}
|
||||
while ($classname) {
|
||||
$destructor = "_$classname";
|
||||
if (method_exists($this, $destructor)) {
|
||||
global $_PEAR_destructor_object_list;
|
||||
$_PEAR_destructor_object_list[] = &$this;
|
||||
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", get_class($this));
|
||||
}
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ isError()
|
||||
|
||||
/**
|
||||
* Tell whether a value is a PEAR error.
|
||||
*
|
||||
* @param mixed the value to test
|
||||
* @access public
|
||||
* @return bool true if parameter is an error
|
||||
*/
|
||||
function isError($data) {
|
||||
return (bool)(is_object($data) &&
|
||||
(get_class($data) == 'pear_error' ||
|
||||
is_subclass_of($data, 'pear_error')));
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ setErrorHandling()
|
||||
|
||||
/**
|
||||
* Sets how errors generated by this DB 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 or
|
||||
* PEAR_ERROR_CALLBACK.
|
||||
*
|
||||
* @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
|
||||
*
|
||||
* @since PHP 4.0.5
|
||||
*/
|
||||
|
||||
function setErrorHandling($mode = null, $options = null)
|
||||
{
|
||||
if (isset($this)) {
|
||||
$setmode = &$this->_default_error_mode;
|
||||
$setoptions = &$this->_default_error_options;
|
||||
//$setcallback = &$this->_default_error_callback;
|
||||
} else {
|
||||
$setmode = &$GLOBALS['_PEAR_default_error_mode'];
|
||||
$setoptions = &$GLOBALS['_PEAR_default_error_options'];
|
||||
//$setcallback = &$GLOBALS['_PEAR_default_error_callback'];
|
||||
}
|
||||
|
||||
switch ($mode) {
|
||||
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;
|
||||
if ((is_string($options) && function_exists($options)) ||
|
||||
(is_array($options) && method_exists(@$options[0], @$options[1])))
|
||||
{
|
||||
$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.
|
||||
*
|
||||
* @param mixed a single error code or an array of error codes
|
||||
* to expect
|
||||
*
|
||||
* @return int the new depth of the "expected errors" stack
|
||||
*/
|
||||
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);
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ 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 $message a text error message or a PEAR error object
|
||||
*
|
||||
* @param $code a numeric error code (it is up to your class
|
||||
* to define these if you want to use codes)
|
||||
*
|
||||
* @param $mode One of PEAR_ERROR_RETURN, PEAR_ERROR_PRINT,
|
||||
* PEAR_ERROR_TRIGGER, PEAR_ERROR_DIE or
|
||||
* PEAR_ERROR_CALLBACK.
|
||||
*
|
||||
* @param $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 $userinfo If you need to pass along for example debug
|
||||
* information, this parameter is meant for that.
|
||||
*
|
||||
* @param $error_class The returned error object will be instantiated
|
||||
* from this class, if specified.
|
||||
*
|
||||
* @param $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 = $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;
|
||||
}
|
||||
}
|
||||
|
||||
if ($mode === null) {
|
||||
if (isset($this) && isset($this->_default_error_mode)) {
|
||||
$mode = $this->_default_error_mode;
|
||||
} else {
|
||||
$mode = $GLOBALS['_PEAR_default_error_mode'];
|
||||
}
|
||||
}
|
||||
|
||||
if ($mode == PEAR_ERROR_TRIGGER && $options === null) {
|
||||
if (isset($this)) {
|
||||
if (isset($this->_default_error_options)) {
|
||||
$options = $this->_default_error_options;
|
||||
}
|
||||
} else {
|
||||
$options = $GLOBALS['_PEAR_default_error_options'];
|
||||
}
|
||||
}
|
||||
|
||||
if ($mode == PEAR_ERROR_CALLBACK) {
|
||||
if (!is_string($options) &&
|
||||
!(is_array($options) && sizeof($options) == 2 &&
|
||||
is_object($options[0]) && is_string($options[1])))
|
||||
{
|
||||
if (isset($this) && isset($this->_default_error_options)) {
|
||||
$options = $this->_default_error_options;
|
||||
} else {
|
||||
$options = $GLOBALS['_PEAR_default_error_options'];
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if ($options === null) {
|
||||
if (isset($this)) {
|
||||
if (isset($this->_default_error_options)) {
|
||||
$options = $this->_default_error_options;
|
||||
}
|
||||
} else {
|
||||
$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);
|
||||
}
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ 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 $mode mixed (same as setErrorHandling)
|
||||
* @param $options mixed (same as setErrorHandling)
|
||||
*
|
||||
* @return bool Always true
|
||||
*
|
||||
* @see PEAR::setErrorHandling
|
||||
*/
|
||||
function pushErrorHandling($mode, $options = null)
|
||||
{
|
||||
$stack = &$GLOBALS['_PEAR_error_handler_stack'];
|
||||
if (!is_array($stack)) {
|
||||
if (isset($this)) {
|
||||
$def_mode = &$this->_default_error_mode;
|
||||
$def_options = &$this->_default_error_options;
|
||||
// XXX Used anywhere?
|
||||
//$def_callback = &$this->_default_error_callback;
|
||||
} else {
|
||||
$def_mode = &$GLOBALS['_PEAR_default_error_mode'];
|
||||
$def_options = &$GLOBALS['_PEAR_default_error_options'];
|
||||
// XXX Used anywhere?
|
||||
//$def_callback = &$GLOBALS['_PEAR_default_error_callback'];
|
||||
}
|
||||
$stack = array();
|
||||
$stack[] = array($def_mode, $def_options);
|
||||
}
|
||||
|
||||
if (isset($this)) {
|
||||
$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];
|
||||
if (isset($this)) {
|
||||
$this->setErrorHandling($mode, $options);
|
||||
} else {
|
||||
PEAR::setErrorHandling($mode, $options);
|
||||
}
|
||||
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);
|
||||
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();
|
||||
}
|
||||
}
|
||||
|
||||
// }}}
|
||||
|
||||
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 = '';
|
||||
|
||||
// Wait until we have a stack-groping function in PHP.
|
||||
//var $file = '';
|
||||
//var $line = 0;
|
||||
|
||||
|
||||
// }}}
|
||||
// {{{ constructor
|
||||
|
||||
/**
|
||||
* PEAR_Error constructor
|
||||
*
|
||||
* @param $message error message
|
||||
*
|
||||
* @param $code (optional) error code
|
||||
*
|
||||
* @param $mode (optional) error mode, one of: PEAR_ERROR_RETURN,
|
||||
* PEAR_ERROR_PRINT, PEAR_ERROR_DIE, PEAR_ERROR_TRIGGER or
|
||||
* PEAR_ERROR_CALLBACK
|
||||
*
|
||||
* @param $level (optional) error level, _OR_ in the case of
|
||||
* PEAR_ERROR_CALLBACK, the callback function or object/method
|
||||
* tuple.
|
||||
*
|
||||
* @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 ($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_string($this->callback) && strlen($this->callback)) {
|
||||
call_user_func($this->callback, $this);
|
||||
} elseif (is_array($this->callback) &&
|
||||
sizeof($this->callback) == 2 &&
|
||||
is_object($this->callback[0]) &&
|
||||
is_string($this->callback[1]) &&
|
||||
strlen($this->callback[1])) {
|
||||
@call_user_method($this->callback[1], $this->callback[0],
|
||||
$this);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ 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();
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ 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 = get_class($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"]',
|
||||
get_class($this), $this->message, $this->code,
|
||||
$callback, $this->error_message_prefix,
|
||||
$this->userinfo);
|
||||
}
|
||||
if ($this->mode & PEAR_ERROR_CALLBACK) {
|
||||
$modes[] = 'callback';
|
||||
}
|
||||
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"]',
|
||||
get_class($this), $this->message, $this->code,
|
||||
implode("|", $modes), $levels[$this->level],
|
||||
$this->error_message_prefix,
|
||||
$this->userinfo);
|
||||
}
|
||||
|
||||
// }}}
|
||||
}
|
||||
|
||||
register_shutdown_function("_PEAR_call_destructors");
|
||||
|
||||
/*
|
||||
* Local Variables:
|
||||
* mode: php
|
||||
* tab-width: 4
|
||||
* c-basic-offset: 4
|
||||
* End:
|
||||
*/
|
||||
?>
|
||||
213
html/illt/ajaxReqIllt.php
Normal file
213
html/illt/ajaxReqIllt.php
Normal file
@@ -0,0 +1,213 @@
|
||||
<?php
|
||||
include_once ("../include/mcglobal.inc.php");
|
||||
include_once ("../include/auth.inc.php");
|
||||
include_once ("../illt/inc_serviceunit.inc.php");
|
||||
include_once ("../include/html.inc.php");
|
||||
include_once ("../include/inc_stock.inc.php");
|
||||
include_once ("../locating/xServer.inc.php");
|
||||
|
||||
|
||||
// Check HTTP-Parameters
|
||||
getSecHttpVars("1",array("f_act", "mode", "actionObjType", "actionObjId", "rootStockSU", "crvhId", "currDay", "hour", "hourUnit", "timeslots", "jbId", "csId", "content", "crvhSidMovedTo",
|
||||
"filter_1", "filter_2", "filter_3", "filter_4", "filter_5", "containerCssWidth"));
|
||||
|
||||
if ($mode != "") :
|
||||
header("Content-Type: text/html; charset=ISO-8859-1\n");
|
||||
endif;
|
||||
|
||||
// echo "alert('" . $mode . " ' + '" . $actionObjType . " ' + '" . $actionObjId . " ' + '" . $currDay . " ' + '" . $jbId . " ');";
|
||||
|
||||
|
||||
// Default CSS
|
||||
// ----------------
|
||||
// Constants
|
||||
$constMenuItemWidth = "100px";
|
||||
$constMenuColWidth = "100px";
|
||||
$constBackground = "#CDD9FD";
|
||||
$constMenuBackground = array();
|
||||
$constMenuBackground[0] = "#1b12b9";
|
||||
$constMenuBackground[1] = "#1b12b9";
|
||||
$constMenuBackground[2] = "#4e45ec";
|
||||
$constMenuBackground[3] = "#97bcFF";
|
||||
$constMenuBackgroundImage = array();
|
||||
$constMenuBackgroundImage[0] = "spacer_blue_menu_01.jpg";
|
||||
$constMenuBackgroundImage[1] = "spacer_blue_menu_01.jpg";
|
||||
$constMenuBackgroundImage[2] = "spacer_blue_menu_02.jpg";
|
||||
$constMenuBackgroundImage[3] = "spacer_blue_menu_03.jpg";
|
||||
$constMenuColor = array();
|
||||
$constMenuColor[0] = "#FFFFFF";
|
||||
$constMenuColor[1] = "#FFFFFF";
|
||||
$constMenuColor[2] = "#FFFFFF";
|
||||
$constMenuColor[3] = "#FFFFFF";
|
||||
$constMaincontentBackground = "#CDD9FD";
|
||||
$constMaincontent2Background = "#CDD9FD";
|
||||
$constButtonBackground = "#1b12b9";
|
||||
$constButtonColor = "#FFFFFF";
|
||||
$constButtonColor2 = "#4e45ec";
|
||||
$constButtonOnMouseOverColor = "#97bcFF";
|
||||
$constListBgCol1 = "#AAAAFF";
|
||||
$constListBgCol2 = "#AAAAFF";
|
||||
$constListBgCol3 = "#CCCCFF";
|
||||
$constListBgCol4 = "#CCCCFF";
|
||||
$constPageHeadlineBgCol = "#1b12b9";
|
||||
$constTickerBgCol = "#CDD9FD";
|
||||
|
||||
$atiColsTypesArray = array(); // Represents the fields ati_data_01, ati_data_02, ..., ati_data_xx only!
|
||||
$atiColsTypes = getParameterValue("0", "STK_ATI_COLUMN_TYPES", $hq_id);
|
||||
if ($atiColsTypes != "") :
|
||||
$atiColsTypesArray = spliti(",", $atiColsTypes);
|
||||
else :
|
||||
// Default
|
||||
$atiColsTypesArray = array("varchar","number","number","date","integer","float2","integer","float2","float2","","","","","","","","","","integer","integer");
|
||||
endif;
|
||||
|
||||
$colArray = array();
|
||||
$colArray["bg"] = $constBackground;
|
||||
$colArray["blue"] = "#0000FF";
|
||||
$colArray["green"] = "#00FF00";
|
||||
$colArray["red"] = "#FF0000";
|
||||
$colArray["white"] = "#FFFFFF";
|
||||
$colArray["yellow"] = "#FFFF00";
|
||||
$colArray["black"] = "#000000";
|
||||
$colArray["gray"] = "#DDDDDD";
|
||||
$colArray["gold"] = "#969325";
|
||||
$colArray["beige"] = "#EFE4B0";
|
||||
$colArray["light_red"] = "#FF8888";
|
||||
$colArray["light_green"] = "#88FF88";
|
||||
$colArray["light_blue"] = "#8888FF";
|
||||
$colArray["light_yellow"] = "#FFFF88";
|
||||
$colArray["light_gray"] = "#EEEEEE";
|
||||
|
||||
if ($containerCssWidth == "") : $containerCssWidth = "900"; endif;
|
||||
|
||||
// Number of data fields in "articleitem" (ati_data_01, ati_data_02, ...)
|
||||
$maxNumOfAtiDataFields = getParameterValue("0", "MAX_NUM_OF_ATI_DATA_FIELDS", $hq_id);
|
||||
if ($maxNumOfAtiDataFields == "" || !is_numeric($maxNumOfAtiDataFields)) :
|
||||
$maxNumOfAtiDataFields = "30";
|
||||
endif;
|
||||
|
||||
// Init array for threshold values
|
||||
$f_tv = array();
|
||||
|
||||
// ----------------
|
||||
|
||||
|
||||
// Output service unit message data
|
||||
function outSuMsgData($actionObjId, $outDataArray) {
|
||||
global $colArray, $containerCssWidth;
|
||||
$outputData = "";
|
||||
$outDataArrayLen = count($outDataArray);
|
||||
$outputData .= "<table>\n"
|
||||
. "<tr>\n"
|
||||
. " <td class=\"f10bp1_blue\">" . getLngt("BETRIEBSMELDUNGEN:") . " </td>\n"
|
||||
. "</tr>\n"
|
||||
. "</table><br>\n";
|
||||
if ($outDataArrayLen > 0) :
|
||||
$outputData .= "<table width=\"" . $containerCssWidth . "px\" border=\"1\">"
|
||||
. " <tr>"
|
||||
. " <td colspan=\"6\" class=\"f10np1\" style=\"text-align:center;color:" . $colArray["white"] . ";background-color:" . $colArray["red"] . ";\"><b>" . $actionObjId . "<b></td>"
|
||||
. " </tr>"
|
||||
. " <tr>"
|
||||
. " <td class=\"f8np1\" style=\"width:100;text-align:center;color:" . $colArray["white"] . ";background-color:" . $colArray["red"] . ";\"><b>" . getLngt("Code") . "</b></td>"
|
||||
. " <td class=\"f8np1\" style=\"text-align:center;color:" . $colArray["white"] . ";background-color:" . $colArray["red"] . ";\"><b>" . getLngt("Beschreibung") . "</td>"
|
||||
. " <td class=\"f8np1\" style=\"text-align:center;color:" . $colArray["white"] . ";background-color:" . $colArray["red"] . ";\"><b>" . getLngt("Text") . "</td>"
|
||||
. " </tr>";
|
||||
for ($j = 0; $j < $outDataArrayLen; $j++) :
|
||||
$outputData .= $outDataArray[$j];
|
||||
endfor;
|
||||
$outputData .= "</table>";
|
||||
endif;
|
||||
return $outputData;
|
||||
}
|
||||
|
||||
// Output log data
|
||||
function outSuHistoryData($actionObjType, $actionObjId, $rootStockSU, $outDataArray, $filter_1) {
|
||||
global $colArray, $containerCssWidth;
|
||||
$outputData = "";
|
||||
$outDataArrayLen = count($outDataArray);
|
||||
$outputData .= "<table>\n"
|
||||
. "<tr>\n"
|
||||
. " <td class=\"f10bp1_blue\">" . getLngt("ZUSTANDSVERLAUF:") . " </td>\n"
|
||||
. " <td>\n"
|
||||
. " <select name=\"f_suhd_filter_1\" onChange=\"ajaxRequestContainerHtmlGet('../illt/ajaxReqIllt.php', 'cc_01', 'mode=getSuHistoryData&actionObjType=" . $actionObjType . "&actionObjId=" . $actionObjId . "&filter_1=' + getSelectedValue('f_suhd_filter_1') + '&rootStockSU=" . $rootStockSU . "');\">\n"
|
||||
. " <option value=\"0\" " . ($filter_1 == "0" ? "selected" : "") . ">" . getLngt("Alle Zustandsdatensätze") . "</option>\n"
|
||||
. " <option value=\"1\" " . ($filter_1 == "1" ? "selected" : "") . ">" . getLngt("Kritische Zustandsdatensätze (mindestens ein Wert)") . "</option>\n"
|
||||
. " <option value=\"2\" " . ($filter_1 == "2" ? "selected" : "") . ">" . getLngt("Unkritische Zustandsdatensätze (alle Werte)") . "</option>\n"
|
||||
. " </select> \n"
|
||||
. " </td>\n"
|
||||
. " <td>\n"
|
||||
. defineButtonType08("Aktualisieren", "action_log_reload", "finishPage('processAction');", "140", "", "", "", "", "", "", "1")
|
||||
. " </td>\n"
|
||||
. "</tr>\n"
|
||||
. "</table><br>\n";
|
||||
if ($outDataArrayLen > 0) :
|
||||
$outputData .= "<table width=\"" . $containerCssWidth . "px\" border=\"1\">"
|
||||
. " <tr><td colspan=\"6\" class=\"f10np1\" style=\"text-align:center;color:" . $colArray["white"] . ";background-color:" . $colArray["red"] . ";\"><b>" . $actionObjId . "<b></td></tr>"
|
||||
. " <tr>"
|
||||
. " <td class=\"f8np1\" style=\"width:120;text-align:center;color:" . $colArray["white"] . ";background-color:" . $colArray["red"] . ";\" onClick=\"logChangeOrderBy('0');\"><b>" . getLngt("Zeitpunkt") . "</b></td>"
|
||||
. " <td class=\"f8np1\" style=\"width: 60;text-align:center;color:" . $colArray["white"] . ";background-color:" . $colArray["red"] . ";\" onClick=\"logChangeOrderBy('1');\"><b>" . getLngt("BEK") . "</td>"
|
||||
. " <td class=\"f8np1\" style=\"width: 60;text-align:center;color:" . $colArray["white"] . ";background-color:" . $colArray["red"] . ";\" onClick=\"logChangeOrderBy('2');\"><b>" . getLngt("MEK") . "</td>"
|
||||
. " <td class=\"f8np1\" style=\"width: 60;text-align:center;color:" . $colArray["white"] . ";background-color:" . $colArray["red"] . ";\" onClick=\"logChangeOrderBy('3');\"><b>" . getLngt("H1") . "</td>"
|
||||
. " <td class=\"f8np1\" style=\"width: 60;text-align:center;color:" . $colArray["white"] . ";background-color:" . $colArray["red"] . ";\" onClick=\"logChangeOrderBy('4');\"><b>" . getLngt("H2") . "</td>"
|
||||
. " <td class=\"f8np1\" style=\"width: 60;text-align:center;color:" . $colArray["white"] . ";background-color:" . $colArray["red"] . ";\" onClick=\"logChangeOrderBy('5');\"><b>" . getLngt("H3") . "</td>"
|
||||
. " </tr>";
|
||||
for ($j = 0; $j < $outDataArrayLen; $j++) :
|
||||
$outputData .= $outDataArray[$j];
|
||||
endfor;
|
||||
$outputData .= "</table>";
|
||||
endif;
|
||||
return $outputData;
|
||||
}
|
||||
|
||||
|
||||
// ***********
|
||||
// * ACTIONS *
|
||||
// ***********
|
||||
if ($mode == "getSuMessageData") :
|
||||
|
||||
// Service unit messages
|
||||
$retVal = "";
|
||||
if ($actionObjId != "") :
|
||||
$outMessageArray = array();
|
||||
getSuMessageData($actionObjId);
|
||||
$retVal = outSuMsgData($actionObjId, $outMessageArray);
|
||||
endif;
|
||||
echo $retVal;
|
||||
|
||||
|
||||
elseif ($mode == "getSuHistoryData") :
|
||||
|
||||
$retVal = "";
|
||||
if ($actionObjType != "" && $actionObjId != "" && $rootStockSU != "") :
|
||||
|
||||
// Get vector of article(type) IDs ("at_id") of service units
|
||||
// $suAtIdArray = getColVectorFromDB2ArrayByClause("phoenix.article", "at_id", "at_group = '," . $suGroupId . ",'", "", "at_id");
|
||||
$suAtIdString = getParameterValue("0", "SU_AT_TYPES_FOR_TV", $hq_id);
|
||||
$suAtIdArray = explode(",", $suAtIdString);
|
||||
$suAtIdArrayLen = count($suAtIdArray);
|
||||
|
||||
// Get thresholdvalues
|
||||
getThresholdValues($suAtIdArray);
|
||||
|
||||
// Get type of the service unit for corresponding threashold values
|
||||
$atId = getFieldValueFromId("phoenix.articleitem", "ati_serialno ", $actionObjId, "at_id");
|
||||
|
||||
/*
|
||||
$jsTv = "";
|
||||
for ($j = 1; $j <= $maxNumOfAtiDataFields; $j++) :
|
||||
if ($f_tv[$atId][$j] != "" && is_numeric($f_tv[$atId][$j])) :
|
||||
$jsTv .= "&value_". pad($j,2) . "=" . $f_tv[$atId][$j];
|
||||
endif;
|
||||
endfor;
|
||||
*/
|
||||
if ($filter_1 == "") : $filter_1 = "0"; endif;
|
||||
$f_log_filter_1 = $filter_1;
|
||||
$outLogArray = array();
|
||||
getSuHistoryData("0", "AND stk.stk_pre_id = '" . $rootStockSU . "' AND atih.atih_serialno = '" . $actionObjId . "'");
|
||||
$retVal = outSuHistoryData($actionObjType, $actionObjId, $rootStockSU, $outLogArray, $filter_1);
|
||||
endif;
|
||||
echo $retVal;
|
||||
|
||||
endif;
|
||||
|
||||
?>
|
||||
519
html/illt/ati_bank_announcement_scan.php
Normal file
519
html/illt/ati_bank_announcement_scan.php
Normal file
@@ -0,0 +1,519 @@
|
||||
<?php
|
||||
/*=======================================================================
|
||||
*
|
||||
* ati_bank_announcement_scan.php
|
||||
*
|
||||
=======================================================================*/
|
||||
|
||||
|
||||
include_once ("../include/mcglobal.inc.php");
|
||||
include_once ("../include/auth.inc.php");
|
||||
include_once ("../include/inc_wording_wrapper.inc.php");
|
||||
|
||||
getSecHttpVars("1",array("f_act", "customerId", "cscIdRoot", "cscIdActual", "objecttypemode", "correctScannedCodes", "errLevel", "trackingIDsNotFound",
|
||||
"f_article_type", "f_csc_selected", "numOfObjectsToBeBooked", "statusMessage", "deactivateMenu"));
|
||||
|
||||
// Select user-type for mode of security check
|
||||
$userType = getFieldValueFromId("user","usr_id",$usr_id,"usr_type");
|
||||
$userTypeName = getUserTypeName($userType);
|
||||
|
||||
// Check for authentication access and granted rights
|
||||
$usrAccessArray["cs"] = "1";
|
||||
authCheckForAccess($hq_id, $usr_id, $emp_id, "1", $customerId, $cscIdRoot, $cscIdActual);
|
||||
if (!(authCheckEmployeeRights($emp_id, "0") || authCheckEmployeeRights($emp_id, "4"))) : gotoReferer("1"); endif;
|
||||
|
||||
if ($selYear == "") : $selYear = date("Y"); endif;
|
||||
if ($selMonth == "") : $selMonth = date("m"); endif;
|
||||
if ($selDay == "") : $selDay = date("d"); endif;
|
||||
|
||||
include_once ("../groupware/calendar.php");
|
||||
|
||||
$deactivateMenuStatic = "1";
|
||||
|
||||
getLanguage(__FILE__);
|
||||
|
||||
$pageTitel = getLngt("Objekte ausbuchen");
|
||||
include_once ("../admin/menu.php");
|
||||
include_once ("../include/html.inc.php");
|
||||
|
||||
getCurrentScript(__FILE__);
|
||||
|
||||
// Init
|
||||
$debug = false;
|
||||
$execute = true;
|
||||
if ($objecttypemode == "") : $objecttypemode = "ati_announcement_1"; endif;
|
||||
if (!isset($correctScannedCodes)) : $correctScannedCodes = ""; endif;
|
||||
$correctScannedCodesArr = array();
|
||||
if ($correctScannedCodes != "") :
|
||||
$correctScannedCodesArr = explode(",", $correctScannedCodes);
|
||||
endif;
|
||||
$correctScannedCodesArrLen = count($correctScannedCodesArr);
|
||||
$cscPreIdOfSelected = "";
|
||||
if ($f_csc_selected != "" && is_numeric($f_csc_selected)) :
|
||||
$cscPreIdOfSelected = getFieldValueFromId("costcenter","csc_id",$f_csc_selected,"csc_pre_id"); // Selected costcenter has to have a "csc_pre_id" (!!!!)
|
||||
endif;
|
||||
$currCscName = "Keine " . wrapPhrase("Kostenstelle", $objecttypemode) . " ausgewählt!";
|
||||
|
||||
if ($debug) :
|
||||
echo "errLevel = " . $errLevel . "<br>";
|
||||
echo "cscIdActual = " . $cscIdActual . "<br>";
|
||||
echo "f_article_type = " . $f_article_type . "<br>";
|
||||
echo "f_csc_selected = " . $f_csc_selected . "<br>";
|
||||
echo "cscPreIdOfSelected = " . $cscPreIdOfSelected . "<br>";
|
||||
echo "correctScannedCodesArrLen = " . $correctScannedCodesArrLen . "<br>";
|
||||
echo "selYear = " . $selYear . "<br>";
|
||||
echo "selMonth = " . $selMonth . "<br>";
|
||||
echo "selDay = " . $selDay . "<br>";
|
||||
echo "execute = " . $execute . "<br>";
|
||||
endif;
|
||||
|
||||
|
||||
// Get objects to be booked
|
||||
function getObjectsToBeBooked ($cscId, $atId) {
|
||||
global $db, $PHP_SELF;
|
||||
$objectsToBeBooked = array();
|
||||
if ($cscId != "" && is_numeric($cscId) && $atId != "" && is_numeric($atId)) :
|
||||
// Get all fixed objects (e.g. safebags) to be booked to bank by costcenter employee in frontend
|
||||
$sqlquery = "SELECT atih.atih_serialno, atih.atih_createtime"
|
||||
. " FROM phoenix_log.articleitemhistory AS atih"
|
||||
. " WHERE atih.csc_id = '" . $cscId . "' AND"
|
||||
. " atih.at_id = '" . $atId . "' AND"
|
||||
. " atih.atih_data_28 = '1'"
|
||||
. " ORDER BY atih.atih_serialno";
|
||||
// echo $sqlquery;
|
||||
$result = $db->query($sqlquery);
|
||||
if (DB::isError($result)) die ("$PHP_SELF: " . $result->getMessage());
|
||||
while ($row = $result->fetch_assoc()):
|
||||
$objectsToBeBooked[] = $row["atih_serialno"];
|
||||
endwhile;
|
||||
$result->free();
|
||||
endif;
|
||||
return $objectsToBeBooked;
|
||||
}
|
||||
|
||||
|
||||
// Check days having access regarding special costcenter (!!!!)
|
||||
$atihDailyBookingPermanentlyEnabled = false;
|
||||
$parDailyBookingPermanentlyEnabled = getParameterValue("0", "ATIH_DAILY_BOOKING_PERMANENTLY_ENABLED", $hq_id);
|
||||
if ($parDailyBookingPermanentlyEnabled == "") : $parDailyBookingPermanentlyEnabled = getParameterValue("0", "ATIH_DAILY_BOOKING_PERMANENTLY_ENABLED", "0"); endif;
|
||||
if ($parDailyBookingPermanentlyEnabled == "1") :
|
||||
$atihDailyBookingPermanentlyEnabled = true;
|
||||
endif;
|
||||
$f_selUsrId = "0"; $f_ap_cat_search_1 = ""; $f_ap_cat_search_2 = ""; $f_ap_cat_search_3 = ""; $f_ap_cat_search_4 = ""; $f_ap_visibility_search = array(); $f_hq_id = array($hq_id);
|
||||
$bookingDaysArr = getAppointmentsFromDB($selYear, $selMonth, $selDay, $selYear, $selMonth, $selDay, "", $f_csc_selected, "1");
|
||||
$bookingDaysArrLen = count($bookingDaysArr); // Has to be at least >= 1 regarding the ap_type = "1". Otherwise access will not be granted! (!!!!)
|
||||
|
||||
if ($atihDailyBookingPermanentlyEnabled || $bookingDaysArrLen > 0) :
|
||||
|
||||
if ($execute && $f_csc_selected != "" && is_numeric($f_csc_selected) && $cscPreIdOfSelected != "" && is_numeric($cscPreIdOfSelected) && $f_article_type != "" && is_numeric($f_article_type)) :
|
||||
|
||||
// Book objects
|
||||
if ($f_act == "book") :
|
||||
|
||||
$objectsToBeBooked = getObjectsToBeBooked($f_csc_selected, $f_article_type);
|
||||
$objectsToBeBookedLen = count($objectsToBeBooked);
|
||||
|
||||
if ($debug) :
|
||||
echo "objectsToBeBookedLen = " . $objectsToBeBookedLen . "<br>";
|
||||
echo "numOfObjectsToBeBooked = " . $numOfObjectsToBeBooked . "<br>";
|
||||
endif;
|
||||
|
||||
// Get POST parameter for scanned objects
|
||||
for ($i = 0; $i < $objectsToBeBookedLen; $i++) :
|
||||
list($snr[$objectsToBeBooked[$i]]) = getSecHttpVars("1",array("snr_" . $objectsToBeBooked[$i]));
|
||||
endfor;
|
||||
|
||||
if ($debug) :
|
||||
echo "<br>"; print_r($snr); echo "<br><br>";
|
||||
endif;
|
||||
|
||||
// Scans without concrete objects in database
|
||||
// HERE !!!!!!!!!!!!!!!!!!!!!!!!!!!!
|
||||
|
||||
if ($objectsToBeBookedLen > 0 && $correctScannedCodesArrLen > 0 && $numOfObjectsToBeBooked > 0) :
|
||||
|
||||
if ($objectsToBeBookedLen == $numOfObjectsToBeBooked) : // && $correctScannedCodesArrLen == $numOfObjectsToBeBooked
|
||||
|
||||
// First check all codes being scanned are identically to codes to be scanned after submit
|
||||
$codesScannedCorrectly = true;
|
||||
for ($i = 0; $i < $objectsToBeBookedLen; $i++) :
|
||||
// Check for object being scanned correctly. If NOT then check for $errLevel has to be "1" (!!!!)
|
||||
if (!in_array($objectsToBeBooked[$i],$correctScannedCodesArr)) :
|
||||
$codesScannedCorrectly = false;
|
||||
break;
|
||||
endif;
|
||||
endfor;
|
||||
|
||||
if ($debug) :
|
||||
echo "<br>"; print_r($objectsToBeBooked); echo "<br><br>"; print_r($correctScannedCodesArr); echo "<br><br>";
|
||||
endif;
|
||||
|
||||
if (true) :
|
||||
|
||||
TA("B");
|
||||
|
||||
$objectsNotScanned = ""; // For status message output only
|
||||
for ($i = 0; $i < $objectsToBeBookedLen; $i++) :
|
||||
if ($debug) :
|
||||
echo "snr[$objectsToBeBooked[$i]] = " . $snr[$objectsToBeBooked[$i]] . "<br>";
|
||||
endif;
|
||||
if ($snr[$objectsToBeBooked[$i]] == "1") :
|
||||
updateStmt("phoenix_log.articleitemhistory", "atih_serialno", $objectsToBeBooked[$i], array("atih_data_28", "2"),"csc_id = '" . $f_csc_selected . "' AND atih_data_28 = '1'");
|
||||
// Log update
|
||||
// ............
|
||||
else :
|
||||
if ($objectsNotScanned != "") : $objectsNotScanned .= ","; endif;
|
||||
$objectsNotScanned .= $objectsToBeBooked[$i];
|
||||
endif;
|
||||
endfor;
|
||||
if ($objectsNotScanned != "") :
|
||||
$statusMessage = getLngt("Folgende Objekte wurden NICHT ausgebucht, weil ein Scan NICHT erfolgte:") . " [" . $objectsNotScanned . "]";
|
||||
endif;
|
||||
|
||||
TA("C");
|
||||
TA("E");
|
||||
|
||||
// Send mail for failed scan(s)
|
||||
$sendMailText = "";
|
||||
if (!$codesScannedCorrectly || ($errLevel & 1) == 1) :
|
||||
$sendMailText .= "Fehlende Objekte: " . $objectsNotScanned . " ";
|
||||
endif;
|
||||
if (($errLevel & 2) == 2) :
|
||||
$sendMailText .= "Zusätzliche Objekte: " . $trackingIDsNotFound;
|
||||
endif;
|
||||
if ($sendMailText != "") :
|
||||
sendExternalMail($sendMailText, "HHA.SCAN.EREIGNISSE", "ASSECUTOR-INFO@hochbahn.de", "sys-op@assecutor.de", "", "proj.hha@assecutor.de", "", "", "sendMailBooking.log");
|
||||
endif;
|
||||
else :
|
||||
$statusMessage = getLngt("TRANSAKTIONSFEHLER! Die gescannten Objekte scheinen mit den abzuschließenden Objekten NICHT übereinzustimmen! Bitte leider nochmal den Scan-Prozess wiederholen!");
|
||||
endif;
|
||||
else :
|
||||
$statusMessage = getLngt("ÜBERTRAGUNGSFEHLER! Die Anzahl der gescannten Objekte scheint mit der Anzahl abzuschließender Objekte NICHT übereinzustimmen! Bitte leider nochmal den Scan-Prozess wiederholen!");
|
||||
endif;
|
||||
else :
|
||||
$statusMessage = getLngt("Es sind derzeit keine Objekte im Bestand, die ausgebucht werden können!");
|
||||
endif;
|
||||
endif;
|
||||
|
||||
// Reload objects to be scanned
|
||||
$objectsToBeBooked = getObjectsToBeBooked ($f_csc_selected, $f_article_type);
|
||||
$objectsToBeBookedLen = count($objectsToBeBooked);
|
||||
|
||||
// Current costcenter name regarding a special virtual number mapping it
|
||||
if ($f_csc_selected != "") :
|
||||
$currCscName = getFieldValueFromId("costcenter", "csc_id", $f_csc_selected, "csc_name");
|
||||
endif;
|
||||
|
||||
|
||||
$htmlOut = "";
|
||||
for ($i = 0; $i < $objectsToBeBookedLen; $i++) :
|
||||
$htmlOut .= "<input type=\"text\" id=\"atih_" . $objectsToBeBooked[$i] . "\" name=\"atih_" . $objectsToBeBooked[$i] . "\" value=\"" . $objectsToBeBooked[$i] . "\" size=\"20\" readonly>\n";
|
||||
$htmlOut .= "<input type=\"hidden\" id=\"snr_" . $objectsToBeBooked[$i] . "\" name=\"snr_" . $objectsToBeBooked[$i] . "\" value=\"\"><br>\n";
|
||||
endfor;
|
||||
else :
|
||||
$execute = false;
|
||||
$currCscName = "";
|
||||
if ($f_csc_selected == "" || $cscPreIdOfSelected == "") :
|
||||
$currCscName .= "Es wurde keine " . wrapPhrase("Kostenstelle", $objecttypemode) . " ausgewählt!" . "<br><br>";
|
||||
endif;
|
||||
if ($f_article_type == "" || !is_numeric($f_article_type)) :
|
||||
$currCscName .= "Es wurde kein Objekttyp ausgewählt!" . "<br><br>";
|
||||
endif;
|
||||
$statusMessage = getLngt("Ein Bearbeitung kann nur nach Auswahl der operativen Einheit bzw. des Objekttyps erfolgen!");
|
||||
endif;
|
||||
else :
|
||||
$execute = false;
|
||||
$currCscName = getLngt("Am heutigen Tag findet keine Ausbuchung statt!") . "<br><br>";
|
||||
$statusMessage = getLngt("Am heutigen Tag findet keine Ausbuchung statt!");
|
||||
endif;
|
||||
|
||||
if ($debug) :
|
||||
echo "currCscName = " . $currCscName . "<br>";
|
||||
echo "statusMessage = " . $statusMessage . "<br>";
|
||||
echo "execute = " . $execute . "<br>";
|
||||
endif;
|
||||
?>
|
||||
|
||||
|
||||
<html>
|
||||
|
||||
<head>
|
||||
<title><?php echo $pageTitel ?></title>
|
||||
|
||||
<link rel="stylesheet" type="text/css" href="../css/phoenix.css">
|
||||
<style type="text/css">
|
||||
<?php include_once ("../css/navigation.css.php"); ?>
|
||||
</style>
|
||||
|
||||
<?php include_once ("../include/js_framework.inc.php"); ?>
|
||||
|
||||
<script src="../include/checkFormTags.js" type="text/javascript"></script>
|
||||
|
||||
<script type="text/javascript">
|
||||
<!--
|
||||
|
||||
/********************************************************************************/
|
||||
// Quelle: http://9elements.com/html5demos/audio/
|
||||
// Audioelement erstellen
|
||||
var ackSnd;
|
||||
var hintSnd;
|
||||
var warnSnd;
|
||||
var finishOkSnd;
|
||||
var soundOn = true;
|
||||
|
||||
try {
|
||||
ackSnd = new Audio("");
|
||||
hintSnd = new Audio("");
|
||||
warnSnd = new Audio("");
|
||||
finishOkSnd = new Audio("");
|
||||
} catch (e) {
|
||||
soundOn = false;
|
||||
}
|
||||
|
||||
function initSounds() {
|
||||
if (soundOn) {
|
||||
// im DOM einfügen, sonst wird es nicht abgespielt
|
||||
// document.body.appendChild(ackSnd);
|
||||
document.body.appendChild(hintSnd);
|
||||
document.body.appendChild(warnSnd);
|
||||
|
||||
// herausfinden welcher Medientyp abgespielt werden kann
|
||||
var canPlayType = warnSnd.canPlayType("audio/wav");
|
||||
if(canPlayType.match(/maybe|probably/i)) {
|
||||
ackSnd.src = '../tools/sound/coin.mp3';
|
||||
hintSnd.src = '../tools/sound/dead.wav';
|
||||
warnSnd.src = '../tools/sound/smash.mp3';
|
||||
finishOkSnd.src = '../tools/sound/doorbell.wav';
|
||||
} else {
|
||||
soundOn = false;
|
||||
}
|
||||
}
|
||||
// if (soundOn) {
|
||||
// alert("Sound is on!")
|
||||
// } else {
|
||||
// alert("Sound is off!")
|
||||
// }
|
||||
}
|
||||
|
||||
function beepAck () {
|
||||
if (soundOn)
|
||||
ackSnd.play();
|
||||
}
|
||||
|
||||
function beepHint () {
|
||||
if (soundOn)
|
||||
hintSnd.play();
|
||||
}
|
||||
|
||||
function beepWarn () {
|
||||
if (soundOn)
|
||||
warnSnd.play();
|
||||
}
|
||||
|
||||
function beepFinishOk () {
|
||||
if (soundOn)
|
||||
finishOkSnd.play();
|
||||
}
|
||||
/********************************************************************************/
|
||||
|
||||
// NAVIGATION
|
||||
<?php echo $jsMenuOut; ?>
|
||||
|
||||
var numOfObjectsToBeBooked = <?php echo $objectsToBeBookedLen ?>;
|
||||
|
||||
var atihArr = Array();
|
||||
<?php
|
||||
for ($i = 0; $i < $objectsToBeBookedLen; $i++) :
|
||||
echo "atihArr[" . $i . "] = '" . $objectsToBeBooked[$i] . "'\n";
|
||||
endfor;
|
||||
?>
|
||||
var atihArrLen = atihArr.length; // Equals "$objectsToBeBookedLen" and equals "numOfObjectsToBeBooked"
|
||||
|
||||
function setScanFocus() {
|
||||
if ($('#f_scan')) {
|
||||
$('#f_scan').focus();
|
||||
}
|
||||
}
|
||||
|
||||
// Check all barcodes of the list are scanned completely
|
||||
function checkAllCodesAreScanned () {
|
||||
var listSannedCompletely = true;
|
||||
for(var i=0; i<atihArrLen; ++i) {
|
||||
if ($('#snr_' + atihArr[i]).val() != '1') {
|
||||
listSannedCompletely = false;
|
||||
}
|
||||
}
|
||||
return listSannedCompletely;
|
||||
}
|
||||
|
||||
function executeScanCode() {
|
||||
frm = document.forms[0];
|
||||
var scan_value = trim($('#f_scan').val());
|
||||
var trackingIDsNotFound;
|
||||
var IDfound = false;
|
||||
if (scan_value != '') {
|
||||
IDfound = false;
|
||||
for(var i=0; i<atihArrLen; ++i) {
|
||||
atih_val = $('#atih_' + atihArr[i]).val();
|
||||
snr_found_val = $('#snr_' + atihArr[i]).val();
|
||||
if (atih_val == scan_value) {
|
||||
IDfound = true;
|
||||
$("#atih_" + atihArr[i]).css("background-color", "#00FF00");
|
||||
if (snr_found_val == '1') {
|
||||
beepHint();
|
||||
alert('<?php echo getLngt("Das Objekt hatten Sie schon gescanned!") ?>');
|
||||
} else {
|
||||
// Single existing code has been scanned correctly
|
||||
$('#snr_' + atihArr[i]).val('1');
|
||||
// Update list of correct scanned Codes
|
||||
correctScannedCodes = $('#correctScannedCodes').val();
|
||||
if (correctScannedCodes != '') {$('#correctScannedCodes').val($('#correctScannedCodes').val().concat(','))};
|
||||
$('#correctScannedCodes').val($('#correctScannedCodes').val().concat(scan_value))
|
||||
beepAck();
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!IDfound) {
|
||||
beepWarn();
|
||||
alert('<?php echo getLngt("Das Objekt ist NICHT in der Liste enthalten!") ?>');
|
||||
// Check number is in the text field of numbers doing not exist ("double or multiple fail scan")
|
||||
trackingIDsNotFound = $('#trackingIDsNotFound').val();
|
||||
if (trackingIDsNotFound.indexOf(scan_value) == -1) {
|
||||
if (trackingIDsNotFound != '') {$('#trackingIDsNotFound').val($('#trackingIDsNotFound').val().concat(','))};
|
||||
$('#trackingIDsNotFound').val($('#trackingIDsNotFound').val().concat(scan_value))
|
||||
} else {
|
||||
beepHint();
|
||||
alert('<?php echo getLngt("Das Objekt hatten Sie schon gescanned UND es ist NICHT in der Liste enthalten!") ?>');
|
||||
}
|
||||
}
|
||||
if (checkAllCodesAreScanned ()) {
|
||||
beepFinishOk();
|
||||
}
|
||||
}
|
||||
$('#f_scan').val('');
|
||||
setScanFocus();
|
||||
}
|
||||
|
||||
function execBodyOnLoad() {
|
||||
<?php
|
||||
echo $phpCurrentNavigationOnLoad;
|
||||
?>
|
||||
initSounds();
|
||||
// initForm();
|
||||
displayStatusMessage();
|
||||
setScanFocus();
|
||||
}
|
||||
|
||||
function finishPage(f_act) {
|
||||
document.forms[0].f_act.value = f_act;
|
||||
document.forms[0].submit();
|
||||
}
|
||||
|
||||
function finishSave() {
|
||||
var listScannedCompletly = checkAllCodesAreScanned();
|
||||
var trackingIDsNotFound = $('#trackingIDsNotFound').val();
|
||||
var doBook = false;
|
||||
var errLevel = '0';
|
||||
// Check cases
|
||||
if (listScannedCompletly && trackingIDsNotFound == '') {
|
||||
if (confirm('<?php echo getLngt("Alle Objekte einwandfrei gescanned und keine fehlerhaften Scans! Möchten Sie die Ausbuchung jetzt durchführen?") ?>')) {
|
||||
doBook = true;
|
||||
}
|
||||
} else {
|
||||
if (!listScannedCompletly) {
|
||||
if (confirm('<?php echo getLngt("Mindestens ein Objekt wurde NICHT gescanned! Möchten Sie DENNOCH die Ausbuchung jetzt durchführen?") ?>')) {
|
||||
errLevel = '1';
|
||||
doBook = true;
|
||||
}
|
||||
}
|
||||
if (trackingIDsNotFound != '') {
|
||||
if (confirm('<?php echo getLngt("Es wurde mindestens ein Objekt zusätzlich gescanned, welches nicht in der Liste verzeichnet ist! Möchten Sie DENNOCH die Ausbuchung jetzt durchführen?") ?>')) {
|
||||
if (errLevel == '1') {
|
||||
errLevel = '3';
|
||||
} else {
|
||||
errLevel = '2';
|
||||
}
|
||||
doBook = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (doBook) {
|
||||
if (errLevel != '0') {
|
||||
$('#errLevel').val(errLevel);
|
||||
}
|
||||
finishPage('book');
|
||||
} else {
|
||||
alert('<?php echo getLngt("Der Vorgang wurde abgebrochen! Schließen Sie ggfs. die Seite, öffnen Sie sie neu und wiederholen Sie den Vorgang!") ?>');
|
||||
}
|
||||
}
|
||||
|
||||
-->
|
||||
</script>
|
||||
|
||||
|
||||
</head>
|
||||
|
||||
<body onLoad="execBodyOnLoad();">
|
||||
|
||||
<?php echo $phpMenuOut ?>
|
||||
<?php echo $phpReducedMenuOut ?>
|
||||
<?php echo $phpPageTitelOut ?>
|
||||
|
||||
<div class="maincontent" name="maincontent" id="maincontent">
|
||||
|
||||
<form name="scan" action="../illt/ati_bank_announcement_scan.php" method="post">
|
||||
|
||||
<input type="hidden" name="f_act" value="">
|
||||
<?php echo $phpCurrentNavigationInputHidden ?>
|
||||
<input type="hidden" name="deactivateMenu" value="<?php echo ec($deactivateMenu) ?>">
|
||||
<input type="hidden" name="statusMessage" value="">
|
||||
|
||||
<input type="hidden" name="customerId" value="<?php echo $customerId ?>">
|
||||
<input type="hidden" name="cscIdRoot" value="<?php echo $cscIdRoot ?>">
|
||||
<input type="hidden" name="cscIdActual" value="<?php echo $cscIdActual ?>">
|
||||
|
||||
<input type="hidden" name="numOfObjectsToBeBooked" value="<?php echo $objectsToBeBookedLen ?>">
|
||||
<input type="hidden" name="f_article_type" value="<?php echo $f_article_type ?>">
|
||||
<input type="hidden" name="f_csc_selected" value="<?php echo $f_csc_selected ?>">
|
||||
|
||||
<input type="hidden" id="errLevel" name="errLevel" value="0">
|
||||
<input type="hidden" id="correctScannedCodes" name="correctScannedCodes" value="">
|
||||
|
||||
<br><br>
|
||||
|
||||
<center>
|
||||
|
||||
<?php if ($execute) : ?>
|
||||
<span class="f10bp1_blue"><?php echo getLngt(wrapPhrase("KOSTENSTELLE", $objecttypemode)) ?>: <?php echo $currCscName ?></span><br><br><br>
|
||||
<?php else : ?>
|
||||
<span class="f10bp1_blue"><?php echo $currCscName ?></span><br><br><br>
|
||||
<?php endif; ?>
|
||||
|
||||
<?php if ($execute) : ?>
|
||||
<b><?php echo getLngt("BARCODE-SCAN:") ?></b> <input type="text" id="f_scan" name="f_scan" value="" size="20" onblur="javascript:executeScanCode();" border="2">
|
||||
|
||||
<br><br>
|
||||
|
||||
<?php echo $htmlOut ?>
|
||||
|
||||
<br><br>
|
||||
|
||||
<b><?php echo getLngt("Nicht zuzuordnende Objektnummern:") ?></b><br>
|
||||
<textarea id="trackingIDsNotFound" name="trackingIDsNotFound" cols="100" rows="3" onblur="javascript:setScanFocus();"></textarea>
|
||||
|
||||
<br><br>
|
||||
|
||||
<input type="button" name="button_save_changes" value="<?php echo getLngt("Ausbuchen") ?>" onclick="javascript:finishSave();">
|
||||
<?php endif; ?>
|
||||
|
||||
</center>
|
||||
|
||||
</div>
|
||||
|
||||
</form>
|
||||
|
||||
</div>
|
||||
|
||||
</body>
|
||||
|
||||
</html>
|
||||
84
html/illt/average_increase.php
Normal file
84
html/illt/average_increase.php
Normal file
@@ -0,0 +1,84 @@
|
||||
<?php
|
||||
/*=======================================================================
|
||||
*
|
||||
* average_increase.php
|
||||
*
|
||||
* Autor: Marc Vollmann
|
||||
*
|
||||
=======================================================================*/
|
||||
|
||||
// include_once ("../include/auth.inc.php");
|
||||
include_once ("../include/mcglobal.inc.php");
|
||||
|
||||
|
||||
// Overload function because of call by console
|
||||
function authCheckEmployeeRights($emp_id, $menuModeId, $referer = "") {
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
$errMsg = "";
|
||||
$hq_id = "";
|
||||
if (isset($argv[1]) && $argv[1] == "acapella7890") :
|
||||
if (isset($argv[2]) && $argv[2] != "") :
|
||||
$hq_id = $argv[2];
|
||||
if (isset($argv[3]) && $argv[3] != "") :
|
||||
$currentTimestamp = $argv[3];
|
||||
else :
|
||||
$errMsg = "average_increase failed by missing call timestamp";
|
||||
endif;
|
||||
else :
|
||||
$errMsg = "average_increase failed by missing headquarters ID";
|
||||
endif;
|
||||
else :
|
||||
$errMsg = "average_increase failed by access code";
|
||||
endif;
|
||||
|
||||
if ($errMsg != "") :
|
||||
sendInternalMail($errMsg . " [HQ_ID:" . $hq_id . "] " . " [TIMESTAMP:" . $currentTimestamp . "] ");
|
||||
die();
|
||||
endif;
|
||||
|
||||
|
||||
ini_set('memory_limit', '256M');
|
||||
|
||||
// Execution-Time for script
|
||||
set_time_limit(30000);
|
||||
|
||||
|
||||
include_once ("../include/inc_stock.inc.php");
|
||||
include_once ("../illt/inc_serviceunit.inc.php");
|
||||
|
||||
|
||||
$fire = true;
|
||||
|
||||
// After the data are imported, compute the major probability regarding the service intervals
|
||||
// Do this here and store the current states into "articleitem", because a realtime computation is not to be recommended
|
||||
if ($fire) :
|
||||
|
||||
// Get number of all article types
|
||||
$articleGroupPhrase = "(at_group LIKE '%,1,%') ";
|
||||
// $numOfAllArticleTypes = getCountOfTable("article", $articleGroupPhrase); // Number of ALL article types
|
||||
$articleTypeArray = getColVectorFromDB2ArrayByClause("article", "at_id", $articleGroupPhrase, "", "at_id", "");
|
||||
$numOfAllArticleTypes = count($articleTypeArray);
|
||||
|
||||
if ($numOfAllArticleTypes > 0) :
|
||||
$rootStockSU = getParameterValue("0", "SU_STK_ROOT", $hq_id); // Get root stock where all service units belong to
|
||||
if ($rootStockSU != "" && is_numeric($rootStockSU)) :
|
||||
$suSerialNoArray = getColVectorFromDB2ArrayByClause("phoenix.articleitem", "ati_serialno", "at_id IN (" . implode(",", $articleTypeArray) . ")", "", "");
|
||||
$suSerialNoArrayLen = count($suSerialNoArray);
|
||||
for ($i = 0; $i < $suSerialNoArrayLen; $i++) :
|
||||
// $probabilityToNextServiceMax = getSuHistoryData("2", "AND stk.stk_pre_id = '" . $rootStockSU . "' AND atih.atih_serialno = '" . $suSerialNoArray[$i] . "'");
|
||||
// updateStmt("phoenix.articleitem", "ati_serialno", $suSerialNoArray[$i], array("ati_data_18", $probabilityToNextServiceMax));
|
||||
// // $outReportArray[] = $suSerialNoArray[$i] . " <- Serviceinterval neu berechnet: " . $probabilityToNextServiceMax;
|
||||
|
||||
$serviceStatisticDataArray = getSuHistoryData("2", "AND stk.stk_pre_id = '" . $rootStockSU . "' AND atih.atih_serialno = '" . $suSerialNoArray[$i] . "'", "", "2");
|
||||
$probabilityToNextServiceMax = $serviceStatisticDataArray[0];
|
||||
$averageIncreaseValues = implode(",", $serviceStatisticDataArray[1]);
|
||||
updateStmt("phoenix.articleitem", "ati_serialno", $suSerialNoArray[$i], array("ati_data_18", $probabilityToNextServiceMax, "ati_data_26", $averageIncreaseValues));
|
||||
endfor;
|
||||
endif;
|
||||
endif;
|
||||
endif;
|
||||
|
||||
?>
|
||||
163
html/illt/cron_special_HHA.php
Normal file
163
html/illt/cron_special_HHA.php
Normal file
@@ -0,0 +1,163 @@
|
||||
<?php
|
||||
|
||||
include_once ("../include/mcglobal.inc.php");
|
||||
include_once ("../include/html.inc.php");
|
||||
include_once ("../include/inc_html2pdf.inc.php");
|
||||
// include_once ("htmlMimeMail.php");
|
||||
// include_once ("../include/barcode_BCGcode39_saveImage.php");
|
||||
// include_once ("../include/barcode_BCGcode128_saveImage.php");
|
||||
|
||||
// Error reporting
|
||||
error_reporting(E_ERROR | E_WARNING | E_PARSE);
|
||||
|
||||
|
||||
// getSecHttpVars("0", array("bo_id", "magic", "subject", "body", "filename_suffix"));
|
||||
|
||||
|
||||
$currentClientIP = trim($_SERVER['REMOTE_ADDR']);
|
||||
|
||||
$currentTime = date("Y-m-d H:i:s");
|
||||
$currentDate = date("d.m.Y");
|
||||
$currentTimeSpecial_01 = date("Ymd_His");
|
||||
|
||||
$absoluteSystemPath = getAbsoluteSystemPath();
|
||||
$outputFormatField = defineOutputFormats();
|
||||
|
||||
$subject = trim($subject);
|
||||
$body = trim($body);
|
||||
$filename_suffix = trim($filename_suffix);
|
||||
|
||||
$logFile = "../log/HLS_Safebags_Forgotten" . ($filename_suffix != "" ? "_" . $filename_suffix : "") . ".log";
|
||||
$csvFile = $currentTimeSpecial_01 . ($filename_suffix != "" ? "_" . $filename_suffix : "") . ".csv";
|
||||
$csvPathAndFile = "../temp/download/" . $csvFile;
|
||||
$hqId = "1";
|
||||
$title = "HHA :: Vermeintlich vergessene Safebags";
|
||||
$opState = "";
|
||||
$mailResultMsg = "";
|
||||
|
||||
|
||||
if ($argv[1] == "acapella7890") :
|
||||
|
||||
// echo "currentClientIP = " . $currentClientIP . "\n";
|
||||
|
||||
if (true || $currentClientIP != "") :
|
||||
|
||||
$f_article_type = "4285"; // Safebags Geld
|
||||
|
||||
// ATTENTION: Currently without stock ["....AND atih.stk_id = '" . $stkIdObject . "'...."]
|
||||
$sqlquery = "SELECT atih.csc_id, csc.csc_name, atih.usr_id, usr.usr_name, usr.usr_firstname, atih.atih_serialno, atih.atih_data_04, atih.atih_data_05, atih.atih_data_28, atih.atih_data_29, atih.atih_data_29"
|
||||
. " FROM phoenix_log.articleitemhistory AS atih, phoenix.costcenter AS csc, phoenix.user AS usr"
|
||||
. " WHERE atih.at_id = '" . $f_article_type . "' AND atih_data_28 = '1' AND atih.atih_createtime <= DATE_SUB(NOW(), INTERVAL 7 DAY) AND"
|
||||
. " atih.csc_id = csc.csc_id AND atih.usr_id = usr.usr_id"
|
||||
. " ORDER BY atih.csc_id, atih.atih_data_04";
|
||||
|
||||
$result = $db->query($sqlquery);
|
||||
if (DB::isError($result)) die ("$PHP_SELF: " . $result->getMessage());
|
||||
$i = 0;
|
||||
while ($row = $result->fetch_assoc()):
|
||||
|
||||
$output .= "<tr>\n";
|
||||
$output .= "<td align=\"right\">" . ($i + 1) . " </td>\n";
|
||||
$output .= "<td>" . $row["csc_name"] . " </td>\n";
|
||||
$output .= "<td>" . $row["atih_serialno"] . " </td>\n";
|
||||
$output .= "<td>" . substr($row["atih_data_04"], 0, 10) . " </td>\n";
|
||||
$output .= "<td align=\"right\">" . number_format($row["atih_data_05"], 2, ",", "") . " </td>\n";
|
||||
$output .= "<td>" . $row["usr_name"] . ", " . $row["usr_firstname"] . " </td>\n";
|
||||
$output .= "</tr>\n";
|
||||
$i++;
|
||||
endwhile;
|
||||
$result->free();
|
||||
|
||||
// Send mail if there is at least one forgotten safebag
|
||||
if ($i > 0) :
|
||||
|
||||
$mailtext = "<html><head><meta http-equiv=\"content-type\" content=\"text/html; charset=ISO-8859-1\">"
|
||||
. "<style>"
|
||||
. " .table1 {border-collapse: collapse; border: 1px solid black;}"
|
||||
. " .td1 {border: 1px solid black;}"
|
||||
. "</style>"
|
||||
. "</head><body>";
|
||||
|
||||
$headline = "";
|
||||
$headline .= "<tr>";
|
||||
$headline .= "<td class=\"td1\"> " . getLngt("Pos.") . " </td>";
|
||||
$headline .= "<td class=\"td1\"> " . getLngt("Verkaufsstelle") . " </td>";
|
||||
$headline .= "<td class=\"td1\"> " . getLngt("Safebag") . " </td>";
|
||||
$headline .= "<td class=\"td1\"> " . getLngt("Datum") . " </td>";
|
||||
$headline .= "<td class=\"td1\"> " . getLngt("Betrag") . " </td>";
|
||||
$headline .= "<td class=\"td1\"> " . getLngt("Mitarbeiter") . " </td>";
|
||||
$headline .= "</tr>";
|
||||
|
||||
$mailtext .= "<table border=\"0\">";
|
||||
$mailtext .= $headline;
|
||||
$mailtext .= $output;
|
||||
$mailtext .= "</table>";
|
||||
$mailtext .= "</body>";
|
||||
|
||||
// Generate PDF document
|
||||
// $fileNameTarget = generatePDF($mailtext, $title, "0", "0", "", "", "");
|
||||
|
||||
// Send mail with attached (generated) PDF document
|
||||
if (true) :
|
||||
|
||||
$mailSubject = $title;
|
||||
if ($subject != "") :
|
||||
$mailSubject = $subject;
|
||||
endif;
|
||||
$mailToAddresses = "ASSECUTOR-INFO@hochbahn.de";
|
||||
// $mailToAddresses = "marcelo.juliao_de_seixas@hochbahn.de";
|
||||
$mailAttachedFileType = "";
|
||||
$mailCcAddresses = "";
|
||||
$mailBccAddresses = "proj.hha@assecutor.de";
|
||||
// $mailBccAddresses = "";
|
||||
$mailSenderAddress = getParameterValue("0", "MAIL_SENDER_ADDRESS", $hqId);
|
||||
if ($mailSenderAddress == "") :
|
||||
$mailSenderAddress = "sys-op@assecutor.de";
|
||||
endif;
|
||||
// Generate mail (object)
|
||||
$mailObj = new htmlMimeMail();
|
||||
$mailObj->setFrom($mailSenderAddress);
|
||||
if ($mailCcAddresses != "") :
|
||||
$mailObj->setCc($mailCcAddresses);
|
||||
endif;
|
||||
if ($mailBccAddresses != "") :
|
||||
$mailObj->setBcc($mailBccAddresses);
|
||||
endif;
|
||||
$mailObj->setSubject($mailSubject);
|
||||
|
||||
// Mail content
|
||||
$mailObj->setHtml($mailtext, null, "./");
|
||||
// $mailObj->setText($mailtext);
|
||||
|
||||
/*
|
||||
if (file_exists($csvPathAndFile)) :
|
||||
$attachment = $mailObj->getFile($csvPathAndFile);
|
||||
$mailObj->addAttachment($attachment, $csvFile, 'text/csv');
|
||||
endif;
|
||||
*/
|
||||
|
||||
$mailResult = $mailObj->send(array($mailToAddresses), 'smtp');
|
||||
// $mailResult = sendPDFMail($hqId, $mailtext, $title, $mailToAddresses, $fileNameTarget, $mailSubject, $mailText, $mailAttachedFileType, $mailCcAddresses, $mailBccAddresses, $mailSenderAddress, $parKeyForLogFile, $objId, $cascadingObjType);
|
||||
|
||||
if ($mailResult) :
|
||||
$mailResultMsg = "OK";
|
||||
else :
|
||||
$mailResultMsg = "NOK";
|
||||
endif;
|
||||
$opState = $mailResultMsg;
|
||||
endif;
|
||||
endif;
|
||||
else :
|
||||
$opState = "ERR 101 : Unknown client IP!";
|
||||
endif;
|
||||
else :
|
||||
// $opState = "ERR 100 : Authentication!";
|
||||
endif;
|
||||
|
||||
|
||||
// Append to log file
|
||||
writeToFile($logFile, "datetime=" . $currentTime . "|IP=" . $currentClientIP . "|cr_id=" . $boExtId1 . "|day=" . $boExtId0 . "|bo_id=" . $boId . "|mail_result=" . $mailResultMsg . "|op_state=" . $opState);
|
||||
|
||||
// echo "OK";
|
||||
// echo $opState;
|
||||
?>
|
||||
2268
html/illt/inc_serviceunit.inc.php
Normal file
2268
html/illt/inc_serviceunit.inc.php
Normal file
File diff suppressed because it is too large
Load Diff
4844
html/illt/servicejob.php
Normal file
4844
html/illt/servicejob.php
Normal file
File diff suppressed because it is too large
Load Diff
19
html/illt/test.php
Normal file
19
html/illt/test.php
Normal file
@@ -0,0 +1,19 @@
|
||||
<?php
|
||||
|
||||
include_once ("../include/mcglobal.inc.php");
|
||||
include_once ("../include/auth.inc.php");
|
||||
// include_once ("../include/html.inc.php");
|
||||
// include_once ("../include/inc_vehicle.inc.php");
|
||||
include_once ("../include/inc_stock.inc.php");
|
||||
// include_once ("../locating/xServer.inc.php");
|
||||
include_once ("../illt/inc_serviceunit.inc.php");
|
||||
|
||||
illtInitGlobals();
|
||||
|
||||
include_once ("../include/inc_calendar.inc.php");
|
||||
|
||||
|
||||
$xTest = getServiceUnits();
|
||||
// var_export($xTest);
|
||||
print_r($xTest);
|
||||
?>
|
||||
Reference in New Issue
Block a user