/obs_saisons/SPIP-v1-8-3/modules/configuration/DB.php |
---|
New file |
0,0 → 1,1489 |
<?php |
/* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4: */ |
/** |
* Database independent query interface |
* |
* PHP versions 4 and 5 |
* |
* LICENSE: This source file is subject to version 3.0 of the PHP license |
* that is available through the world-wide-web at the following URI: |
* http://www.php.net/license/3_0.txt. If you did not receive a copy of |
* the PHP License and are unable to obtain it through the web, please |
* send a note to license@php.net so we can mail you a copy immediately. |
* |
* @category Database |
* @package DB |
* @author Stig Bakken <ssb@php.net> |
* @author Tomas V.V.Cox <cox@idecnet.com> |
* @author Daniel Convissor <danielc@php.net> |
* @copyright 1997-2007 The PHP Group |
* @license http://www.php.net/license/3_0.txt PHP License 3.0 |
* @version CVS: $Id: DB.php,v 1.1 2008/07/07 18:00:48 mrflos Exp $ |
* @link http://pear.php.net/package/DB |
*/ |
/** |
* Obtain the PEAR class so it can be extended from |
*/ |
require_once 'PEAR.php'; |
// {{{ constants |
// {{{ error codes |
/**#@+ |
* One of PEAR DB's portable error codes. |
* @see DB_common::errorCode(), DB::errorMessage() |
* |
* {@internal If you add an error code here, make sure you also add a textual |
* version of it in DB::errorMessage().}} |
*/ |
/** |
* The code returned by many methods upon success |
*/ |
define('DB_OK', 1); |
/** |
* Unkown error |
*/ |
define('DB_ERROR', -1); |
/** |
* Syntax error |
*/ |
define('DB_ERROR_SYNTAX', -2); |
/** |
* Tried to insert a duplicate value into a primary or unique index |
*/ |
define('DB_ERROR_CONSTRAINT', -3); |
/** |
* An identifier in the query refers to a non-existant object |
*/ |
define('DB_ERROR_NOT_FOUND', -4); |
/** |
* Tried to create a duplicate object |
*/ |
define('DB_ERROR_ALREADY_EXISTS', -5); |
/** |
* The current driver does not support the action you attempted |
*/ |
define('DB_ERROR_UNSUPPORTED', -6); |
/** |
* The number of parameters does not match the number of placeholders |
*/ |
define('DB_ERROR_MISMATCH', -7); |
/** |
* A literal submitted did not match the data type expected |
*/ |
define('DB_ERROR_INVALID', -8); |
/** |
* The current DBMS does not support the action you attempted |
*/ |
define('DB_ERROR_NOT_CAPABLE', -9); |
/** |
* A literal submitted was too long so the end of it was removed |
*/ |
define('DB_ERROR_TRUNCATED', -10); |
/** |
* A literal number submitted did not match the data type expected |
*/ |
define('DB_ERROR_INVALID_NUMBER', -11); |
/** |
* A literal date submitted did not match the data type expected |
*/ |
define('DB_ERROR_INVALID_DATE', -12); |
/** |
* Attempt to divide something by zero |
*/ |
define('DB_ERROR_DIVZERO', -13); |
/** |
* A database needs to be selected |
*/ |
define('DB_ERROR_NODBSELECTED', -14); |
/** |
* Could not create the object requested |
*/ |
define('DB_ERROR_CANNOT_CREATE', -15); |
/** |
* Could not drop the database requested because it does not exist |
*/ |
define('DB_ERROR_CANNOT_DROP', -17); |
/** |
* An identifier in the query refers to a non-existant table |
*/ |
define('DB_ERROR_NOSUCHTABLE', -18); |
/** |
* An identifier in the query refers to a non-existant column |
*/ |
define('DB_ERROR_NOSUCHFIELD', -19); |
/** |
* The data submitted to the method was inappropriate |
*/ |
define('DB_ERROR_NEED_MORE_DATA', -20); |
/** |
* The attempt to lock the table failed |
*/ |
define('DB_ERROR_NOT_LOCKED', -21); |
/** |
* The number of columns doesn't match the number of values |
*/ |
define('DB_ERROR_VALUE_COUNT_ON_ROW', -22); |
/** |
* The DSN submitted has problems |
*/ |
define('DB_ERROR_INVALID_DSN', -23); |
/** |
* Could not connect to the database |
*/ |
define('DB_ERROR_CONNECT_FAILED', -24); |
/** |
* The PHP extension needed for this DBMS could not be found |
*/ |
define('DB_ERROR_EXTENSION_NOT_FOUND',-25); |
/** |
* The present user has inadequate permissions to perform the task requestd |
*/ |
define('DB_ERROR_ACCESS_VIOLATION', -26); |
/** |
* The database requested does not exist |
*/ |
define('DB_ERROR_NOSUCHDB', -27); |
/** |
* Tried to insert a null value into a column that doesn't allow nulls |
*/ |
define('DB_ERROR_CONSTRAINT_NOT_NULL',-29); |
/**#@-*/ |
// }}} |
// {{{ prepared statement-related |
/**#@+ |
* Identifiers for the placeholders used in prepared statements. |
* @see DB_common::prepare() |
*/ |
/** |
* Indicates a scalar (<kbd>?</kbd>) placeholder was used |
* |
* Quote and escape the value as necessary. |
*/ |
define('DB_PARAM_SCALAR', 1); |
/** |
* Indicates an opaque (<kbd>&</kbd>) placeholder was used |
* |
* The value presented is a file name. Extract the contents of that file |
* and place them in this column. |
*/ |
define('DB_PARAM_OPAQUE', 2); |
/** |
* Indicates a misc (<kbd>!</kbd>) placeholder was used |
* |
* The value should not be quoted or escaped. |
*/ |
define('DB_PARAM_MISC', 3); |
/**#@-*/ |
// }}} |
// {{{ binary data-related |
/**#@+ |
* The different ways of returning binary data from queries. |
*/ |
/** |
* Sends the fetched data straight through to output |
*/ |
define('DB_BINMODE_PASSTHRU', 1); |
/** |
* Lets you return data as usual |
*/ |
define('DB_BINMODE_RETURN', 2); |
/** |
* Converts the data to hex format before returning it |
* |
* For example the string "123" would become "313233". |
*/ |
define('DB_BINMODE_CONVERT', 3); |
/**#@-*/ |
// }}} |
// {{{ fetch modes |
/**#@+ |
* Fetch Modes. |
* @see DB_common::setFetchMode() |
*/ |
/** |
* Indicates the current default fetch mode should be used |
* @see DB_common::$fetchmode |
*/ |
define('DB_FETCHMODE_DEFAULT', 0); |
/** |
* Column data indexed by numbers, ordered from 0 and up |
*/ |
define('DB_FETCHMODE_ORDERED', 1); |
/** |
* Column data indexed by column names |
*/ |
define('DB_FETCHMODE_ASSOC', 2); |
/** |
* Column data as object properties |
*/ |
define('DB_FETCHMODE_OBJECT', 3); |
/** |
* For multi-dimensional results, make the column name the first level |
* of the array and put the row number in the second level of the array |
* |
* This is flipped from the normal behavior, which puts the row numbers |
* in the first level of the array and the column names in the second level. |
*/ |
define('DB_FETCHMODE_FLIPPED', 4); |
/**#@-*/ |
/**#@+ |
* Old fetch modes. Left here for compatibility. |
*/ |
define('DB_GETMODE_ORDERED', DB_FETCHMODE_ORDERED); |
define('DB_GETMODE_ASSOC', DB_FETCHMODE_ASSOC); |
define('DB_GETMODE_FLIPPED', DB_FETCHMODE_FLIPPED); |
/**#@-*/ |
// }}} |
// {{{ tableInfo() && autoPrepare()-related |
/**#@+ |
* The type of information to return from the tableInfo() method. |
* |
* Bitwised constants, so they can be combined using <kbd>|</kbd> |
* and removed using <kbd>^</kbd>. |
* |
* @see DB_common::tableInfo() |
* |
* {@internal Since the TABLEINFO constants are bitwised, if more of them are |
* added in the future, make sure to adjust DB_TABLEINFO_FULL accordingly.}} |
*/ |
define('DB_TABLEINFO_ORDER', 1); |
define('DB_TABLEINFO_ORDERTABLE', 2); |
define('DB_TABLEINFO_FULL', 3); |
/**#@-*/ |
/**#@+ |
* The type of query to create with the automatic query building methods. |
* @see DB_common::autoPrepare(), DB_common::autoExecute() |
*/ |
define('DB_AUTOQUERY_INSERT', 1); |
define('DB_AUTOQUERY_UPDATE', 2); |
/**#@-*/ |
// }}} |
// {{{ portability modes |
/**#@+ |
* Portability Modes. |
* |
* Bitwised constants, so they can be combined using <kbd>|</kbd> |
* and removed using <kbd>^</kbd>. |
* |
* @see DB_common::setOption() |
* |
* {@internal Since the PORTABILITY constants are bitwised, if more of them are |
* added in the future, make sure to adjust DB_PORTABILITY_ALL accordingly.}} |
*/ |
/** |
* Turn off all portability features |
*/ |
define('DB_PORTABILITY_NONE', 0); |
/** |
* Convert names of tables and fields to lower case |
* when using the get*(), fetch*() and tableInfo() methods |
*/ |
define('DB_PORTABILITY_LOWERCASE', 1); |
/** |
* Right trim the data output by get*() and fetch*() |
*/ |
define('DB_PORTABILITY_RTRIM', 2); |
/** |
* Force reporting the number of rows deleted |
*/ |
define('DB_PORTABILITY_DELETE_COUNT', 4); |
/** |
* Enable hack that makes numRows() work in Oracle |
*/ |
define('DB_PORTABILITY_NUMROWS', 8); |
/** |
* Makes certain error messages in certain drivers compatible |
* with those from other DBMS's |
* |
* + mysql, mysqli: change unique/primary key constraints |
* DB_ERROR_ALREADY_EXISTS -> DB_ERROR_CONSTRAINT |
* |
* + odbc(access): MS's ODBC driver reports 'no such field' as code |
* 07001, which means 'too few parameters.' When this option is on |
* that code gets mapped to DB_ERROR_NOSUCHFIELD. |
*/ |
define('DB_PORTABILITY_ERRORS', 16); |
/** |
* Convert null values to empty strings in data output by |
* get*() and fetch*() |
*/ |
define('DB_PORTABILITY_NULL_TO_EMPTY', 32); |
/** |
* Turn on all portability features |
*/ |
define('DB_PORTABILITY_ALL', 63); |
/**#@-*/ |
// }}} |
// }}} |
// {{{ class DB |
/** |
* Database independent query interface |
* |
* The main "DB" class is simply a container class with some static |
* methods for creating DB objects as well as some utility functions |
* common to all parts of DB. |
* |
* The object model of DB is as follows (indentation means inheritance): |
* <pre> |
* DB The main DB class. This is simply a utility class |
* with some "static" methods for creating DB objects as |
* well as common utility functions for other DB classes. |
* |
* DB_common The base for each DB implementation. Provides default |
* | implementations (in OO lingo virtual methods) for |
* | the actual DB implementations as well as a bunch of |
* | query utility functions. |
* | |
* +-DB_mysql The DB implementation for MySQL. Inherits DB_common. |
* When calling DB::factory or DB::connect for MySQL |
* connections, the object returned is an instance of this |
* class. |
* </pre> |
* |
* @category Database |
* @package DB |
* @author Stig Bakken <ssb@php.net> |
* @author Tomas V.V.Cox <cox@idecnet.com> |
* @author Daniel Convissor <danielc@php.net> |
* @copyright 1997-2007 The PHP Group |
* @license http://www.php.net/license/3_0.txt PHP License 3.0 |
* @version Release: 1.7.14RC1 |
* @link http://pear.php.net/package/DB |
*/ |
class DB |
{ |
// {{{ &factory() |
/** |
* Create a new DB object for the specified database type but don't |
* connect to the database |
* |
* @param string $type the database type (eg "mysql") |
* @param array $options an associative array of option names and values |
* |
* @return object a new DB object. A DB_Error object on failure. |
* |
* @see DB_common::setOption() |
*/ |
function &factory($type, $options = false) |
{ |
if (!is_array($options)) { |
$options = array('persistent' => $options); |
} |
if (isset($options['debug']) && $options['debug'] >= 2) { |
// expose php errors with sufficient debug level |
include_once "DB/{$type}.php"; |
} else { |
@include_once "DB/{$type}.php"; |
} |
$classname = "DB_${type}"; |
if (!class_exists($classname)) { |
$tmp = PEAR::raiseError(null, DB_ERROR_NOT_FOUND, null, null, |
"Unable to include the DB/{$type}.php" |
. " file for '$dsn'", |
'DB_Error', true); |
return $tmp; |
} |
@$obj = new $classname; |
foreach ($options as $option => $value) { |
$test = $obj->setOption($option, $value); |
if (DB::isError($test)) { |
return $test; |
} |
} |
return $obj; |
} |
// }}} |
// {{{ &connect() |
/** |
* Create a new DB object including a connection to the specified database |
* |
* Example 1. |
* <code> |
* require_once 'DB.php'; |
* |
* $dsn = 'pgsql://user:password@host/database'; |
* $options = array( |
* 'debug' => 2, |
* 'portability' => DB_PORTABILITY_ALL, |
* ); |
* |
* $db =& DB::connect($dsn, $options); |
* if (PEAR::isError($db)) { |
* die($db->getMessage()); |
* } |
* </code> |
* |
* @param mixed $dsn the string "data source name" or array in the |
* format returned by DB::parseDSN() |
* @param array $options an associative array of option names and values |
* |
* @return object a new DB object. A DB_Error object on failure. |
* |
* @uses DB_dbase::connect(), DB_fbsql::connect(), DB_ibase::connect(), |
* DB_ifx::connect(), DB_msql::connect(), DB_mssql::connect(), |
* DB_mysql::connect(), DB_mysqli::connect(), DB_oci8::connect(), |
* DB_odbc::connect(), DB_pgsql::connect(), DB_sqlite::connect(), |
* DB_sybase::connect() |
* |
* @uses DB::parseDSN(), DB_common::setOption(), PEAR::isError() |
*/ |
function &connect($dsn, $options = array()) |
{ |
$dsninfo = DB::parseDSN($dsn); |
$type = $dsninfo['phptype']; |
if (!is_array($options)) { |
/* |
* For backwards compatibility. $options used to be boolean, |
* indicating whether the connection should be persistent. |
*/ |
$options = array('persistent' => $options); |
} |
if (isset($options['debug']) && $options['debug'] >= 2) { |
// expose php errors with sufficient debug level |
include_once "DB/${type}.php"; |
} else { |
@include_once "DB/${type}.php"; |
} |
$classname = "DB_${type}"; |
if (!class_exists($classname)) { |
$tmp = PEAR::raiseError(null, DB_ERROR_NOT_FOUND, null, null, |
"Unable to include the DB/{$type}.php" |
. " file for '$dsn'", |
'DB_Error', true); |
return $tmp; |
} |
@$obj = new $classname; |
foreach ($options as $option => $value) { |
$test = $obj->setOption($option, $value); |
if (DB::isError($test)) { |
return $test; |
} |
} |
$err = $obj->connect($dsninfo, $obj->getOption('persistent')); |
if (DB::isError($err)) { |
if (is_array($dsn)) { |
$err->addUserInfo(DB::getDSNString($dsn, true)); |
} else { |
$err->addUserInfo($dsn); |
} |
return $err; |
} |
return $obj; |
} |
// }}} |
// {{{ apiVersion() |
/** |
* Return the DB API version |
* |
* @return string the DB API version number |
*/ |
function apiVersion() |
{ |
return '1.7.14RC1'; |
} |
// }}} |
// {{{ isError() |
/** |
* Determines if a variable is a DB_Error object |
* |
* @param mixed $value the variable to check |
* |
* @return bool whether $value is DB_Error object |
*/ |
function isError($value) |
{ |
return is_a($value, 'DB_Error'); |
} |
// }}} |
// {{{ isConnection() |
/** |
* Determines if a value is a DB_<driver> object |
* |
* @param mixed $value the value to test |
* |
* @return bool whether $value is a DB_<driver> object |
*/ |
function isConnection($value) |
{ |
return (is_object($value) && |
is_subclass_of($value, 'db_common') && |
method_exists($value, 'simpleQuery')); |
} |
// }}} |
// {{{ isManip() |
/** |
* Tell whether a query is a data manipulation or data definition query |
* |
* Examples of data manipulation queries are INSERT, UPDATE and DELETE. |
* Examples of data definition queries are CREATE, DROP, ALTER, GRANT, |
* REVOKE. |
* |
* @param string $query the query |
* |
* @return boolean whether $query is a data manipulation query |
*/ |
function isManip($query) |
{ |
$manips = 'INSERT|UPDATE|DELETE|REPLACE|' |
. 'CREATE|DROP|' |
. 'LOAD DATA|SELECT .* INTO .* FROM|COPY|' |
. 'ALTER|GRANT|REVOKE|' |
. 'LOCK|UNLOCK'; |
if (preg_match('/^\s*"?(' . $manips . ')\s+/i', $query)) { |
return true; |
} |
return false; |
} |
// }}} |
// {{{ errorMessage() |
/** |
* Return a textual error message for a DB error code |
* |
* @param integer $value the DB error code |
* |
* @return string the error message or false if the error code was |
* not recognized |
*/ |
function errorMessage($value) |
{ |
static $errorMessages; |
if (!isset($errorMessages)) { |
$errorMessages = array( |
DB_ERROR => 'unknown error', |
DB_ERROR_ACCESS_VIOLATION => 'insufficient permissions', |
DB_ERROR_ALREADY_EXISTS => 'already exists', |
DB_ERROR_CANNOT_CREATE => 'can not create', |
DB_ERROR_CANNOT_DROP => 'can not drop', |
DB_ERROR_CONNECT_FAILED => 'connect failed', |
DB_ERROR_CONSTRAINT => 'constraint violation', |
DB_ERROR_CONSTRAINT_NOT_NULL=> 'null value violates not-null constraint', |
DB_ERROR_DIVZERO => 'division by zero', |
DB_ERROR_EXTENSION_NOT_FOUND=> 'extension not found', |
DB_ERROR_INVALID => 'invalid', |
DB_ERROR_INVALID_DATE => 'invalid date or time', |
DB_ERROR_INVALID_DSN => 'invalid DSN', |
DB_ERROR_INVALID_NUMBER => 'invalid number', |
DB_ERROR_MISMATCH => 'mismatch', |
DB_ERROR_NEED_MORE_DATA => 'insufficient data supplied', |
DB_ERROR_NODBSELECTED => 'no database selected', |
DB_ERROR_NOSUCHDB => 'no such database', |
DB_ERROR_NOSUCHFIELD => 'no such field', |
DB_ERROR_NOSUCHTABLE => 'no such table', |
DB_ERROR_NOT_CAPABLE => 'DB backend not capable', |
DB_ERROR_NOT_FOUND => 'not found', |
DB_ERROR_NOT_LOCKED => 'not locked', |
DB_ERROR_SYNTAX => 'syntax error', |
DB_ERROR_UNSUPPORTED => 'not supported', |
DB_ERROR_TRUNCATED => 'truncated', |
DB_ERROR_VALUE_COUNT_ON_ROW => 'value count on row', |
DB_OK => 'no error', |
); |
} |
if (DB::isError($value)) { |
$value = $value->getCode(); |
} |
return isset($errorMessages[$value]) ? $errorMessages[$value] |
: $errorMessages[DB_ERROR]; |
} |
// }}} |
// {{{ parseDSN() |
/** |
* Parse a data source name |
* |
* Additional keys can be added by appending a URI query string to the |
* end of the DSN. |
* |
* The format of the supplied DSN is in its fullest form: |
* <code> |
* phptype(dbsyntax)://username:password@protocol+hostspec/database?option=8&another=true |
* </code> |
* |
* Most variations are allowed: |
* <code> |
* phptype://username:password@protocol+hostspec:110//usr/db_file.db?mode=0644 |
* phptype://username:password@hostspec/database_name |
* phptype://username:password@hostspec |
* phptype://username@hostspec |
* phptype://hostspec/database |
* phptype://hostspec |
* phptype(dbsyntax) |
* phptype |
* </code> |
* |
* @param string $dsn Data Source Name to be parsed |
* |
* @return array an associative array with the following keys: |
* + phptype: Database backend used in PHP (mysql, odbc etc.) |
* + dbsyntax: Database used with regards to SQL syntax etc. |
* + protocol: Communication protocol to use (tcp, unix etc.) |
* + hostspec: Host specification (hostname[:port]) |
* + database: Database to use on the DBMS server |
* + username: User name for login |
* + password: Password for login |
*/ |
function parseDSN($dsn) |
{ |
$parsed = array( |
'phptype' => false, |
'dbsyntax' => false, |
'username' => false, |
'password' => false, |
'protocol' => false, |
'hostspec' => false, |
'port' => false, |
'socket' => false, |
'database' => false, |
); |
if (is_array($dsn)) { |
$dsn = array_merge($parsed, $dsn); |
if (!$dsn['dbsyntax']) { |
$dsn['dbsyntax'] = $dsn['phptype']; |
} |
return $dsn; |
} |
// Find phptype and dbsyntax |
if (($pos = strpos($dsn, '://')) !== false) { |
$str = substr($dsn, 0, $pos); |
$dsn = substr($dsn, $pos + 3); |
} else { |
$str = $dsn; |
$dsn = null; |
} |
// Get phptype and dbsyntax |
// $str => phptype(dbsyntax) |
if (preg_match('|^(.+?)\((.*?)\)$|', $str, $arr)) { |
$parsed['phptype'] = $arr[1]; |
$parsed['dbsyntax'] = !$arr[2] ? $arr[1] : $arr[2]; |
} else { |
$parsed['phptype'] = $str; |
$parsed['dbsyntax'] = $str; |
} |
if (!count($dsn)) { |
return $parsed; |
} |
// Get (if found): username and password |
// $dsn => username:password@protocol+hostspec/database |
if (($at = strrpos($dsn,'@')) !== false) { |
$str = substr($dsn, 0, $at); |
$dsn = substr($dsn, $at + 1); |
if (($pos = strpos($str, ':')) !== false) { |
$parsed['username'] = rawurldecode(substr($str, 0, $pos)); |
$parsed['password'] = rawurldecode(substr($str, $pos + 1)); |
} else { |
$parsed['username'] = rawurldecode($str); |
} |
} |
// Find protocol and hostspec |
if (preg_match('|^([^(]+)\((.*?)\)/?(.*?)$|', $dsn, $match)) { |
// $dsn => proto(proto_opts)/database |
$proto = $match[1]; |
$proto_opts = $match[2] ? $match[2] : false; |
$dsn = $match[3]; |
} else { |
// $dsn => protocol+hostspec/database (old format) |
if (strpos($dsn, '+') !== false) { |
list($proto, $dsn) = explode('+', $dsn, 2); |
} |
if (strpos($dsn, '/') !== false) { |
list($proto_opts, $dsn) = explode('/', $dsn, 2); |
} else { |
$proto_opts = $dsn; |
$dsn = null; |
} |
} |
// process the different protocol options |
$parsed['protocol'] = (!empty($proto)) ? $proto : 'tcp'; |
$proto_opts = rawurldecode($proto_opts); |
if (strpos($proto_opts, ':') !== false) { |
list($proto_opts, $parsed['port']) = explode(':', $proto_opts); |
} |
if ($parsed['protocol'] == 'tcp') { |
$parsed['hostspec'] = $proto_opts; |
} elseif ($parsed['protocol'] == 'unix') { |
$parsed['socket'] = $proto_opts; |
} |
// Get dabase if any |
// $dsn => database |
if ($dsn) { |
if (($pos = strpos($dsn, '?')) === false) { |
// /database |
$parsed['database'] = rawurldecode($dsn); |
} else { |
// /database?param1=value1¶m2=value2 |
$parsed['database'] = rawurldecode(substr($dsn, 0, $pos)); |
$dsn = substr($dsn, $pos + 1); |
if (strpos($dsn, '&') !== false) { |
$opts = explode('&', $dsn); |
} else { // database?param1=value1 |
$opts = array($dsn); |
} |
foreach ($opts as $opt) { |
list($key, $value) = explode('=', $opt); |
if (!isset($parsed[$key])) { |
// don't allow params overwrite |
$parsed[$key] = rawurldecode($value); |
} |
} |
} |
} |
return $parsed; |
} |
// }}} |
// {{{ getDSNString() |
/** |
* Returns the given DSN in a string format suitable for output. |
* |
* @param array|string the DSN to parse and format |
* @param boolean true to hide the password, false to include it |
* @return string |
*/ |
function getDSNString($dsn, $hidePassword) { |
/* Calling parseDSN will ensure that we have all the array elements |
* defined, and means that we deal with strings and array in the same |
* manner. */ |
$dsnArray = DB::parseDSN($dsn); |
if ($hidePassword) { |
$dsnArray['password'] = 'PASSWORD'; |
} |
/* Protocol is special-cased, as using the default "tcp" along with an |
* Oracle TNS connection string fails. */ |
if (is_string($dsn) && strpos($dsn, 'tcp') === false && $dsnArray['protocol'] == 'tcp') { |
$dsnArray['protocol'] = false; |
} |
// Now we just have to construct the actual string. This is ugly. |
$dsnString = $dsnArray['phptype']; |
if ($dsnArray['dbsyntax']) { |
$dsnString .= '('.$dsnArray['dbsyntax'].')'; |
} |
$dsnString .= '://' |
.$dsnArray['username'] |
.':' |
.$dsnArray['password'] |
.'@' |
.$dsnArray['protocol']; |
if ($dsnArray['socket']) { |
$dsnString .= '('.$dsnArray['socket'].')'; |
} |
if ($dsnArray['protocol'] && $dsnArray['hostspec']) { |
$dsnString .= '+'; |
} |
$dsnString .= $dsnArray['hostspec']; |
if ($dsnArray['port']) { |
$dsnString .= ':'.$dsnArray['port']; |
} |
$dsnString .= '/'.$dsnArray['database']; |
/* Option handling. Unfortunately, parseDSN simply places options into |
* the top-level array, so we'll first get rid of the fields defined by |
* DB and see what's left. */ |
unset($dsnArray['phptype'], |
$dsnArray['dbsyntax'], |
$dsnArray['username'], |
$dsnArray['password'], |
$dsnArray['protocol'], |
$dsnArray['socket'], |
$dsnArray['hostspec'], |
$dsnArray['port'], |
$dsnArray['database'] |
); |
if (count($dsnArray) > 0) { |
$dsnString .= '?'; |
$i = 0; |
foreach ($dsnArray as $key => $value) { |
if (++$i > 1) { |
$dsnString .= '&'; |
} |
$dsnString .= $key.'='.$value; |
} |
} |
return $dsnString; |
} |
// }}} |
} |
// }}} |
// {{{ class DB_Error |
/** |
* DB_Error implements a class for reporting portable database error |
* messages |
* |
* @category Database |
* @package DB |
* @author Stig Bakken <ssb@php.net> |
* @copyright 1997-2007 The PHP Group |
* @license http://www.php.net/license/3_0.txt PHP License 3.0 |
* @version Release: 1.7.14RC1 |
* @link http://pear.php.net/package/DB |
*/ |
class DB_Error extends PEAR_Error |
{ |
// {{{ constructor |
/** |
* DB_Error constructor |
* |
* @param mixed $code DB error code, or string with error message |
* @param int $mode what "error mode" to operate in |
* @param int $level what error level to use for $mode & |
* PEAR_ERROR_TRIGGER |
* @param mixed $debuginfo additional debug info, such as the last query |
* |
* @see PEAR_Error |
*/ |
function DB_Error($code = DB_ERROR, $mode = PEAR_ERROR_RETURN, |
$level = E_USER_NOTICE, $debuginfo = null) |
{ |
if (is_int($code)) { |
$this->PEAR_Error('DB Error: ' . DB::errorMessage($code), $code, |
$mode, $level, $debuginfo); |
} else { |
$this->PEAR_Error("DB Error: $code", DB_ERROR, |
$mode, $level, $debuginfo); |
} |
} |
// }}} |
} |
// }}} |
// {{{ class DB_result |
/** |
* This class implements a wrapper for a DB result set |
* |
* A new instance of this class will be returned by the DB implementation |
* after processing a query that returns data. |
* |
* @category Database |
* @package DB |
* @author Stig Bakken <ssb@php.net> |
* @copyright 1997-2007 The PHP Group |
* @license http://www.php.net/license/3_0.txt PHP License 3.0 |
* @version Release: 1.7.14RC1 |
* @link http://pear.php.net/package/DB |
*/ |
class DB_result |
{ |
// {{{ properties |
/** |
* Should results be freed automatically when there are no more rows? |
* @var boolean |
* @see DB_common::$options |
*/ |
var $autofree; |
/** |
* A reference to the DB_<driver> object |
* @var object |
*/ |
var $dbh; |
/** |
* The current default fetch mode |
* @var integer |
* @see DB_common::$fetchmode |
*/ |
var $fetchmode; |
/** |
* The name of the class into which results should be fetched when |
* DB_FETCHMODE_OBJECT is in effect |
* |
* @var string |
* @see DB_common::$fetchmode_object_class |
*/ |
var $fetchmode_object_class; |
/** |
* The number of rows to fetch from a limit query |
* @var integer |
*/ |
var $limit_count = null; |
/** |
* The row to start fetching from in limit queries |
* @var integer |
*/ |
var $limit_from = null; |
/** |
* The execute parameters that created this result |
* @var array |
* @since Property available since Release 1.7.0 |
*/ |
var $parameters; |
/** |
* The query string that created this result |
* |
* Copied here incase it changes in $dbh, which is referenced |
* |
* @var string |
* @since Property available since Release 1.7.0 |
*/ |
var $query; |
/** |
* The query result resource id created by PHP |
* @var resource |
*/ |
var $result; |
/** |
* The present row being dealt with |
* @var integer |
*/ |
var $row_counter = null; |
/** |
* The prepared statement resource id created by PHP in $dbh |
* |
* This resource is only available when the result set was created using |
* a driver's native execute() method, not PEAR DB's emulated one. |
* |
* Copied here incase it changes in $dbh, which is referenced |
* |
* {@internal Mainly here because the InterBase/Firebird API is only |
* able to retrieve data from result sets if the statemnt handle is |
* still in scope.}} |
* |
* @var resource |
* @since Property available since Release 1.7.0 |
*/ |
var $statement; |
// }}} |
// {{{ constructor |
/** |
* This constructor sets the object's properties |
* |
* @param object &$dbh the DB object reference |
* @param resource $result the result resource id |
* @param array $options an associative array with result options |
* |
* @return void |
*/ |
function DB_result(&$dbh, $result, $options = array()) |
{ |
$this->autofree = $dbh->options['autofree']; |
$this->dbh = &$dbh; |
$this->fetchmode = $dbh->fetchmode; |
$this->fetchmode_object_class = $dbh->fetchmode_object_class; |
$this->parameters = $dbh->last_parameters; |
$this->query = $dbh->last_query; |
$this->result = $result; |
$this->statement = empty($dbh->last_stmt) ? null : $dbh->last_stmt; |
foreach ($options as $key => $value) { |
$this->setOption($key, $value); |
} |
} |
/** |
* Set options for the DB_result object |
* |
* @param string $key the option to set |
* @param mixed $value the value to set the option to |
* |
* @return void |
*/ |
function setOption($key, $value = null) |
{ |
switch ($key) { |
case 'limit_from': |
$this->limit_from = $value; |
break; |
case 'limit_count': |
$this->limit_count = $value; |
} |
} |
// }}} |
// {{{ fetchRow() |
/** |
* Fetch a row of data and return it by reference into an array |
* |
* The type of array returned can be controlled either by setting this |
* method's <var>$fetchmode</var> parameter or by changing the default |
* fetch mode setFetchMode() before calling this method. |
* |
* There are two options for standardizing the information returned |
* from databases, ensuring their values are consistent when changing |
* DBMS's. These portability options can be turned on when creating a |
* new DB object or by using setOption(). |
* |
* + <var>DB_PORTABILITY_LOWERCASE</var> |
* convert names of fields to lower case |
* |
* + <var>DB_PORTABILITY_RTRIM</var> |
* right trim the data |
* |
* @param int $fetchmode the constant indicating how to format the data |
* @param int $rownum the row number to fetch (index starts at 0) |
* |
* @return mixed an array or object containing the row's data, |
* NULL when the end of the result set is reached |
* or a DB_Error object on failure. |
* |
* @see DB_common::setOption(), DB_common::setFetchMode() |
*/ |
function &fetchRow($fetchmode = DB_FETCHMODE_DEFAULT, $rownum = null) |
{ |
if ($fetchmode === DB_FETCHMODE_DEFAULT) { |
$fetchmode = $this->fetchmode; |
} |
if ($fetchmode === DB_FETCHMODE_OBJECT) { |
$fetchmode = DB_FETCHMODE_ASSOC; |
$object_class = $this->fetchmode_object_class; |
} |
if (is_null($rownum) && $this->limit_from !== null) { |
if ($this->row_counter === null) { |
$this->row_counter = $this->limit_from; |
// Skip rows |
if ($this->dbh->features['limit'] === false) { |
$i = 0; |
while ($i++ < $this->limit_from) { |
$this->dbh->fetchInto($this->result, $arr, $fetchmode); |
} |
} |
} |
if ($this->row_counter >= ($this->limit_from + $this->limit_count)) |
{ |
if ($this->autofree) { |
$this->free(); |
} |
$tmp = null; |
return $tmp; |
} |
if ($this->dbh->features['limit'] === 'emulate') { |
$rownum = $this->row_counter; |
} |
$this->row_counter++; |
} |
$res = $this->dbh->fetchInto($this->result, $arr, $fetchmode, $rownum); |
if ($res === DB_OK) { |
if (isset($object_class)) { |
// The default mode is specified in the |
// DB_common::fetchmode_object_class property |
if ($object_class == 'stdClass') { |
$arr = (object) $arr; |
} else { |
$arr = new $object_class($arr); |
} |
} |
return $arr; |
} |
if ($res == null && $this->autofree) { |
$this->free(); |
} |
return $res; |
} |
// }}} |
// {{{ fetchInto() |
/** |
* Fetch a row of data into an array which is passed by reference |
* |
* The type of array returned can be controlled either by setting this |
* method's <var>$fetchmode</var> parameter or by changing the default |
* fetch mode setFetchMode() before calling this method. |
* |
* There are two options for standardizing the information returned |
* from databases, ensuring their values are consistent when changing |
* DBMS's. These portability options can be turned on when creating a |
* new DB object or by using setOption(). |
* |
* + <var>DB_PORTABILITY_LOWERCASE</var> |
* convert names of fields to lower case |
* |
* + <var>DB_PORTABILITY_RTRIM</var> |
* right trim the data |
* |
* @param array &$arr the variable where the data should be placed |
* @param int $fetchmode the constant indicating how to format the data |
* @param int $rownum the row number to fetch (index starts at 0) |
* |
* @return mixed DB_OK if a row is processed, NULL when the end of the |
* result set is reached or a DB_Error object on failure |
* |
* @see DB_common::setOption(), DB_common::setFetchMode() |
*/ |
function fetchInto(&$arr, $fetchmode = DB_FETCHMODE_DEFAULT, $rownum = null) |
{ |
if ($fetchmode === DB_FETCHMODE_DEFAULT) { |
$fetchmode = $this->fetchmode; |
} |
if ($fetchmode === DB_FETCHMODE_OBJECT) { |
$fetchmode = DB_FETCHMODE_ASSOC; |
$object_class = $this->fetchmode_object_class; |
} |
if (is_null($rownum) && $this->limit_from !== null) { |
if ($this->row_counter === null) { |
$this->row_counter = $this->limit_from; |
// Skip rows |
if ($this->dbh->features['limit'] === false) { |
$i = 0; |
while ($i++ < $this->limit_from) { |
$this->dbh->fetchInto($this->result, $arr, $fetchmode); |
} |
} |
} |
if ($this->row_counter >= ( |
$this->limit_from + $this->limit_count)) |
{ |
if ($this->autofree) { |
$this->free(); |
} |
return null; |
} |
if ($this->dbh->features['limit'] === 'emulate') { |
$rownum = $this->row_counter; |
} |
$this->row_counter++; |
} |
$res = $this->dbh->fetchInto($this->result, $arr, $fetchmode, $rownum); |
if ($res === DB_OK) { |
if (isset($object_class)) { |
// default mode specified in the |
// DB_common::fetchmode_object_class property |
if ($object_class == 'stdClass') { |
$arr = (object) $arr; |
} else { |
$arr = new $object_class($arr); |
} |
} |
return DB_OK; |
} |
if ($res == null && $this->autofree) { |
$this->free(); |
} |
return $res; |
} |
// }}} |
// {{{ numCols() |
/** |
* Get the the number of columns in a result set |
* |
* @return int the number of columns. A DB_Error object on failure. |
*/ |
function numCols() |
{ |
return $this->dbh->numCols($this->result); |
} |
// }}} |
// {{{ numRows() |
/** |
* Get the number of rows in a result set |
* |
* @return int the number of rows. A DB_Error object on failure. |
*/ |
function numRows() |
{ |
if ($this->dbh->features['numrows'] === 'emulate' |
&& $this->dbh->options['portability'] & DB_PORTABILITY_NUMROWS) |
{ |
if ($this->dbh->features['prepare']) { |
$res = $this->dbh->query($this->query, $this->parameters); |
} else { |
$res = $this->dbh->query($this->query); |
} |
if (DB::isError($res)) { |
return $res; |
} |
$i = 0; |
while ($res->fetchInto($tmp, DB_FETCHMODE_ORDERED)) { |
$i++; |
} |
$count = $i; |
} else { |
$count = $this->dbh->numRows($this->result); |
} |
/* fbsql is checked for here because limit queries are implemented |
* using a TOP() function, which results in fbsql_num_rows still |
* returning the total number of rows that would have been returned, |
* rather than the real number. As a result, we'll just do the limit |
* calculations for fbsql in the same way as a database with emulated |
* limits. Unfortunately, we can't just do this in DB_fbsql::numRows() |
* because that only gets the result resource, rather than the full |
* DB_Result object. */ |
if (($this->dbh->features['limit'] === 'emulate' |
&& $this->limit_from !== null) |
|| $this->dbh->phptype == 'fbsql') { |
$limit_count = is_null($this->limit_count) ? $count : $this->limit_count; |
if ($count < $this->limit_from) { |
$count = 0; |
} elseif ($count < ($this->limit_from + $limit_count)) { |
$count -= $this->limit_from; |
} else { |
$count = $limit_count; |
} |
} |
return $count; |
} |
// }}} |
// {{{ nextResult() |
/** |
* Get the next result if a batch of queries was executed |
* |
* @return bool true if a new result is available or false if not |
*/ |
function nextResult() |
{ |
return $this->dbh->nextResult($this->result); |
} |
// }}} |
// {{{ free() |
/** |
* Frees the resources allocated for this result set |
* |
* @return bool true on success. A DB_Error object on failure. |
*/ |
function free() |
{ |
$err = $this->dbh->freeResult($this->result); |
if (DB::isError($err)) { |
return $err; |
} |
$this->result = false; |
$this->statement = false; |
return true; |
} |
// }}} |
// {{{ tableInfo() |
/** |
* @see DB_common::tableInfo() |
* @deprecated Method deprecated some time before Release 1.2 |
*/ |
function tableInfo($mode = null) |
{ |
if (is_string($mode)) { |
return $this->dbh->raiseError(DB_ERROR_NEED_MORE_DATA); |
} |
return $this->dbh->tableInfo($this, $mode); |
} |
// }}} |
// {{{ getQuery() |
/** |
* Determine the query string that created this result |
* |
* @return string the query string |
* |
* @since Method available since Release 1.7.0 |
*/ |
function getQuery() |
{ |
return $this->query; |
} |
// }}} |
// {{{ getRowCounter() |
/** |
* Tells which row number is currently being processed |
* |
* @return integer the current row being looked at. Starts at 1. |
*/ |
function getRowCounter() |
{ |
return $this->row_counter; |
} |
// }}} |
} |
// }}} |
// {{{ class DB_row |
/** |
* PEAR DB Row Object |
* |
* The object contains a row of data from a result set. Each column's data |
* is placed in a property named for the column. |
* |
* @category Database |
* @package DB |
* @author Stig Bakken <ssb@php.net> |
* @copyright 1997-2007 The PHP Group |
* @license http://www.php.net/license/3_0.txt PHP License 3.0 |
* @version Release: 1.7.14RC1 |
* @link http://pear.php.net/package/DB |
* @see DB_common::setFetchMode() |
*/ |
class DB_row |
{ |
// {{{ constructor |
/** |
* The constructor places a row's data into properties of this object |
* |
* @param array the array containing the row's data |
* |
* @return void |
*/ |
function DB_row(&$arr) |
{ |
foreach ($arr as $key => $value) { |
$this->$key = &$arr[$key]; |
} |
} |
// }}} |
} |
// }}} |
/* |
* Local variables: |
* tab-width: 4 |
* c-basic-offset: 4 |
* End: |
*/ |
?> |
/obs_saisons/SPIP-v1-8-3/modules/configuration/Auth/Anonymous.php |
---|
New file |
0,0 → 1,138 |
<?php |
/* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4 foldmethod=marker: */ |
/** |
* Anonymous authentication support |
* |
* PHP versions 4 and 5 |
* |
* LICENSE: This source file is subject to version 3.01 of the PHP license |
* that is available through the world-wide-web at the following URI: |
* http://www.php.net/license/3_01.txt. If you did not receive a copy of |
* the PHP License and are unable to obtain it through the web, please |
* send a note to license@php.net so we can mail you a copy immediately. |
* |
* @category Authentication |
* @package Auth |
* @author Yavor Shahpasov <yavo@netsmart.com.cy> |
* @author Adam Ashley <aashley@php.net> |
* @copyright 2001-2006 The PHP Group |
* @license http://www.php.net/license/3_01.txt PHP License 3.01 |
* @version CVS: $Id: Anonymous.php,v 1.6 2007/06/12 03:11:26 aashley Exp $ |
* @link http://pear.php.net/package/Auth |
* @since File available since Release 1.3.0 |
*/ |
/** |
* Include Auth package |
*/ |
require_once 'Auth.php'; |
/** |
* Anonymous Authentication |
* |
* This class provides anonymous authentication if username and password |
* were not supplied |
* |
* @category Authentication |
* @package Auth |
* @author Yavor Shahpasov <yavo@netsmart.com.cy> |
* @author Adam Ashley <aashley@php.net> |
* @copyright 2001-2006 The PHP Group |
* @license http://www.php.net/license/3_01.txt PHP License 3.01 |
* @version Release: 1.6.1 File: $Revision: 1.6 $ |
* @link http://pear.php.net/package/Auth |
* @since Class available since Release 1.3.0 |
*/ |
class Auth_Anonymous extends Auth |
{ |
// {{{ properties |
/** |
* Whether to allow anonymous authentication |
* |
* @var boolean |
*/ |
var $allow_anonymous = true; |
/** |
* Username to use for anonymous user |
* |
* @var string |
*/ |
var $anonymous_username = 'anonymous'; |
// }}} |
// {{{ Auth_Anonymous() [constructor] |
/** |
* Pass all parameters to Parent Auth class |
* |
* Set up the storage driver. |
* |
* @param string Type of the storage driver |
* @param mixed Additional options for the storage driver |
* (example: if you are using DB as the storage |
* driver, you have to pass the dsn string here) |
* |
* @param string Name of the function that creates the login form |
* @param boolean Should the login form be displayed if neccessary? |
* @return void |
* @see Auth::Auth() |
*/ |
function Auth_Anonymous($storageDriver, $options = '', $loginFunction = '', $showLogin = true) { |
parent::Auth($storageDriver, $options, $loginFunction, $showLogin); |
} |
// }}} |
// {{{ login() |
/** |
* Login function |
* |
* If no username & password is passed then login as the username |
* provided in $this->anonymous_username else call standard login() |
* function. |
* |
* @return void |
* @access private |
* @see Auth::login() |
*/ |
function login() { |
if ( $this->allow_anonymous |
&& empty($this->username) |
&& empty($this->password) ) { |
$this->setAuth($this->anonymous_username); |
if (is_callable($this->loginCallback)) { |
call_user_func_array($this->loginCallback, array($this->username, $this) ); |
} |
} else { |
// Call normal login system |
parent::login(); |
} |
} |
// }}} |
// {{{ forceLogin() |
/** |
* Force the user to login |
* |
* Calling this function forces the user to provide a real username and |
* password before continuing. |
* |
* @return void |
*/ |
function forceLogin() { |
$this->allow_anonymous = false; |
if( !empty($this->session['username']) && $this->session['username'] == $this->anonymous_username ) { |
$this->logout(); |
} |
} |
// }}} |
} |
?> |
/obs_saisons/SPIP-v1-8-3/modules/configuration/Auth/Auth.php |
---|
New file |
0,0 → 1,30 |
<?php |
/* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4 foldmethod=marker: */ |
/** |
* Provide compatibility with previous Auth include location. |
* |
* PHP versions 4 and 5 |
* |
* LICENSE: This source file is subject to version 3.01 of the PHP license |
* that is available through the world-wide-web at the following URI: |
* http://www.php.net/license/3_01.txt. If you did not receive a copy of |
* the PHP License and are unable to obtain it through the web, please |
* send a note to license@php.net so we can mail you a copy immediately. |
* |
* @category Authentication |
* @package Auth |
* @author Martin Jansen <mj@php.net> |
* @copyright 2001-2006 The PHP Group |
* @license http://www.php.net/license/3_01.txt PHP License 3.01 |
* @version CVS: $Id: Auth.php,v 1.4 2006/03/02 06:53:08 aashley Exp $ |
* @link http://pear.php.net/package/Auth |
* @deprecated File deprecated since Release 1.2.0 |
*/ |
/** |
* Include Auth package |
*/ |
require_once 'Auth.php'; |
?> |
/obs_saisons/SPIP-v1-8-3/modules/configuration/Auth/Controller.php |
---|
New file |
0,0 → 1,302 |
<?php |
/* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4 foldmethod=marker: */ |
/** |
* Auth Controller |
* |
* PHP versions 4 and 5 |
* |
* LICENSE: This source file is subject to version 3.01 of the PHP license |
* that is available through the world-wide-web at the following URI: |
* http://www.php.net/license/3_01.txt. If you did not receive a copy of |
* the PHP License and are unable to obtain it through the web, please |
* send a note to license@php.net so we can mail you a copy immediately. |
* |
* @category Authentication |
* @package Auth |
* @author Yavor Shahpasov <yavo@netsmart.com.cy> |
* @author Adam Ashley <aashley@php.net> |
* @copyright 2001-2006 The PHP Group |
* @license http://www.php.net/license/3_01.txt PHP License 3.01 |
* @version CVS: $Id: Controller.php,v 1.11 2007/06/12 03:11:26 aashley Exp $ |
* @link http://pear.php.net/package/Auth |
* @since File available since Release 1.3.0 |
*/ |
/** |
* Controlls access to a group of php access |
* and redirects to a predefined login page as |
* needed |
* |
* In all pages |
* <code> |
* include_once('Auth.php'); |
* include_once('Auth/Controller.php'); |
* $_auth = new Auth('File', 'passwd'); |
* $authController = new Auth_Controller($_auth, 'login.php', 'index.php'); |
* $authController->start(); |
* </code> |
* |
* In login.php |
* <code> |
* include_once('Auth.php'); |
* include_once('Auth/Controller.php'); |
* $_auth = new Auth('File', 'passwd'); |
* $authController = new Auth_Controller($_auth, 'login.php', 'index.php'); |
* $authController->start(); |
* if( $authController->isAuthorised() ){ |
* $authController->redirectBack(); |
* } |
* </code> |
* |
* @category Authentication |
* @author Yavor Shahpasov <yavo@netsmart.com.cy> |
* @author Adam Ashley <aashley@php.net> |
* @copyright 2001-2006 The PHP Group |
* @license http://www.php.net/license/3_01.txt PHP License 3.01 |
* @version Release: 1.6.1 File: $Revision: 1.11 $ |
* @link http://pear.php.net/package/Auth |
* @since Class available since Release 1.3.0 |
*/ |
class Auth_Controller |
{ |
// {{{ properties |
/** |
* The Auth instance this controller is managing |
* |
* @var object Auth |
*/ |
var $auth = null; |
/** |
* The login URL |
* @var string |
* */ |
var $login = null; |
/** |
* The default index page to use when the caller page is not set |
* |
* @var string |
*/ |
var $default = null; |
/** |
* If this is set to true after a succesfull login the |
* Auth_Controller::redirectBack() is invoked automatically |
* |
* @var boolean |
*/ |
var $autoRedirectBack = false; |
// }}} |
// {{{ Auth_Controller() [constructor] |
/** |
* Constructor |
* |
* @param Auth An auth instance |
* @param string The login page |
* @param string The default page to go to if return page is not set |
* @param array Some rules about which urls need to be sent to the login page |
* @return void |
* @todo Add a list of urls which need redirection |
*/ |
function Auth_Controller(&$auth_obj, $login='login.php', $default='index.php', $accessList=array()) |
{ |
$this->auth =& $auth_obj; |
$this->_loginPage = $login; |
$this->_defaultPage = $default; |
@session_start(); |
if (!empty($_GET['return']) && $_GET['return'] && !strstr($_GET['return'], $this->_loginPage)) { |
$this->auth->setAuthData('returnUrl', $_GET['return']); |
} |
if(!empty($_GET['authstatus']) && $this->auth->status == '') { |
$this->auth->status = $_GET['authstatus']; |
} |
} |
// }}} |
// {{{ setAutoRedirectBack() |
/** |
* Enables auto redirection when login is done |
* |
* @param bool Sets the autoRedirectBack flag to this |
* @see Auth_Controller::autoRedirectBack |
* @return void |
*/ |
function setAutoRedirectBack($flag = true) |
{ |
$this->autoRedirectBack = $flag; |
} |
// }}} |
// {{{ redirectBack() |
/** |
* Redirects Back to the calling page |
* |
* @return void |
*/ |
function redirectBack() |
{ |
// If redirectback go there |
// else go to the default page |
$returnUrl = $this->auth->getAuthData('returnUrl'); |
if(!$returnUrl) { |
$returnUrl = $this->_defaultPage; |
} |
// Add some entropy to the return to make it unique |
// avoind problems with cached pages and proxies |
if(strpos($returnUrl, '?') === false) { |
$returnUrl .= '?'; |
} |
$returnUrl .= uniqid(''); |
// Track the auth status |
if($this->auth->status != '') { |
$url .= '&authstatus='.$this->auth->status; |
} |
header('Location:'.$returnUrl); |
print("You could not be redirected to <a href=\"$returnUrl\">$returnUrl</a>"); |
} |
// }}} |
// {{{ redirectLogin() |
/** |
* Redirects to the login Page if not authorised |
* |
* put return page on the query or in auth |
* |
* @return void |
*/ |
function redirectLogin() |
{ |
// Go to the login Page |
// For Auth, put some check to avoid infinite redirects, this should at least exclude |
// the login page |
$url = $this->_loginPage; |
if(strpos($url, '?') === false) { |
$url .= '?'; |
} |
if(!strstr($_SERVER['PHP_SELF'], $this->_loginPage)) { |
$url .= 'return='.urlencode($_SERVER['PHP_SELF']); |
} |
// Track the auth status |
if($this->auth->status != '') { |
$url .= '&authstatus='.$this->auth->status; |
} |
header('Location:'.$url); |
print("You could not be redirected to <a href=\"$url\">$url</a>"); |
} |
// }}} |
// {{{ start() |
/** |
* Starts the Auth Procedure |
* |
* If the page requires login the user is redirected to the login page |
* otherwise the Auth::start is called to initialize Auth |
* |
* @return void |
* @todo Implement an access list which specifies which urls/pages need login and which do not |
*/ |
function start() |
{ |
// Check the accessList here |
// ACL should be a list of urls with allow/deny |
// If allow set allowLogin to false |
// Some wild card matching should be implemented ?,* |
if(!strstr($_SERVER['PHP_SELF'], $this->_loginPage) && !$this->auth->checkAuth()) { |
$this->redirectLogin(); |
} else { |
$this->auth->start(); |
// Logged on and on login page |
if(strstr($_SERVER['PHP_SELF'], $this->_loginPage) && $this->auth->checkAuth()){ |
$this->autoRedirectBack ? |
$this->redirectBack() : |
null ; |
} |
} |
} |
// }}} |
// {{{ isAuthorised() |
/** |
* Checks is the user is logged on |
* @see Auth::checkAuth() |
*/ |
function isAuthorised() |
{ |
return($this->auth->checkAuth()); |
} |
// }}} |
// {{{ checkAuth() |
/** |
* Proxy call to auth |
* @see Auth::checkAuth() |
*/ |
function checkAuth() |
{ |
return($this->auth->checkAuth()); |
} |
// }}} |
// {{{ logout() |
/** |
* Proxy call to auth |
* @see Auth::logout() |
*/ |
function logout() |
{ |
return($this->auth->logout()); |
} |
// }}} |
// {{{ getUsername() |
/** |
* Proxy call to auth |
* @see Auth::getUsername() |
*/ |
function getUsername() |
{ |
return($this->auth->getUsername()); |
} |
// }}} |
// {{{ getStatus() |
/** |
* Proxy call to auth |
* @see Auth::getStatus() |
*/ |
function getStatus() |
{ |
return($this->auth->getStatus()); |
} |
// }}} |
} |
?> |
/obs_saisons/SPIP-v1-8-3/modules/configuration/Container/SAP.php |
---|
New file |
0,0 → 1,179 |
<?php |
/* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4 foldmethod=marker: */ |
/** |
* Storage driver for use against a SAP system using the SAPRFC PHP extension. |
* |
* Requires the SAPRFC ext available at http://saprfc.sourceforge.net/ |
* |
* PHP version 5 |
* |
* LICENSE: This source file is subject to version 3.01 of the PHP license |
* that is available through the world-wide-web at the following URI: |
* http://www.php.net/license/3_01.txt. If you did not receive a copy of |
* the PHP License and are unable to obtain it through the web, please |
* send a note to license@php.net so we can mail you a copy immediately. |
* |
* @category Authentication |
* @package Auth |
* @author Stoyan Stefanov <ssttoo@gmail.com> |
* @author Adam Ashley <aashley@php.net> |
* @copyright 2001-2006 The PHP Group |
* @license http://www.php.net/license/3_01.txt PHP License 3.01 |
* @version CVS: $Id: SAP.php,v 1.5 2007/06/12 03:11:26 aashley Exp $ |
* @link http://pear.php.net/package/Auth |
* @since File available since Release 1.4.0 |
*/ |
/** |
* Include Auth_Container base class |
*/ |
require_once 'Auth/Container.php'; |
/** |
* Include PEAR for error handling |
*/ |
require_once 'PEAR.php'; |
/** |
* Performs authentication against a SAP system using the SAPRFC PHP extension. |
* |
* When the option GETSSO2 is TRUE (default) |
* the Single Sign-On (SSO) ticket is retrieved |
* and stored as an Auth attribute called 'sap' |
* in order to be reused for consecutive connections. |
* |
* @category Authentication |
* @package Auth |
* @author Stoyan Stefanov <ssttoo@gmail.com> |
* @author Adam Ashley <aashley@php.net> |
* @copyright 2001-2006 The PHP Group |
* @license http://www.php.net/license/3_01.txt PHP License 3.01 |
* @version Release: 1.6.1 File: $Revision: 1.5 $ |
* @since Class available since Release 1.4.0 |
*/ |
class Auth_Container_SAP extends Auth_Container { |
// {{{ properties |
/** |
* @var array Default options |
*/ |
var $options = array( |
'CLIENT' => '000', |
'LANG' => 'EN', |
'GETSSO2' => true, |
); |
// }}} |
// {{{ Auth_Container_SAP() |
/** |
* Class constructor. Checks that required options |
* are present and that the SAPRFC extension is loaded |
* |
* Options that can be passed and their defaults: |
* <pre> |
* array( |
* 'ASHOST' => "", |
* 'SYSNR' => "", |
* 'CLIENT' => "000", |
* 'GWHOST' =>"", |
* 'GWSERV' =>"", |
* 'MSHOST' =>"", |
* 'R3NAME' =>"", |
* 'GROUP' =>"", |
* 'LANG' =>"EN", |
* 'TRACE' =>"", |
* 'GETSSO2'=> true |
* ) |
* </pre> |
* |
* @param array array of options. |
* @return void |
*/ |
function Auth_Container_SAP($options) |
{ |
$saprfc_loaded = PEAR::loadExtension('saprfc'); |
if (!$saprfc_loaded) { |
return PEAR::raiseError('Cannot use SAP authentication, ' |
.'SAPRFC extension not loaded!'); |
} |
if (empty($options['R3NAME']) && empty($options['ASHOST'])) { |
return PEAR::raiseError('R3NAME or ASHOST required for authentication'); |
} |
$this->options = array_merge($this->options, $options); |
} |
// }}} |
// {{{ fetchData() |
/** |
* Performs username and password check |
* |
* @param string Username |
* @param string Password |
* @return boolean TRUE on success (valid user), FALSE otherwise |
*/ |
function fetchData($username, $password) |
{ |
$this->log('Auth_Container_SAP::fetchData() called.', AUTH_LOG_DEBUG); |
$connection_options = $this->options; |
$connection_options['USER'] = $username; |
$connection_options['PASSWD'] = $password; |
$rfc = saprfc_open($connection_options); |
if (!$rfc) { |
$message = "Couldn't connect to the SAP system."; |
$error = $this->getError(); |
if ($error['message']) { |
$message .= ': ' . $error['message']; |
} |
PEAR::raiseError($message, null, null, null, @$erorr['all']); |
return false; |
} else { |
if (!empty($this->options['GETSSO2'])) { |
$this->log('Attempting to retrieve SSO2 ticket.', AUTH_LOG_DEBUG); |
if ($ticket = @saprfc_get_ticket($rfc)) { |
$this->options['MYSAPSSO2'] = $ticket; |
unset($this->options['GETSSO2']); |
$this->_auth_obj->setAuthData('sap', $this->options); |
} else { |
PEAR::raiseError("SSO ticket retrieval failed"); |
} |
} |
@saprfc_close($rfc); |
return true; |
} |
} |
// }}} |
// {{{ getError() |
/** |
* Retrieves the last error from the SAP connection |
* and returns it as an array. |
* |
* @return array Array of error information |
*/ |
function getError() |
{ |
$error = array(); |
$sap_error = saprfc_error(); |
if (empty($err)) { |
return $error; |
} |
$err = explode("n", $sap_error); |
foreach ($err AS $line) { |
$item = split(':', $line); |
$error[strtolower(trim($item[0]))] = trim($item[1]); |
} |
$error['all'] = $sap_error; |
return $error; |
} |
// }}} |
} |
?> |
/obs_saisons/SPIP-v1-8-3/modules/configuration/Container/MDB2.php |
---|
New file |
0,0 → 1,624 |
<?php |
/* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4 foldmethod=marker: */ |
/** |
* Storage driver for use against PEAR MDB2 |
* |
* PHP versions 4 and 5 |
* |
* LICENSE: This source file is subject to version 3.01 of the PHP license |
* that is available through the world-wide-web at the following URI: |
* http://www.php.net/license/3_01.txt. If you did not receive a copy of |
* the PHP License and are unable to obtain it through the web, please |
* send a note to license@php.net so we can mail you a copy immediately. |
* |
* @category Authentication |
* @package Auth |
* @author Lorenzo Alberton <l.alberton@quipo.it> |
* @author Adam Ashley <aashley@php.net> |
* @copyright 2001-2006 The PHP Group |
* @license http://www.php.net/license/3_01.txt PHP License 3.01 |
* @version CVS: $Id: MDB2.php,v 1.24 2008/04/04 07:57:02 aashley Exp $ |
* @link http://pear.php.net/package/Auth |
* @since File available since Release 1.3.0 |
*/ |
/** |
* Include Auth_Container base class |
*/ |
require_once 'Auth/Container.php'; |
/** |
* Include PEAR MDB2 package |
*/ |
require_once 'MDB2.php'; |
/** |
* Storage driver for fetching login data from a database |
* |
* This storage driver can use all databases which are supported |
* by the PEAR MDB2 abstraction layer to fetch login data. |
* |
* @category Authentication |
* @package Auth |
* @author Lorenzo Alberton <l.alberton@quipo.it> |
* @author Adam Ashley <aashley@php.net> |
* @copyright 2001-2006 The PHP Group |
* @license http://www.php.net/license/3_01.txt PHP License 3.01 |
* @version Release: 1.6.1 File: $Revision: 1.24 $ |
* @link http://pear.php.net/package/Auth |
* @since Class available since Release 1.3.0 |
*/ |
class Auth_Container_MDB2 extends Auth_Container |
{ |
// {{{ properties |
/** |
* Additional options for the storage container |
* @var array |
*/ |
var $options = array(); |
/** |
* MDB object |
* @var object |
*/ |
var $db = null; |
var $dsn = ''; |
/** |
* User that is currently selected from the DB. |
* @var string |
*/ |
var $activeUser = ''; |
// }}} |
// {{{ Auth_Container_MDB2() [constructor] |
/** |
* Constructor of the container class |
* |
* Initate connection to the database via PEAR::MDB2 |
* |
* @param string Connection data or MDB2 object |
* @return object Returns an error object if something went wrong |
*/ |
function Auth_Container_MDB2($dsn) |
{ |
$this->_setDefaults(); |
if (is_array($dsn)) { |
$this->_parseOptions($dsn); |
if (empty($this->options['dsn'])) { |
PEAR::raiseError('No connection parameters specified!'); |
} |
} else { |
$this->options['dsn'] = $dsn; |
} |
} |
// }}} |
// {{{ _connect() |
/** |
* Connect to database by using the given DSN string |
* |
* @access private |
* @param mixed DSN string | array | mdb object |
* @return mixed Object on error, otherwise bool |
*/ |
function _connect($dsn) |
{ |
$this->log('Auth_Container_MDB2::_connect() called.', AUTH_LOG_DEBUG); |
if (is_string($dsn) || is_array($dsn)) { |
$this->db =& MDB2::connect($dsn, $this->options['db_options']); |
} elseif (is_subclass_of($dsn, 'MDB2_Driver_Common')) { |
$this->db = $dsn; |
} elseif (is_object($dsn) && MDB2::isError($dsn)) { |
return PEAR::raiseError($dsn->getMessage(), $dsn->code); |
} else { |
return PEAR::raiseError('The given dsn was not valid in file ' . __FILE__ . ' at line ' . __LINE__, |
41, |
PEAR_ERROR_RETURN, |
null, |
null |
); |
} |
if (MDB2::isError($this->db) || PEAR::isError($this->db)) { |
return PEAR::raiseError($this->db->getMessage(), $this->db->code); |
} |
if ($this->options['auto_quote']) { |
if (strpos('.', $this->options['table']) === false) { |
$this->options['final_table'] = $this->db->quoteIdentifier($this->options['table'], true); |
} else { |
$t = explode('.', $this->options['table']); |
for ($i = 0, $count = count($t); $i < $count; $i++) |
$t[$i] = $this->db->quoteIdentifier($t[$i], true); |
$this->options['final_table'] = implode('.', $t); |
} |
$this->options['final_usernamecol'] = $this->db->quoteIdentifier($this->options['usernamecol'], true); |
$this->options['final_passwordcol'] = $this->db->quoteIdentifier($this->options['passwordcol'], true); |
} else { |
$this->options['final_table'] = $this->options['table']; |
$this->options['final_usernamecol'] = $this->options['usernamecol']; |
$this->options['final_passwordcol'] = $this->options['passwordcol']; |
} |
return true; |
} |
// }}} |
// {{{ _prepare() |
/** |
* Prepare database connection |
* |
* This function checks if we have already opened a connection to |
* the database. If that's not the case, a new connection is opened. |
* |
* @access private |
* @return mixed True or a MDB error object. |
*/ |
function _prepare() |
{ |
if (is_subclass_of($this->db, 'MDB2_Driver_Common')) { |
return true; |
} |
return $this->_connect($this->options['dsn']); |
} |
// }}} |
// {{{ query() |
/** |
* Prepare query to the database |
* |
* This function checks if we have already opened a connection to |
* the database. If that's not the case, a new connection is opened. |
* After that the query is passed to the database. |
* |
* @access public |
* @param string Query string |
* @return mixed a MDB_result object or MDB_OK on success, a MDB |
* or PEAR error on failure |
*/ |
function query($query) |
{ |
$this->log('Auth_Container_MDB2::query() called.', AUTH_LOG_DEBUG); |
$err = $this->_prepare(); |
if ($err !== true) { |
return $err; |
} |
return $this->db->exec($query); |
} |
// }}} |
// {{{ _setDefaults() |
/** |
* Set some default options |
* |
* @access private |
* @return void |
*/ |
function _setDefaults() |
{ |
$this->options['table'] = 'auth'; |
$this->options['usernamecol'] = 'username'; |
$this->options['passwordcol'] = 'password'; |
$this->options['dsn'] = ''; |
$this->options['db_fields'] = ''; |
$this->options['cryptType'] = 'md5'; |
$this->options['db_options'] = array(); |
$this->options['db_where'] = ''; |
$this->options['auto_quote'] = true; |
} |
// }}} |
// {{{ _parseOptions() |
/** |
* Parse options passed to the container class |
* |
* @access private |
* @param array |
*/ |
function _parseOptions($array) |
{ |
foreach ($array as $key => $value) { |
if (isset($this->options[$key])) { |
$this->options[$key] = $value; |
} |
} |
} |
// }}} |
// {{{ _quoteDBFields() |
/** |
* Quote the db_fields option to avoid the possibility of SQL injection. |
* |
* @access private |
* @return string A properly quoted string that can be concatenated into a |
* SELECT clause. |
*/ |
function _quoteDBFields() |
{ |
if (isset($this->options['db_fields'])) { |
if (is_array($this->options['db_fields'])) { |
if ($this->options['auto_quote']) { |
$fields = array(); |
foreach ($this->options['db_fields'] as $field) { |
$fields[] = $this->db->quoteIdentifier($field, true); |
} |
return implode(', ', $fields); |
} else { |
return implode(', ', $this->options['db_fields']); |
} |
} else { |
if (strlen($this->options['db_fields']) > 0) { |
if ($this->options['auto_quote']) { |
return $this->db->quoteIdentifier($this->options['db_fields'], true); |
} else { |
return $this->options['db_fields']; |
} |
} |
} |
} |
return ''; |
} |
// }}} |
// {{{ fetchData() |
/** |
* Get user information from database |
* |
* This function uses the given username to fetch |
* the corresponding login data from the database |
* table. If an account that matches the passed username |
* and password is found, the function returns true. |
* Otherwise it returns false. |
* |
* @param string Username |
* @param string Password |
* @param boolean If true password is secured using a md5 hash |
* the frontend and auth are responsible for making sure the container supports |
* challenge response password authentication |
* @return mixed Error object or boolean |
*/ |
function fetchData($username, $password, $isChallengeResponse=false) |
{ |
$this->log('Auth_Container_MDB2::fetchData() called.', AUTH_LOG_DEBUG); |
// Prepare for a database query |
$err = $this->_prepare(); |
if ($err !== true) { |
return PEAR::raiseError($err->getMessage(), $err->getCode()); |
} |
//Check if db_fields contains a *, if so assume all columns are selected |
if (is_string($this->options['db_fields']) |
&& strstr($this->options['db_fields'], '*')) { |
$sql_from = '*'; |
} else { |
$sql_from = $this->options['final_usernamecol']. |
", ".$this->options['final_passwordcol']; |
if (strlen($fields = $this->_quoteDBFields()) > 0) { |
$sql_from .= ', '.$fields; |
} |
} |
$query = sprintf("SELECT %s FROM %s WHERE %s = %s", |
$sql_from, |
$this->options['final_table'], |
$this->options['final_usernamecol'], |
$this->db->quote($username, 'text') |
); |
// check if there is an optional parameter db_where |
if ($this->options['db_where'] != '') { |
// there is one, so add it to the query |
$query .= " AND ".$this->options['db_where']; |
} |
$this->log('Running SQL against MDB2: '.$query, AUTH_LOG_DEBUG); |
$res = $this->db->queryRow($query, null, MDB2_FETCHMODE_ASSOC); |
if (MDB2::isError($res) || PEAR::isError($res)) { |
return PEAR::raiseError($res->getMessage(), $res->getCode()); |
} |
if (!is_array($res)) { |
$this->activeUser = ''; |
return false; |
} |
// Perform trimming here before the hashing |
$password = trim($password, "\r\n"); |
$res[$this->options['passwordcol']] = trim($res[$this->options['passwordcol']], "\r\n"); |
// If using Challenge Response md5 the pass with the secret |
if ($isChallengeResponse) { |
$res[$this->options['passwordcol']] = |
md5($res[$this->options['passwordcol']].$this->_auth_obj->session['loginchallenege']); |
// UGLY cannot avoid without modifying verifyPassword |
if ($this->options['cryptType'] == 'md5') { |
$res[$this->options['passwordcol']] = md5($res[$this->options['passwordcol']]); |
} |
} |
if ($this->verifyPassword($password, |
$res[$this->options['passwordcol']], |
$this->options['cryptType'])) { |
// Store additional field values in the session |
foreach ($res as $key => $value) { |
if ($key == $this->options['passwordcol'] || |
$key == $this->options['usernamecol']) { |
continue; |
} |
$this->log('Storing additional field: '.$key, AUTH_LOG_DEBUG); |
// Use reference to the auth object if exists |
// This is because the auth session variable can change so a static call to setAuthData does not make sense |
$this->_auth_obj->setAuthData($key, $value); |
} |
return true; |
} |
$this->activeUser = $res[$this->options['usernamecol']]; |
return false; |
} |
// }}} |
// {{{ listUsers() |
/** |
* Returns a list of users from the container |
* |
* @return mixed array|PEAR_Error |
* @access public |
*/ |
function listUsers() |
{ |
$this->log('Auth_Container_MDB2::listUsers() called.', AUTH_LOG_DEBUG); |
$err = $this->_prepare(); |
if ($err !== true) { |
return PEAR::raiseError($err->getMessage(), $err->getCode()); |
} |
$retVal = array(); |
//Check if db_fields contains a *, if so assume all columns are selected |
if ( is_string($this->options['db_fields']) |
&& strstr($this->options['db_fields'], '*')) { |
$sql_from = '*'; |
} else { |
$sql_from = $this->options['final_usernamecol']. |
", ".$this->options['final_passwordcol']; |
if (strlen($fields = $this->_quoteDBFields()) > 0) { |
$sql_from .= ', '.$fields; |
} |
} |
$query = sprintf('SELECT %s FROM %s', |
$sql_from, |
$this->options['final_table'] |
); |
// check if there is an optional parameter db_where |
if ($this->options['db_where'] != '') { |
// there is one, so add it to the query |
$query .= " WHERE ".$this->options['db_where']; |
} |
$this->log('Running SQL against MDB2: '.$query, AUTH_LOG_DEBUG); |
$res = $this->db->queryAll($query, null, MDB2_FETCHMODE_ASSOC); |
if (MDB2::isError($res)) { |
return PEAR::raiseError($res->getMessage(), $res->getCode()); |
} else { |
foreach ($res as $user) { |
$user['username'] = $user[$this->options['usernamecol']]; |
$retVal[] = $user; |
} |
} |
$this->log('Found '.count($retVal).' users.', AUTH_LOG_DEBUG); |
return $retVal; |
} |
// }}} |
// {{{ addUser() |
/** |
* Add user to the storage container |
* |
* @access public |
* @param string Username |
* @param string Password |
* @param mixed Additional information that are stored in the DB |
* |
* @return mixed True on success, otherwise error object |
*/ |
function addUser($username, $password, $additional = "") |
{ |
$this->log('Auth_Container_MDB2::addUser() called.', AUTH_LOG_DEBUG); |
// Prepare for a database query |
$err = $this->_prepare(); |
if ($err !== true) { |
return PEAR::raiseError($err->getMessage(), $err->getCode()); |
} |
if (isset($this->options['cryptType']) && $this->options['cryptType'] == 'none') { |
$cryptFunction = 'strval'; |
} elseif (isset($this->options['cryptType']) && function_exists($this->options['cryptType'])) { |
$cryptFunction = $this->options['cryptType']; |
} else { |
$cryptFunction = 'md5'; |
} |
$password = $cryptFunction($password); |
$additional_key = ''; |
$additional_value = ''; |
if (is_array($additional)) { |
foreach ($additional as $key => $value) { |
if ($this->options['auto_quote']) { |
$additional_key .= ', ' . $this->db->quoteIdentifier($key, true); |
} else { |
$additional_key .= ', ' . $key; |
} |
$additional_value .= ', ' . $this->db->quote($value, 'text'); |
} |
} |
$query = sprintf("INSERT INTO %s (%s, %s%s) VALUES (%s, %s%s)", |
$this->options['final_table'], |
$this->options['final_usernamecol'], |
$this->options['final_passwordcol'], |
$additional_key, |
$this->db->quote($username, 'text'), |
$this->db->quote($password, 'text'), |
$additional_value |
); |
$this->log('Running SQL against MDB2: '.$query, AUTH_LOG_DEBUG); |
$res = $this->query($query); |
if (MDB2::isError($res)) { |
return PEAR::raiseError($res->getMessage(), $res->code); |
} |
return true; |
} |
// }}} |
// {{{ removeUser() |
/** |
* Remove user from the storage container |
* |
* @access public |
* @param string Username |
* |
* @return mixed True on success, otherwise error object |
*/ |
function removeUser($username) |
{ |
$this->log('Auth_Container_MDB2::removeUser() called.', AUTH_LOG_DEBUG); |
// Prepare for a database query |
$err = $this->_prepare(); |
if ($err !== true) { |
return PEAR::raiseError($err->getMessage(), $err->getCode()); |
} |
$query = sprintf("DELETE FROM %s WHERE %s = %s", |
$this->options['final_table'], |
$this->options['final_usernamecol'], |
$this->db->quote($username, 'text') |
); |
// check if there is an optional parameter db_where |
if ($this->options['db_where'] != '') { |
// there is one, so add it to the query |
$query .= " AND ".$this->options['db_where']; |
} |
$this->log('Running SQL against MDB2: '.$query, AUTH_LOG_DEBUG); |
$res = $this->query($query); |
if (MDB2::isError($res)) { |
return PEAR::raiseError($res->getMessage(), $res->code); |
} |
return true; |
} |
// }}} |
// {{{ changePassword() |
/** |
* Change password for user in the storage container |
* |
* @param string Username |
* @param string The new password (plain text) |
*/ |
function changePassword($username, $password) |
{ |
$this->log('Auth_Container_MDB2::changePassword() called.', AUTH_LOG_DEBUG); |
// Prepare for a database query |
$err = $this->_prepare(); |
if ($err !== true) { |
return PEAR::raiseError($err->getMessage(), $err->getCode()); |
} |
if (isset($this->options['cryptType']) && $this->options['cryptType'] == 'none') { |
$cryptFunction = 'strval'; |
} elseif (isset($this->options['cryptType']) && function_exists($this->options['cryptType'])) { |
$cryptFunction = $this->options['cryptType']; |
} else { |
$cryptFunction = 'md5'; |
} |
$password = $cryptFunction($password); |
$query = sprintf("UPDATE %s SET %s = %s WHERE %s = %s", |
$this->options['final_table'], |
$this->options['final_passwordcol'], |
$this->db->quote($password, 'text'), |
$this->options['final_usernamecol'], |
$this->db->quote($username, 'text') |
); |
// check if there is an optional parameter db_where |
if ($this->options['db_where'] != '') { |
// there is one, so add it to the query |
$query .= " AND ".$this->options['db_where']; |
} |
$this->log('Running SQL against MDB2: '.$query, AUTH_LOG_DEBUG); |
$res = $this->query($query); |
if (MDB2::isError($res)) { |
return PEAR::raiseError($res->getMessage(), $res->code); |
} |
return true; |
} |
// }}} |
// {{{ supportsChallengeResponse() |
/** |
* Determine if this container supports |
* password authentication with challenge response |
* |
* @return bool |
* @access public |
*/ |
function supportsChallengeResponse() |
{ |
return in_array($this->options['cryptType'], array('md5', 'none', '')); |
} |
// }}} |
// {{{ getCryptType() |
/** |
* Returns the selected crypt type for this container |
* |
* @return string Function used to crypt the password |
*/ |
function getCryptType() |
{ |
return $this->options['cryptType']; |
} |
// }}} |
} |
?> |
/obs_saisons/SPIP-v1-8-3/modules/configuration/Container/DB.php |
---|
New file |
0,0 → 1,639 |
<?php |
/* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4 foldmethod=marker: */ |
/** |
* Storage driver for use against PEAR DB |
* |
* PHP versions 4 and 5 |
* |
* LICENSE: This source file is subject to version 3.01 of the PHP license |
* that is available through the world-wide-web at the following URI: |
* http://www.php.net/license/3_01.txt. If you did not receive a copy of |
* the PHP License and are unable to obtain it through the web, please |
* send a note to license@php.net so we can mail you a copy immediately. |
* |
* @category Authentication |
* @package Auth |
* @author Martin Jansen <mj@php.net> |
* @author Adam Ashley <aashley@php.net> |
* @copyright 2001-2006 The PHP Group |
* @license http://www.php.net/license/3_01.txt PHP License 3.01 |
* @version CVS: $Id: DB.php,v 1.74 2008/04/04 07:57:02 aashley Exp $ |
* @link http://pear.php.net/package/Auth |
*/ |
/** |
* Include Auth_Container base class |
*/ |
require_once 'Auth/Container.php'; |
/** |
* Include PEAR DB |
*/ |
require_once 'DB.php'; |
/** |
* Storage driver for fetching login data from a database |
* |
* This storage driver can use all databases which are supported |
* by the PEAR DB abstraction layer to fetch login data. |
* |
* @category Authentication |
* @package Auth |
* @author Martin Jansen <mj@php.net> |
* @author Adam Ashley <aashley@php.net> |
* @copyright 2001-2006 The PHP Group |
* @license http://www.php.net/license/3_01.txt PHP License 3.01 |
* @version Release: 1.6.1 File: $Revision: 1.74 $ |
* @link http://pear.php.net/package/Auth |
*/ |
class Auth_Container_DB extends Auth_Container |
{ |
// {{{ properties |
/** |
* Additional options for the storage container |
* @var array |
*/ |
var $options = array(); |
/** |
* DB object |
* @var object |
*/ |
var $db = null; |
var $dsn = ''; |
/** |
* User that is currently selected from the DB. |
* @var string |
*/ |
var $activeUser = ''; |
// }}} |
// {{{ Auth_Container_DB [constructor] |
/** |
* Constructor of the container class |
* |
* Save the initial options passed to the container. Initiation of the DB |
* connection is no longer performed here and is only done when needed. |
* |
* @param string Connection data or DB object |
* @return object Returns an error object if something went wrong |
*/ |
function Auth_Container_DB($dsn) |
{ |
$this->_setDefaults(); |
if (is_array($dsn)) { |
$this->_parseOptions($dsn); |
if (empty($this->options['dsn'])) { |
PEAR::raiseError('No connection parameters specified!'); |
} |
} else { |
$this->options['dsn'] = $dsn; |
} |
} |
// }}} |
// {{{ _connect() |
/** |
* Connect to database by using the given DSN string |
* |
* @access private |
* @param string DSN string |
* @return mixed Object on error, otherwise bool |
*/ |
function _connect($dsn) |
{ |
$this->log('Auth_Container_DB::_connect() called.', AUTH_LOG_DEBUG); |
if (is_string($dsn) || is_array($dsn)) { |
$this->db = DB::Connect($dsn, $this->options['db_options']); |
} elseif (is_subclass_of($dsn, 'db_common')) { |
$this->db = $dsn; |
} elseif (DB::isError($dsn)) { |
return PEAR::raiseError($dsn->getMessage(), $dsn->getCode()); |
} else { |
return PEAR::raiseError('The given dsn was not valid in file ' . __FILE__ . ' at line ' . __LINE__, |
41, |
PEAR_ERROR_RETURN, |
null, |
null |
); |
} |
if (DB::isError($this->db) || PEAR::isError($this->db)) { |
return PEAR::raiseError($this->db->getMessage(), $this->db->getCode()); |
} else { |
return true; |
} |
} |
// }}} |
// {{{ _prepare() |
/** |
* Prepare database connection |
* |
* This function checks if we have already opened a connection to |
* the database. If that's not the case, a new connection is opened. |
* |
* @access private |
* @return mixed True or a DB error object. |
*/ |
function _prepare() |
{ |
if (!DB::isConnection($this->db)) { |
$res = $this->_connect($this->options['dsn']); |
if (DB::isError($res) || PEAR::isError($res)) { |
return $res; |
} |
} |
if ($this->options['auto_quote'] && $this->db->dsn['phptype'] != 'sqlite') { |
if (strpos('.', $this->options['table']) === false) { |
$this->options['final_table'] = $this->db->quoteIdentifier($this->options['table']); |
} else { |
$t = explode('.', $this->options['table']); |
for ($i = 0, $count = count($t); $i < $count; $i++) |
$t[$i] = $this->db->quoteIdentifier($t[$i]); |
$this->options['final_table'] = implode('.', $t); |
} |
$this->options['final_usernamecol'] = $this->db->quoteIdentifier($this->options['usernamecol']); |
$this->options['final_passwordcol'] = $this->db->quoteIdentifier($this->options['passwordcol']); |
} else { |
$this->options['final_table'] = $this->options['table']; |
$this->options['final_usernamecol'] = $this->options['usernamecol']; |
$this->options['final_passwordcol'] = $this->options['passwordcol']; |
} |
return true; |
} |
// }}} |
// {{{ query() |
/** |
* Prepare query to the database |
* |
* This function checks if we have already opened a connection to |
* the database. If that's not the case, a new connection is opened. |
* After that the query is passed to the database. |
* |
* @access public |
* @param string Query string |
* @return mixed a DB_result object or DB_OK on success, a DB |
* or PEAR error on failure |
*/ |
function query($query) |
{ |
$err = $this->_prepare(); |
if ($err !== true) { |
return $err; |
} |
return $this->db->query($query); |
} |
// }}} |
// {{{ _setDefaults() |
/** |
* Set some default options |
* |
* @access private |
* @return void |
*/ |
function _setDefaults() |
{ |
$this->options['table'] = 'auth'; |
$this->options['usernamecol'] = 'username'; |
$this->options['passwordcol'] = 'password'; |
$this->options['dsn'] = ''; |
$this->options['db_fields'] = ''; |
$this->options['cryptType'] = 'md5'; |
$this->options['db_options'] = array(); |
$this->options['db_where'] = ''; |
$this->options['auto_quote'] = true; |
} |
// }}} |
// {{{ _parseOptions() |
/** |
* Parse options passed to the container class |
* |
* @access private |
* @param array |
*/ |
function _parseOptions($array) |
{ |
foreach ($array as $key => $value) { |
if (isset($this->options[$key])) { |
$this->options[$key] = $value; |
} |
} |
} |
// }}} |
// {{{ _quoteDBFields() |
/** |
* Quote the db_fields option to avoid the possibility of SQL injection. |
* |
* @access private |
* @return string A properly quoted string that can be concatenated into a |
* SELECT clause. |
*/ |
function _quoteDBFields() |
{ |
if (isset($this->options['db_fields'])) { |
if (is_array($this->options['db_fields'])) { |
if ($this->options['auto_quote']) { |
$fields = array(); |
foreach ($this->options['db_fields'] as $field) { |
$fields[] = $this->db->quoteIdentifier($field); |
} |
return implode(', ', $fields); |
} else { |
return implode(', ', $this->options['db_fields']); |
} |
} else { |
if (strlen($this->options['db_fields']) > 0) { |
if ($this->options['auto_quote']) { |
return $this->db->quoteIdentifier($this->options['db_fields']); |
} else { |
return $this->options['db_fields']; |
} |
} |
} |
} |
return ''; |
} |
// }}} |
// {{{ fetchData() |
/** |
* Get user information from database |
* |
* This function uses the given username to fetch |
* the corresponding login data from the database |
* table. If an account that matches the passed username |
* and password is found, the function returns true. |
* Otherwise it returns false. |
* |
* @param string Username |
* @param string Password |
* @param boolean If true password is secured using a md5 hash |
* the frontend and auth are responsible for making sure the container supports |
* challenge response password authentication |
* @return mixed Error object or boolean |
*/ |
function fetchData($username, $password, $isChallengeResponse=false) |
{ |
$this->log('Auth_Container_DB::fetchData() called.', AUTH_LOG_DEBUG); |
// Prepare for a database query |
$err = $this->_prepare(); |
if ($err !== true) { |
return PEAR::raiseError($err->getMessage(), $err->getCode()); |
} |
// Find if db_fields contains a *, if so assume all columns are selected |
if (is_string($this->options['db_fields']) |
&& strstr($this->options['db_fields'], '*')) { |
$sql_from = "*"; |
} else { |
$sql_from = $this->options['final_usernamecol']. |
", ".$this->options['final_passwordcol']; |
if (strlen($fields = $this->_quoteDBFields()) > 0) { |
$sql_from .= ', '.$fields; |
} |
} |
$query = "SELECT ".$sql_from. |
" FROM ".$this->options['final_table']. |
" WHERE ".$this->options['final_usernamecol']." = ".$this->db->quoteSmart($username); |
// check if there is an optional parameter db_where |
if ($this->options['db_where'] != '') { |
// there is one, so add it to the query |
$query .= " AND ".$this->options['db_where']; |
} |
$this->log('Running SQL against DB: '.$query, AUTH_LOG_DEBUG); |
$res = $this->db->getRow($query, null, DB_FETCHMODE_ASSOC); |
if (DB::isError($res)) { |
return PEAR::raiseError($res->getMessage(), $res->getCode()); |
} |
if (!is_array($res)) { |
$this->activeUser = ''; |
return false; |
} |
// Perform trimming here before the hashihg |
$password = trim($password, "\r\n"); |
$res[$this->options['passwordcol']] = trim($res[$this->options['passwordcol']], "\r\n"); |
// If using Challenge Response md5 the pass with the secret |
if ($isChallengeResponse) { |
$res[$this->options['passwordcol']] = md5($res[$this->options['passwordcol']] |
.$this->_auth_obj->session['loginchallenege']); |
// UGLY cannot avoid without modifying verifyPassword |
if ($this->options['cryptType'] == 'md5') { |
$res[$this->options['passwordcol']] = md5($res[$this->options['passwordcol']]); |
} |
//print " Hashed Password [{$res[$this->options['passwordcol']]}]<br/>\n"; |
} |
if ($this->verifyPassword($password, |
$res[$this->options['passwordcol']], |
$this->options['cryptType'])) { |
// Store additional field values in the session |
foreach ($res as $key => $value) { |
if ($key == $this->options['passwordcol'] || |
$key == $this->options['usernamecol']) { |
continue; |
} |
$this->log('Storing additional field: '.$key, AUTH_LOG_DEBUG); |
// Use reference to the auth object if exists |
// This is because the auth session variable can change so a |
// static call to setAuthData does not make sence |
$this->_auth_obj->setAuthData($key, $value); |
} |
return true; |
} |
$this->activeUser = $res[$this->options['usernamecol']]; |
return false; |
} |
// }}} |
// {{{ listUsers() |
/** |
* Returns a list of users from the container |
* |
* @return mixed |
* @access public |
*/ |
function listUsers() |
{ |
$this->log('Auth_Container_DB::listUsers() called.', AUTH_LOG_DEBUG); |
$err = $this->_prepare(); |
if ($err !== true) { |
return PEAR::raiseError($err->getMessage(), $err->getCode()); |
} |
$retVal = array(); |
// Find if db_fields contains a *, if so assume all col are selected |
if ( is_string($this->options['db_fields']) |
&& strstr($this->options['db_fields'], '*')) { |
$sql_from = "*"; |
} else { |
$sql_from = $this->options['final_usernamecol']. |
", ".$this->options['final_passwordcol']; |
if (strlen($fields = $this->_quoteDBFields()) > 0) { |
$sql_from .= ', '.$fields; |
} |
} |
$query = sprintf("SELECT %s FROM %s", |
$sql_from, |
$this->options['final_table'] |
); |
// check if there is an optional parameter db_where |
if ($this->options['db_where'] != '') { |
// there is one, so add it to the query |
$query .= " WHERE ".$this->options['db_where']; |
} |
$this->log('Running SQL against DB: '.$query, AUTH_LOG_DEBUG); |
$res = $this->db->getAll($query, null, DB_FETCHMODE_ASSOC); |
if (DB::isError($res)) { |
return PEAR::raiseError($res->getMessage(), $res->getCode()); |
} else { |
foreach ($res as $user) { |
$user['username'] = $user[$this->options['usernamecol']]; |
$retVal[] = $user; |
} |
} |
$this->log('Found '.count($retVal).' users.', AUTH_LOG_DEBUG); |
return $retVal; |
} |
// }}} |
// {{{ addUser() |
/** |
* Add user to the storage container |
* |
* @access public |
* @param string Username |
* @param string Password |
* @param mixed Additional information that are stored in the DB |
* |
* @return mixed True on success, otherwise error object |
*/ |
function addUser($username, $password, $additional = "") |
{ |
$this->log('Auth_Container_DB::addUser() called.', AUTH_LOG_DEBUG); |
$err = $this->_prepare(); |
if ($err !== true) { |
return PEAR::raiseError($err->getMessage(), $err->getCode()); |
} |
if ( isset($this->options['cryptType']) |
&& $this->options['cryptType'] == 'none') { |
$cryptFunction = 'strval'; |
} elseif ( isset($this->options['cryptType']) |
&& function_exists($this->options['cryptType'])) { |
$cryptFunction = $this->options['cryptType']; |
} else { |
$cryptFunction = 'md5'; |
} |
$password = $cryptFunction($password); |
$additional_key = ''; |
$additional_value = ''; |
if (is_array($additional)) { |
foreach ($additional as $key => $value) { |
if ($this->options['auto_quote']) { |
$additional_key .= ', ' . $this->db->quoteIdentifier($key); |
} else { |
$additional_key .= ', ' . $key; |
} |
$additional_value .= ", " . $this->db->quoteSmart($value); |
} |
} |
$query = sprintf("INSERT INTO %s (%s, %s%s) VALUES (%s, %s%s)", |
$this->options['final_table'], |
$this->options['final_usernamecol'], |
$this->options['final_passwordcol'], |
$additional_key, |
$this->db->quoteSmart($username), |
$this->db->quoteSmart($password), |
$additional_value |
); |
$this->log('Running SQL against DB: '.$query, AUTH_LOG_DEBUG); |
$res = $this->query($query); |
if (DB::isError($res)) { |
return PEAR::raiseError($res->getMessage(), $res->getCode()); |
} else { |
return true; |
} |
} |
// }}} |
// {{{ removeUser() |
/** |
* Remove user from the storage container |
* |
* @access public |
* @param string Username |
* |
* @return mixed True on success, otherwise error object |
*/ |
function removeUser($username) |
{ |
$this->log('Auth_Container_DB::removeUser() called.', AUTH_LOG_DEBUG); |
$err = $this->_prepare(); |
if ($err !== true) { |
return PEAR::raiseError($err->getMessage(), $err->getCode()); |
} |
// check if there is an optional parameter db_where |
if ($this->options['db_where'] != '') { |
// there is one, so add it to the query |
$where = " AND ".$this->options['db_where']; |
} else { |
$where = ''; |
} |
$query = sprintf("DELETE FROM %s WHERE %s = %s %s", |
$this->options['final_table'], |
$this->options['final_usernamecol'], |
$this->db->quoteSmart($username), |
$where |
); |
$this->log('Running SQL against DB: '.$query, AUTH_LOG_DEBUG); |
$res = $this->query($query); |
if (DB::isError($res)) { |
return PEAR::raiseError($res->getMessage(), $res->getCode()); |
} else { |
return true; |
} |
} |
// }}} |
// {{{ changePassword() |
/** |
* Change password for user in the storage container |
* |
* @param string Username |
* @param string The new password (plain text) |
*/ |
function changePassword($username, $password) |
{ |
$this->log('Auth_Container_DB::changePassword() called.', AUTH_LOG_DEBUG); |
$err = $this->_prepare(); |
if ($err !== true) { |
return PEAR::raiseError($err->getMessage(), $err->getCode()); |
} |
if ( isset($this->options['cryptType']) |
&& $this->options['cryptType'] == 'none') { |
$cryptFunction = 'strval'; |
} elseif ( isset($this->options['cryptType']) |
&& function_exists($this->options['cryptType'])) { |
$cryptFunction = $this->options['cryptType']; |
} else { |
$cryptFunction = 'md5'; |
} |
$password = $cryptFunction($password); |
// check if there is an optional parameter db_where |
if ($this->options['db_where'] != '') { |
// there is one, so add it to the query |
$where = " AND ".$this->options['db_where']; |
} else { |
$where = ''; |
} |
$query = sprintf("UPDATE %s SET %s = %s WHERE %s = %s %s", |
$this->options['final_table'], |
$this->options['final_passwordcol'], |
$this->db->quoteSmart($password), |
$this->options['final_usernamecol'], |
$this->db->quoteSmart($username), |
$where |
); |
$this->log('Running SQL against DB: '.$query, AUTH_LOG_DEBUG); |
$res = $this->query($query); |
if (DB::isError($res)) { |
return PEAR::raiseError($res->getMessage(), $res->getCode()); |
} else { |
return true; |
} |
} |
// }}} |
// {{{ supportsChallengeResponse() |
/** |
* Determine if this container supports |
* password authentication with challenge response |
* |
* @return bool |
* @access public |
*/ |
function supportsChallengeResponse() |
{ |
return in_array($this->options['cryptType'], array('md5', 'none', '')); |
} |
// }}} |
// {{{ getCryptType() |
/** |
* Returns the selected crypt type for this container |
*/ |
function getCryptType() |
{ |
return($this->options['cryptType']); |
} |
// }}} |
} |
?> |
/obs_saisons/SPIP-v1-8-3/modules/configuration/Container/IMAP.php |
---|
New file |
0,0 → 1,210 |
<?php |
/* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4 foldmethod=marker: */ |
/** |
* Storage driver for use against IMAP servers |
* |
* PHP versions 4 and 5 |
* |
* LICENSE: This source file is subject to version 3.01 of the PHP license |
* that is available through the world-wide-web at the following URI: |
* http://www.php.net/license/3_01.txt. If you did not receive a copy of |
* the PHP License and are unable to obtain it through the web, please |
* send a note to license@php.net so we can mail you a copy immediately. |
* |
* @category Authentication |
* @package Auth |
* @author Jeroen Houben <jeroen@terena.nl> |
* @author Adam Ashley <aashley@php.net> |
* @copyright 2001-2006 The PHP Group |
* @license http://www.php.net/license/3_01.txt PHP License 3.01 |
* @version CVS: $Id: IMAP.php,v 1.18 2007/06/12 03:11:26 aashley Exp $ |
* @link http://pear.php.net/package/Auth |
* @since File available since Release 1.2.0 |
*/ |
/** |
* Include Auth_Container base class |
*/ |
require_once "Auth/Container.php"; |
/** |
* Include PEAR class for error handling |
*/ |
require_once "PEAR.php"; |
/** |
* Storage driver for fetching login data from an IMAP server |
* |
* This class is based on LDAP containers, but it very simple. |
* By default it connects to localhost:143 |
* The constructor will first check if the host:port combination is |
* actually reachable. This behaviour can be disabled. |
* It then tries to create an IMAP stream (without opening a mailbox) |
* If you wish to pass extended options to the connections, you may |
* do so by specifying protocol options. |
* |
* To use this storage containers, you have to use the |
* following syntax: |
* |
* <?php |
* ... |
* $params = array( |
* 'host' => 'mail.example.com', |
* 'port' => 143, |
* ); |
* $myAuth = new Auth('IMAP', $params); |
* ... |
* |
* By default we connect without any protocol options set. However, some |
* servers require you to connect with the notls or norsh options set. |
* To do this you need to add the following value to the params array: |
* 'baseDSN' => '/imap/notls/norsh' |
* |
* To connect to an SSL IMAP server: |
* 'baseDSN' => '/imap/ssl' |
* |
* To connect to an SSL IMAP server with a self-signed certificate: |
* 'baseDSN' => '/imap/ssl/novalidate-cert' |
* |
* Further options may be available and can be found on the php site at |
* http://www.php.net/manual/function.imap-open.php |
* |
* @category Authentication |
* @package Auth |
* @author Jeroen Houben <jeroen@terena.nl> |
* @author Cipriano Groenendal <cipri@campai.nl> |
* @author Adam Ashley <aashley@php.net> |
* @copyright 2001-2006 The PHP Group |
* @license http://www.php.net/license/3_01.txt PHP License 3.01 |
* @version Release: 1.6.1 File: $Revision: 1.18 $ |
* @link http://pear.php.net/package/Auth |
* @since Class available since Release 1.2.0 |
*/ |
class Auth_Container_IMAP extends Auth_Container |
{ |
// {{{ properties |
/** |
* Options for the class |
* @var array |
*/ |
var $options = array(); |
// }}} |
// {{{ Auth_Container_IMAP() [constructor] |
/** |
* Constructor of the container class |
* |
* @param $params associative array with host, port, baseDSN, checkServer |
* and userattr key |
* @return object Returns an error object if something went wrong |
* @todo Use PEAR Net_IMAP if IMAP extension not loaded |
*/ |
function Auth_Container_IMAP($params) |
{ |
if (!extension_loaded('imap')) { |
return PEAR::raiseError('Cannot use IMAP authentication, ' |
.'IMAP extension not loaded!', 41, PEAR_ERROR_DIE); |
} |
$this->_setDefaults(); |
// set parameters (if any) |
if (is_array($params)) { |
$this->_parseOptions($params); |
} |
if ($this->options['checkServer']) { |
$this->_checkServer($this->options['timeout']); |
} |
return true; |
} |
// }}} |
// {{{ _setDefaults() |
/** |
* Set some default options |
* |
* @access private |
*/ |
function _setDefaults() |
{ |
$this->options['host'] = 'localhost'; |
$this->options['port'] = 143; |
$this->options['baseDSN'] = ''; |
$this->options['checkServer'] = true; |
$this->options['timeout'] = 20; |
} |
// }}} |
// {{{ _checkServer() |
/** |
* Check if the given server and port are reachable |
* |
* @access private |
*/ |
function _checkServer() { |
$this->log('Auth_Container_IMAP::_checkServer() called.', AUTH_LOG_DEBUG); |
$fp = @fsockopen ($this->options['host'], $this->options['port'], |
$errno, $errstr, $this->options['timeout']); |
if (is_resource($fp)) { |
@fclose($fp); |
} else { |
$message = "Error connecting to IMAP server " |
. $this->options['host'] |
. ":" . $this->options['port']; |
return PEAR::raiseError($message, 41); |
} |
} |
// }}} |
// {{{ _parseOptions() |
/** |
* Parse options passed to the container class |
* |
* @access private |
* @param array |
*/ |
function _parseOptions($array) |
{ |
foreach ($array as $key => $value) { |
$this->options[$key] = $value; |
} |
} |
// }}} |
// {{{ fetchData() |
/** |
* Try to open a IMAP stream using $username / $password |
* |
* @param string Username |
* @param string Password |
* @return boolean |
*/ |
function fetchData($username, $password) |
{ |
$this->log('Auth_Container_IMAP::fetchData() called.', AUTH_LOG_DEBUG); |
$dsn = '{'.$this->options['host'].':'.$this->options['port'].$this->options['baseDSN'].'}'; |
$conn = @imap_open ($dsn, $username, $password, OP_HALFOPEN); |
if (is_resource($conn)) { |
$this->log('Successfully connected to IMAP server.', AUTH_LOG_DEBUG); |
$this->activeUser = $username; |
@imap_close($conn); |
return true; |
} else { |
$this->log('Connection to IMAP server failed.', AUTH_LOG_DEBUG); |
$this->activeUser = ''; |
return false; |
} |
} |
// }}} |
} |
?> |
/obs_saisons/SPIP-v1-8-3/modules/configuration/Container/vpopmail.php |
---|
New file |
0,0 → 1,88 |
<?php |
/* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4 foldmethod=marker: */ |
/** |
* Storage driver for use against vpopmail setups |
* |
* PHP versions 4 and 5 |
* |
* LICENSE: This source file is subject to version 3.01 of the PHP license |
* that is available through the world-wide-web at the following URI: |
* http://www.php.net/license/3_01.txt. If you did not receive a copy of |
* the PHP License and are unable to obtain it through the web, please |
* send a note to license@php.net so we can mail you a copy immediately. |
* |
* @category Authentication |
* @package Auth |
* @author Stanislav Grozev <tacho@orbitel.bg> |
* @author Adam Ashley <aashley@php.net> |
* @copyright 2001-2006 The PHP Group |
* @license http://www.php.net/license/3_01.txt PHP License 3.01 |
* @version CVS: $Id: vpopmail.php,v 1.10 2007/06/12 03:11:26 aashley Exp $ |
* @link http://pear.php.net/package/Auth |
* @since File available since Release 1.2.0 |
*/ |
/** |
* Include Auth_Container base class |
*/ |
require_once "Auth/Container.php"; |
/** |
* Include PEAR package for error handling |
*/ |
require_once "PEAR.php"; |
/** |
* Storage driver for fetching login data from vpopmail |
* |
* @category Authentication |
* @package Auth |
* @author Stanislav Grozev <tacho@orbitel.bg> |
* @author Adam Ashley <aashley@php.net> |
* @copyright 2001-2006 The PHP Group |
* @license http://www.php.net/license/3_01.txt PHP License 3.01 |
* @version Release: 1.6.1 File: $Revision: 1.10 $ |
* @link http://pear.php.net/package/Auth |
* @since Class available since Release 1.2.0 |
*/ |
class Auth_Container_vpopmail extends Auth_Container { |
// {{{ Constructor |
/** |
* Constructor of the container class |
* |
* @return void |
*/ |
function Auth_Container_vpopmail() |
{ |
if (!extension_loaded('vpopmail')) { |
return PEAR::raiseError('Cannot use VPOPMail authentication, ' |
.'VPOPMail extension not loaded!', 41, PEAR_ERROR_DIE); |
} |
} |
// }}} |
// {{{ fetchData() |
/** |
* Get user information from vpopmail |
* |
* @param string Username - has to be valid email address |
* @param string Password |
* @return boolean |
*/ |
function fetchData($username, $password) |
{ |
$this->log('Auth_Container_vpopmail::fetchData() called.', AUTH_LOG_DEBUG); |
$userdata = array(); |
$userdata = preg_split("/@/", $username, 2); |
$result = @vpopmail_auth_user($userdata[0], $userdata[1], $password); |
return $result; |
} |
// }}} |
} |
?> |
/obs_saisons/SPIP-v1-8-3/modules/configuration/Container/SOAP5.php |
---|
New file |
0,0 → 1,268 |
<?php |
/* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4 foldmethod=marker: */ |
/** |
* Storage driver for use against a SOAP service using PHP5 SoapClient |
* |
* PHP version 5 |
* |
* LICENSE: This source file is subject to version 3.01 of the PHP license |
* that is available through the world-wide-web at the following URI: |
* http://www.php.net/license/3_01.txt. If you did not receive a copy of |
* the PHP License and are unable to obtain it through the web, please |
* send a note to license@php.net so we can mail you a copy immediately. |
* |
* @category Authentication |
* @package Auth |
* @author Based upon Auth_Container_SOAP by Bruno Pedro <bpedro@co.sapo.pt> |
* @author Marcel Oelke <puRe@rednoize.com> |
* @author Adam Ashley <aashley@php.net> |
* @copyright 2001-2006 The PHP Group |
* @license http://www.php.net/license/3_01.txt PHP License 3.01 |
* @version CVS: $Id: SOAP5.php,v 1.9 2007/07/02 08:25:41 aashley Exp $ |
* @since File available since Release 1.4.0 |
*/ |
/** |
* Include Auth_Container base class |
*/ |
require_once "Auth/Container.php"; |
/** |
* Include PEAR package for error handling |
*/ |
require_once "PEAR.php"; |
/** |
* Storage driver for fetching login data from SOAP using the PHP5 Builtin SOAP |
* functions. This is a modification of the SOAP Storage driver from Bruno Pedro |
* thats using the PEAR SOAP Package. |
* |
* This class takes one parameter (options), where |
* you specify the following fields: |
* * location and uri, or wsdl file |
* * method to call on the SOAP service |
* * usernamefield, the name of the parameter where the username is supplied |
* * passwordfield, the name of the parameter where the password is supplied |
* * matchpassword, whether to look for the password in the response from |
* the function call or assume that no errors means user |
* authenticated. |
* |
* See http://www.php.net/manual/en/ref.soap.php for further details |
* on options for the PHP5 SoapClient which are passed through. |
* |
* Example usage without WSDL: |
* |
* <?php |
* |
* $options = array ( |
* 'wsdl' => NULL, |
* 'location' => 'http://your.soap.service/endpoint', |
* 'uri' => 'urn:/Your/Namespace', |
* 'method' => 'checkAuth', |
* 'usernamefield' => 'username', |
* 'passwordfield' => 'password', |
* 'matchpasswords' => false, |
* '_features' => array ( |
* 'extra_parameter' => 'example_value', |
* 'another_parameter' => 'foobar' |
* ) |
* ); |
* |
* $auth = new Auth('SOAP5', $options); |
* $auth->start(); |
* |
* ?> |
* |
* Example usage with WSDL: |
* |
* <?php |
* |
* $options = array ( |
* 'wsdl' => 'http://your.soap.service/wsdl', |
* 'method' => 'checkAuth', |
* 'usernamefield' => 'username', |
* 'passwordfield' => 'password', |
* 'matchpasswords' => false, |
* '_features' => array ( |
* 'extra_parameter' => 'example_value', |
* 'another_parameter' => 'foobar' |
* ) |
* ); |
* |
* $auth = new Auth('SOAP5', $options); |
* $auth->start(); |
* |
* ?> |
* |
* @category Authentication |
* @package Auth |
* @author Based upon Auth_Container_SOAP by Bruno Pedro <bpedro@co.sapo.pt> |
* @author Marcel Oelke <puRe@rednoize.com> |
* @author Adam Ashley <aashley@php.net> |
* @copyright 2001-2006 The PHP Group |
* @license http://www.php.net/license/3_01.txt PHP License 3.01 |
* @version Release: 1.6.1 File: $Revision: 1.9 $ |
* @since Class available since Release 1.4.0 |
*/ |
class Auth_Container_SOAP5 extends Auth_Container |
{ |
// {{{ properties |
/** |
* Required options for the class |
* @var array |
* @access private |
*/ |
var $_requiredOptions = array( |
'location', |
'uri', |
'method', |
'usernamefield', |
'passwordfield', |
'wsdl', |
); |
/** |
* Options for the class |
* @var array |
* @access private |
*/ |
var $_options = array(); |
/** |
* Optional SOAP features |
* @var array |
* @access private |
*/ |
var $_features = array(); |
/** |
* The SOAP response |
* @var array |
* @access public |
*/ |
var $soapResponse = array(); |
// }}} |
// {{{ Auth_Container_SOAP5() |
/** |
* Constructor of the container class |
* |
* @param $options, associative array with endpoint, namespace, method, |
* usernamefield, passwordfield and optional features |
*/ |
function Auth_Container_SOAP5($options) |
{ |
$this->_setDefaults(); |
foreach ($options as $name => $value) { |
$this->_options[$name] = $value; |
} |
if (!empty($this->_options['_features'])) { |
$this->_features = $this->_options['_features']; |
unset($this->_options['_features']); |
} |
} |
// }}} |
// {{{ fetchData() |
/** |
* Fetch data from SOAP service |
* |
* Requests the SOAP service for the given username/password |
* combination. |
* |
* @param string Username |
* @param string Password |
* @return mixed Returns the SOAP response or false if something went wrong |
*/ |
function fetchData($username, $password) |
{ |
$this->log('Auth_Container_SOAP5::fetchData() called.', AUTH_LOG_DEBUG); |
$result = $this->_validateOptions(); |
if (PEAR::isError($result)) |
return $result; |
// create a SOAP client |
$soapClient = new SoapClient($this->_options["wsdl"], $this->_options); |
$params = array(); |
// first, assign the optional features |
foreach ($this->_features as $fieldName => $fieldValue) { |
$params[$fieldName] = $fieldValue; |
} |
// assign username and password ... |
$params[$this->_options['usernamefield']] = $username; |
$params[$this->_options['passwordfield']] = $password; |
try { |
$this->soapResponse = $soapClient->__soapCall($this->_options['method'], $params); |
if ($this->_options['matchpasswords']) { |
// check if passwords match |
if ($password == $this->soapResponse[$this->_options['passwordfield']]) { |
return true; |
} else { |
return false; |
} |
} else { |
return true; |
} |
} catch (SoapFault $e) { |
return PEAR::raiseError("Error retrieving authentication data. Received SOAP Fault: ".$e->faultstring, $e->faultcode); |
} |
} |
// }}} |
// {{{ _validateOptions() |
/** |
* Validate that the options passed to the container class are enough for us to proceed |
* |
* @access private |
* @param array |
*/ |
function _validateOptions() |
{ |
if ( ( is_null($this->_options['wsdl']) |
&& is_null($this->_options['location']) |
&& is_null($this->_options['uri'])) |
|| ( is_null($this->_options['wsdl']) |
&& ( is_null($this->_options['location']) |
|| is_null($this->_options['uri'])))) { |
return PEAR::raiseError('Either a WSDL file or a location/uri pair must be specified.'); |
} |
if (is_null($this->_options['method'])) { |
return PEAR::raiseError('A method to call on the soap service must be specified.'); |
} |
return true; |
} |
// }}} |
// {{{ _setDefaults() |
/** |
* Set some default options |
* |
* @access private |
* @return void |
*/ |
function _setDefaults() |
{ |
$this->_options['wsdl'] = null; |
$this->_options['location'] = null; |
$this->_options['uri'] = null; |
$this->_options['method'] = null; |
$this->_options['usernamefield'] = 'username'; |
$this->_options['passwordfield'] = 'password'; |
$this->_options['matchpasswords'] = true; |
} |
// }}} |
} |
?> |
/obs_saisons/SPIP-v1-8-3/modules/configuration/Container/PEAR.php |
---|
New file |
0,0 → 1,159 |
<?php |
/* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4 foldmethod=marker: */ |
/** |
* Storage driver for use against PEAR website |
* |
* PHP versions 4 and 5 |
* |
* LICENSE: This source file is subject to version 3.01 of the PHP license |
* that is available through the world-wide-web at the following URI: |
* http://www.php.net/license/3_01.txt. If you did not receive a copy of |
* the PHP License and are unable to obtain it through the web, please |
* send a note to license@php.net so we can mail you a copy immediately. |
* |
* @category Authentication |
* @package Auth |
* @author Yavor Shahpasov <yavo@netsmart.com.cy> |
* @author Adam Ashley <aashley@php.net> |
* @copyright 2001-2006 The PHP Group |
* @license http://www.php.net/license/3_01.txt PHP License 3.01 |
* @version CVS: $Id: PEAR.php,v 1.13 2008/04/04 00:53:53 aashley Exp $ |
* @link http://pear.php.net/package/Auth |
* @since File available since Release 1.3.0 |
*/ |
/** |
* Include PEAR HTTP_Client. |
*/ |
require_once 'HTTP/Client.php'; |
/** |
* Include Auth_Container base class |
*/ |
require_once 'Auth/Container.php'; |
/** |
* Storage driver for authenticating against PEAR website |
* |
* This driver provides a method for authenticating against the pear.php.net |
* authentication system. |
* |
* Supports two options: |
* - "url": The base URL with schema to authenticate against |
* - "karma": An array of karma levels which the user needs one of. |
* When empty, no karma level is required. |
* |
* @category Authentication |
* @package Auth |
* @author Yavor Shahpasov <yavo@netsmart.com.cy> |
* @author Adam Ashley <aashley@php.net> |
* @author Adam Harvey <aharvey@php.net> |
* @copyright 2001-2007 The PHP Group |
* @license http://www.php.net/license/3_01.txt PHP License 3.01 |
* @version Release: 1.6.1 File: $Revision: 1.13 $ |
* @link http://pear.php.net/package/Auth |
* @since Class available since Release 1.3.0 |
*/ |
class Auth_Container_Pear extends Auth_Container |
{ |
// {{{ properties |
/** |
* URL to connect to, with schema |
* |
* @var string |
*/ |
var $url = 'https://pear.php.net/rest-login.php/'; |
/** |
* Array of karma levels the user can have. |
* A user needs only one of the levels to succeed login. |
* No levels mean that only username and password need to match |
* |
* @var array |
*/ |
var $karma = array(); |
// }}} |
// {{{ Auth_Container_Pear() [constructor] |
/** |
* Constructor |
* |
* Accepts options "url" and "karma", see class docs. |
* |
* @param array $data Array of options |
* |
* @return void |
*/ |
function Auth_Container_Pear($data = null) |
{ |
if (!is_array($data)) { |
PEAR::raiseError('The options for Auth_Container_Pear must be an array'); |
} |
if (isset($data['karma'])) { |
if (is_array($data['karma'])) { |
$this->karma = $data['karma']; |
} else { |
$this->karma = array($data['karma']); |
} |
} |
if (isset($data['url'])) { |
$this->url = $data['url']; |
} |
} |
// }}} |
// {{{ fetchData() |
/** |
* Get user information from pear.php.net |
* |
* This function uses the given username and password to authenticate |
* against the pear.php.net website |
* |
* @param string Username |
* @param string Password |
* @return mixed Error object or boolean |
*/ |
function fetchData($username, $password) |
{ |
$this->log('Auth_Container_PEAR::fetchData() called.', AUTH_LOG_DEBUG); |
$client = new HTTP_Client; |
$this->log('Auth_Container_PEAR::fetchData() getting salt.', AUTH_LOG_DEBUG); |
$code = $client->get($this->url . '/getsalt'); |
if ($code != 200) { |
return PEAR::raiseError('Bad response to salt request.', $code); |
} |
$resp = $client->currentResponse(); |
$salt = $resp['body']; |
$this->log('Auth_Container_PEAR::fetchData() calling validate.', AUTH_LOG_DEBUG); |
$postOptions = array( |
'username' => $username, |
'password' => md5($salt . md5($password)) |
); |
if (is_array($this->karma) && count($this->karma) > 0) { |
$postOptions['karma'] = implode(',', $this->karma); |
} |
$code = $client->post($this->url . '/validate', $postOptions); |
if ($code != 200) { |
return PEAR::raiseError('Bad response to validate request.', $code); |
} |
$resp = $client->currentResponse(); |
list($code, $message) = explode(' ', $resp['body'], 1); |
if ($code != 8) { |
return PEAR::raiseError($message, $code); |
} |
return true; |
} |
// }}} |
} |
?> |
/obs_saisons/SPIP-v1-8-3/modules/configuration/Container/RADIUS.php |
---|
New file |
0,0 → 1,182 |
<?php |
/* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4 foldmethod=marker: */ |
/** |
* Storage driver for use against RADIUS servers |
* |
* PHP versions 4 and 5 |
* |
* LICENSE: This source file is subject to version 3.01 of the PHP license |
* that is available through the world-wide-web at the following URI: |
* http://www.php.net/license/3_01.txt. If you did not receive a copy of |
* the PHP License and are unable to obtain it through the web, please |
* send a note to license@php.net so we can mail you a copy immediately. |
* |
* @category Authentication |
* @package Auth |
* @author Michael Bretterklieber <michael@bretterklieber.com> |
* @author Adam Ashley <aashley@php.net> |
* @copyright 2001-2006 The PHP Group |
* @license http://www.php.net/license/3_01.txt PHP License 3.01 |
* @version CVS: $Id: RADIUS.php,v 1.16 2007/06/12 03:11:26 aashley Exp $ |
* @link http://pear.php.net/package/Auth |
* @since File available since Release 1.2.0 |
*/ |
/** |
* Include Auth_Container base class |
*/ |
require_once "Auth/Container.php"; |
/** |
* Include PEAR Auth_RADIUS package |
*/ |
require_once "Auth/RADIUS.php"; |
/** |
* Storage driver for authenticating users against RADIUS servers. |
* |
* @category Authentication |
* @package Auth |
* @author Michael Bretterklieber <michael@bretterklieber.com> |
* @author Adam Ashley <aashley@php.net> |
* @copyright 2001-2006 The PHP Group |
* @license http://www.php.net/license/3_01.txt PHP License 3.01 |
* @version Release: 1.6.1 File: $Revision: 1.16 $ |
* @link http://pear.php.net/package/Auth |
* @since Class available since Release 1.2.0 |
*/ |
class Auth_Container_RADIUS extends Auth_Container |
{ |
// {{{ properties |
/** |
* Contains a RADIUS object |
* @var object |
*/ |
var $radius; |
/** |
* Contains the authentication type |
* @var string |
*/ |
var $authtype; |
// }}} |
// {{{ Auth_Container_RADIUS() [constructor] |
/** |
* Constructor of the container class. |
* |
* $options can have these keys: |
* 'servers' an array containing an array: servername, port, |
* sharedsecret, timeout, maxtries |
* 'configfile' The filename of the configuration file |
* 'authtype' The type of authentication, one of: PAP, CHAP_MD5, |
* MSCHAPv1, MSCHAPv2, default is PAP |
* |
* @param $options associative array |
* @return object Returns an error object if something went wrong |
*/ |
function Auth_Container_RADIUS($options) |
{ |
$this->authtype = 'PAP'; |
if (isset($options['authtype'])) { |
$this->authtype = $options['authtype']; |
} |
$classname = 'Auth_RADIUS_' . $this->authtype; |
if (!class_exists($classname)) { |
PEAR::raiseError("Unknown Authtype, please use one of: " |
."PAP, CHAP_MD5, MSCHAPv1, MSCHAPv2!", 41, PEAR_ERROR_DIE); |
} |
$this->radius = new $classname; |
if (isset($options['configfile'])) { |
$this->radius->setConfigfile($options['configfile']); |
} |
$servers = $options['servers']; |
if (is_array($servers)) { |
foreach ($servers as $server) { |
$servername = $server[0]; |
$port = isset($server[1]) ? $server[1] : 0; |
$sharedsecret = isset($server[2]) ? $server[2] : 'testing123'; |
$timeout = isset($server[3]) ? $server[3] : 3; |
$maxtries = isset($server[4]) ? $server[4] : 3; |
$this->radius->addServer($servername, $port, $sharedsecret, $timeout, $maxtries); |
} |
} |
if (!$this->radius->start()) { |
PEAR::raiseError($this->radius->getError(), 41, PEAR_ERROR_DIE); |
} |
} |
// }}} |
// {{{ fetchData() |
/** |
* Authenticate |
* |
* @param string Username |
* @param string Password |
* @return bool true on success, false on reject |
*/ |
function fetchData($username, $password, $challenge = null) |
{ |
$this->log('Auth_Container_RADIUS::fetchData() called.', AUTH_LOG_DEBUG); |
switch($this->authtype) { |
case 'CHAP_MD5': |
case 'MSCHAPv1': |
if (isset($challenge)) { |
$this->radius->challenge = $challenge; |
$this->radius->chapid = 1; |
$this->radius->response = pack('H*', $password); |
} else { |
require_once 'Crypt/CHAP.php'; |
$classname = 'Crypt_' . $this->authtype; |
$crpt = new $classname; |
$crpt->password = $password; |
$this->radius->challenge = $crpt->challenge; |
$this->radius->chapid = $crpt->chapid; |
$this->radius->response = $crpt->challengeResponse(); |
} |
break; |
case 'MSCHAPv2': |
require_once 'Crypt/CHAP.php'; |
$crpt = new Crypt_MSCHAPv2; |
$crpt->username = $username; |
$crpt->password = $password; |
$this->radius->challenge = $crpt->authChallenge; |
$this->radius->peerChallenge = $crpt->peerChallenge; |
$this->radius->chapid = $crpt->chapid; |
$this->radius->response = $crpt->challengeResponse(); |
break; |
default: |
$this->radius->password = $password; |
break; |
} |
$this->radius->username = $username; |
$this->radius->putAuthAttributes(); |
$result = $this->radius->send(); |
if (PEAR::isError($result)) { |
return false; |
} |
$this->radius->getAttributes(); |
// just for debugging |
// $this->radius->dumpAttributes(); |
return $result; |
} |
// }}} |
} |
?> |
/obs_saisons/SPIP-v1-8-3/modules/configuration/Container/Multiple.php |
---|
New file |
0,0 → 1,188 |
<?php |
/* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4 foldmethod=marker: */ |
/** |
* Storage driver for using multiple storage drivers in a fall through fashion |
* |
* PHP versions 4 and 5 |
* |
* LICENSE: This source file is subject to version 3.01 of the PHP license |
* that is available through the world-wide-web at the following URI: |
* http://www.php.net/license/3_01.txt. If you did not receive a copy of |
* the PHP License and are unable to obtain it through the web, please |
* send a note to license@php.net so we can mail you a copy immediately. |
* |
* @category Authentication |
* @package Auth |
* @author Adam Ashley <aashley@php.net> |
* @copyright 2001-2006 The PHP Group |
* @license http://www.php.net/license/3_01.txt PHP License 3.01 |
* @version CVS: $Id: Multiple.php,v 1.4 2007/06/12 03:11:26 aashley Exp $ |
* @since File available since Release 1.5.0 |
*/ |
/** |
* Include Auth_Container base class |
*/ |
require_once "Auth/Container.php"; |
/** |
* Include PEAR package for error handling |
*/ |
require_once "PEAR.php"; |
/** |
* Storage driver for using multiple storage drivers in a fall through fashion |
* |
* This storage driver provides a mechanism for working through multiple |
* storage drivers until either one allows successful login or the list is |
* exhausted. |
* |
* This container takes an array of options of the following form: |
* |
* array( |
* array( |
* 'type' => <standard container type name>, |
* 'options' => <normal array of options for container>, |
* ), |
* ); |
* |
* Full example: |
* |
* $options = array( |
* array( |
* 'type' => 'DB', |
* 'options' => array( |
* 'dsn' => "mysql://user:password@localhost/database", |
* ), |
* ), |
* array( |
* 'type' => 'Array', |
* 'options' => array( |
* 'cryptType' => 'md5', |
* 'users' => array( |
* 'admin' => md5('password'), |
* ), |
* ), |
* ), |
* ); |
* |
* $auth = new Auth('Multiple', $options); |
* |
* @category Authentication |
* @package Auth |
* @author Adam Ashley <aashley@php.net> |
* @copyright 2001-2006 The PHP Group |
* @license http://www.php.net/license/3_01.txt PHP License 3.01 |
* @version Release: 1.6.1 File: $Revision: 1.4 $ |
* @since File available since Release 1.5.0 |
*/ |
class Auth_Container_Multiple extends Auth_Container { |
// {{{ properties |
/** |
* The options for each container |
* |
* @var array $options |
*/ |
var $options = array(); |
/** |
* The instanciated containers |
* |
* @var array $containers |
*/ |
var $containers = array(); |
// }}} |
// {{{ Auth_Container_Multiple() |
/** |
* Constructor for Array Container |
* |
* @param array $data Options for the container |
* @return void |
*/ |
function Auth_Container_Multiple($options) |
{ |
if (!is_array($options)) { |
PEAR::raiseError('The options for Auth_Container_Multiple must be an array'); |
} |
if (count($options) < 1) { |
PEAR::raiseError('You must define at least one sub container to use in Auth_Container_Multiple'); |
} |
foreach ($options as $option) { |
if (!isset($option['type'])) { |
PEAR::raiseError('No type defined for sub container'); |
} |
} |
$this->options = $options; |
} |
// }}} |
// {{{ fetchData() |
/** |
* Get user information from array |
* |
* This function uses the given username to fetch the corresponding |
* login data from the array. If an account that matches the passed |
* username and password is found, the function returns true. |
* Otherwise it returns false. |
* |
* @param string Username |
* @param string Password |
* @return boolean|PEAR_Error Error object or boolean |
*/ |
function fetchData($user, $pass) |
{ |
$this->log('Auth_Container_Multiple::fetchData() called.', AUTH_LOG_DEBUG); |
foreach ($this->options as $key => $options) { |
$this->log('Using Container '.$key.' of type '.$options['type'].'.', AUTH_LOG_DEBUG); |
if (isset($this->containers[$key]) && is_a($this->containers[$key], 'Auth_Container')) { |
$container = &$this->containers[$key]; |
} else { |
$this->containers[$key] = &$this->_auth_obj->_factory($options['type'], $options['options']); |
$this->containers[$key]->_auth_obj = &$this->_auth_obj; |
$container = &$this->containers[$key]; |
} |
$result = $container->fetchData($user, $pass); |
if (PEAR::isError($result)) { |
$this->log('Container '.$key.': '.$result->getMessage(), AUTH_LOG_ERR); |
return $result; |
} elseif ($result == true) { |
$this->log('Container '.$key.': Authentication successful.', AUTH_LOG_DEBUG); |
return true; |
} else { |
$this->log('Container '.$key.': Authentication failed.', AUTH_LOG_DEBUG); |
} |
} |
$this->log('Auth_Container_Multiple: All containers rejected user credentials.', AUTH_LOG_DEBUG); |
return false; |
} |
// }}} |
} |
?> |
/obs_saisons/SPIP-v1-8-3/modules/configuration/Container/KADM5.php |
---|
New file |
0,0 → 1,171 |
<?php |
/* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4 foldmethod=marker: */ |
/** |
* Storage driver for Authentication on a Kerberos V server. |
* |
* PHP versions 4 and 5 |
* |
* LICENSE: This source file is subject to version 3.01 of the PHP license |
* that is available through the world-wide-web at the following URI: |
* http://www.php.net/license/3_01.txt. If you did not receive a copy of |
* the PHP License and are unable to obtain it through the web, please |
* send a note to license@php.net so we can mail you a copy immediately. |
* |
* @category Authentication |
* @package Auth |
* @author Andrew Teixeira <ateixeira@gmail.com> |
* @author Adam Ashley <aashley@php.net> |
* @copyright 2001-2006 The PHP Group |
* @license http://www.php.net/license/3_01.txt PHP License 3.01 |
* @version CVS: $Id: KADM5.php,v 1.6 2007/06/12 03:11:26 aashley Exp $ |
* @link http://pear.php.net/package/Auth |
* @since File available since Release 1.4.0 |
*/ |
/** |
* Include Auth_Container base class |
*/ |
require_once 'Auth/Container.php'; |
/** |
* Include PEAR for error handling |
*/ |
require_once 'PEAR.php'; |
/** |
* Storage driver for Authentication on a Kerberos V server. |
* |
* Available options: |
* hostname: The hostname of the kerberos server |
* realm: The Kerberos V realm |
* timeout: The timeout for checking the server |
* checkServer: Set to true to check if the server is running when |
* constructing the object |
* |
* @category Authentication |
* @package Auth |
* @author Andrew Teixeira <ateixeira@gmail.com> |
* @author Adam Ashley <aashley@php.net> |
* @copyright 2001-2006 The PHP Group |
* @license http://www.php.net/license/3_01.txt PHP License 3.01 |
* @version Release: 1.6.1 File: $Revision: 1.6 $ |
* @link http://pear.php.net/package/Auth |
* @since Class available since Release 1.4.0 |
*/ |
class Auth_Container_KADM5 extends Auth_Container { |
// {{{ properties |
/** |
* Options for the class |
* @var string |
*/ |
var $options = array(); |
// }}} |
// {{{ Auth_Container_KADM5() |
/** |
* Constructor of the container class |
* |
* $options can have these keys: |
* 'hostname' The hostname of the kerberos server |
* 'realm' The Kerberos V realm |
* 'timeout' The timeout for checking the server |
* 'checkServer' Set to true to check if the server is running when |
* constructing the object |
* |
* @param $options associative array |
* @return object Returns an error object if something went wrong |
*/ |
function Auth_Container_KADM5($options) { |
if (!extension_loaded('kadm5')) { |
return PEAR::raiseError("Cannot use Kerberos V authentication, KADM5 extension not loaded!", 41, PEAR_ERROR_DIE); |
} |
$this->_setDefaults(); |
if (isset($options['hostname'])) { |
$this->options['hostname'] = $options['hostname']; |
} |
if (isset($options['realm'])) { |
$this->options['realm'] = $options['realm']; |
} |
if (isset($options['timeout'])) { |
$this->options['timeout'] = $options['timeout']; |
} |
if (isset($options['checkServer'])) { |
$this->options['checkServer'] = $options['checkServer']; |
} |
if ($this->options['checkServer']) { |
$this->_checkServer(); |
} |
} |
// }}} |
// {{{ fetchData() |
/** |
* Try to login to the KADM5 server |
* |
* @param string Username |
* @param string Password |
* @return boolean |
*/ |
function fetchData($username, $password) { |
$this->log('Auth_Container_KADM5::fetchData() called.', AUTH_LOG_DEBUG); |
if ( ($username == NULL) || ($password == NULL) ) { |
return false; |
} |
$server = $this->options['hostname']; |
$realm = $this->options['realm']; |
$check = @kadm5_init_with_password($server, $realm, $username, $password); |
if ($check == false) { |
return false; |
} else { |
return true; |
} |
} |
// }}} |
// {{{ _setDefaults() |
/** |
* Set some default options |
* |
* @access private |
*/ |
function _setDefaults() { |
$this->options['hostname'] = 'localhost'; |
$this->options['realm'] = NULL; |
$this->options['timeout'] = 10; |
$this->options['checkServer'] = false; |
} |
// }}} |
// {{{ _checkServer() |
/** |
* Check if the given server and port are reachable |
* |
* @access private |
*/ |
function _checkServer() { |
$fp = @fsockopen ($this->options['hostname'], 88, $errno, $errstr, $this->options['timeout']); |
if (is_resource($fp)) { |
@fclose($fp); |
} else { |
$message = "Error connecting to Kerberos V server " |
.$this->options['hostname'].":".$this->options['port']; |
return PEAR::raiseError($message, 41, PEAR_ERROR_DIE); |
} |
} |
// }}} |
} |
?> |
/obs_saisons/SPIP-v1-8-3/modules/configuration/Container/SOAP.php |
---|
New file |
0,0 → 1,229 |
<?php |
/* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4 foldmethod=marker: */ |
/** |
* Storage driver for use against a SOAP service |
* |
* PHP versions 4 and 5 |
* |
* LICENSE: This source file is subject to version 3.01 of the PHP license |
* that is available through the world-wide-web at the following URI: |
* http://www.php.net/license/3_01.txt. If you did not receive a copy of |
* the PHP License and are unable to obtain it through the web, please |
* send a note to license@php.net so we can mail you a copy immediately. |
* |
* @category Authentication |
* @package Auth |
* @author Bruno Pedro <bpedro@co.sapo.pt> |
* @author Adam Ashley <aashley@php.net> |
* @copyright 2001-2006 The PHP Group |
* @license http://www.php.net/license/3_01.txt PHP License 3.01 |
* @version CVS: $Id: SOAP.php,v 1.13 2007/06/12 03:11:26 aashley Exp $ |
* @link http://pear.php.net/package/Auth |
* @since File available since Release 1.2.0 |
*/ |
/** |
* Include Auth_Container base class |
*/ |
require_once "Auth/Container.php"; |
/** |
* Include PEAR package for error handling |
*/ |
require_once "PEAR.php"; |
/** |
* Include PEAR SOAP_Client |
*/ |
require_once 'SOAP/Client.php'; |
/** |
* Storage driver for fetching login data from SOAP |
* |
* This class takes one parameter (options), where |
* you specify the following fields: endpoint, namespace, |
* method, encoding, usernamefield and passwordfield. |
* |
* You can use specify features of your SOAP service |
* by providing its parameters in an associative manner by |
* using the '_features' array through the options parameter. |
* |
* The 'matchpassword' option should be set to false if your |
* webservice doesn't return (username,password) pairs, but |
* instead returns error when the login is invalid. |
* |
* Example usage: |
* |
* <?php |
* |
* ... |
* |
* $options = array ( |
* 'endpoint' => 'http://your.soap.service/endpoint', |
* 'namespace' => 'urn:/Your/Namespace', |
* 'method' => 'get', |
* 'encoding' => 'UTF-8', |
* 'usernamefield' => 'login', |
* 'passwordfield' => 'password', |
* 'matchpasswords' => false, |
* '_features' => array ( |
* 'example_feature' => 'example_value', |
* 'another_example' => '' |
* ) |
* ); |
* $auth = new Auth('SOAP', $options, 'loginFunction'); |
* $auth->start(); |
* |
* ... |
* |
* ?> |
* |
* @category Authentication |
* @package Auth |
* @author Bruno Pedro <bpedro@co.sapo.pt> |
* @author Adam Ashley <aashley@php.net> |
* @copyright 2001-2006 The PHP Group |
* @license http://www.php.net/license/3_01.txt PHP License 3.01 |
* @version Release: 1.6.1 File: $Revision: 1.13 $ |
* @link http://pear.php.net/package/Auth |
* @since Class available since Release 1.2.0 |
*/ |
class Auth_Container_SOAP extends Auth_Container |
{ |
// {{{ properties |
/** |
* Required options for the class |
* @var array |
* @access private |
*/ |
var $_requiredOptions = array( |
'endpoint', |
'namespace', |
'method', |
'encoding', |
'usernamefield', |
'passwordfield', |
); |
/** |
* Options for the class |
* @var array |
* @access private |
*/ |
var $_options = array(); |
/** |
* Optional SOAP features |
* @var array |
* @access private |
*/ |
var $_features = array(); |
/** |
* The SOAP response |
* @var array |
* @access public |
*/ |
var $soapResponse = array(); |
/** |
* The SOAP client |
* @var mixed |
* @access public |
*/ |
var $soapClient = null; |
// }}} |
// {{{ Auth_Container_SOAP() [constructor] |
/** |
* Constructor of the container class |
* |
* @param $options, associative array with endpoint, namespace, method, |
* usernamefield, passwordfield and optional features |
*/ |
function Auth_Container_SOAP($options) |
{ |
$this->_options = $options; |
if (!isset($this->_options['matchpasswords'])) { |
$this->_options['matchpasswords'] = true; |
} |
if (!empty($this->_options['_features'])) { |
$this->_features = $this->_options['_features']; |
unset($this->_options['_features']); |
} |
} |
// }}} |
// {{{ fetchData() |
/** |
* Fetch data from SOAP service |
* |
* Requests the SOAP service for the given username/password |
* combination. |
* |
* @param string Username |
* @param string Password |
* @return mixed Returns the SOAP response or false if something went wrong |
*/ |
function fetchData($username, $password) |
{ |
$this->log('Auth_Container_SOAP::fetchData() called.', AUTH_LOG_DEBUG); |
// check if all required options are set |
if (array_intersect($this->_requiredOptions, array_keys($this->_options)) != $this->_requiredOptions) { |
return false; |
} else { |
// create a SOAP client and set encoding |
$this->soapClient = new SOAP_Client($this->_options['endpoint']); |
$this->soapClient->setEncoding($this->_options['encoding']); |
} |
// set the trace option if requested |
if (isset($this->_options['trace'])) { |
$this->soapClient->__options['trace'] = true; |
} |
// set the timeout option if requested |
if (isset($this->_options['timeout'])) { |
$this->soapClient->__options['timeout'] = $this->_options['timeout']; |
} |
// assign username and password fields |
$usernameField = new SOAP_Value($this->_options['usernamefield'],'string', $username); |
$passwordField = new SOAP_Value($this->_options['passwordfield'],'string', $password); |
$SOAPParams = array($usernameField, $passwordField); |
// assign optional features |
foreach ($this->_features as $fieldName => $fieldValue) { |
$SOAPParams[] = new SOAP_Value($fieldName, 'string', $fieldValue); |
} |
// make SOAP call |
$this->soapResponse = $this->soapClient->call( |
$this->_options['method'], |
$SOAPParams, |
array('namespace' => $this->_options['namespace']) |
); |
if (!PEAR::isError($this->soapResponse)) { |
if ($this->_options['matchpasswords']) { |
// check if passwords match |
if ($password == $this->soapResponse->{$this->_options['passwordfield']}) { |
return true; |
} else { |
return false; |
} |
} else { |
return true; |
} |
} else { |
return false; |
} |
} |
// }}} |
} |
?> |
/obs_saisons/SPIP-v1-8-3/modules/configuration/Container/MDB.php |
---|
New file |
0,0 → 1,625 |
<?php |
/* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4 foldmethod=marker: */ |
/** |
* Storage driver for use against PEAR MDB |
* |
* PHP versions 4 and 5 |
* |
* LICENSE: This source file is subject to version 3.01 of the PHP license |
* that is available through the world-wide-web at the following URI: |
* http://www.php.net/license/3_01.txt. If you did not receive a copy of |
* the PHP License and are unable to obtain it through the web, please |
* send a note to license@php.net so we can mail you a copy immediately. |
* |
* @category Authentication |
* @package Auth |
* @author Lorenzo Alberton <l.alberton@quipo.it> |
* @author Adam Ashley <aashley@php.net> |
* @copyright 2001-2006 The PHP Group |
* @license http://www.php.net/license/3_01.txt PHP License 3.01 |
* @version CVS: $Id: MDB.php,v 1.37 2008/04/04 07:57:02 aashley Exp $ |
* @link http://pear.php.net/package/Auth |
* @since File available since Release 1.2.3 |
*/ |
/** |
* Include Auth_Container base class |
*/ |
require_once 'Auth/Container.php'; |
/** |
* Include PEAR MDB package |
*/ |
require_once 'MDB.php'; |
/** |
* Storage driver for fetching login data from a database |
* |
* This storage driver can use all databases which are supported |
* by the PEAR MDB abstraction layer to fetch login data. |
* |
* @category Authentication |
* @package Auth |
* @author Lorenzo Alberton <l.alberton@quipo.it> |
* @author Adam Ashley <aashley@php.net> |
* @copyright 2001-2006 The PHP Group |
* @license http://www.php.net/license/3_01.txt PHP License 3.01 |
* @version Release: 1.6.1 File: $Revision: 1.37 $ |
* @link http://pear.php.net/package/Auth |
* @since Class available since Release 1.2.3 |
*/ |
class Auth_Container_MDB extends Auth_Container |
{ |
// {{{ properties |
/** |
* Additional options for the storage container |
* @var array |
*/ |
var $options = array(); |
/** |
* MDB object |
* @var object |
*/ |
var $db = null; |
var $dsn = ''; |
/** |
* User that is currently selected from the DB. |
* @var string |
*/ |
var $activeUser = ''; |
// }}} |
// {{{ Auth_Container_MDB() [constructor] |
/** |
* Constructor of the container class |
* |
* Initate connection to the database via PEAR::MDB |
* |
* @param string Connection data or MDB object |
* @return object Returns an error object if something went wrong |
*/ |
function Auth_Container_MDB($dsn) |
{ |
$this->_setDefaults(); |
if (is_array($dsn)) { |
$this->_parseOptions($dsn); |
if (empty($this->options['dsn'])) { |
PEAR::raiseError('No connection parameters specified!'); |
} |
} else { |
$this->options['dsn'] = $dsn; |
} |
} |
// }}} |
// {{{ _connect() |
/** |
* Connect to database by using the given DSN string |
* |
* @access private |
* @param mixed DSN string | array | mdb object |
* @return mixed Object on error, otherwise bool |
*/ |
function _connect($dsn) |
{ |
$this->log('Auth_Container_MDB::_connect() called.', AUTH_LOG_DEBUG); |
if (is_string($dsn) || is_array($dsn)) { |
$this->db =& MDB::connect($dsn, $this->options['db_options']); |
} elseif (is_subclass_of($dsn, 'mdb_common')) { |
$this->db = $dsn; |
} elseif (is_object($dsn) && MDB::isError($dsn)) { |
return PEAR::raiseError($dsn->getMessage(), $dsn->code); |
} else { |
return PEAR::raiseError('The given dsn was not valid in file ' . __FILE__ . ' at line ' . __LINE__, |
41, |
PEAR_ERROR_RETURN, |
null, |
null |
); |
} |
if (MDB::isError($this->db) || PEAR::isError($this->db)) { |
return PEAR::raiseError($this->db->getMessage(), $this->db->code); |
} |
if ($this->options['auto_quote']) { |
if (strpos('.', $this->options['table']) === false) { |
$this->options['final_table'] = $this->db->quoteIdentifier($this->options['table']); |
} else { |
$t = explode('.', $this->options['table']); |
for ($i = 0, $count = count($t); $i < $count; $i++) |
$t[$i] = $this->db->quoteIdentifier($t[$i]); |
$this->options['final_table'] = implode('.', $t); |
} |
$this->options['final_usernamecol'] = $this->db->quoteIdentifier($this->options['usernamecol']); |
$this->options['final_passwordcol'] = $this->db->quoteIdentifier($this->options['passwordcol']); |
} else { |
$this->options['final_table'] = $this->options['table']; |
$this->options['final_usernamecol'] = $this->options['usernamecol']; |
$this->options['final_passwordcol'] = $this->options['passwordcol']; |
} |
return true; |
} |
// }}} |
// {{{ _prepare() |
/** |
* Prepare database connection |
* |
* This function checks if we have already opened a connection to |
* the database. If that's not the case, a new connection is opened. |
* |
* @access private |
* @return mixed True or a MDB error object. |
*/ |
function _prepare() |
{ |
if (is_subclass_of($this->db, 'mdb_common')) { |
return true; |
} |
return $this->_connect($this->options['dsn']); |
} |
// }}} |
// {{{ query() |
/** |
* Prepare query to the database |
* |
* This function checks if we have already opened a connection to |
* the database. If that's not the case, a new connection is opened. |
* After that the query is passed to the database. |
* |
* @access public |
* @param string Query string |
* @return mixed a MDB_result object or MDB_OK on success, a MDB |
* or PEAR error on failure |
*/ |
function query($query) |
{ |
$this->log('Auth_Container_MDB::query() called.', AUTH_LOG_DEBUG); |
$err = $this->_prepare(); |
if ($err !== true) { |
return $err; |
} |
return $this->db->query($query); |
} |
// }}} |
// {{{ _setDefaults() |
/** |
* Set some default options |
* |
* @access private |
* @return void |
*/ |
function _setDefaults() |
{ |
$this->options['table'] = 'auth'; |
$this->options['usernamecol'] = 'username'; |
$this->options['passwordcol'] = 'password'; |
$this->options['dsn'] = ''; |
$this->options['db_fields'] = ''; |
$this->options['cryptType'] = 'md5'; |
$this->options['db_options'] = array(); |
$this->options['db_where'] = ''; |
$this->options['auto_quote'] = true; |
} |
// }}} |
// {{{ _parseOptions() |
/** |
* Parse options passed to the container class |
* |
* @access private |
* @param array |
*/ |
function _parseOptions($array) |
{ |
foreach ($array as $key => $value) { |
if (isset($this->options[$key])) { |
$this->options[$key] = $value; |
} |
} |
} |
// }}} |
// {{{ _quoteDBFields() |
/** |
* Quote the db_fields option to avoid the possibility of SQL injection. |
* |
* @access private |
* @return string A properly quoted string that can be concatenated into a |
* SELECT clause. |
*/ |
function _quoteDBFields() |
{ |
if (isset($this->options['db_fields'])) { |
if (is_array($this->options['db_fields'])) { |
if ($this->options['auto_quote']) { |
$fields = array(); |
foreach ($this->options['db_fields'] as $field) { |
$fields[] = $this->db->quoteIdentifier($field); |
} |
return implode(', ', $fields); |
} else { |
return implode(', ', $this->options['db_fields']); |
} |
} else { |
if (strlen($this->options['db_fields']) > 0) { |
if ($this->options['auto_quote']) { |
return $this->db->quoteIdentifier($this->options['db_fields']); |
} else { |
return $this->options['db_fields']; |
} |
} |
} |
} |
return ''; |
} |
// }}} |
// {{{ fetchData() |
/** |
* Get user information from database |
* |
* This function uses the given username to fetch |
* the corresponding login data from the database |
* table. If an account that matches the passed username |
* and password is found, the function returns true. |
* Otherwise it returns false. |
* |
* @param string Username |
* @param string Password |
* @param boolean If true password is secured using a md5 hash |
* the frontend and auth are responsible for making sure the container supports |
* challenge response password authentication |
* @return mixed Error object or boolean |
*/ |
function fetchData($username, $password, $isChallengeResponse=false) |
{ |
$this->log('Auth_Container_MDB::fetchData() called.', AUTH_LOG_DEBUG); |
// Prepare for a database query |
$err = $this->_prepare(); |
if ($err !== true) { |
return PEAR::raiseError($err->getMessage(), $err->getCode()); |
} |
//Check if db_fields contains a *, if so assume all columns are selected |
if (is_string($this->options['db_fields']) |
&& strstr($this->options['db_fields'], '*')) { |
$sql_from = '*'; |
} else { |
$sql_from = $this->options['final_usernamecol']. |
", ".$this->options['final_passwordcol']; |
if (strlen($fields = $this->_quoteDBFields()) > 0) { |
$sql_from .= ', '.$fields; |
} |
} |
$query = sprintf("SELECT %s FROM %s WHERE %s = %s", |
$sql_from, |
$this->options['final_table'], |
$this->options['final_usernamecol'], |
$this->db->getTextValue($username) |
); |
// check if there is an optional parameter db_where |
if ($this->options['db_where'] != '') { |
// there is one, so add it to the query |
$query .= " AND ".$this->options['db_where']; |
} |
$this->log('Running SQL against MDB: '.$query, AUTH_LOG_DEBUG); |
$res = $this->db->getRow($query, null, null, null, MDB_FETCHMODE_ASSOC); |
if (MDB::isError($res) || PEAR::isError($res)) { |
return PEAR::raiseError($res->getMessage(), $res->getCode()); |
} |
if (!is_array($res)) { |
$this->activeUser = ''; |
return false; |
} |
// Perform trimming here before the hashing |
$password = trim($password, "\r\n"); |
$res[$this->options['passwordcol']] = trim($res[$this->options['passwordcol']], "\r\n"); |
// If using Challenge Response md5 the pass with the secret |
if ($isChallengeResponse) { |
$res[$this->options['passwordcol']] = |
md5($res[$this->options['passwordcol']].$this->_auth_obj->session['loginchallenege']); |
// UGLY cannot avoid without modifying verifyPassword |
if ($this->options['cryptType'] == 'md5') { |
$res[$this->options['passwordcol']] = md5($res[$this->options['passwordcol']]); |
} |
} |
if ($this->verifyPassword($password, |
$res[$this->options['passwordcol']], |
$this->options['cryptType'])) { |
// Store additional field values in the session |
foreach ($res as $key => $value) { |
if ($key == $this->options['passwordcol'] || |
$key == $this->options['usernamecol']) { |
continue; |
} |
$this->log('Storing additional field: '.$key, AUTH_LOG_DEBUG); |
// Use reference to the auth object if exists |
// This is because the auth session variable can change so a static |
// call to setAuthData does not make sense |
$this->_auth_obj->setAuthData($key, $value); |
} |
return true; |
} |
$this->activeUser = $res[$this->options['usernamecol']]; |
return false; |
} |
// }}} |
// {{{ listUsers() |
/** |
* Returns a list of users from the container |
* |
* @return mixed array|PEAR_Error |
* @access public |
*/ |
function listUsers() |
{ |
$this->log('Auth_Container_MDB::listUsers() called.', AUTH_LOG_DEBUG); |
$err = $this->_prepare(); |
if ($err !== true) { |
return PEAR::raiseError($err->getMessage(), $err->getCode()); |
} |
$retVal = array(); |
//Check if db_fields contains a *, if so assume all columns are selected |
if ( is_string($this->options['db_fields']) |
&& strstr($this->options['db_fields'], '*')) { |
$sql_from = '*'; |
} else { |
$sql_from = $this->options['final_usernamecol'] |
.', '.$this->options['final_passwordcol']; |
if (strlen($fields = $this->_quoteDBFields()) > 0) { |
$sql_from .= ', '.$fields; |
} |
} |
$query = sprintf('SELECT %s FROM %s', |
$sql_from, |
$this->options['final_table'] |
); |
// check if there is an optional parameter db_where |
if ($this->options['db_where'] != '') { |
// there is one, so add it to the query |
$query .= " WHERE ".$this->options['db_where']; |
} |
$this->log('Running SQL against MDB: '.$query, AUTH_LOG_DEBUG); |
$res = $this->db->getAll($query, null, null, null, MDB_FETCHMODE_ASSOC); |
if (MDB::isError($res)) { |
return PEAR::raiseError($res->getMessage(), $res->getCode()); |
} else { |
foreach ($res as $user) { |
$user['username'] = $user[$this->options['usernamecol']]; |
$retVal[] = $user; |
} |
} |
$this->log('Found '.count($retVal).' users.', AUTH_LOG_DEBUG); |
return $retVal; |
} |
// }}} |
// {{{ addUser() |
/** |
* Add user to the storage container |
* |
* @access public |
* @param string Username |
* @param string Password |
* @param mixed Additional information that are stored in the DB |
* |
* @return mixed True on success, otherwise error object |
*/ |
function addUser($username, $password, $additional = "") |
{ |
$this->log('Auth_Container_MDB::addUser() called.', AUTH_LOG_DEBUG); |
$err = $this->_prepare(); |
if ($err !== true) { |
return PEAR::raiseError($err->getMessage(), $err->getCode()); |
} |
if (isset($this->options['cryptType']) && $this->options['cryptType'] == 'none') { |
$cryptFunction = 'strval'; |
} elseif (isset($this->options['cryptType']) && function_exists($this->options['cryptType'])) { |
$cryptFunction = $this->options['cryptType']; |
} else { |
$cryptFunction = 'md5'; |
} |
$password = $cryptFunction($password); |
$additional_key = ''; |
$additional_value = ''; |
if (is_array($additional)) { |
foreach ($additional as $key => $value) { |
if ($this->options['auto_quote']) { |
$additional_key .= ', ' . $this->db->quoteIdentifier($key); |
} else { |
$additional_key .= ', ' . $key; |
} |
$additional_value .= ', ' . $this->db->getTextValue($value); |
} |
} |
$query = sprintf("INSERT INTO %s (%s, %s%s) VALUES (%s, %s%s)", |
$this->options['final_table'], |
$this->options['final_usernamecol'], |
$this->options['final_passwordcol'], |
$additional_key, |
$this->db->getTextValue($username), |
$this->db->getTextValue($password), |
$additional_value |
); |
$this->log('Running SQL against MDB: '.$query, AUTH_LOG_DEBUG); |
$res = $this->query($query); |
if (MDB::isError($res)) { |
return PEAR::raiseError($res->getMessage(), $res->code); |
} |
return true; |
} |
// }}} |
// {{{ removeUser() |
/** |
* Remove user from the storage container |
* |
* @access public |
* @param string Username |
* |
* @return mixed True on success, otherwise error object |
*/ |
function removeUser($username) |
{ |
$this->log('Auth_Container_MDB::removeUser() called.', AUTH_LOG_DEBUG); |
$err = $this->_prepare(); |
if ($err !== true) { |
return PEAR::raiseError($err->getMessage(), $err->getCode()); |
} |
$query = sprintf("DELETE FROM %s WHERE %s = %s", |
$this->options['final_table'], |
$this->options['final_usernamecol'], |
$this->db->getTextValue($username) |
); |
// check if there is an optional parameter db_where |
if ($this->options['db_where'] != '') { |
// there is one, so add it to the query |
$query .= " AND ".$this->options['db_where']; |
} |
$this->log('Running SQL against MDB: '.$query, AUTH_LOG_DEBUG); |
$res = $this->query($query); |
if (MDB::isError($res)) { |
return PEAR::raiseError($res->getMessage(), $res->code); |
} |
return true; |
} |
// }}} |
// {{{ changePassword() |
/** |
* Change password for user in the storage container |
* |
* @param string Username |
* @param string The new password (plain text) |
*/ |
function changePassword($username, $password) |
{ |
$this->log('Auth_Container_MDB::changePassword() called.', AUTH_LOG_DEBUG); |
$err = $this->_prepare(); |
if ($err !== true) { |
return PEAR::raiseError($err->getMessage(), $err->getCode()); |
} |
if (isset($this->options['cryptType']) && $this->options['cryptType'] == 'none') { |
$cryptFunction = 'strval'; |
} elseif (isset($this->options['cryptType']) && function_exists($this->options['cryptType'])) { |
$cryptFunction = $this->options['cryptType']; |
} else { |
$cryptFunction = 'md5'; |
} |
$password = $cryptFunction($password); |
$query = sprintf("UPDATE %s SET %s = %s WHERE %s = %s", |
$this->options['final_table'], |
$this->options['final_passwordcol'], |
$this->db->getTextValue($password), |
$this->options['final_usernamecol'], |
$this->db->getTextValue($username) |
); |
// check if there is an optional parameter db_where |
if ($this->options['db_where'] != '') { |
// there is one, so add it to the query |
$query .= " AND ".$this->options['db_where']; |
} |
$this->log('Running SQL against MDB: '.$query, AUTH_LOG_DEBUG); |
$res = $this->query($query); |
if (MDB::isError($res)) { |
return PEAR::raiseError($res->getMessage(), $res->code); |
} |
return true; |
} |
// }}} |
// {{{ supportsChallengeResponse() |
/** |
* Determine if this container supports |
* password authentication with challenge response |
* |
* @return bool |
* @access public |
*/ |
function supportsChallengeResponse() |
{ |
return in_array($this->options['cryptType'], array('md5', 'none', '')); |
} |
// }}} |
// {{{ getCryptType() |
/** |
* Returns the selected crypt type for this container |
* |
* @return string Function used to crypt the password |
*/ |
function getCryptType() |
{ |
return $this->options['cryptType']; |
} |
// }}} |
} |
?> |
/obs_saisons/SPIP-v1-8-3/modules/configuration/Container/NetVPOPMaild.php |
---|
New file |
0,0 → 1,129 |
<?php |
/* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4 foldmethod=marker: */ |
/** |
* Storage driver for use with a Vpopmaild server |
* |
* PHP versions 5 |
* |
* LICENSE: This source file is subject to version 3.01 of the PHP license |
* that is available through the world-wide-web at the following URI: |
* http://www.php.net/license/3_01.txt. If you did not receive a copy of |
* the PHP License and are unable to obtain it through the web, please |
* send a note to license@php.net so we can mail you a copy immediately. |
* |
* @category Authentication |
* @package Auth |
* @author Bill Shupp <hostmaster@shupp.org> |
* @author Stefan Ekman <stekman@sedata.org> |
* @author Martin Jansen <mj@php.net> |
* @author Mika Tuupola <tuupola@appelsiini.net> |
* @author Adam Ashley <aashley@php.net> |
* @copyright 2001-2006 The PHP Group |
* @license http://www.php.net/license/3_01.txt PHP License 3.01 |
* @link http://pear.php.net/package/Auth |
* @since File available since Release 1.2.0 |
*/ |
/** |
* Include Auth_Container base class |
*/ |
require_once 'Auth/Container.php'; |
/** |
* Include PEAR package for error handling |
*/ |
require_once 'PEAR.php'; |
/** |
* Include PEAR Net_Vpopmaild package |
*/ |
require_once 'Net/Vpopmaild.php'; |
/** |
* Storage driver for Authentication on a Vpopmaild server. |
* |
* @category Authentication |
* @package Auth |
* @author Martin Jansen <mj@php.net> |
* @author Mika Tuupola <tuupola@appelsiini.net> |
* @author Adam Ashley <aashley@php.net> |
* @copyright 2001-2006 The PHP Group |
* @license http://www.php.net/license/3_01.txt PHP License 3.01 |
* @version Release: 1.5.4 File: $Revision: 1.1 $ |
* @link http://pear.php.net/package/Auth |
* @since Class available since Release 1.6.0 |
*/ |
class Auth_Container_Vpopmaild extends Auth_Container |
{ |
/** |
* Vpopmaild Server |
* @var string |
*/ |
var $server = 'localhost'; |
/** |
* Vpopmaild Server port |
* @var string |
*/ |
var $port = 89; |
/** |
* Constructor of the container class |
* |
* @param $server string server or server:port combination |
* @return object Returns an error object if something went wrong |
*/ |
function Auth_Container_Vpopmaild($server=null) |
{ |
if (isset($server) && !is_null($server)) { |
if (is_array($server)) { |
if (isset($server['host'])) { |
$this->server = $server['host']; |
} |
if (isset($server['port'])) { |
$this->port = $server['port']; |
} |
} else { |
if (strstr($server, ':')) { |
$serverparts = explode(':', trim($server)); |
$this->server = $serverparts[0]; |
$this->port = $serverparts[1]; |
} else { |
$this->server = $server; |
} |
} |
} |
} |
/** |
* fetchData() |
* |
* Try to login to the Vpopmaild server |
* |
* @param string username |
* @param string password |
* |
* @return boolean |
*/ |
function fetchData($username, $password) |
{ |
$this->log('Auth_Container_Vpopmaild::fetchData() called.', AUTH_LOG_DEBUG); |
$vpopmaild =& new Net_Vpopmaild(); |
// Connect |
try { |
$res = $vpopmaild->connect($this->server, $this->port, $this->method); |
} catch (Net_Vpopmaild_FatalException $e) { |
$this->log('Connection to Vpopmaild server failed.', AUTH_LOG_DEBUG); |
return PEAR::raiseError($e->getMessage(), $e->getCode()); |
} |
// Authenticate |
try { |
$result = $vpopmaild->clogin($username, $password); |
$vpopmaild->quit(); |
} catch (Net_Vpopmaild_Exception $e) { |
return PEAR::raiseError($e->getMessage(), $e->getCode()); |
} |
return $result; |
} |
} |
?> |
/obs_saisons/SPIP-v1-8-3/modules/configuration/Container/DBLite.php |
---|
New file |
0,0 → 1,320 |
<?php |
/* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4 foldmethod=marker: */ |
/** |
* Reduced storage driver for use against PEAR DB |
* |
* PHP versions 4 and 5 |
* |
* LICENSE: This source file is subject to version 3.01 of the PHP license |
* that is available through the world-wide-web at the following URI: |
* http://www.php.net/license/3_01.txt. If you did not receive a copy of |
* the PHP License and are unable to obtain it through the web, please |
* send a note to license@php.net so we can mail you a copy immediately. |
* |
* @category Authentication |
* @package Auth |
* @author Martin Jansen <mj@php.net> |
* @author Adam Ashley <aashley@php.net> |
* @copyright 2001-2006 The PHP Group |
* @license http://www.php.net/license/3_01.txt PHP License 3.01 |
* @version CVS: $Id: DBLite.php,v 1.20 2008/04/04 07:57:02 aashley Exp $ |
* @link http://pear.php.net/package/Auth |
* @since File available since Release 1.3.0 |
*/ |
/** |
* Include Auth_Container base class |
*/ |
require_once 'Auth/Container.php'; |
/** |
* Include PEAR DB package |
*/ |
require_once 'DB.php'; |
/** |
* A lighter storage driver for fetching login data from a database |
* |
* This driver is derived from the DB storage container but |
* with the user manipulation function removed for smaller file size |
* by the PEAR DB abstraction layer to fetch login data. |
* |
* @category Authentication |
* @package Auth |
* @author Martin Jansen <mj@php.net> |
* @author Adam Ashley <aashley@php.net> |
* @copyright 2001-2006 The PHP Group |
* @license http://www.php.net/license/3_01.txt PHP License 3.01 |
* @version Release: 1.6.1 File: $Revision: 1.20 $ |
* @link http://pear.php.net/package/Auth |
* @since Class available since Release 1.3.0 |
*/ |
class Auth_Container_DBLite extends Auth_Container |
{ |
// {{{ properties |
/** |
* Additional options for the storage container |
* @var array |
*/ |
var $options = array(); |
/** |
* DB object |
* @var object |
*/ |
var $db = null; |
var $dsn = ''; |
/** |
* User that is currently selected from the DB. |
* @var string |
*/ |
var $activeUser = ''; |
// }}} |
// {{{ Auth_Container_DBLite() [constructor] |
/** |
* Constructor of the container class |
* |
* Initate connection to the database via PEAR::DB |
* |
* @param string Connection data or DB object |
* @return object Returns an error object if something went wrong |
*/ |
function Auth_Container_DBLite($dsn) |
{ |
$this->options['table'] = 'auth'; |
$this->options['usernamecol'] = 'username'; |
$this->options['passwordcol'] = 'password'; |
$this->options['dsn'] = ''; |
$this->options['db_fields'] = ''; |
$this->options['cryptType'] = 'md5'; |
$this->options['db_options'] = array(); |
$this->options['db_where'] = ''; |
$this->options['auto_quote'] = true; |
if (is_array($dsn)) { |
$this->_parseOptions($dsn); |
if (empty($this->options['dsn'])) { |
PEAR::raiseError('No connection parameters specified!'); |
} |
} else { |
$this->options['dsn'] = $dsn; |
} |
} |
// }}} |
// {{{ _connect() |
/** |
* Connect to database by using the given DSN string |
* |
* @access private |
* @param string DSN string |
* @return mixed Object on error, otherwise bool |
*/ |
function _connect(&$dsn) |
{ |
$this->log('Auth_Container_DBLite::_connect() called.', AUTH_LOG_DEBUG); |
if (is_string($dsn) || is_array($dsn)) { |
$this->db =& DB::connect($dsn, $this->options['db_options']); |
} elseif (is_subclass_of($dsn, "db_common")) { |
$this->db =& $dsn; |
} else { |
return PEAR::raiseError("Invalid dsn or db object given"); |
} |
if (DB::isError($this->db) || PEAR::isError($this->db)) { |
return PEAR::raiseError($this->db->getMessage(), $this->db->getCode()); |
} else { |
return true; |
} |
} |
// }}} |
// {{{ _prepare() |
/** |
* Prepare database connection |
* |
* This function checks if we have already opened a connection to |
* the database. If that's not the case, a new connection is opened. |
* |
* @access private |
* @return mixed True or a DB error object. |
*/ |
function _prepare() |
{ |
if (!DB::isConnection($this->db)) { |
$res = $this->_connect($this->options['dsn']); |
if (DB::isError($res) || PEAR::isError($res)) { |
return $res; |
} |
} |
if ($this->options['auto_quote'] && $this->db->dsn['phptype'] != 'sqlite') { |
if (strpos('.', $this->options['table']) === false) { |
$this->options['final_table'] = $this->db->quoteIdentifier($this->options['table']); |
} else { |
$t = explode('.', $this->options['table']); |
for ($i = 0, $count = count($t); $i < $count; $i++) |
$t[$i] = $this->db->quoteIdentifier($t[$i]); |
$this->options['final_table'] = implode('.', $t); |
} |
$this->options['final_usernamecol'] = $this->db->quoteIdentifier($this->options['usernamecol']); |
$this->options['final_passwordcol'] = $this->db->quoteIdentifier($this->options['passwordcol']); |
} else { |
$this->options['final_table'] = $this->options['table']; |
$this->options['final_usernamecol'] = $this->options['usernamecol']; |
$this->options['final_passwordcol'] = $this->options['passwordcol']; |
} |
return true; |
} |
// }}} |
// {{{ _parseOptions() |
/** |
* Parse options passed to the container class |
* |
* @access private |
* @param array |
*/ |
function _parseOptions($array) |
{ |
foreach ($array as $key => $value) { |
if (isset($this->options[$key])) { |
$this->options[$key] = $value; |
} |
} |
} |
// }}} |
// {{{ _quoteDBFields() |
/** |
* Quote the db_fields option to avoid the possibility of SQL injection. |
* |
* @access private |
* @return string A properly quoted string that can be concatenated into a |
* SELECT clause. |
*/ |
function _quoteDBFields() |
{ |
if (isset($this->options['db_fields'])) { |
if (is_array($this->options['db_fields'])) { |
if ($this->options['auto_quote']) { |
$fields = array(); |
foreach ($this->options['db_fields'] as $field) { |
$fields[] = $this->db->quoteIdentifier($field); |
} |
return implode(', ', $fields); |
} else { |
return implode(', ', $this->options['db_fields']); |
} |
} else { |
if (strlen($this->options['db_fields']) > 0) { |
if ($this->options['auto_quote']) { |
return $this->db->quoteIdentifier($this->options['db_fields']); |
} else { |
$this->options['db_fields']; |
} |
} |
} |
} |
return ''; |
} |
// }}} |
// {{{ fetchData() |
/** |
* Get user information from database |
* |
* This function uses the given username to fetch |
* the corresponding login data from the database |
* table. If an account that matches the passed username |
* and password is found, the function returns true. |
* Otherwise it returns false. |
* |
* @param string Username |
* @param string Password |
* @return mixed Error object or boolean |
*/ |
function fetchData($username, $password) |
{ |
$this->log('Auth_Container_DBLite::fetchData() called.', AUTH_LOG_DEBUG); |
// Prepare for a database query |
$err = $this->_prepare(); |
if ($err !== true) { |
return PEAR::raiseError($err->getMessage(), $err->getCode()); |
} |
// Find if db_fields contains a *, if so assume all col are selected |
if (is_string($this->options['db_fields']) |
&& strstr($this->options['db_fields'], '*')) { |
$sql_from = "*"; |
} else { |
$sql_from = $this->options['final_usernamecol']. |
", ".$this->options['final_passwordcol']; |
if (strlen($fields = $this->_quoteDBFields()) > 0) { |
$sql_from .= ', '.$fields; |
} |
} |
$query = "SELECT ".$sql_from. |
" FROM ".$this->options['final_table']. |
" WHERE ".$this->options['final_usernamecol']." = ".$this->db->quoteSmart($username); |
// check if there is an optional parameter db_where |
if ($this->options['db_where'] != '') { |
// there is one, so add it to the query |
$query .= " AND ".$this->options['db_where']; |
} |
$this->log('Running SQL against DB: '.$query, AUTH_LOG_DEBUG); |
$res = $this->db->getRow($query, null, DB_FETCHMODE_ASSOC); |
if (DB::isError($res)) { |
return PEAR::raiseError($res->getMessage(), $res->getCode()); |
} |
if (!is_array($res)) { |
$this->activeUser = ''; |
return false; |
} |
if ($this->verifyPassword(trim($password, "\r\n"), |
trim($res[$this->options['passwordcol']], "\r\n"), |
$this->options['cryptType'])) { |
// Store additional field values in the session |
foreach ($res as $key => $value) { |
if ($key == $this->options['passwordcol'] || |
$key == $this->options['usernamecol']) { |
continue; |
} |
$this->log('Storing additional field: '.$key, AUTH_LOG_DEBUG); |
// Use reference to the auth object if exists |
// This is because the auth session variable can change so a static call to setAuthData does not make sence |
if (is_object($this->_auth_obj)) { |
$this->_auth_obj->setAuthData($key, $value); |
} else { |
Auth::setAuthData($key, $value); |
} |
} |
$this->activeUser = $res[$this->options['usernamecol']]; |
return true; |
} |
$this->activeUser = $res[$this->options['usernamecol']]; |
return false; |
} |
// }}} |
} |
?> |
/obs_saisons/SPIP-v1-8-3/modules/configuration/Container/SMBPasswd.php |
---|
New file |
0,0 → 1,182 |
<?php |
/* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4 foldmethod=marker: */ |
/** |
* Storage driver for use against Samba password files |
* |
* PHP versions 4 and 5 |
* |
* LICENSE: This source file is subject to version 3.01 of the PHP license |
* that is available through the world-wide-web at the following URI: |
* http://www.php.net/license/3_01.txt. If you did not receive a copy of |
* the PHP License and are unable to obtain it through the web, please |
* send a note to license@php.net so we can mail you a copy immediately. |
* |
* @category Authentication |
* @package Auth |
* @author Michael Bretterklieber <michael@bretterklieber.com> |
* @author Adam Ashley <aashley@php.net> |
* @copyright 2001-2006 The PHP Group |
* @license http://www.php.net/license/3_01.txt PHP License 3.01 |
* @version CVS: $Id: SMBPasswd.php,v 1.8 2007/06/12 03:11:26 aashley Exp $ |
* @link http://pear.php.net/package/Auth |
* @since File available since Release 1.2.3 |
*/ |
/** |
* Include PEAR File_SMBPasswd |
*/ |
require_once "File/SMBPasswd.php"; |
/** |
* Include Auth_Container Base file |
*/ |
require_once "Auth/Container.php"; |
/** |
* Include PEAR class for error handling |
*/ |
require_once "PEAR.php"; |
/** |
* Storage driver for fetching login data from an SAMBA smbpasswd file. |
* |
* This storage container can handle SAMBA smbpasswd files. |
* |
* Example: |
* $a = new Auth("SMBPasswd", '/usr/local/private/smbpasswd'); |
* $a->start(); |
* if ($a->getAuth()) { |
* printf ("AUTH OK<br>\n"); |
* $a->logout(); |
* } |
* |
* @category Authentication |
* @package Auth |
* @author Michael Bretterklieber <michael@bretterklieber.com> |
* @author Adam Ashley <aashley@php.net> |
* @package Auth |
* @copyright 2001-2006 The PHP Group |
* @license http://www.php.net/license/3_01.txt PHP License 3.01 |
* @version Release: 1.6.1 File: $Revision: 1.8 $ |
* @link http://pear.php.net/package/Auth |
* @since Class available since Release 1.2.3 |
*/ |
class Auth_Container_SMBPasswd extends Auth_Container |
{ |
// {{{ properties |
/** |
* File_SMBPasswd object |
* @var object |
*/ |
var $pwfile; |
// }}} |
// {{{ Auth_Container_SMBPasswd() [constructor] |
/** |
* Constructor of the container class |
* |
* @param $filename string filename for a passwd type file |
* @return object Returns an error object if something went wrong |
*/ |
function Auth_Container_SMBPasswd($filename) |
{ |
$this->pwfile = new File_SMBPasswd($filename,0); |
if (!$this->pwfile->load()) { |
PEAR::raiseError("Error while reading file contents.", 41, PEAR_ERROR_DIE); |
return; |
} |
} |
// }}} |
// {{{ fetchData() |
/** |
* Get user information from pwfile |
* |
* @param string Username |
* @param string Password |
* @return boolean |
*/ |
function fetchData($username, $password) |
{ |
$this->log('Auth_Container_SMBPasswd::fetchData() called.', AUTH_LOG_DEBUG); |
return $this->pwfile->verifyAccount($username, $password); |
} |
// }}} |
// {{{ listUsers() |
function listUsers() |
{ |
$this->log('Auth_Container_SMBPasswd::fetchData() called.', AUTH_LOG_DEBUG); |
return $this->pwfile->getAccounts(); |
} |
// }}} |
// {{{ addUser() |
/** |
* Add a new user to the storage container |
* |
* @param string Username |
* @param string Password |
* @param array Additional information |
* |
* @return boolean |
*/ |
function addUser($username, $password, $additional = '') |
{ |
$this->log('Auth_Container_SMBPasswd::addUser() called.', AUTH_LOG_DEBUG); |
$res = $this->pwfile->addUser($user, $additional['userid'], $pass); |
if ($res === true) { |
return $this->pwfile->save(); |
} |
return $res; |
} |
// }}} |
// {{{ removeUser() |
/** |
* Remove user from the storage container |
* |
* @param string Username |
*/ |
function removeUser($username) |
{ |
$this->log('Auth_Container_SMBPasswd::removeUser() called.', AUTH_LOG_DEBUG); |
$res = $this->pwfile->delUser($username); |
if ($res === true) { |
return $this->pwfile->save(); |
} |
return $res; |
} |
// }}} |
// {{{ changePassword() |
/** |
* Change password for user in the storage container |
* |
* @param string Username |
* @param string The new password |
*/ |
function changePassword($username, $password) |
{ |
$this->log('Auth_Container_SMBPasswd::changePassword() called.', AUTH_LOG_DEBUG); |
$res = $this->pwfile->modUser($username, '', $password); |
if ($res === true) { |
return $this->pwfile->save(); |
} |
return $res; |
} |
// }}} |
} |
?> |
/obs_saisons/SPIP-v1-8-3/modules/configuration/Container/Array.php |
---|
New file |
0,0 → 1,161 |
<?php |
/* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4 foldmethod=marker: */ |
/** |
* Storage driver for use against a PHP Array |
* |
* PHP versions 4 and 5 |
* |
* LICENSE: This source file is subject to version 3.01 of the PHP license |
* that is available through the world-wide-web at the following URI: |
* http://www.php.net/license/3_01.txt. If you did not receive a copy of |
* the PHP License and are unable to obtain it through the web, please |
* send a note to license@php.net so we can mail you a copy immediately. |
* |
* @category Authentication |
* @package Auth |
* @author georg_1 at have2 dot com |
* @author Adam Ashley <aashley@php.net> |
* @copyright 2001-2006 The PHP Group |
* @license http://www.php.net/license/3_01.txt PHP License 3.01 |
* @version CVS: $Id: Array.php,v 1.5 2007/06/12 03:11:26 aashley Exp $ |
* @since File available since Release 1.4.0 |
*/ |
/** |
* Include Auth_Container base class |
*/ |
require_once "Auth/Container.php"; |
/** |
* Include PEAR package for error handling |
*/ |
require_once "PEAR.php"; |
/** |
* Storage driver for fetching authentication data from a PHP Array |
* |
* This container takes two options when configuring: |
* |
* cryptType: The crypt used to store the password. Currently recognised |
* are: none, md5 and crypt. default: none |
* users: A named array of usernames and passwords. |
* Ex: |
* array( |
* 'guest' => '084e0343a0486ff05530df6c705c8bb4', // password guest |
* 'georg' => 'fc77dba827fcc88e0243404572c51325' // password georg |
* ) |
* |
* Usage Example: |
* <?php |
* $AuthOptions = array( |
* 'users' => array( |
* 'guest' => '084e0343a0486ff05530df6c705c8bb4', // password guest |
* 'georg' => 'fc77dba827fcc88e0243404572c51325' // password georg |
* ), |
* 'cryptType'=>'md5', |
* ); |
* |
* $auth = new Auth("Array", $AuthOptions); |
* ?> |
* |
* @category Authentication |
* @package Auth |
* @author georg_1 at have2 dot com |
* @author Adam Ashley <aashley@php.net> |
* @copyright 2001-2006 The PHP Group |
* @license http://www.php.net/license/3_01.txt PHP License 3.01 |
* @version Release: 1.6.1 File: $Revision: 1.5 $ |
* @since File available since Release 1.4.0 |
*/ |
class Auth_Container_Array extends Auth_Container { |
// {{{ properties |
/** |
* The users and their password to authenticate against |
* |
* @var array $users |
*/ |
var $users; |
/** |
* The cryptType used on the passwords |
* |
* @var string $cryptType |
*/ |
var $cryptType = 'none'; |
// }}} |
// {{{ Auth_Container_Array() |
/** |
* Constructor for Array Container |
* |
* @param array $data Options for the container |
* @return void |
*/ |
function Auth_Container_Array($data) |
{ |
if (!is_array($data)) { |
PEAR::raiseError('The options for Auth_Container_Array must be an array'); |
} |
if (isset($data['users']) && is_array($data['users'])) { |
$this->users = $data['users']; |
} else { |
$this->users = array(); |
PEAR::raiseError('Auth_Container_Array: no user data found in options array'); |
} |
if (isset($data['cryptType'])) { |
$this->cryptType = $data['cryptType']; |
} |
} |
// }}} |
// {{{ fetchData() |
/** |
* Get user information from array |
* |
* This function uses the given username to fetch the corresponding |
* login data from the array. If an account that matches the passed |
* username and password is found, the function returns true. |
* Otherwise it returns false. |
* |
* @param string Username |
* @param string Password |
* @return boolean|PEAR_Error Error object or boolean |
*/ |
function fetchData($user, $pass) |
{ |
$this->log('Auth_Container_Array::fetchData() called.', AUTH_LOG_DEBUG); |
if ( isset($this->users[$user]) |
&& $this->verifyPassword($pass, $this->users[$user], $this->cryptType)) { |
return true; |
} |
return false; |
} |
// }}} |
// {{{ listUsers() |
/** |
* Returns a list of users available within the container |
* |
* @return array |
*/ |
function listUsers() |
{ |
$this->log('Auth_Container_Array::listUsers() called.', AUTH_LOG_DEBUG); |
$ret = array(); |
foreach ($this->users as $username => $password) { |
$ret[]['username'] = $username; |
} |
return $ret; |
} |
// }}} |
} |
?> |
/obs_saisons/SPIP-v1-8-3/modules/configuration/Container/File.php |
---|
New file |
0,0 → 1,314 |
<?php |
/* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4 foldmethod=marker: */ |
/** |
* Storage driver for use against a generic password file |
* |
* PHP versions 4 and 5 |
* |
* LICENSE: This source file is subject to version 3.01 of the PHP license |
* that is available through the world-wide-web at the following URI: |
* http://www.php.net/license/3_01.txt. If you did not receive a copy of |
* the PHP License and are unable to obtain it through the web, please |
* send a note to license@php.net so we can mail you a copy immediately. |
* |
* @category Authentication |
* @package Auth |
* @author Stefan Ekman <stekman@sedata.org> |
* @author Martin Jansen <mj@php.net> |
* @author Mika Tuupola <tuupola@appelsiini.net> |
* @author Michael Wallner <mike@php.net> |
* @author Adam Ashley <aashley@php.net> |
* @copyright 2001-2006 The PHP Group |
* @license http://www.php.net/license/3_01.txt PHP License 3.01 |
* @version CVS: $Id: File.php,v 1.25 2007/06/12 03:11:26 aashley Exp $ |
* @link http://pear.php.net/package/Auth |
*/ |
/** |
* Include PEAR File_Passwd package |
*/ |
require_once "File/Passwd.php"; |
/** |
* Include Auth_Container base class |
*/ |
require_once "Auth/Container.php"; |
/** |
* Include PEAR package for error handling |
*/ |
require_once "PEAR.php"; |
/** |
* Storage driver for fetching login data from an encrypted password file. |
* |
* This storage container can handle CVS pserver style passwd files. |
* |
* @category Authentication |
* @package Auth |
* @author Stefan Ekman <stekman@sedata.org> |
* @author Martin Jansen <mj@php.net> |
* @author Mika Tuupola <tuupola@appelsiini.net> |
* @author Michael Wallner <mike@php.net> |
* @author Adam Ashley <aashley@php.net> |
* @copyright 2001-2006 The PHP Group |
* @license http://www.php.net/license/3_01.txt PHP License 3.01 |
* @version Release: 1.6.1 File: $Revision: 1.25 $ |
* @link http://pear.php.net/package/Auth |
*/ |
class Auth_Container_File extends Auth_Container |
{ |
// {{{ properties |
/** |
* Path to passwd file |
* |
* @var string |
*/ |
var $pwfile = ''; |
/** |
* Options for container |
* |
* @var array |
*/ |
var $options = array(); |
// }}} |
// {{{ Auth_Container_File() [constructor] |
/** |
* Constructor of the container class |
* |
* @param string $filename path to passwd file |
* @return object Auth_Container_File new Auth_Container_File object |
*/ |
function Auth_Container_File($filename) { |
$this->_setDefaults(); |
// Only file is a valid option here |
if(is_array($filename)) { |
$this->pwfile = $filename['file']; |
$this->_parseOptions($filename); |
} else { |
$this->pwfile = $filename; |
} |
} |
// }}} |
// {{{ fetchData() |
/** |
* Authenticate an user |
* |
* @param string username |
* @param string password |
* @return mixed boolean|PEAR_Error |
*/ |
function fetchData($user, $pass) |
{ |
$this->log('Auth_Container_File::fetchData() called.', AUTH_LOG_DEBUG); |
return File_Passwd::staticAuth($this->options['type'], $this->pwfile, $user, $pass); |
} |
// }}} |
// {{{ listUsers() |
/** |
* List all available users |
* |
* @return array |
*/ |
function listUsers() |
{ |
$this->log('Auth_Container_File::listUsers() called.', AUTH_LOG_DEBUG); |
$pw_obj = &$this->_load(); |
if (PEAR::isError($pw_obj)) { |
return array(); |
} |
$users = $pw_obj->listUser(); |
if (!is_array($users)) { |
return array(); |
} |
foreach ($users as $key => $value) { |
$retVal[] = array("username" => $key, |
"password" => $value['passwd'], |
"cvsuser" => $value['system']); |
} |
$this->log('Found '.count($retVal).' users.', AUTH_LOG_DEBUG); |
return $retVal; |
} |
// }}} |
// {{{ addUser() |
/** |
* Add a new user to the storage container |
* |
* @param string username |
* @param string password |
* @param mixed Additional parameters to File_Password_*::addUser() |
* |
* @return boolean |
*/ |
function addUser($user, $pass, $additional='') |
{ |
$this->log('Auth_Container_File::addUser() called.', AUTH_LOG_DEBUG); |
$params = array($user, $pass); |
if (is_array($additional)) { |
foreach ($additional as $item) { |
$params[] = $item; |
} |
} else { |
$params[] = $additional; |
} |
$pw_obj = &$this->_load(); |
if (PEAR::isError($pw_obj)) { |
return false; |
} |
$res = call_user_func_array(array(&$pw_obj, 'addUser'), $params); |
if (PEAR::isError($res)) { |
return false; |
} |
$res = $pw_obj->save(); |
if (PEAR::isError($res)) { |
return false; |
} |
return true; |
} |
// }}} |
// {{{ removeUser() |
/** |
* Remove user from the storage container |
* |
* @param string Username |
* @return boolean |
*/ |
function removeUser($user) |
{ |
$this->log('Auth_Container_File::removeUser() called.', AUTH_LOG_DEBUG); |
$pw_obj = &$this->_load(); |
if (PEAR::isError($pw_obj)) { |
return false; |
} |
$res = $pw_obj->delUser($user); |
if (PEAR::isError($res)) { |
return false; |
} |
$res = $pw_obj->save(); |
if (PEAR::isError($res)) { |
return false; |
} |
return true; |
} |
// }}} |
// {{{ changePassword() |
/** |
* Change password for user in the storage container |
* |
* @param string Username |
* @param string The new password |
*/ |
function changePassword($username, $password) |
{ |
$this->log('Auth_Container_File::changePassword() called.', AUTH_LOG_DEBUG); |
$pw_obj = &$this->_load(); |
if (PEAR::isError($pw_obj)) { |
return false; |
} |
$res = $pw_obj->changePasswd($username, $password); |
if (PEAR::isError($res)) { |
return false; |
} |
$res = $pw_obj->save(); |
if (PEAR::isError($res)) { |
return false; |
} |
return true; |
} |
// }}} |
// {{{ _load() |
/** |
* Load and initialize the File_Passwd object |
* |
* @return object File_Passwd_Cvs|PEAR_Error |
*/ |
function &_load() |
{ |
static $pw_obj; |
if (!isset($pw_obj)) { |
$this->log('Instanciating File_Password object of type '.$this->options['type'], AUTH_LOG_DEBUG); |
$pw_obj = File_Passwd::factory($this->options['type']); |
if (PEAR::isError($pw_obj)) { |
return $pw_obj; |
} |
$pw_obj->setFile($this->pwfile); |
$res = $pw_obj->load(); |
if (PEAR::isError($res)) { |
return $res; |
} |
} |
return $pw_obj; |
} |
// }}} |
// {{{ _setDefaults() |
/** |
* Set some default options |
* |
* @access private |
* @return void |
*/ |
function _setDefaults() |
{ |
$this->options['type'] = 'Cvs'; |
} |
// }}} |
// {{{ _parseOptions() |
/** |
* Parse options passed to the container class |
* |
* @access private |
* @param array |
*/ |
function _parseOptions($array) |
{ |
foreach ($array as $key => $value) { |
if (isset($this->options[$key])) { |
$this->options[$key] = $value; |
} |
} |
} |
// }}} |
} |
?> |
/obs_saisons/SPIP-v1-8-3/modules/configuration/Container/LDAP.php |
---|
New file |
0,0 → 1,766 |
<?php |
/* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4 foldmethod=marker: */ |
/** |
* Storage driver for use against an LDAP server |
* |
* PHP versions 4 and 5 |
* |
* LICENSE: This source file is subject to version 3.01 of the PHP license |
* that is available through the world-wide-web at the following URI: |
* http://www.php.net/license/3_01.txt. If you did not receive a copy of |
* the PHP License and are unable to obtain it through the web, please |
* send a note to license@php.net so we can mail you a copy immediately. |
* |
* @category Authentication |
* @package Auth |
* @author Jan Wagner <wagner@netsols.de> |
* @author Adam Ashley <aashley@php.net> |
* @author Hugues Peeters <hugues.peeters@claroline.net> |
* @copyright 2001-2006 The PHP Group |
* @license http://www.php.net/license/3_01.txt PHP License 3.01 |
* @version CVS: $Id: LDAP.php,v 1.43 2007/06/12 03:11:26 aashley Exp $ |
* @link http://pear.php.net/package/Auth |
*/ |
/** |
* Include Auth_Container base class |
*/ |
require_once "Auth/Container.php"; |
/** |
* Include PEAR package for error handling |
*/ |
require_once "PEAR.php"; |
/** |
* Storage driver for fetching login data from LDAP |
* |
* This class is heavily based on the DB and File containers. By default it |
* connects to localhost:389 and searches for uid=$username with the scope |
* "sub". If no search base is specified, it will try to determine it via |
* the namingContexts attribute. It takes its parameters in a hash, connects |
* to the ldap server, binds anonymously, searches for the user, and tries |
* to bind as the user with the supplied password. When a group was set, it |
* will look for group membership of the authenticated user. If all goes |
* well the authentication was successful. |
* |
* Parameters: |
* |
* host: localhost (default), ldap.netsols.de or 127.0.0.1 |
* port: 389 (default) or 636 or whereever your server runs |
* url: ldap://localhost:389/ |
* useful for ldaps://, works only with openldap2 ? |
* it will be preferred over host and port |
* version: LDAP version to use, ususally 2 (default) or 3, |
* must be an integer! |
* referrals: If set, determines whether the LDAP library automatically |
* follows referrals returned by LDAP servers or not. Possible |
* values are true (default) or false. |
* binddn: If set, searching for user will be done after binding |
* as this user, if not set the bind will be anonymous. |
* This is reported to make the container work with MS |
* Active Directory, but should work with any server that |
* is configured this way. |
* This has to be a complete dn for now (basedn and |
* userdn will not be appended). |
* bindpw: The password to use for binding with binddn |
* basedn: the base dn of your server |
* userdn: gets prepended to basedn when searching for user |
* userscope: Scope for user searching: one, sub (default), or base |
* userattr: the user attribute to search for (default: uid) |
* userfilter: filter that will be added to the search filter |
* this way: (&(userattr=username)(userfilter)) |
* default: (objectClass=posixAccount) |
* attributes: array of additional attributes to fetch from entry. |
* these will added to auth data and can be retrieved via |
* Auth::getAuthData(). An empty array will fetch all attributes, |
* array('') will fetch no attributes at all (default) |
* If you add 'dn' as a value to this array, the users DN that was |
* used for binding will be added to auth data as well. |
* attrformat: The returned format of the additional data defined in the |
* 'attributes' option. Two formats are available. |
* LDAP returns data formatted in a |
* multidimensional array where each array starts with a |
* 'count' element providing the number of attributes in the |
* entry, or the number of values for attributes. When set |
* to this format, the only way to retrieve data from the |
* Auth object is by calling getAuthData('attributes'). |
* AUTH returns data formatted in a |
* structure more compliant with other Auth Containers, |
* where each attribute element can be directly called by |
* getAuthData() method from Auth. |
* For compatibily with previous LDAP container versions, |
* the default format is LDAP. |
* groupdn: gets prepended to basedn when searching for group |
* groupattr: the group attribute to search for (default: cn) |
* groupfilter: filter that will be added to the search filter when |
* searching for a group: |
* (&(groupattr=group)(memberattr=username)(groupfilter)) |
* default: (objectClass=groupOfUniqueNames) |
* memberattr : the attribute of the group object where the user dn |
* may be found (default: uniqueMember) |
* memberisdn: whether the memberattr is the dn of the user (default) |
* or the value of userattr (usually uid) |
* group: the name of group to search for |
* groupscope: Scope for group searching: one, sub (default), or base |
* start_tls: enable/disable the use of START_TLS encrypted connection |
* (default: false) |
* debug: Enable/Disable debugging output (default: false) |
* try_all: Whether to try all user accounts returned from the search |
* or just the first one. (default: false) |
* |
* To use this storage container, you have to use the following syntax: |
* |
* <?php |
* ... |
* |
* $a1 = new Auth("LDAP", array( |
* 'host' => 'localhost', |
* 'port' => '389', |
* 'version' => 3, |
* 'basedn' => 'o=netsols,c=de', |
* 'userattr' => 'uid' |
* 'binddn' => 'cn=admin,o=netsols,c=de', |
* 'bindpw' => 'password')); |
* |
* $a2 = new Auth('LDAP', array( |
* 'url' => 'ldaps://ldap.netsols.de', |
* 'basedn' => 'o=netsols,c=de', |
* 'userscope' => 'one', |
* 'userdn' => 'ou=People', |
* 'groupdn' => 'ou=Groups', |
* 'groupfilter' => '(objectClass=posixGroup)', |
* 'memberattr' => 'memberUid', |
* 'memberisdn' => false, |
* 'group' => 'admin' |
* )); |
* |
* $a3 = new Auth('LDAP', array( |
* 'host' => 'ldap.netsols.de', |
* 'port' => 389, |
* 'version' => 3, |
* 'referrals' => false, |
* 'basedn' => 'dc=netsols,dc=de', |
* 'binddn' => 'cn=Jan Wagner,cn=Users,dc=netsols,dc=de', |
* 'bindpw' => 'password', |
* 'userattr' => 'samAccountName', |
* 'userfilter' => '(objectClass=user)', |
* 'attributes' => array(''), |
* 'group' => 'testing', |
* 'groupattr' => 'samAccountName', |
* 'groupfilter' => '(objectClass=group)', |
* 'memberattr' => 'member', |
* 'memberisdn' => true, |
* 'groupdn' => 'cn=Users', |
* 'groupscope' => 'one', |
* 'debug' => true); |
* |
* The parameter values have to correspond |
* to the ones for your LDAP server of course. |
* |
* When talking to a Microsoft ActiveDirectory server you have to |
* use 'samaccountname' as the 'userattr' and follow special rules |
* to translate the ActiveDirectory directory names into 'basedn'. |
* The 'basedn' for the default 'Users' folder on an ActiveDirectory |
* server for the ActiveDirectory Domain (which is not related to |
* its DNS name) "win2000.example.org" would be: |
* "CN=Users, DC=win2000, DC=example, DC=org' |
* where every component of the domain name becomes a DC attribute |
* of its own. If you want to use a custom users folder you have to |
* replace "CN=Users" with a sequence of "OU" attributes that specify |
* the path to your custom folder in reverse order. |
* So the ActiveDirectory folder |
* "win2000.example.org\Custom\Accounts" |
* would become |
* "OU=Accounts, OU=Custom, DC=win2000, DC=example, DC=org' |
* |
* It seems that binding anonymously to an Active Directory |
* is not allowed, so you have to set binddn and bindpw for |
* user searching. |
* |
* LDAP Referrals need to be set to false for AD to work sometimes. |
* |
* Example a3 shows a full blown and tested example for connection to |
* Windows 2000 Active Directory with group mebership checking |
* |
* Note also that if you want an encrypted connection to an MS LDAP |
* server, then, on your webserver, you must specify |
* TLS_REQCERT never |
* in /etc/ldap/ldap.conf or in the webserver user's ~/.ldaprc (which |
* may or may not be read depending on your configuration). |
* |
* |
* @category Authentication |
* @package Auth |
* @author Jan Wagner <wagner@netsols.de> |
* @author Adam Ashley <aashley@php.net> |
* @author Hugues Peeters <hugues.peeters@claroline.net> |
* @copyright 2001-2006 The PHP Group |
* @license http://www.php.net/license/3_01.txt PHP License 3.01 |
* @version Release: 1.6.1 File: $Revision: 1.43 $ |
* @link http://pear.php.net/package/Auth |
*/ |
class Auth_Container_LDAP extends Auth_Container |
{ |
// {{{ properties |
/** |
* Options for the class |
* @var array |
*/ |
var $options = array(); |
/** |
* Connection ID of LDAP Link |
* @var string |
*/ |
var $conn_id = false; |
// }}} |
// {{{ Auth_Container_LDAP() [constructor] |
/** |
* Constructor of the container class |
* |
* @param $params, associative hash with host,port,basedn and userattr key |
* @return object Returns an error object if something went wrong |
*/ |
function Auth_Container_LDAP($params) |
{ |
if (false === extension_loaded('ldap')) { |
return PEAR::raiseError('Auth_Container_LDAP: LDAP Extension not loaded', |
41, PEAR_ERROR_DIE); |
} |
$this->_setDefaults(); |
if (is_array($params)) { |
$this->_parseOptions($params); |
} |
} |
// }}} |
// {{{ _prepare() |
/** |
* Prepare LDAP connection |
* |
* This function checks if we have already opened a connection to |
* the LDAP server. If that's not the case, a new connection is opened. |
* |
* @access private |
* @return mixed True or a PEAR error object. |
*/ |
function _prepare() |
{ |
if (!$this->_isValidLink()) { |
$res = $this->_connect(); |
if (PEAR::isError($res)) { |
return $res; |
} |
} |
return true; |
} |
// }}} |
// {{{ _connect() |
/** |
* Connect to the LDAP server using the global options |
* |
* @access private |
* @return object Returns a PEAR error object if an error occurs. |
*/ |
function _connect() |
{ |
$this->log('Auth_Container_LDAP::_connect() called.', AUTH_LOG_DEBUG); |
// connect |
if (isset($this->options['url']) && $this->options['url'] != '') { |
$this->log('Connecting with URL', AUTH_LOG_DEBUG); |
$conn_params = array($this->options['url']); |
} else { |
$this->log('Connecting with host:port', AUTH_LOG_DEBUG); |
$conn_params = array($this->options['host'], $this->options['port']); |
} |
if (($this->conn_id = @call_user_func_array('ldap_connect', $conn_params)) === false) { |
$this->log('Connection to server failed.', AUTH_LOG_DEBUG); |
$this->log('LDAP ERROR: '.ldap_errno($this->conn_id).': '.ldap_error($this->conn_id), AUTH_LOG_DEBUG); |
return PEAR::raiseError('Auth_Container_LDAP: Could not connect to server.', 41); |
} |
$this->log('Successfully connected to server', AUTH_LOG_DEBUG); |
// switch LDAP version |
if (is_numeric($this->options['version']) && $this->options['version'] > 2) { |
$this->log("Switching to LDAP version {$this->options['version']}", AUTH_LOG_DEBUG); |
@ldap_set_option($this->conn_id, LDAP_OPT_PROTOCOL_VERSION, $this->options['version']); |
// start TLS if available |
if (isset($this->options['start_tls']) && $this->options['start_tls']) { |
$this->log("Starting TLS session", AUTH_LOG_DEBUG); |
if (@ldap_start_tls($this->conn_id) === false) { |
$this->log('Could not start TLS session', AUTH_LOG_DEBUG); |
$this->log('LDAP ERROR: '.ldap_errno($this->conn_id).': '.ldap_error($this->conn_id), AUTH_LOG_DEBUG); |
return PEAR::raiseError('Auth_Container_LDAP: Could not start tls.', 41); |
} |
} |
} |
// switch LDAP referrals |
if (is_bool($this->options['referrals'])) { |
$this->log("Switching LDAP referrals to " . (($this->options['referrals']) ? 'true' : 'false'), AUTH_LOG_DEBUG); |
if (@ldap_set_option($this->conn_id, LDAP_OPT_REFERRALS, $this->options['referrals']) === false) { |
$this->log('Could not change LDAP referrals options', AUTH_LOG_DEBUG); |
$this->log('LDAP ERROR: '.ldap_errno($this->conn_id).': '.ldap_error($this->conn_id), AUTH_LOG_DEBUG); |
} |
} |
// bind with credentials or anonymously |
if (strlen($this->options['binddn']) && strlen($this->options['bindpw'])) { |
$this->log('Binding with credentials', AUTH_LOG_DEBUG); |
$bind_params = array($this->conn_id, $this->options['binddn'], $this->options['bindpw']); |
} else { |
$this->log('Binding anonymously', AUTH_LOG_DEBUG); |
$bind_params = array($this->conn_id); |
} |
// bind for searching |
if ((@call_user_func_array('ldap_bind', $bind_params)) === false) { |
$this->log('Bind failed', AUTH_LOG_DEBUG); |
$this->log('LDAP ERROR: '.ldap_errno($this->conn_id).': '.ldap_error($this->conn_id), AUTH_LOG_DEBUG); |
$this->_disconnect(); |
return PEAR::raiseError("Auth_Container_LDAP: Could not bind to LDAP server.", 41); |
} |
$this->log('Binding was successful', AUTH_LOG_DEBUG); |
return true; |
} |
// }}} |
// {{{ _disconnect() |
/** |
* Disconnects (unbinds) from ldap server |
* |
* @access private |
*/ |
function _disconnect() |
{ |
$this->log('Auth_Container_LDAP::_disconnect() called.', AUTH_LOG_DEBUG); |
if ($this->_isValidLink()) { |
$this->log('disconnecting from server'); |
@ldap_unbind($this->conn_id); |
} |
} |
// }}} |
// {{{ _getBaseDN() |
/** |
* Tries to find Basedn via namingContext Attribute |
* |
* @access private |
*/ |
function _getBaseDN() |
{ |
$this->log('Auth_Container_LDAP::_getBaseDN() called.', AUTH_LOG_DEBUG); |
$err = $this->_prepare(); |
if ($err !== true) { |
return PEAR::raiseError($err->getMessage(), $err->getCode()); |
} |
if ($this->options['basedn'] == "" && $this->_isValidLink()) { |
$this->log("basedn not set, searching via namingContexts.", AUTH_LOG_DEBUG); |
$result_id = @ldap_read($this->conn_id, "", "(objectclass=*)", array("namingContexts")); |
if (@ldap_count_entries($this->conn_id, $result_id) == 1) { |
$this->log("got result for namingContexts", AUTH_LOG_DEBUG); |
$entry_id = @ldap_first_entry($this->conn_id, $result_id); |
$attrs = @ldap_get_attributes($this->conn_id, $entry_id); |
$basedn = $attrs['namingContexts'][0]; |
if ($basedn != "") { |
$this->log("result for namingContexts was $basedn", AUTH_LOG_DEBUG); |
$this->options['basedn'] = $basedn; |
} |
} |
@ldap_free_result($result_id); |
} |
// if base ist still not set, raise error |
if ($this->options['basedn'] == "") { |
return PEAR::raiseError("Auth_Container_LDAP: LDAP search base not specified!", 41); |
} |
return true; |
} |
// }}} |
// {{{ _isValidLink() |
/** |
* determines whether there is a valid ldap conenction or not |
* |
* @accessd private |
* @return boolean |
*/ |
function _isValidLink() |
{ |
if (is_resource($this->conn_id)) { |
if (get_resource_type($this->conn_id) == 'ldap link') { |
return true; |
} |
} |
return false; |
} |
// }}} |
// {{{ _setDefaults() |
/** |
* Set some default options |
* |
* @access private |
*/ |
function _setDefaults() |
{ |
$this->options['url'] = ''; |
$this->options['host'] = 'localhost'; |
$this->options['port'] = '389'; |
$this->options['version'] = 2; |
$this->options['referrals'] = true; |
$this->options['binddn'] = ''; |
$this->options['bindpw'] = ''; |
$this->options['basedn'] = ''; |
$this->options['userdn'] = ''; |
$this->options['userscope'] = 'sub'; |
$this->options['userattr'] = 'uid'; |
$this->options['userfilter'] = '(objectClass=posixAccount)'; |
$this->options['attributes'] = array(''); // no attributes |
$this->options['attrformat'] = 'AUTH'; // returns attribute like other Auth containers |
$this->options['group'] = ''; |
$this->options['groupdn'] = ''; |
$this->options['groupscope'] = 'sub'; |
$this->options['groupattr'] = 'cn'; |
$this->options['groupfilter'] = '(objectClass=groupOfUniqueNames)'; |
$this->options['memberattr'] = 'uniqueMember'; |
$this->options['memberisdn'] = true; |
$this->options['start_tls'] = false; |
$this->options['debug'] = false; |
$this->options['try_all'] = false; // Try all user ids returned not just the first one |
} |
// }}} |
// {{{ _parseOptions() |
/** |
* Parse options passed to the container class |
* |
* @access private |
* @param array |
*/ |
function _parseOptions($array) |
{ |
$array = $this->_setV12OptionsToV13($array); |
foreach ($array as $key => $value) { |
if (array_key_exists($key, $this->options)) { |
if ($key == 'attributes') { |
if (is_array($value)) { |
$this->options[$key] = $value; |
} else { |
$this->options[$key] = explode(',', $value); |
} |
} else { |
$this->options[$key] = $value; |
} |
} |
} |
} |
// }}} |
// {{{ _setV12OptionsToV13() |
/** |
* Adapt deprecated options from Auth 1.2 LDAP to Auth 1.3 LDAP |
* |
* @author Hugues Peeters <hugues.peeters@claroline.net> |
* @access private |
* @param array |
* @return array |
*/ |
function _setV12OptionsToV13($array) |
{ |
if (isset($array['useroc'])) |
$array['userfilter'] = "(objectClass=".$array['useroc'].")"; |
if (isset($array['groupoc'])) |
$array['groupfilter'] = "(objectClass=".$array['groupoc'].")"; |
if (isset($array['scope'])) |
$array['userscope'] = $array['scope']; |
return $array; |
} |
// }}} |
// {{{ _scope2function() |
/** |
* Get search function for scope |
* |
* @param string scope |
* @return string ldap search function |
*/ |
function _scope2function($scope) |
{ |
switch($scope) { |
case 'one': |
$function = 'ldap_list'; |
break; |
case 'base': |
$function = 'ldap_read'; |
break; |
default: |
$function = 'ldap_search'; |
break; |
} |
return $function; |
} |
// }}} |
// {{{ fetchData() |
/** |
* Fetch data from LDAP server |
* |
* Searches the LDAP server for the given username/password |
* combination. Escapes all LDAP meta characters in username |
* before performing the query. |
* |
* @param string Username |
* @param string Password |
* @return boolean |
*/ |
function fetchData($username, $password) |
{ |
$this->log('Auth_Container_LDAP::fetchData() called.', AUTH_LOG_DEBUG); |
$err = $this->_prepare(); |
if ($err !== true) { |
return PEAR::raiseError($err->getMessage(), $err->getCode()); |
} |
$err = $this->_getBaseDN(); |
if ($err !== true) { |
return PEAR::raiseError($err->getMessage(), $err->getCode()); |
} |
// UTF8 Encode username for LDAPv3 |
if (@ldap_get_option($this->conn_id, LDAP_OPT_PROTOCOL_VERSION, $ver) && $ver == 3) { |
$this->log('UTF8 encoding username for LDAPv3', AUTH_LOG_DEBUG); |
$username = utf8_encode($username); |
} |
// make search filter |
$filter = sprintf('(&(%s=%s)%s)', |
$this->options['userattr'], |
$this->_quoteFilterString($username), |
$this->options['userfilter']); |
// make search base dn |
$search_basedn = $this->options['userdn']; |
if ($search_basedn != '' && substr($search_basedn, -1) != ',') { |
$search_basedn .= ','; |
} |
$search_basedn .= $this->options['basedn']; |
// attributes |
$searchAttributes = $this->options['attributes']; |
// make functions params array |
$func_params = array($this->conn_id, $search_basedn, $filter, $searchAttributes); |
// search function to use |
$func_name = $this->_scope2function($this->options['userscope']); |
$this->log("Searching with $func_name and filter $filter in $search_basedn", AUTH_LOG_DEBUG); |
// search |
if (($result_id = @call_user_func_array($func_name, $func_params)) === false) { |
$this->log('User not found', AUTH_LOG_DEBUG); |
} elseif (@ldap_count_entries($this->conn_id, $result_id) >= 1) { // did we get some possible results? |
$this->log('User(s) found', AUTH_LOG_DEBUG); |
$first = true; |
$entry_id = null; |
do { |
// then get the user dn |
if ($first) { |
$entry_id = @ldap_first_entry($this->conn_id, $result_id); |
$first = false; |
} else { |
$entry_id = @ldap_next_entry($this->conn_id, $entry_id); |
if ($entry_id === false) |
break; |
} |
$user_dn = @ldap_get_dn($this->conn_id, $entry_id); |
// as the dn is not fetched as an attribute, we save it anyway |
if (is_array($searchAttributes) && in_array('dn', $searchAttributes)) { |
$this->log('Saving DN to AuthData', AUTH_LOG_DEBUG); |
$this->_auth_obj->setAuthData('dn', $user_dn); |
} |
// fetch attributes |
if ($attributes = @ldap_get_attributes($this->conn_id, $entry_id)) { |
if (is_array($attributes) && isset($attributes['count']) && |
$attributes['count'] > 0) { |
// ldap_get_attributes() returns a specific multi dimensional array |
// format containing all the attributes and where each array starts |
// with a 'count' element providing the number of attributes in the |
// entry, or the number of values for attribute. For compatibility |
// reasons, it remains the default format returned by LDAP container |
// setAuthData(). |
// The code below optionally returns attributes in another format, |
// more compliant with other Auth containers, where each attribute |
// element are directly set in the 'authData' list. This option is |
// enabled by setting 'attrformat' to |
// 'AUTH' in the 'options' array. |
// eg. $this->options['attrformat'] = 'AUTH' |
if ( strtoupper($this->options['attrformat']) == 'AUTH' ) { |
$this->log('Saving attributes to Auth data in AUTH format', AUTH_LOG_DEBUG); |
unset ($attributes['count']); |
foreach ($attributes as $attributeName => $attributeValue ) { |
if (is_int($attributeName)) continue; |
if (is_array($attributeValue) && isset($attributeValue['count'])) { |
unset ($attributeValue['count']); |
} |
if (count($attributeValue)<=1) $attributeValue = $attributeValue[0]; |
$this->log('Storing additional field: '.$attributeName, AUTH_LOG_DEBUG); |
$this->_auth_obj->setAuthData($attributeName, $attributeValue); |
} |
} |
else |
{ |
$this->log('Saving attributes to Auth data in LDAP format', AUTH_LOG_DEBUG); |
$this->_auth_obj->setAuthData('attributes', $attributes); |
} |
} |
} |
@ldap_free_result($result_id); |
// need to catch an empty password as openldap seems to return TRUE |
// if anonymous binding is allowed |
if ($password != "") { |
$this->log("Bind as $user_dn", AUTH_LOG_DEBUG); |
// try binding as this user with the supplied password |
if (@ldap_bind($this->conn_id, $user_dn, $password)) { |
$this->log('Bind successful', AUTH_LOG_DEBUG); |
// check group if appropiate |
if (strlen($this->options['group'])) { |
// decide whether memberattr value is a dn or the username |
$this->log('Checking group membership', AUTH_LOG_DEBUG); |
$return = $this->checkGroup(($this->options['memberisdn']) ? $user_dn : $username); |
$this->_disconnect(); |
return $return; |
} else { |
$this->log('Authenticated', AUTH_LOG_DEBUG); |
$this->_disconnect(); |
return true; // user authenticated |
} // checkGroup |
} // bind |
} // non-empty password |
} while ($this->options['try_all'] == true); // interate through entries |
} // get results |
// default |
$this->log('NOT authenticated!', AUTH_LOG_DEBUG); |
$this->_disconnect(); |
return false; |
} |
// }}} |
// {{{ checkGroup() |
/** |
* Validate group membership |
* |
* Searches the LDAP server for group membership of the |
* supplied username. Quotes all LDAP filter meta characters in |
* the user name before querying the LDAP server. |
* |
* @param string Distinguished Name of the authenticated User |
* @return boolean |
*/ |
function checkGroup($user) |
{ |
$this->log('Auth_Container_LDAP::checkGroup() called.', AUTH_LOG_DEBUG); |
$err = $this->_prepare(); |
if ($err !== true) { |
return PEAR::raiseError($err->getMessage(), $err->getCode()); |
} |
// make filter |
$filter = sprintf('(&(%s=%s)(%s=%s)%s)', |
$this->options['groupattr'], |
$this->options['group'], |
$this->options['memberattr'], |
$this->_quoteFilterString($user), |
$this->options['groupfilter']); |
// make search base dn |
$search_basedn = $this->options['groupdn']; |
if ($search_basedn != '' && substr($search_basedn, -1) != ',') { |
$search_basedn .= ','; |
} |
$search_basedn .= $this->options['basedn']; |
$func_params = array($this->conn_id, $search_basedn, $filter, |
array($this->options['memberattr'])); |
$func_name = $this->_scope2function($this->options['groupscope']); |
$this->log("Searching with $func_name and filter $filter in $search_basedn", AUTH_LOG_DEBUG); |
// search |
if (($result_id = @call_user_func_array($func_name, $func_params)) != false) { |
if (@ldap_count_entries($this->conn_id, $result_id) == 1) { |
@ldap_free_result($result_id); |
$this->log('User is member of group', AUTH_LOG_DEBUG); |
return true; |
} |
} |
// default |
$this->log('User is NOT member of group', AUTH_LOG_DEBUG); |
return false; |
} |
// }}} |
// {{{ _quoteFilterString() |
/** |
* Escapes LDAP filter special characters as defined in RFC 2254. |
* |
* @access private |
* @param string Filter String |
*/ |
function _quoteFilterString($filter_str) |
{ |
$metas = array( '\\', '*', '(', ')', "\x00"); |
$quoted_metas = array('\\\\', '\*', '\(', '\)', "\\\x00"); |
return str_replace($metas, $quoted_metas, $filter_str); |
} |
// }}} |
} |
?> |
/obs_saisons/SPIP-v1-8-3/modules/configuration/Container/POP3.php |
---|
New file |
0,0 → 1,145 |
<?php |
/* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4 foldmethod=marker: */ |
/** |
* Storage driver for use against a POP3 server |
* |
* PHP versions 4 and 5 |
* |
* LICENSE: This source file is subject to version 3.01 of the PHP license |
* that is available through the world-wide-web at the following URI: |
* http://www.php.net/license/3_01.txt. If you did not receive a copy of |
* the PHP License and are unable to obtain it through the web, please |
* send a note to license@php.net so we can mail you a copy immediately. |
* |
* @category Authentication |
* @package Auth |
* @author Stefan Ekman <stekman@sedata.org> |
* @author Martin Jansen <mj@php.net> |
* @author Mika Tuupola <tuupola@appelsiini.net> |
* @author Adam Ashley <aashley@php.net> |
* @copyright 2001-2006 The PHP Group |
* @license http://www.php.net/license/3_01.txt PHP License 3.01 |
* @version CVS: $Id: POP3.php,v 1.12 2007/06/12 03:11:26 aashley Exp $ |
* @link http://pear.php.net/package/Auth |
* @since File available since Release 1.2.0 |
*/ |
/** |
* Include Auth_Container base class |
*/ |
require_once 'Auth/Container.php'; |
/** |
* Include PEAR package for error handling |
*/ |
require_once 'PEAR.php'; |
/** |
* Include PEAR Net_POP3 package |
*/ |
require_once 'Net/POP3.php'; |
/** |
* Storage driver for Authentication on a POP3 server. |
* |
* @category Authentication |
* @package Auth |
* @author Martin Jansen <mj@php.net> |
* @author Mika Tuupola <tuupola@appelsiini.net> |
* @author Adam Ashley <aashley@php.net> |
* @copyright 2001-2006 The PHP Group |
* @license http://www.php.net/license/3_01.txt PHP License 3.01 |
* @version Release: 1.6.1 File: $Revision: 1.12 $ |
* @link http://pear.php.net/package/Auth |
* @since Class available since Release 1.2.0 |
*/ |
class Auth_Container_POP3 extends Auth_Container |
{ |
// {{{ properties |
/** |
* POP3 Server |
* @var string |
*/ |
var $server='localhost'; |
/** |
* POP3 Server port |
* @var string |
*/ |
var $port='110'; |
/** |
* POP3 Authentication method |
* |
* Prefered POP3 authentication method. Acceptable values: |
* Boolean TRUE - Use Net_POP3's autodetection |
* String 'DIGEST-MD5','CRAM-MD5','LOGIN','PLAIN','APOP','USER' |
* - Attempt this authentication style first |
* then fallback to autodetection. |
* @var mixed |
*/ |
var $method=true; |
// }}} |
// {{{ Auth_Container_POP3() [constructor] |
/** |
* Constructor of the container class |
* |
* @param $server string server or server:port combination |
* @return object Returns an error object if something went wrong |
*/ |
function Auth_Container_POP3($server=null) |
{ |
if (isset($server) && !is_null($server)) { |
if (is_array($server)) { |
if (isset($server['host'])) { |
$this->server = $server['host']; |
} |
if (isset($server['port'])) { |
$this->port = $server['port']; |
} |
if (isset($server['method'])) { |
$this->method = $server['method']; |
} |
} else { |
if (strstr($server, ':')) { |
$serverparts = explode(':', trim($server)); |
$this->server = $serverparts[0]; |
$this->port = $serverparts[1]; |
} else { |
$this->server = $server; |
} |
} |
} |
} |
// }}} |
// {{{ fetchData() |
/** |
* Try to login to the POP3 server |
* |
* @param string Username |
* @param string Password |
* @return boolean |
*/ |
function fetchData($username, $password) |
{ |
$this->log('Auth_Container_POP3::fetchData() called.', AUTH_LOG_DEBUG); |
$pop3 =& new Net_POP3(); |
$res = $pop3->connect($this->server, $this->port, $this->method); |
if (!$res) { |
$this->log('Connection to POP3 server failed.', AUTH_LOG_DEBUG); |
return $res; |
} |
$result = $pop3->login($username, $password); |
$pop3->disconnect(); |
return $result; |
} |
// }}} |
} |
?> |
/obs_saisons/SPIP-v1-8-3/modules/configuration/DB/msql.php |
---|
New file |
0,0 → 1,831 |
<?php |
/* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4: */ |
/** |
* The PEAR DB driver for PHP's msql extension |
* for interacting with Mini SQL databases |
* |
* PHP's mSQL extension did weird things with NULL values prior to PHP |
* 4.3.11 and 5.0.4. Make sure your version of PHP meets or exceeds |
* those versions. |
* |
* PHP versions 4 and 5 |
* |
* LICENSE: This source file is subject to version 3.0 of the PHP license |
* that is available through the world-wide-web at the following URI: |
* http://www.php.net/license/3_0.txt. If you did not receive a copy of |
* the PHP License and are unable to obtain it through the web, please |
* send a note to license@php.net so we can mail you a copy immediately. |
* |
* @category Database |
* @package DB |
* @author Daniel Convissor <danielc@php.net> |
* @copyright 1997-2007 The PHP Group |
* @license http://www.php.net/license/3_0.txt PHP License 3.0 |
* @version CVS: $Id: msql.php,v 1.1 2008/07/07 18:00:39 mrflos Exp $ |
* @link http://pear.php.net/package/DB |
*/ |
/** |
* Obtain the DB_common class so it can be extended from |
*/ |
require_once 'DB/common.php'; |
/** |
* The methods PEAR DB uses to interact with PHP's msql extension |
* for interacting with Mini SQL databases |
* |
* These methods overload the ones declared in DB_common. |
* |
* PHP's mSQL extension did weird things with NULL values prior to PHP |
* 4.3.11 and 5.0.4. Make sure your version of PHP meets or exceeds |
* those versions. |
* |
* @category Database |
* @package DB |
* @author Daniel Convissor <danielc@php.net> |
* @copyright 1997-2007 The PHP Group |
* @license http://www.php.net/license/3_0.txt PHP License 3.0 |
* @version Release: 1.7.14RC1 |
* @link http://pear.php.net/package/DB |
* @since Class not functional until Release 1.7.0 |
*/ |
class DB_msql extends DB_common |
{ |
// {{{ properties |
/** |
* The DB driver type (mysql, oci8, odbc, etc.) |
* @var string |
*/ |
var $phptype = 'msql'; |
/** |
* The database syntax variant to be used (db2, access, etc.), if any |
* @var string |
*/ |
var $dbsyntax = 'msql'; |
/** |
* The capabilities of this DB implementation |
* |
* The 'new_link' element contains the PHP version that first provided |
* new_link support for this DBMS. Contains false if it's unsupported. |
* |
* Meaning of the 'limit' element: |
* + 'emulate' = emulate with fetch row by number |
* + 'alter' = alter the query |
* + false = skip rows |
* |
* @var array |
*/ |
var $features = array( |
'limit' => 'emulate', |
'new_link' => false, |
'numrows' => true, |
'pconnect' => true, |
'prepare' => false, |
'ssl' => false, |
'transactions' => false, |
); |
/** |
* A mapping of native error codes to DB error codes |
* @var array |
*/ |
var $errorcode_map = array( |
); |
/** |
* The raw database connection created by PHP |
* @var resource |
*/ |
var $connection; |
/** |
* The DSN information for connecting to a database |
* @var array |
*/ |
var $dsn = array(); |
/** |
* The query result resource created by PHP |
* |
* Used to make affectedRows() work. Only contains the result for |
* data manipulation queries. Contains false for other queries. |
* |
* @var resource |
* @access private |
*/ |
var $_result; |
// }}} |
// {{{ constructor |
/** |
* This constructor calls <kbd>$this->DB_common()</kbd> |
* |
* @return void |
*/ |
function DB_msql() |
{ |
$this->DB_common(); |
} |
// }}} |
// {{{ connect() |
/** |
* Connect to the database server, log in and open the database |
* |
* Don't call this method directly. Use DB::connect() instead. |
* |
* Example of how to connect: |
* <code> |
* require_once 'DB.php'; |
* |
* // $dsn = 'msql://hostname/dbname'; // use a TCP connection |
* $dsn = 'msql:///dbname'; // use a socket |
* $options = array( |
* 'portability' => DB_PORTABILITY_ALL, |
* ); |
* |
* $db = DB::connect($dsn, $options); |
* if (PEAR::isError($db)) { |
* die($db->getMessage()); |
* } |
* </code> |
* |
* @param array $dsn the data source name |
* @param bool $persistent should the connection be persistent? |
* |
* @return int DB_OK on success. A DB_Error object on failure. |
*/ |
function connect($dsn, $persistent = false) |
{ |
if (!PEAR::loadExtension('msql')) { |
return $this->raiseError(DB_ERROR_EXTENSION_NOT_FOUND); |
} |
$this->dsn = $dsn; |
if ($dsn['dbsyntax']) { |
$this->dbsyntax = $dsn['dbsyntax']; |
} |
$params = array(); |
if ($dsn['hostspec']) { |
$params[] = $dsn['port'] |
? $dsn['hostspec'] . ',' . $dsn['port'] |
: $dsn['hostspec']; |
} |
$connect_function = $persistent ? 'msql_pconnect' : 'msql_connect'; |
$ini = ini_get('track_errors'); |
$php_errormsg = ''; |
if ($ini) { |
$this->connection = @call_user_func_array($connect_function, |
$params); |
} else { |
@ini_set('track_errors', 1); |
$this->connection = @call_user_func_array($connect_function, |
$params); |
@ini_set('track_errors', $ini); |
} |
if (!$this->connection) { |
if (($err = @msql_error()) != '') { |
return $this->raiseError(DB_ERROR_CONNECT_FAILED, |
null, null, null, |
$err); |
} else { |
return $this->raiseError(DB_ERROR_CONNECT_FAILED, |
null, null, null, |
$php_errormsg); |
} |
} |
if (!@msql_select_db($dsn['database'], $this->connection)) { |
return $this->msqlRaiseError(); |
} |
return DB_OK; |
} |
// }}} |
// {{{ disconnect() |
/** |
* Disconnects from the database server |
* |
* @return bool TRUE on success, FALSE on failure |
*/ |
function disconnect() |
{ |
$ret = @msql_close($this->connection); |
$this->connection = null; |
return $ret; |
} |
// }}} |
// {{{ simpleQuery() |
/** |
* Sends a query to the database server |
* |
* @param string the SQL query string |
* |
* @return mixed + a PHP result resrouce for successful SELECT queries |
* + the DB_OK constant for other successful queries |
* + a DB_Error object on failure |
*/ |
function simpleQuery($query) |
{ |
$this->last_query = $query; |
$query = $this->modifyQuery($query); |
$result = @msql_query($query, $this->connection); |
if (!$result) { |
return $this->msqlRaiseError(); |
} |
// Determine which queries that should return data, and which |
// should return an error code only. |
if ($this->_checkManip($query)) { |
$this->_result = $result; |
return DB_OK; |
} else { |
$this->_result = false; |
return $result; |
} |
} |
// }}} |
// {{{ nextResult() |
/** |
* Move the internal msql result pointer to the next available result |
* |
* @param a valid fbsql result resource |
* |
* @access public |
* |
* @return true if a result is available otherwise return false |
*/ |
function nextResult($result) |
{ |
return false; |
} |
// }}} |
// {{{ fetchInto() |
/** |
* Places a row from the result set into the given array |
* |
* Formating of the array and the data therein are configurable. |
* See DB_result::fetchInto() for more information. |
* |
* This method is not meant to be called directly. Use |
* DB_result::fetchInto() instead. It can't be declared "protected" |
* because DB_result is a separate object. |
* |
* PHP's mSQL extension did weird things with NULL values prior to PHP |
* 4.3.11 and 5.0.4. Make sure your version of PHP meets or exceeds |
* those versions. |
* |
* @param resource $result the query result resource |
* @param array $arr the referenced array to put the data in |
* @param int $fetchmode how the resulting array should be indexed |
* @param int $rownum the row number to fetch (0 = first row) |
* |
* @return mixed DB_OK on success, NULL when the end of a result set is |
* reached or on failure |
* |
* @see DB_result::fetchInto() |
*/ |
function fetchInto($result, &$arr, $fetchmode, $rownum = null) |
{ |
if ($rownum !== null) { |
if (!@msql_data_seek($result, $rownum)) { |
return null; |
} |
} |
if ($fetchmode & DB_FETCHMODE_ASSOC) { |
$arr = @msql_fetch_array($result, MSQL_ASSOC); |
if ($this->options['portability'] & DB_PORTABILITY_LOWERCASE && $arr) { |
$arr = array_change_key_case($arr, CASE_LOWER); |
} |
} else { |
$arr = @msql_fetch_row($result); |
} |
if (!$arr) { |
return null; |
} |
if ($this->options['portability'] & DB_PORTABILITY_RTRIM) { |
$this->_rtrimArrayValues($arr); |
} |
if ($this->options['portability'] & DB_PORTABILITY_NULL_TO_EMPTY) { |
$this->_convertNullArrayValuesToEmpty($arr); |
} |
return DB_OK; |
} |
// }}} |
// {{{ freeResult() |
/** |
* Deletes the result set and frees the memory occupied by the result set |
* |
* This method is not meant to be called directly. Use |
* DB_result::free() instead. It can't be declared "protected" |
* because DB_result is a separate object. |
* |
* @param resource $result PHP's query result resource |
* |
* @return bool TRUE on success, FALSE if $result is invalid |
* |
* @see DB_result::free() |
*/ |
function freeResult($result) |
{ |
return is_resource($result) ? msql_free_result($result) : false; |
} |
// }}} |
// {{{ numCols() |
/** |
* Gets the number of columns in a result set |
* |
* This method is not meant to be called directly. Use |
* DB_result::numCols() instead. It can't be declared "protected" |
* because DB_result is a separate object. |
* |
* @param resource $result PHP's query result resource |
* |
* @return int the number of columns. A DB_Error object on failure. |
* |
* @see DB_result::numCols() |
*/ |
function numCols($result) |
{ |
$cols = @msql_num_fields($result); |
if (!$cols) { |
return $this->msqlRaiseError(); |
} |
return $cols; |
} |
// }}} |
// {{{ numRows() |
/** |
* Gets the number of rows in a result set |
* |
* This method is not meant to be called directly. Use |
* DB_result::numRows() instead. It can't be declared "protected" |
* because DB_result is a separate object. |
* |
* @param resource $result PHP's query result resource |
* |
* @return int the number of rows. A DB_Error object on failure. |
* |
* @see DB_result::numRows() |
*/ |
function numRows($result) |
{ |
$rows = @msql_num_rows($result); |
if ($rows === false) { |
return $this->msqlRaiseError(); |
} |
return $rows; |
} |
// }}} |
// {{{ affected() |
/** |
* Determines the number of rows affected by a data maniuplation query |
* |
* 0 is returned for queries that don't manipulate data. |
* |
* @return int the number of rows. A DB_Error object on failure. |
*/ |
function affectedRows() |
{ |
if (!$this->_result) { |
return 0; |
} |
return msql_affected_rows($this->_result); |
} |
// }}} |
// {{{ nextId() |
/** |
* Returns the next free id in a sequence |
* |
* @param string $seq_name name of the sequence |
* @param boolean $ondemand when true, the seqence is automatically |
* created if it does not exist |
* |
* @return int the next id number in the sequence. |
* A DB_Error object on failure. |
* |
* @see DB_common::nextID(), DB_common::getSequenceName(), |
* DB_msql::createSequence(), DB_msql::dropSequence() |
*/ |
function nextId($seq_name, $ondemand = true) |
{ |
$seqname = $this->getSequenceName($seq_name); |
$repeat = false; |
do { |
$this->pushErrorHandling(PEAR_ERROR_RETURN); |
$result = $this->query("SELECT _seq FROM ${seqname}"); |
$this->popErrorHandling(); |
if ($ondemand && DB::isError($result) && |
$result->getCode() == DB_ERROR_NOSUCHTABLE) { |
$repeat = true; |
$this->pushErrorHandling(PEAR_ERROR_RETURN); |
$result = $this->createSequence($seq_name); |
$this->popErrorHandling(); |
if (DB::isError($result)) { |
return $this->raiseError($result); |
} |
} else { |
$repeat = false; |
} |
} while ($repeat); |
if (DB::isError($result)) { |
return $this->raiseError($result); |
} |
$arr = $result->fetchRow(DB_FETCHMODE_ORDERED); |
$result->free(); |
return $arr[0]; |
} |
// }}} |
// {{{ createSequence() |
/** |
* Creates a new sequence |
* |
* Also creates a new table to associate the sequence with. Uses |
* a separate table to ensure portability with other drivers. |
* |
* @param string $seq_name name of the new sequence |
* |
* @return int DB_OK on success. A DB_Error object on failure. |
* |
* @see DB_common::createSequence(), DB_common::getSequenceName(), |
* DB_msql::nextID(), DB_msql::dropSequence() |
*/ |
function createSequence($seq_name) |
{ |
$seqname = $this->getSequenceName($seq_name); |
$res = $this->query('CREATE TABLE ' . $seqname |
. ' (id INTEGER NOT NULL)'); |
if (DB::isError($res)) { |
return $res; |
} |
$res = $this->query("CREATE SEQUENCE ON ${seqname}"); |
return $res; |
} |
// }}} |
// {{{ dropSequence() |
/** |
* Deletes a sequence |
* |
* @param string $seq_name name of the sequence to be deleted |
* |
* @return int DB_OK on success. A DB_Error object on failure. |
* |
* @see DB_common::dropSequence(), DB_common::getSequenceName(), |
* DB_msql::nextID(), DB_msql::createSequence() |
*/ |
function dropSequence($seq_name) |
{ |
return $this->query('DROP TABLE ' . $this->getSequenceName($seq_name)); |
} |
// }}} |
// {{{ quoteIdentifier() |
/** |
* mSQL does not support delimited identifiers |
* |
* @param string $str the identifier name to be quoted |
* |
* @return object a DB_Error object |
* |
* @see DB_common::quoteIdentifier() |
* @since Method available since Release 1.7.0 |
*/ |
function quoteIdentifier($str) |
{ |
return $this->raiseError(DB_ERROR_UNSUPPORTED); |
} |
// }}} |
// {{{ quoteFloat() |
/** |
* Formats a float value for use within a query in a locale-independent |
* manner. |
* |
* @param float the float value to be quoted. |
* @return string the quoted string. |
* @see DB_common::quoteSmart() |
* @since Method available since release 1.7.8. |
*/ |
function quoteFloat($float) { |
return $this->escapeSimple(str_replace(',', '.', strval(floatval($float)))); |
} |
// }}} |
// {{{ escapeSimple() |
/** |
* Escapes a string according to the current DBMS's standards |
* |
* @param string $str the string to be escaped |
* |
* @return string the escaped string |
* |
* @see DB_common::quoteSmart() |
* @since Method available since Release 1.7.0 |
*/ |
function escapeSimple($str) |
{ |
return addslashes($str); |
} |
// }}} |
// {{{ msqlRaiseError() |
/** |
* Produces a DB_Error object regarding the current problem |
* |
* @param int $errno if the error is being manually raised pass a |
* DB_ERROR* constant here. If this isn't passed |
* the error information gathered from the DBMS. |
* |
* @return object the DB_Error object |
* |
* @see DB_common::raiseError(), |
* DB_msql::errorNative(), DB_msql::errorCode() |
*/ |
function msqlRaiseError($errno = null) |
{ |
$native = $this->errorNative(); |
if ($errno === null) { |
$errno = $this->errorCode($native); |
} |
return $this->raiseError($errno, null, null, null, $native); |
} |
// }}} |
// {{{ errorNative() |
/** |
* Gets the DBMS' native error message produced by the last query |
* |
* @return string the DBMS' error message |
*/ |
function errorNative() |
{ |
return @msql_error(); |
} |
// }}} |
// {{{ errorCode() |
/** |
* Determines PEAR::DB error code from the database's text error message |
* |
* @param string $errormsg the error message returned from the database |
* |
* @return integer the error number from a DB_ERROR* constant |
*/ |
function errorCode($errormsg) |
{ |
static $error_regexps; |
// PHP 5.2+ prepends the function name to $php_errormsg, so we need |
// this hack to work around it, per bug #9599. |
$errormsg = preg_replace('/^msql[a-z_]+\(\): /', '', $errormsg); |
if (!isset($error_regexps)) { |
$error_regexps = array( |
'/^Access to database denied/i' |
=> DB_ERROR_ACCESS_VIOLATION, |
'/^Bad index name/i' |
=> DB_ERROR_ALREADY_EXISTS, |
'/^Bad order field/i' |
=> DB_ERROR_SYNTAX, |
'/^Bad type for comparison/i' |
=> DB_ERROR_SYNTAX, |
'/^Can\'t perform LIKE on/i' |
=> DB_ERROR_SYNTAX, |
'/^Can\'t use TEXT fields in LIKE comparison/i' |
=> DB_ERROR_SYNTAX, |
'/^Couldn\'t create temporary table/i' |
=> DB_ERROR_CANNOT_CREATE, |
'/^Error creating table file/i' |
=> DB_ERROR_CANNOT_CREATE, |
'/^Field .* cannot be null$/i' |
=> DB_ERROR_CONSTRAINT_NOT_NULL, |
'/^Index (field|condition) .* cannot be null$/i' |
=> DB_ERROR_SYNTAX, |
'/^Invalid date format/i' |
=> DB_ERROR_INVALID_DATE, |
'/^Invalid time format/i' |
=> DB_ERROR_INVALID, |
'/^Literal value for .* is wrong type$/i' |
=> DB_ERROR_INVALID_NUMBER, |
'/^No Database Selected/i' |
=> DB_ERROR_NODBSELECTED, |
'/^No value specified for field/i' |
=> DB_ERROR_VALUE_COUNT_ON_ROW, |
'/^Non unique value for unique index/i' |
=> DB_ERROR_CONSTRAINT, |
'/^Out of memory for temporary table/i' |
=> DB_ERROR_CANNOT_CREATE, |
'/^Permission denied/i' |
=> DB_ERROR_ACCESS_VIOLATION, |
'/^Reference to un-selected table/i' |
=> DB_ERROR_SYNTAX, |
'/^syntax error/i' |
=> DB_ERROR_SYNTAX, |
'/^Table .* exists$/i' |
=> DB_ERROR_ALREADY_EXISTS, |
'/^Unknown database/i' |
=> DB_ERROR_NOSUCHDB, |
'/^Unknown field/i' |
=> DB_ERROR_NOSUCHFIELD, |
'/^Unknown (index|system variable)/i' |
=> DB_ERROR_NOT_FOUND, |
'/^Unknown table/i' |
=> DB_ERROR_NOSUCHTABLE, |
'/^Unqualified field/i' |
=> DB_ERROR_SYNTAX, |
); |
} |
foreach ($error_regexps as $regexp => $code) { |
if (preg_match($regexp, $errormsg)) { |
return $code; |
} |
} |
return DB_ERROR; |
} |
// }}} |
// {{{ tableInfo() |
/** |
* Returns information about a table or a result set |
* |
* @param object|string $result DB_result object from a query or a |
* string containing the name of a table. |
* While this also accepts a query result |
* resource identifier, this behavior is |
* deprecated. |
* @param int $mode a valid tableInfo mode |
* |
* @return array an associative array with the information requested. |
* A DB_Error object on failure. |
* |
* @see DB_common::setOption() |
*/ |
function tableInfo($result, $mode = null) |
{ |
if (is_string($result)) { |
/* |
* Probably received a table name. |
* Create a result resource identifier. |
*/ |
$id = @msql_query("SELECT * FROM $result", |
$this->connection); |
$got_string = true; |
} elseif (isset($result->result)) { |
/* |
* Probably received a result object. |
* Extract the result resource identifier. |
*/ |
$id = $result->result; |
$got_string = false; |
} else { |
/* |
* Probably received a result resource identifier. |
* Copy it. |
* Deprecated. Here for compatibility only. |
*/ |
$id = $result; |
$got_string = false; |
} |
if (!is_resource($id)) { |
return $this->raiseError(DB_ERROR_NEED_MORE_DATA); |
} |
if ($this->options['portability'] & DB_PORTABILITY_LOWERCASE) { |
$case_func = 'strtolower'; |
} else { |
$case_func = 'strval'; |
} |
$count = @msql_num_fields($id); |
$res = array(); |
if ($mode) { |
$res['num_fields'] = $count; |
} |
for ($i = 0; $i < $count; $i++) { |
$tmp = @msql_fetch_field($id); |
$flags = ''; |
if ($tmp->not_null) { |
$flags .= 'not_null '; |
} |
if ($tmp->unique) { |
$flags .= 'unique_key '; |
} |
$flags = trim($flags); |
$res[$i] = array( |
'table' => $case_func($tmp->table), |
'name' => $case_func($tmp->name), |
'type' => $tmp->type, |
'len' => msql_field_len($id, $i), |
'flags' => $flags, |
); |
if ($mode & DB_TABLEINFO_ORDER) { |
$res['order'][$res[$i]['name']] = $i; |
} |
if ($mode & DB_TABLEINFO_ORDERTABLE) { |
$res['ordertable'][$res[$i]['table']][$res[$i]['name']] = $i; |
} |
} |
// free the result only if we were called on a table |
if ($got_string) { |
@msql_free_result($id); |
} |
return $res; |
} |
// }}} |
// {{{ getSpecialQuery() |
/** |
* Obtain a list of a given type of objects |
* |
* @param string $type the kind of objects you want to retrieve |
* |
* @return array the array containing the list of objects requested |
* |
* @access protected |
* @see DB_common::getListOf() |
*/ |
function getSpecialQuery($type) |
{ |
switch ($type) { |
case 'databases': |
$id = @msql_list_dbs($this->connection); |
break; |
case 'tables': |
$id = @msql_list_tables($this->dsn['database'], |
$this->connection); |
break; |
default: |
return null; |
} |
if (!$id) { |
return $this->msqlRaiseError(); |
} |
$out = array(); |
while ($row = @msql_fetch_row($id)) { |
$out[] = $row[0]; |
} |
return $out; |
} |
// }}} |
} |
/* |
* Local variables: |
* tab-width: 4 |
* c-basic-offset: 4 |
* End: |
*/ |
?> |
/obs_saisons/SPIP-v1-8-3/modules/configuration/DB/dbase.php |
---|
New file |
0,0 → 1,510 |
<?php |
/* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4: */ |
/** |
* The PEAR DB driver for PHP's dbase extension |
* for interacting with dBase databases |
* |
* PHP versions 4 and 5 |
* |
* LICENSE: This source file is subject to version 3.0 of the PHP license |
* that is available through the world-wide-web at the following URI: |
* http://www.php.net/license/3_0.txt. If you did not receive a copy of |
* the PHP License and are unable to obtain it through the web, please |
* send a note to license@php.net so we can mail you a copy immediately. |
* |
* @category Database |
* @package DB |
* @author Tomas V.V. Cox <cox@idecnet.com> |
* @author Daniel Convissor <danielc@php.net> |
* @copyright 1997-2007 The PHP Group |
* @license http://www.php.net/license/3_0.txt PHP License 3.0 |
* @version CVS: $Id: dbase.php,v 1.1 2008/07/07 18:00:39 mrflos Exp $ |
* @link http://pear.php.net/package/DB |
*/ |
/** |
* Obtain the DB_common class so it can be extended from |
*/ |
require_once 'DB/common.php'; |
/** |
* The methods PEAR DB uses to interact with PHP's dbase extension |
* for interacting with dBase databases |
* |
* These methods overload the ones declared in DB_common. |
* |
* @category Database |
* @package DB |
* @author Tomas V.V. Cox <cox@idecnet.com> |
* @author Daniel Convissor <danielc@php.net> |
* @copyright 1997-2007 The PHP Group |
* @license http://www.php.net/license/3_0.txt PHP License 3.0 |
* @version Release: 1.7.14RC1 |
* @link http://pear.php.net/package/DB |
*/ |
class DB_dbase extends DB_common |
{ |
// {{{ properties |
/** |
* The DB driver type (mysql, oci8, odbc, etc.) |
* @var string |
*/ |
var $phptype = 'dbase'; |
/** |
* The database syntax variant to be used (db2, access, etc.), if any |
* @var string |
*/ |
var $dbsyntax = 'dbase'; |
/** |
* The capabilities of this DB implementation |
* |
* The 'new_link' element contains the PHP version that first provided |
* new_link support for this DBMS. Contains false if it's unsupported. |
* |
* Meaning of the 'limit' element: |
* + 'emulate' = emulate with fetch row by number |
* + 'alter' = alter the query |
* + false = skip rows |
* |
* @var array |
*/ |
var $features = array( |
'limit' => false, |
'new_link' => false, |
'numrows' => true, |
'pconnect' => false, |
'prepare' => false, |
'ssl' => false, |
'transactions' => false, |
); |
/** |
* A mapping of native error codes to DB error codes |
* @var array |
*/ |
var $errorcode_map = array( |
); |
/** |
* The raw database connection created by PHP |
* @var resource |
*/ |
var $connection; |
/** |
* The DSN information for connecting to a database |
* @var array |
*/ |
var $dsn = array(); |
/** |
* A means of emulating result resources |
* @var array |
*/ |
var $res_row = array(); |
/** |
* The quantity of results so far |
* |
* For emulating result resources. |
* |
* @var integer |
*/ |
var $result = 0; |
/** |
* Maps dbase data type id's to human readable strings |
* |
* The human readable values are based on the output of PHP's |
* dbase_get_header_info() function. |
* |
* @var array |
* @since Property available since Release 1.7.0 |
*/ |
var $types = array( |
'C' => 'character', |
'D' => 'date', |
'L' => 'boolean', |
'M' => 'memo', |
'N' => 'number', |
); |
// }}} |
// {{{ constructor |
/** |
* This constructor calls <kbd>$this->DB_common()</kbd> |
* |
* @return void |
*/ |
function DB_dbase() |
{ |
$this->DB_common(); |
} |
// }}} |
// {{{ connect() |
/** |
* Connect to the database and create it if it doesn't exist |
* |
* Don't call this method directly. Use DB::connect() instead. |
* |
* PEAR DB's dbase driver supports the following extra DSN options: |
* + mode An integer specifying the read/write mode to use |
* (0 = read only, 1 = write only, 2 = read/write). |
* Available since PEAR DB 1.7.0. |
* + fields An array of arrays that PHP's dbase_create() function needs |
* to create a new database. This information is used if the |
* dBase file specified in the "database" segment of the DSN |
* does not exist. For more info, see the PHP manual's |
* {@link http://php.net/dbase_create dbase_create()} page. |
* Available since PEAR DB 1.7.0. |
* |
* Example of how to connect and establish a new dBase file if necessary: |
* <code> |
* require_once 'DB.php'; |
* |
* $dsn = array( |
* 'phptype' => 'dbase', |
* 'database' => '/path/and/name/of/dbase/file', |
* 'mode' => 2, |
* 'fields' => array( |
* array('a', 'N', 5, 0), |
* array('b', 'C', 40), |
* array('c', 'C', 255), |
* array('d', 'C', 20), |
* ), |
* ); |
* $options = array( |
* 'debug' => 2, |
* 'portability' => DB_PORTABILITY_ALL, |
* ); |
* |
* $db = DB::connect($dsn, $options); |
* if (PEAR::isError($db)) { |
* die($db->getMessage()); |
* } |
* </code> |
* |
* @param array $dsn the data source name |
* @param bool $persistent should the connection be persistent? |
* |
* @return int DB_OK on success. A DB_Error object on failure. |
*/ |
function connect($dsn, $persistent = false) |
{ |
if (!PEAR::loadExtension('dbase')) { |
return $this->raiseError(DB_ERROR_EXTENSION_NOT_FOUND); |
} |
$this->dsn = $dsn; |
if ($dsn['dbsyntax']) { |
$this->dbsyntax = $dsn['dbsyntax']; |
} |
/* |
* Turn track_errors on for entire script since $php_errormsg |
* is the only way to find errors from the dbase extension. |
*/ |
@ini_set('track_errors', 1); |
$php_errormsg = ''; |
if (!file_exists($dsn['database'])) { |
$this->dsn['mode'] = 2; |
if (empty($dsn['fields']) || !is_array($dsn['fields'])) { |
return $this->raiseError(DB_ERROR_CONNECT_FAILED, |
null, null, null, |
'the dbase file does not exist and ' |
. 'it could not be created because ' |
. 'the "fields" element of the DSN ' |
. 'is not properly set'); |
} |
$this->connection = @dbase_create($dsn['database'], |
$dsn['fields']); |
if (!$this->connection) { |
return $this->raiseError(DB_ERROR_CONNECT_FAILED, |
null, null, null, |
'the dbase file does not exist and ' |
. 'the attempt to create it failed: ' |
. $php_errormsg); |
} |
} else { |
if (!isset($this->dsn['mode'])) { |
$this->dsn['mode'] = 0; |
} |
$this->connection = @dbase_open($dsn['database'], |
$this->dsn['mode']); |
if (!$this->connection) { |
return $this->raiseError(DB_ERROR_CONNECT_FAILED, |
null, null, null, |
$php_errormsg); |
} |
} |
return DB_OK; |
} |
// }}} |
// {{{ disconnect() |
/** |
* Disconnects from the database server |
* |
* @return bool TRUE on success, FALSE on failure |
*/ |
function disconnect() |
{ |
$ret = @dbase_close($this->connection); |
$this->connection = null; |
return $ret; |
} |
// }}} |
// {{{ &query() |
function &query($query = null) |
{ |
// emulate result resources |
$this->res_row[(int)$this->result] = 0; |
$tmp = new DB_result($this, $this->result++); |
return $tmp; |
} |
// }}} |
// {{{ fetchInto() |
/** |
* Places a row from the result set into the given array |
* |
* Formating of the array and the data therein are configurable. |
* See DB_result::fetchInto() for more information. |
* |
* This method is not meant to be called directly. Use |
* DB_result::fetchInto() instead. It can't be declared "protected" |
* because DB_result is a separate object. |
* |
* @param resource $result the query result resource |
* @param array $arr the referenced array to put the data in |
* @param int $fetchmode how the resulting array should be indexed |
* @param int $rownum the row number to fetch (0 = first row) |
* |
* @return mixed DB_OK on success, NULL when the end of a result set is |
* reached or on failure |
* |
* @see DB_result::fetchInto() |
*/ |
function fetchInto($result, &$arr, $fetchmode, $rownum = null) |
{ |
if ($rownum === null) { |
$rownum = $this->res_row[(int)$result]++; |
} |
if ($fetchmode & DB_FETCHMODE_ASSOC) { |
$arr = @dbase_get_record_with_names($this->connection, $rownum); |
if ($this->options['portability'] & DB_PORTABILITY_LOWERCASE && $arr) { |
$arr = array_change_key_case($arr, CASE_LOWER); |
} |
} else { |
$arr = @dbase_get_record($this->connection, $rownum); |
} |
if (!$arr) { |
return null; |
} |
if ($this->options['portability'] & DB_PORTABILITY_RTRIM) { |
$this->_rtrimArrayValues($arr); |
} |
if ($this->options['portability'] & DB_PORTABILITY_NULL_TO_EMPTY) { |
$this->_convertNullArrayValuesToEmpty($arr); |
} |
return DB_OK; |
} |
// }}} |
// {{{ freeResult() |
/** |
* Deletes the result set and frees the memory occupied by the result set. |
* |
* This method is a no-op for dbase, as there aren't result resources in |
* the same sense as most other database backends. |
* |
* @param resource $result PHP's query result resource |
* |
* @return bool TRUE on success, FALSE if $result is invalid |
* |
* @see DB_result::free() |
*/ |
function freeResult($result) |
{ |
return true; |
} |
// }}} |
// {{{ numCols() |
/** |
* Gets the number of columns in a result set |
* |
* This method is not meant to be called directly. Use |
* DB_result::numCols() instead. It can't be declared "protected" |
* because DB_result is a separate object. |
* |
* @param resource $result PHP's query result resource |
* |
* @return int the number of columns. A DB_Error object on failure. |
* |
* @see DB_result::numCols() |
*/ |
function numCols($foo) |
{ |
return @dbase_numfields($this->connection); |
} |
// }}} |
// {{{ numRows() |
/** |
* Gets the number of rows in a result set |
* |
* This method is not meant to be called directly. Use |
* DB_result::numRows() instead. It can't be declared "protected" |
* because DB_result is a separate object. |
* |
* @param resource $result PHP's query result resource |
* |
* @return int the number of rows. A DB_Error object on failure. |
* |
* @see DB_result::numRows() |
*/ |
function numRows($foo) |
{ |
return @dbase_numrecords($this->connection); |
} |
// }}} |
// {{{ quoteBoolean() |
/** |
* Formats a boolean value for use within a query in a locale-independent |
* manner. |
* |
* @param boolean the boolean value to be quoted. |
* @return string the quoted string. |
* @see DB_common::quoteSmart() |
* @since Method available since release 1.7.8. |
*/ |
function quoteBoolean($boolean) { |
return $boolean ? 'T' : 'F'; |
} |
// }}} |
// {{{ tableInfo() |
/** |
* Returns information about the current database |
* |
* @param mixed $result THIS IS UNUSED IN DBASE. The current database |
* is examined regardless of what is provided here. |
* @param int $mode a valid tableInfo mode |
* |
* @return array an associative array with the information requested. |
* A DB_Error object on failure. |
* |
* @see DB_common::tableInfo() |
* @since Method available since Release 1.7.0 |
*/ |
function tableInfo($result = null, $mode = null) |
{ |
if (function_exists('dbase_get_header_info')) { |
$id = @dbase_get_header_info($this->connection); |
if (!$id && $php_errormsg) { |
return $this->raiseError(DB_ERROR, |
null, null, null, |
$php_errormsg); |
} |
} else { |
/* |
* This segment for PHP 4 is loosely based on code by |
* Hadi Rusiah <deegos@yahoo.com> in the comments on |
* the dBase reference page in the PHP manual. |
*/ |
$db = @fopen($this->dsn['database'], 'r'); |
if (!$db) { |
return $this->raiseError(DB_ERROR_CONNECT_FAILED, |
null, null, null, |
$php_errormsg); |
} |
$id = array(); |
$i = 0; |
$line = fread($db, 32); |
while (!feof($db)) { |
$line = fread($db, 32); |
if (substr($line, 0, 1) == chr(13)) { |
break; |
} else { |
$pos = strpos(substr($line, 0, 10), chr(0)); |
$pos = ($pos == 0 ? 10 : $pos); |
$id[$i] = array( |
'name' => substr($line, 0, $pos), |
'type' => $this->types[substr($line, 11, 1)], |
'length' => ord(substr($line, 16, 1)), |
'precision' => ord(substr($line, 17, 1)), |
); |
} |
$i++; |
} |
fclose($db); |
} |
if ($this->options['portability'] & DB_PORTABILITY_LOWERCASE) { |
$case_func = 'strtolower'; |
} else { |
$case_func = 'strval'; |
} |
$res = array(); |
$count = count($id); |
if ($mode) { |
$res['num_fields'] = $count; |
} |
for ($i = 0; $i < $count; $i++) { |
$res[$i] = array( |
'table' => $this->dsn['database'], |
'name' => $case_func($id[$i]['name']), |
'type' => $id[$i]['type'], |
'len' => $id[$i]['length'], |
'flags' => '' |
); |
if ($mode & DB_TABLEINFO_ORDER) { |
$res['order'][$res[$i]['name']] = $i; |
} |
if ($mode & DB_TABLEINFO_ORDERTABLE) { |
$res['ordertable'][$res[$i]['table']][$res[$i]['name']] = $i; |
} |
} |
return $res; |
} |
// }}} |
} |
/* |
* Local variables: |
* tab-width: 4 |
* c-basic-offset: 4 |
* End: |
*/ |
?> |
/obs_saisons/SPIP-v1-8-3/modules/configuration/DB/mysqli.php |
---|
New file |
0,0 → 1,1092 |
<?php |
/* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4: */ |
/** |
* The PEAR DB driver for PHP's mysqli extension |
* for interacting with MySQL databases |
* |
* PHP versions 4 and 5 |
* |
* LICENSE: This source file is subject to version 3.0 of the PHP license |
* that is available through the world-wide-web at the following URI: |
* http://www.php.net/license/3_0.txt. If you did not receive a copy of |
* the PHP License and are unable to obtain it through the web, please |
* send a note to license@php.net so we can mail you a copy immediately. |
* |
* @category Database |
* @package DB |
* @author Daniel Convissor <danielc@php.net> |
* @copyright 1997-2007 The PHP Group |
* @license http://www.php.net/license/3_0.txt PHP License 3.0 |
* @version CVS: $Id: mysqli.php,v 1.1 2008/07/07 18:00:39 mrflos Exp $ |
* @link http://pear.php.net/package/DB |
*/ |
/** |
* Obtain the DB_common class so it can be extended from |
*/ |
require_once 'DB/common.php'; |
/** |
* The methods PEAR DB uses to interact with PHP's mysqli extension |
* for interacting with MySQL databases |
* |
* This is for MySQL versions 4.1 and above. Requires PHP 5. |
* |
* Note that persistent connections no longer exist. |
* |
* These methods overload the ones declared in DB_common. |
* |
* @category Database |
* @package DB |
* @author Daniel Convissor <danielc@php.net> |
* @copyright 1997-2007 The PHP Group |
* @license http://www.php.net/license/3_0.txt PHP License 3.0 |
* @version Release: 1.7.14RC1 |
* @link http://pear.php.net/package/DB |
* @since Class functional since Release 1.6.3 |
*/ |
class DB_mysqli extends DB_common |
{ |
// {{{ properties |
/** |
* The DB driver type (mysql, oci8, odbc, etc.) |
* @var string |
*/ |
var $phptype = 'mysqli'; |
/** |
* The database syntax variant to be used (db2, access, etc.), if any |
* @var string |
*/ |
var $dbsyntax = 'mysqli'; |
/** |
* The capabilities of this DB implementation |
* |
* The 'new_link' element contains the PHP version that first provided |
* new_link support for this DBMS. Contains false if it's unsupported. |
* |
* Meaning of the 'limit' element: |
* + 'emulate' = emulate with fetch row by number |
* + 'alter' = alter the query |
* + false = skip rows |
* |
* @var array |
*/ |
var $features = array( |
'limit' => 'alter', |
'new_link' => false, |
'numrows' => true, |
'pconnect' => false, |
'prepare' => false, |
'ssl' => true, |
'transactions' => true, |
); |
/** |
* A mapping of native error codes to DB error codes |
* @var array |
*/ |
var $errorcode_map = array( |
1004 => DB_ERROR_CANNOT_CREATE, |
1005 => DB_ERROR_CANNOT_CREATE, |
1006 => DB_ERROR_CANNOT_CREATE, |
1007 => DB_ERROR_ALREADY_EXISTS, |
1008 => DB_ERROR_CANNOT_DROP, |
1022 => DB_ERROR_ALREADY_EXISTS, |
1044 => DB_ERROR_ACCESS_VIOLATION, |
1046 => DB_ERROR_NODBSELECTED, |
1048 => DB_ERROR_CONSTRAINT, |
1049 => DB_ERROR_NOSUCHDB, |
1050 => DB_ERROR_ALREADY_EXISTS, |
1051 => DB_ERROR_NOSUCHTABLE, |
1054 => DB_ERROR_NOSUCHFIELD, |
1061 => DB_ERROR_ALREADY_EXISTS, |
1062 => DB_ERROR_ALREADY_EXISTS, |
1064 => DB_ERROR_SYNTAX, |
1091 => DB_ERROR_NOT_FOUND, |
1100 => DB_ERROR_NOT_LOCKED, |
1136 => DB_ERROR_VALUE_COUNT_ON_ROW, |
1142 => DB_ERROR_ACCESS_VIOLATION, |
1146 => DB_ERROR_NOSUCHTABLE, |
1216 => DB_ERROR_CONSTRAINT, |
1217 => DB_ERROR_CONSTRAINT, |
1356 => DB_ERROR_DIVZERO, |
1451 => DB_ERROR_CONSTRAINT, |
1452 => DB_ERROR_CONSTRAINT, |
); |
/** |
* The raw database connection created by PHP |
* @var resource |
*/ |
var $connection; |
/** |
* The DSN information for connecting to a database |
* @var array |
*/ |
var $dsn = array(); |
/** |
* Should data manipulation queries be committed automatically? |
* @var bool |
* @access private |
*/ |
var $autocommit = true; |
/** |
* The quantity of transactions begun |
* |
* {@internal While this is private, it can't actually be designated |
* private in PHP 5 because it is directly accessed in the test suite.}} |
* |
* @var integer |
* @access private |
*/ |
var $transaction_opcount = 0; |
/** |
* The database specified in the DSN |
* |
* It's a fix to allow calls to different databases in the same script. |
* |
* @var string |
* @access private |
*/ |
var $_db = ''; |
/** |
* Array for converting MYSQLI_*_FLAG constants to text values |
* @var array |
* @access public |
* @since Property available since Release 1.6.5 |
*/ |
var $mysqli_flags = array( |
MYSQLI_NOT_NULL_FLAG => 'not_null', |
MYSQLI_PRI_KEY_FLAG => 'primary_key', |
MYSQLI_UNIQUE_KEY_FLAG => 'unique_key', |
MYSQLI_MULTIPLE_KEY_FLAG => 'multiple_key', |
MYSQLI_BLOB_FLAG => 'blob', |
MYSQLI_UNSIGNED_FLAG => 'unsigned', |
MYSQLI_ZEROFILL_FLAG => 'zerofill', |
MYSQLI_AUTO_INCREMENT_FLAG => 'auto_increment', |
MYSQLI_TIMESTAMP_FLAG => 'timestamp', |
MYSQLI_SET_FLAG => 'set', |
// MYSQLI_NUM_FLAG => 'numeric', // unnecessary |
// MYSQLI_PART_KEY_FLAG => 'multiple_key', // duplicatvie |
MYSQLI_GROUP_FLAG => 'group_by' |
); |
/** |
* Array for converting MYSQLI_TYPE_* constants to text values |
* @var array |
* @access public |
* @since Property available since Release 1.6.5 |
*/ |
var $mysqli_types = array( |
MYSQLI_TYPE_DECIMAL => 'decimal', |
MYSQLI_TYPE_TINY => 'tinyint', |
MYSQLI_TYPE_SHORT => 'int', |
MYSQLI_TYPE_LONG => 'int', |
MYSQLI_TYPE_FLOAT => 'float', |
MYSQLI_TYPE_DOUBLE => 'double', |
// MYSQLI_TYPE_NULL => 'DEFAULT NULL', // let flags handle it |
MYSQLI_TYPE_TIMESTAMP => 'timestamp', |
MYSQLI_TYPE_LONGLONG => 'bigint', |
MYSQLI_TYPE_INT24 => 'mediumint', |
MYSQLI_TYPE_DATE => 'date', |
MYSQLI_TYPE_TIME => 'time', |
MYSQLI_TYPE_DATETIME => 'datetime', |
MYSQLI_TYPE_YEAR => 'year', |
MYSQLI_TYPE_NEWDATE => 'date', |
MYSQLI_TYPE_ENUM => 'enum', |
MYSQLI_TYPE_SET => 'set', |
MYSQLI_TYPE_TINY_BLOB => 'tinyblob', |
MYSQLI_TYPE_MEDIUM_BLOB => 'mediumblob', |
MYSQLI_TYPE_LONG_BLOB => 'longblob', |
MYSQLI_TYPE_BLOB => 'blob', |
MYSQLI_TYPE_VAR_STRING => 'varchar', |
MYSQLI_TYPE_STRING => 'char', |
MYSQLI_TYPE_GEOMETRY => 'geometry', |
/* These constants are conditionally compiled in ext/mysqli, so we'll |
* define them by number rather than constant. */ |
16 => 'bit', |
246 => 'decimal', |
); |
// }}} |
// {{{ constructor |
/** |
* This constructor calls <kbd>$this->DB_common()</kbd> |
* |
* @return void |
*/ |
function DB_mysqli() |
{ |
$this->DB_common(); |
} |
// }}} |
// {{{ connect() |
/** |
* Connect to the database server, log in and open the database |
* |
* Don't call this method directly. Use DB::connect() instead. |
* |
* PEAR DB's mysqli driver supports the following extra DSN options: |
* + When the 'ssl' $option passed to DB::connect() is true: |
* + key The path to the key file. |
* + cert The path to the certificate file. |
* + ca The path to the certificate authority file. |
* + capath The path to a directory that contains trusted SSL |
* CA certificates in pem format. |
* + cipher The list of allowable ciphers for SSL encryption. |
* |
* Example of how to connect using SSL: |
* <code> |
* require_once 'DB.php'; |
* |
* $dsn = array( |
* 'phptype' => 'mysqli', |
* 'username' => 'someuser', |
* 'password' => 'apasswd', |
* 'hostspec' => 'localhost', |
* 'database' => 'thedb', |
* 'key' => 'client-key.pem', |
* 'cert' => 'client-cert.pem', |
* 'ca' => 'cacert.pem', |
* 'capath' => '/path/to/ca/dir', |
* 'cipher' => 'AES', |
* ); |
* |
* $options = array( |
* 'ssl' => true, |
* ); |
* |
* $db = DB::connect($dsn, $options); |
* if (PEAR::isError($db)) { |
* die($db->getMessage()); |
* } |
* </code> |
* |
* @param array $dsn the data source name |
* @param bool $persistent should the connection be persistent? |
* |
* @return int DB_OK on success. A DB_Error object on failure. |
*/ |
function connect($dsn, $persistent = false) |
{ |
if (!PEAR::loadExtension('mysqli')) { |
return $this->raiseError(DB_ERROR_EXTENSION_NOT_FOUND); |
} |
$this->dsn = $dsn; |
if ($dsn['dbsyntax']) { |
$this->dbsyntax = $dsn['dbsyntax']; |
} |
$ini = ini_get('track_errors'); |
@ini_set('track_errors', 1); |
$php_errormsg = ''; |
if (((int) $this->getOption('ssl')) === 1) { |
$init = mysqli_init(); |
mysqli_ssl_set( |
$init, |
empty($dsn['key']) ? null : $dsn['key'], |
empty($dsn['cert']) ? null : $dsn['cert'], |
empty($dsn['ca']) ? null : $dsn['ca'], |
empty($dsn['capath']) ? null : $dsn['capath'], |
empty($dsn['cipher']) ? null : $dsn['cipher'] |
); |
if ($this->connection = @mysqli_real_connect( |
$init, |
$dsn['hostspec'], |
$dsn['username'], |
$dsn['password'], |
$dsn['database'], |
$dsn['port'], |
$dsn['socket'])) |
{ |
$this->connection = $init; |
} |
} else { |
$this->connection = @mysqli_connect( |
$dsn['hostspec'], |
$dsn['username'], |
$dsn['password'], |
$dsn['database'], |
$dsn['port'], |
$dsn['socket'] |
); |
} |
@ini_set('track_errors', $ini); |
if (!$this->connection) { |
if (($err = @mysqli_connect_error()) != '') { |
return $this->raiseError(DB_ERROR_CONNECT_FAILED, |
null, null, null, |
$err); |
} else { |
return $this->raiseError(DB_ERROR_CONNECT_FAILED, |
null, null, null, |
$php_errormsg); |
} |
} |
if ($dsn['database']) { |
$this->_db = $dsn['database']; |
} |
return DB_OK; |
} |
// }}} |
// {{{ disconnect() |
/** |
* Disconnects from the database server |
* |
* @return bool TRUE on success, FALSE on failure |
*/ |
function disconnect() |
{ |
$ret = @mysqli_close($this->connection); |
$this->connection = null; |
return $ret; |
} |
// }}} |
// {{{ simpleQuery() |
/** |
* Sends a query to the database server |
* |
* @param string the SQL query string |
* |
* @return mixed + a PHP result resrouce for successful SELECT queries |
* + the DB_OK constant for other successful queries |
* + a DB_Error object on failure |
*/ |
function simpleQuery($query) |
{ |
$ismanip = $this->_checkManip($query); |
$this->last_query = $query; |
$query = $this->modifyQuery($query); |
if ($this->_db) { |
if (!@mysqli_select_db($this->connection, $this->_db)) { |
return $this->mysqliRaiseError(DB_ERROR_NODBSELECTED); |
} |
} |
if (!$this->autocommit && $ismanip) { |
if ($this->transaction_opcount == 0) { |
$result = @mysqli_query($this->connection, 'SET AUTOCOMMIT=0'); |
$result = @mysqli_query($this->connection, 'BEGIN'); |
if (!$result) { |
return $this->mysqliRaiseError(); |
} |
} |
$this->transaction_opcount++; |
} |
$result = @mysqli_query($this->connection, $query); |
if (!$result) { |
return $this->mysqliRaiseError(); |
} |
if (is_object($result)) { |
return $result; |
} |
return DB_OK; |
} |
// }}} |
// {{{ nextResult() |
/** |
* Move the internal mysql result pointer to the next available result. |
* |
* This method has not been implemented yet. |
* |
* @param resource $result a valid sql result resource |
* @return false |
* @access public |
*/ |
function nextResult($result) |
{ |
return false; |
} |
// }}} |
// {{{ fetchInto() |
/** |
* Places a row from the result set into the given array |
* |
* Formating of the array and the data therein are configurable. |
* See DB_result::fetchInto() for more information. |
* |
* This method is not meant to be called directly. Use |
* DB_result::fetchInto() instead. It can't be declared "protected" |
* because DB_result is a separate object. |
* |
* @param resource $result the query result resource |
* @param array $arr the referenced array to put the data in |
* @param int $fetchmode how the resulting array should be indexed |
* @param int $rownum the row number to fetch (0 = first row) |
* |
* @return mixed DB_OK on success, NULL when the end of a result set is |
* reached or on failure |
* |
* @see DB_result::fetchInto() |
*/ |
function fetchInto($result, &$arr, $fetchmode, $rownum = null) |
{ |
if ($rownum !== null) { |
if (!@mysqli_data_seek($result, $rownum)) { |
return null; |
} |
} |
if ($fetchmode & DB_FETCHMODE_ASSOC) { |
$arr = @mysqli_fetch_array($result, MYSQLI_ASSOC); |
if ($this->options['portability'] & DB_PORTABILITY_LOWERCASE && $arr) { |
$arr = array_change_key_case($arr, CASE_LOWER); |
} |
} else { |
$arr = @mysqli_fetch_row($result); |
} |
if (!$arr) { |
return null; |
} |
if ($this->options['portability'] & DB_PORTABILITY_RTRIM) { |
/* |
* Even though this DBMS already trims output, we do this because |
* a field might have intentional whitespace at the end that |
* gets removed by DB_PORTABILITY_RTRIM under another driver. |
*/ |
$this->_rtrimArrayValues($arr); |
} |
if ($this->options['portability'] & DB_PORTABILITY_NULL_TO_EMPTY) { |
$this->_convertNullArrayValuesToEmpty($arr); |
} |
return DB_OK; |
} |
// }}} |
// {{{ freeResult() |
/** |
* Deletes the result set and frees the memory occupied by the result set |
* |
* This method is not meant to be called directly. Use |
* DB_result::free() instead. It can't be declared "protected" |
* because DB_result is a separate object. |
* |
* @param resource $result PHP's query result resource |
* |
* @return bool TRUE on success, FALSE if $result is invalid |
* |
* @see DB_result::free() |
*/ |
function freeResult($result) |
{ |
return is_resource($result) ? mysqli_free_result($result) : false; |
} |
// }}} |
// {{{ numCols() |
/** |
* Gets the number of columns in a result set |
* |
* This method is not meant to be called directly. Use |
* DB_result::numCols() instead. It can't be declared "protected" |
* because DB_result is a separate object. |
* |
* @param resource $result PHP's query result resource |
* |
* @return int the number of columns. A DB_Error object on failure. |
* |
* @see DB_result::numCols() |
*/ |
function numCols($result) |
{ |
$cols = @mysqli_num_fields($result); |
if (!$cols) { |
return $this->mysqliRaiseError(); |
} |
return $cols; |
} |
// }}} |
// {{{ numRows() |
/** |
* Gets the number of rows in a result set |
* |
* This method is not meant to be called directly. Use |
* DB_result::numRows() instead. It can't be declared "protected" |
* because DB_result is a separate object. |
* |
* @param resource $result PHP's query result resource |
* |
* @return int the number of rows. A DB_Error object on failure. |
* |
* @see DB_result::numRows() |
*/ |
function numRows($result) |
{ |
$rows = @mysqli_num_rows($result); |
if ($rows === null) { |
return $this->mysqliRaiseError(); |
} |
return $rows; |
} |
// }}} |
// {{{ autoCommit() |
/** |
* Enables or disables automatic commits |
* |
* @param bool $onoff true turns it on, false turns it off |
* |
* @return int DB_OK on success. A DB_Error object if the driver |
* doesn't support auto-committing transactions. |
*/ |
function autoCommit($onoff = false) |
{ |
// XXX if $this->transaction_opcount > 0, we should probably |
// issue a warning here. |
$this->autocommit = $onoff ? true : false; |
return DB_OK; |
} |
// }}} |
// {{{ commit() |
/** |
* Commits the current transaction |
* |
* @return int DB_OK on success. A DB_Error object on failure. |
*/ |
function commit() |
{ |
if ($this->transaction_opcount > 0) { |
if ($this->_db) { |
if (!@mysqli_select_db($this->connection, $this->_db)) { |
return $this->mysqliRaiseError(DB_ERROR_NODBSELECTED); |
} |
} |
$result = @mysqli_query($this->connection, 'COMMIT'); |
$result = @mysqli_query($this->connection, 'SET AUTOCOMMIT=1'); |
$this->transaction_opcount = 0; |
if (!$result) { |
return $this->mysqliRaiseError(); |
} |
} |
return DB_OK; |
} |
// }}} |
// {{{ rollback() |
/** |
* Reverts the current transaction |
* |
* @return int DB_OK on success. A DB_Error object on failure. |
*/ |
function rollback() |
{ |
if ($this->transaction_opcount > 0) { |
if ($this->_db) { |
if (!@mysqli_select_db($this->connection, $this->_db)) { |
return $this->mysqliRaiseError(DB_ERROR_NODBSELECTED); |
} |
} |
$result = @mysqli_query($this->connection, 'ROLLBACK'); |
$result = @mysqli_query($this->connection, 'SET AUTOCOMMIT=1'); |
$this->transaction_opcount = 0; |
if (!$result) { |
return $this->mysqliRaiseError(); |
} |
} |
return DB_OK; |
} |
// }}} |
// {{{ affectedRows() |
/** |
* Determines the number of rows affected by a data maniuplation query |
* |
* 0 is returned for queries that don't manipulate data. |
* |
* @return int the number of rows. A DB_Error object on failure. |
*/ |
function affectedRows() |
{ |
if ($this->_last_query_manip) { |
return @mysqli_affected_rows($this->connection); |
} else { |
return 0; |
} |
} |
// }}} |
// {{{ nextId() |
/** |
* Returns the next free id in a sequence |
* |
* @param string $seq_name name of the sequence |
* @param boolean $ondemand when true, the seqence is automatically |
* created if it does not exist |
* |
* @return int the next id number in the sequence. |
* A DB_Error object on failure. |
* |
* @see DB_common::nextID(), DB_common::getSequenceName(), |
* DB_mysqli::createSequence(), DB_mysqli::dropSequence() |
*/ |
function nextId($seq_name, $ondemand = true) |
{ |
$seqname = $this->getSequenceName($seq_name); |
do { |
$repeat = 0; |
$this->pushErrorHandling(PEAR_ERROR_RETURN); |
$result = $this->query('UPDATE ' . $seqname |
. ' SET id = LAST_INSERT_ID(id + 1)'); |
$this->popErrorHandling(); |
if ($result === DB_OK) { |
// COMMON CASE |
$id = @mysqli_insert_id($this->connection); |
if ($id != 0) { |
return $id; |
} |
// EMPTY SEQ TABLE |
// Sequence table must be empty for some reason, |
// so fill it and return 1 |
// Obtain a user-level lock |
$result = $this->getOne('SELECT GET_LOCK(' |
. "'${seqname}_lock', 10)"); |
if (DB::isError($result)) { |
return $this->raiseError($result); |
} |
if ($result == 0) { |
return $this->mysqliRaiseError(DB_ERROR_NOT_LOCKED); |
} |
// add the default value |
$result = $this->query('REPLACE INTO ' . $seqname |
. ' (id) VALUES (0)'); |
if (DB::isError($result)) { |
return $this->raiseError($result); |
} |
// Release the lock |
$result = $this->getOne('SELECT RELEASE_LOCK(' |
. "'${seqname}_lock')"); |
if (DB::isError($result)) { |
return $this->raiseError($result); |
} |
// We know what the result will be, so no need to try again |
return 1; |
} elseif ($ondemand && DB::isError($result) && |
$result->getCode() == DB_ERROR_NOSUCHTABLE) |
{ |
// ONDEMAND TABLE CREATION |
$result = $this->createSequence($seq_name); |
// Since createSequence initializes the ID to be 1, |
// we do not need to retrieve the ID again (or we will get 2) |
if (DB::isError($result)) { |
return $this->raiseError($result); |
} else { |
// First ID of a newly created sequence is 1 |
return 1; |
} |
} elseif (DB::isError($result) && |
$result->getCode() == DB_ERROR_ALREADY_EXISTS) |
{ |
// BACKWARDS COMPAT |
// see _BCsequence() comment |
$result = $this->_BCsequence($seqname); |
if (DB::isError($result)) { |
return $this->raiseError($result); |
} |
$repeat = 1; |
} |
} while ($repeat); |
return $this->raiseError($result); |
} |
/** |
* Creates a new sequence |
* |
* @param string $seq_name name of the new sequence |
* |
* @return int DB_OK on success. A DB_Error object on failure. |
* |
* @see DB_common::createSequence(), DB_common::getSequenceName(), |
* DB_mysqli::nextID(), DB_mysqli::dropSequence() |
*/ |
function createSequence($seq_name) |
{ |
$seqname = $this->getSequenceName($seq_name); |
$res = $this->query('CREATE TABLE ' . $seqname |
. ' (id INTEGER UNSIGNED AUTO_INCREMENT NOT NULL,' |
. ' PRIMARY KEY(id))'); |
if (DB::isError($res)) { |
return $res; |
} |
// insert yields value 1, nextId call will generate ID 2 |
return $this->query("INSERT INTO ${seqname} (id) VALUES (0)"); |
} |
// }}} |
// {{{ dropSequence() |
/** |
* Deletes a sequence |
* |
* @param string $seq_name name of the sequence to be deleted |
* |
* @return int DB_OK on success. A DB_Error object on failure. |
* |
* @see DB_common::dropSequence(), DB_common::getSequenceName(), |
* DB_mysql::nextID(), DB_mysql::createSequence() |
*/ |
function dropSequence($seq_name) |
{ |
return $this->query('DROP TABLE ' . $this->getSequenceName($seq_name)); |
} |
// }}} |
// {{{ _BCsequence() |
/** |
* Backwards compatibility with old sequence emulation implementation |
* (clean up the dupes) |
* |
* @param string $seqname the sequence name to clean up |
* |
* @return bool true on success. A DB_Error object on failure. |
* |
* @access private |
*/ |
function _BCsequence($seqname) |
{ |
// Obtain a user-level lock... this will release any previous |
// application locks, but unlike LOCK TABLES, it does not abort |
// the current transaction and is much less frequently used. |
$result = $this->getOne("SELECT GET_LOCK('${seqname}_lock',10)"); |
if (DB::isError($result)) { |
return $result; |
} |
if ($result == 0) { |
// Failed to get the lock, can't do the conversion, bail |
// with a DB_ERROR_NOT_LOCKED error |
return $this->mysqliRaiseError(DB_ERROR_NOT_LOCKED); |
} |
$highest_id = $this->getOne("SELECT MAX(id) FROM ${seqname}"); |
if (DB::isError($highest_id)) { |
return $highest_id; |
} |
// This should kill all rows except the highest |
// We should probably do something if $highest_id isn't |
// numeric, but I'm at a loss as how to handle that... |
$result = $this->query('DELETE FROM ' . $seqname |
. " WHERE id <> $highest_id"); |
if (DB::isError($result)) { |
return $result; |
} |
// If another thread has been waiting for this lock, |
// it will go thru the above procedure, but will have no |
// real effect |
$result = $this->getOne("SELECT RELEASE_LOCK('${seqname}_lock')"); |
if (DB::isError($result)) { |
return $result; |
} |
return true; |
} |
// }}} |
// {{{ quoteIdentifier() |
/** |
* Quotes a string so it can be safely used as a table or column name |
* (WARNING: using names that require this is a REALLY BAD IDEA) |
* |
* WARNING: Older versions of MySQL can't handle the backtick |
* character (<kbd>`</kbd>) in table or column names. |
* |
* @param string $str identifier name to be quoted |
* |
* @return string quoted identifier string |
* |
* @see DB_common::quoteIdentifier() |
* @since Method available since Release 1.6.0 |
*/ |
function quoteIdentifier($str) |
{ |
return '`' . str_replace('`', '``', $str) . '`'; |
} |
// }}} |
// {{{ escapeSimple() |
/** |
* Escapes a string according to the current DBMS's standards |
* |
* @param string $str the string to be escaped |
* |
* @return string the escaped string |
* |
* @see DB_common::quoteSmart() |
* @since Method available since Release 1.6.0 |
*/ |
function escapeSimple($str) |
{ |
return @mysqli_real_escape_string($this->connection, $str); |
} |
// }}} |
// {{{ modifyLimitQuery() |
/** |
* Adds LIMIT clauses to a query string according to current DBMS standards |
* |
* @param string $query the query to modify |
* @param int $from the row to start to fetching (0 = the first row) |
* @param int $count the numbers of rows to fetch |
* @param mixed $params array, string or numeric data to be used in |
* execution of the statement. Quantity of items |
* passed must match quantity of placeholders in |
* query: meaning 1 placeholder for non-array |
* parameters or 1 placeholder per array element. |
* |
* @return string the query string with LIMIT clauses added |
* |
* @access protected |
*/ |
function modifyLimitQuery($query, $from, $count, $params = array()) |
{ |
if (DB::isManip($query) || $this->_next_query_manip) { |
return $query . " LIMIT $count"; |
} else { |
return $query . " LIMIT $from, $count"; |
} |
} |
// }}} |
// {{{ mysqliRaiseError() |
/** |
* Produces a DB_Error object regarding the current problem |
* |
* @param int $errno if the error is being manually raised pass a |
* DB_ERROR* constant here. If this isn't passed |
* the error information gathered from the DBMS. |
* |
* @return object the DB_Error object |
* |
* @see DB_common::raiseError(), |
* DB_mysqli::errorNative(), DB_common::errorCode() |
*/ |
function mysqliRaiseError($errno = null) |
{ |
if ($errno === null) { |
if ($this->options['portability'] & DB_PORTABILITY_ERRORS) { |
$this->errorcode_map[1022] = DB_ERROR_CONSTRAINT; |
$this->errorcode_map[1048] = DB_ERROR_CONSTRAINT_NOT_NULL; |
$this->errorcode_map[1062] = DB_ERROR_CONSTRAINT; |
} else { |
// Doing this in case mode changes during runtime. |
$this->errorcode_map[1022] = DB_ERROR_ALREADY_EXISTS; |
$this->errorcode_map[1048] = DB_ERROR_CONSTRAINT; |
$this->errorcode_map[1062] = DB_ERROR_ALREADY_EXISTS; |
} |
$errno = $this->errorCode(mysqli_errno($this->connection)); |
} |
return $this->raiseError($errno, null, null, null, |
@mysqli_errno($this->connection) . ' ** ' . |
@mysqli_error($this->connection)); |
} |
// }}} |
// {{{ errorNative() |
/** |
* Gets the DBMS' native error code produced by the last query |
* |
* @return int the DBMS' error code |
*/ |
function errorNative() |
{ |
return @mysqli_errno($this->connection); |
} |
// }}} |
// {{{ tableInfo() |
/** |
* Returns information about a table or a result set |
* |
* @param object|string $result DB_result object from a query or a |
* string containing the name of a table. |
* While this also accepts a query result |
* resource identifier, this behavior is |
* deprecated. |
* @param int $mode a valid tableInfo mode |
* |
* @return array an associative array with the information requested. |
* A DB_Error object on failure. |
* |
* @see DB_common::setOption() |
*/ |
function tableInfo($result, $mode = null) |
{ |
if (is_string($result)) { |
// Fix for bug #11580. |
if ($this->_db) { |
if (!@mysqli_select_db($this->connection, $this->_db)) { |
return $this->mysqliRaiseError(DB_ERROR_NODBSELECTED); |
} |
} |
/* |
* Probably received a table name. |
* Create a result resource identifier. |
*/ |
$id = @mysqli_query($this->connection, |
"SELECT * FROM $result LIMIT 0"); |
$got_string = true; |
} elseif (isset($result->result)) { |
/* |
* Probably received a result object. |
* Extract the result resource identifier. |
*/ |
$id = $result->result; |
$got_string = false; |
} else { |
/* |
* Probably received a result resource identifier. |
* Copy it. |
* Deprecated. Here for compatibility only. |
*/ |
$id = $result; |
$got_string = false; |
} |
if (!is_a($id, 'mysqli_result')) { |
return $this->mysqliRaiseError(DB_ERROR_NEED_MORE_DATA); |
} |
if ($this->options['portability'] & DB_PORTABILITY_LOWERCASE) { |
$case_func = 'strtolower'; |
} else { |
$case_func = 'strval'; |
} |
$count = @mysqli_num_fields($id); |
$res = array(); |
if ($mode) { |
$res['num_fields'] = $count; |
} |
for ($i = 0; $i < $count; $i++) { |
$tmp = @mysqli_fetch_field($id); |
$flags = ''; |
foreach ($this->mysqli_flags as $const => $means) { |
if ($tmp->flags & $const) { |
$flags .= $means . ' '; |
} |
} |
if ($tmp->def) { |
$flags .= 'default_' . rawurlencode($tmp->def); |
} |
$flags = trim($flags); |
$res[$i] = array( |
'table' => $case_func($tmp->table), |
'name' => $case_func($tmp->name), |
'type' => isset($this->mysqli_types[$tmp->type]) |
? $this->mysqli_types[$tmp->type] |
: 'unknown', |
// http://bugs.php.net/?id=36579 |
'len' => $tmp->length, |
'flags' => $flags, |
); |
if ($mode & DB_TABLEINFO_ORDER) { |
$res['order'][$res[$i]['name']] = $i; |
} |
if ($mode & DB_TABLEINFO_ORDERTABLE) { |
$res['ordertable'][$res[$i]['table']][$res[$i]['name']] = $i; |
} |
} |
// free the result only if we were called on a table |
if ($got_string) { |
@mysqli_free_result($id); |
} |
return $res; |
} |
// }}} |
// {{{ getSpecialQuery() |
/** |
* Obtains the query string needed for listing a given type of objects |
* |
* @param string $type the kind of objects you want to retrieve |
* |
* @return string the SQL query string or null if the driver doesn't |
* support the object type requested |
* |
* @access protected |
* @see DB_common::getListOf() |
*/ |
function getSpecialQuery($type) |
{ |
switch ($type) { |
case 'tables': |
return 'SHOW TABLES'; |
case 'users': |
return 'SELECT DISTINCT User FROM mysql.user'; |
case 'databases': |
return 'SHOW DATABASES'; |
default: |
return null; |
} |
} |
// }}} |
} |
/* |
* Local variables: |
* tab-width: 4 |
* c-basic-offset: 4 |
* End: |
*/ |
?> |
/obs_saisons/SPIP-v1-8-3/modules/configuration/DB/mssql.php |
---|
New file |
0,0 → 1,963 |
<?php |
/* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4: */ |
/** |
* The PEAR DB driver for PHP's mssql extension |
* for interacting with Microsoft SQL Server databases |
* |
* PHP versions 4 and 5 |
* |
* LICENSE: This source file is subject to version 3.0 of the PHP license |
* that is available through the world-wide-web at the following URI: |
* http://www.php.net/license/3_0.txt. If you did not receive a copy of |
* the PHP License and are unable to obtain it through the web, please |
* send a note to license@php.net so we can mail you a copy immediately. |
* |
* @category Database |
* @package DB |
* @author Sterling Hughes <sterling@php.net> |
* @author Daniel Convissor <danielc@php.net> |
* @copyright 1997-2007 The PHP Group |
* @license http://www.php.net/license/3_0.txt PHP License 3.0 |
* @version CVS: $Id: mssql.php,v 1.1 2008/07/07 18:00:39 mrflos Exp $ |
* @link http://pear.php.net/package/DB |
*/ |
/** |
* Obtain the DB_common class so it can be extended from |
*/ |
require_once 'DB/common.php'; |
/** |
* The methods PEAR DB uses to interact with PHP's mssql extension |
* for interacting with Microsoft SQL Server databases |
* |
* These methods overload the ones declared in DB_common. |
* |
* DB's mssql driver is only for Microsfoft SQL Server databases. |
* |
* If you're connecting to a Sybase database, you MUST specify "sybase" |
* as the "phptype" in the DSN. |
* |
* This class only works correctly if you have compiled PHP using |
* --with-mssql=[dir_to_FreeTDS]. |
* |
* @category Database |
* @package DB |
* @author Sterling Hughes <sterling@php.net> |
* @author Daniel Convissor <danielc@php.net> |
* @copyright 1997-2007 The PHP Group |
* @license http://www.php.net/license/3_0.txt PHP License 3.0 |
* @version Release: 1.7.14RC1 |
* @link http://pear.php.net/package/DB |
*/ |
class DB_mssql extends DB_common |
{ |
// {{{ properties |
/** |
* The DB driver type (mysql, oci8, odbc, etc.) |
* @var string |
*/ |
var $phptype = 'mssql'; |
/** |
* The database syntax variant to be used (db2, access, etc.), if any |
* @var string |
*/ |
var $dbsyntax = 'mssql'; |
/** |
* The capabilities of this DB implementation |
* |
* The 'new_link' element contains the PHP version that first provided |
* new_link support for this DBMS. Contains false if it's unsupported. |
* |
* Meaning of the 'limit' element: |
* + 'emulate' = emulate with fetch row by number |
* + 'alter' = alter the query |
* + false = skip rows |
* |
* @var array |
*/ |
var $features = array( |
'limit' => 'emulate', |
'new_link' => false, |
'numrows' => true, |
'pconnect' => true, |
'prepare' => false, |
'ssl' => false, |
'transactions' => true, |
); |
/** |
* A mapping of native error codes to DB error codes |
* @var array |
*/ |
// XXX Add here error codes ie: 'S100E' => DB_ERROR_SYNTAX |
var $errorcode_map = array( |
102 => DB_ERROR_SYNTAX, |
110 => DB_ERROR_VALUE_COUNT_ON_ROW, |
155 => DB_ERROR_NOSUCHFIELD, |
156 => DB_ERROR_SYNTAX, |
170 => DB_ERROR_SYNTAX, |
207 => DB_ERROR_NOSUCHFIELD, |
208 => DB_ERROR_NOSUCHTABLE, |
245 => DB_ERROR_INVALID_NUMBER, |
319 => DB_ERROR_SYNTAX, |
321 => DB_ERROR_NOSUCHFIELD, |
325 => DB_ERROR_SYNTAX, |
336 => DB_ERROR_SYNTAX, |
515 => DB_ERROR_CONSTRAINT_NOT_NULL, |
547 => DB_ERROR_CONSTRAINT, |
1018 => DB_ERROR_SYNTAX, |
1035 => DB_ERROR_SYNTAX, |
1913 => DB_ERROR_ALREADY_EXISTS, |
2209 => DB_ERROR_SYNTAX, |
2223 => DB_ERROR_SYNTAX, |
2248 => DB_ERROR_SYNTAX, |
2256 => DB_ERROR_SYNTAX, |
2257 => DB_ERROR_SYNTAX, |
2627 => DB_ERROR_CONSTRAINT, |
2714 => DB_ERROR_ALREADY_EXISTS, |
3607 => DB_ERROR_DIVZERO, |
3701 => DB_ERROR_NOSUCHTABLE, |
7630 => DB_ERROR_SYNTAX, |
8134 => DB_ERROR_DIVZERO, |
9303 => DB_ERROR_SYNTAX, |
9317 => DB_ERROR_SYNTAX, |
9318 => DB_ERROR_SYNTAX, |
9331 => DB_ERROR_SYNTAX, |
9332 => DB_ERROR_SYNTAX, |
15253 => DB_ERROR_SYNTAX, |
); |
/** |
* The raw database connection created by PHP |
* @var resource |
*/ |
var $connection; |
/** |
* The DSN information for connecting to a database |
* @var array |
*/ |
var $dsn = array(); |
/** |
* Should data manipulation queries be committed automatically? |
* @var bool |
* @access private |
*/ |
var $autocommit = true; |
/** |
* The quantity of transactions begun |
* |
* {@internal While this is private, it can't actually be designated |
* private in PHP 5 because it is directly accessed in the test suite.}} |
* |
* @var integer |
* @access private |
*/ |
var $transaction_opcount = 0; |
/** |
* The database specified in the DSN |
* |
* It's a fix to allow calls to different databases in the same script. |
* |
* @var string |
* @access private |
*/ |
var $_db = null; |
// }}} |
// {{{ constructor |
/** |
* This constructor calls <kbd>$this->DB_common()</kbd> |
* |
* @return void |
*/ |
function DB_mssql() |
{ |
$this->DB_common(); |
} |
// }}} |
// {{{ connect() |
/** |
* Connect to the database server, log in and open the database |
* |
* Don't call this method directly. Use DB::connect() instead. |
* |
* @param array $dsn the data source name |
* @param bool $persistent should the connection be persistent? |
* |
* @return int DB_OK on success. A DB_Error object on failure. |
*/ |
function connect($dsn, $persistent = false) |
{ |
if (!PEAR::loadExtension('mssql') && !PEAR::loadExtension('sybase') |
&& !PEAR::loadExtension('sybase_ct')) |
{ |
return $this->raiseError(DB_ERROR_EXTENSION_NOT_FOUND); |
} |
$this->dsn = $dsn; |
if ($dsn['dbsyntax']) { |
$this->dbsyntax = $dsn['dbsyntax']; |
} |
$params = array( |
$dsn['hostspec'] ? $dsn['hostspec'] : 'localhost', |
$dsn['username'] ? $dsn['username'] : null, |
$dsn['password'] ? $dsn['password'] : null, |
); |
if ($dsn['port']) { |
$params[0] .= ((substr(PHP_OS, 0, 3) == 'WIN') ? ',' : ':') |
. $dsn['port']; |
} |
$connect_function = $persistent ? 'mssql_pconnect' : 'mssql_connect'; |
$this->connection = @call_user_func_array($connect_function, $params); |
if (!$this->connection) { |
return $this->raiseError(DB_ERROR_CONNECT_FAILED, |
null, null, null, |
@mssql_get_last_message()); |
} |
if ($dsn['database']) { |
if (!@mssql_select_db($dsn['database'], $this->connection)) { |
return $this->raiseError(DB_ERROR_NODBSELECTED, |
null, null, null, |
@mssql_get_last_message()); |
} |
$this->_db = $dsn['database']; |
} |
return DB_OK; |
} |
// }}} |
// {{{ disconnect() |
/** |
* Disconnects from the database server |
* |
* @return bool TRUE on success, FALSE on failure |
*/ |
function disconnect() |
{ |
$ret = @mssql_close($this->connection); |
$this->connection = null; |
return $ret; |
} |
// }}} |
// {{{ simpleQuery() |
/** |
* Sends a query to the database server |
* |
* @param string the SQL query string |
* |
* @return mixed + a PHP result resrouce for successful SELECT queries |
* + the DB_OK constant for other successful queries |
* + a DB_Error object on failure |
*/ |
function simpleQuery($query) |
{ |
$ismanip = $this->_checkManip($query); |
$this->last_query = $query; |
if (!@mssql_select_db($this->_db, $this->connection)) { |
return $this->mssqlRaiseError(DB_ERROR_NODBSELECTED); |
} |
$query = $this->modifyQuery($query); |
if (!$this->autocommit && $ismanip) { |
if ($this->transaction_opcount == 0) { |
$result = @mssql_query('BEGIN TRAN', $this->connection); |
if (!$result) { |
return $this->mssqlRaiseError(); |
} |
} |
$this->transaction_opcount++; |
} |
$result = @mssql_query($query, $this->connection); |
if (!$result) { |
return $this->mssqlRaiseError(); |
} |
// Determine which queries that should return data, and which |
// should return an error code only. |
return $ismanip ? DB_OK : $result; |
} |
// }}} |
// {{{ nextResult() |
/** |
* Move the internal mssql result pointer to the next available result |
* |
* @param a valid fbsql result resource |
* |
* @access public |
* |
* @return true if a result is available otherwise return false |
*/ |
function nextResult($result) |
{ |
return @mssql_next_result($result); |
} |
// }}} |
// {{{ fetchInto() |
/** |
* Places a row from the result set into the given array |
* |
* Formating of the array and the data therein are configurable. |
* See DB_result::fetchInto() for more information. |
* |
* This method is not meant to be called directly. Use |
* DB_result::fetchInto() instead. It can't be declared "protected" |
* because DB_result is a separate object. |
* |
* @param resource $result the query result resource |
* @param array $arr the referenced array to put the data in |
* @param int $fetchmode how the resulting array should be indexed |
* @param int $rownum the row number to fetch (0 = first row) |
* |
* @return mixed DB_OK on success, NULL when the end of a result set is |
* reached or on failure |
* |
* @see DB_result::fetchInto() |
*/ |
function fetchInto($result, &$arr, $fetchmode, $rownum = null) |
{ |
if ($rownum !== null) { |
if (!@mssql_data_seek($result, $rownum)) { |
return null; |
} |
} |
if ($fetchmode & DB_FETCHMODE_ASSOC) { |
$arr = @mssql_fetch_assoc($result); |
if ($this->options['portability'] & DB_PORTABILITY_LOWERCASE && $arr) { |
$arr = array_change_key_case($arr, CASE_LOWER); |
} |
} else { |
$arr = @mssql_fetch_row($result); |
} |
if (!$arr) { |
return null; |
} |
if ($this->options['portability'] & DB_PORTABILITY_RTRIM) { |
$this->_rtrimArrayValues($arr); |
} |
if ($this->options['portability'] & DB_PORTABILITY_NULL_TO_EMPTY) { |
$this->_convertNullArrayValuesToEmpty($arr); |
} |
return DB_OK; |
} |
// }}} |
// {{{ freeResult() |
/** |
* Deletes the result set and frees the memory occupied by the result set |
* |
* This method is not meant to be called directly. Use |
* DB_result::free() instead. It can't be declared "protected" |
* because DB_result is a separate object. |
* |
* @param resource $result PHP's query result resource |
* |
* @return bool TRUE on success, FALSE if $result is invalid |
* |
* @see DB_result::free() |
*/ |
function freeResult($result) |
{ |
return is_resource($result) ? mssql_free_result($result) : false; |
} |
// }}} |
// {{{ numCols() |
/** |
* Gets the number of columns in a result set |
* |
* This method is not meant to be called directly. Use |
* DB_result::numCols() instead. It can't be declared "protected" |
* because DB_result is a separate object. |
* |
* @param resource $result PHP's query result resource |
* |
* @return int the number of columns. A DB_Error object on failure. |
* |
* @see DB_result::numCols() |
*/ |
function numCols($result) |
{ |
$cols = @mssql_num_fields($result); |
if (!$cols) { |
return $this->mssqlRaiseError(); |
} |
return $cols; |
} |
// }}} |
// {{{ numRows() |
/** |
* Gets the number of rows in a result set |
* |
* This method is not meant to be called directly. Use |
* DB_result::numRows() instead. It can't be declared "protected" |
* because DB_result is a separate object. |
* |
* @param resource $result PHP's query result resource |
* |
* @return int the number of rows. A DB_Error object on failure. |
* |
* @see DB_result::numRows() |
*/ |
function numRows($result) |
{ |
$rows = @mssql_num_rows($result); |
if ($rows === false) { |
return $this->mssqlRaiseError(); |
} |
return $rows; |
} |
// }}} |
// {{{ autoCommit() |
/** |
* Enables or disables automatic commits |
* |
* @param bool $onoff true turns it on, false turns it off |
* |
* @return int DB_OK on success. A DB_Error object if the driver |
* doesn't support auto-committing transactions. |
*/ |
function autoCommit($onoff = false) |
{ |
// XXX if $this->transaction_opcount > 0, we should probably |
// issue a warning here. |
$this->autocommit = $onoff ? true : false; |
return DB_OK; |
} |
// }}} |
// {{{ commit() |
/** |
* Commits the current transaction |
* |
* @return int DB_OK on success. A DB_Error object on failure. |
*/ |
function commit() |
{ |
if ($this->transaction_opcount > 0) { |
if (!@mssql_select_db($this->_db, $this->connection)) { |
return $this->mssqlRaiseError(DB_ERROR_NODBSELECTED); |
} |
$result = @mssql_query('COMMIT TRAN', $this->connection); |
$this->transaction_opcount = 0; |
if (!$result) { |
return $this->mssqlRaiseError(); |
} |
} |
return DB_OK; |
} |
// }}} |
// {{{ rollback() |
/** |
* Reverts the current transaction |
* |
* @return int DB_OK on success. A DB_Error object on failure. |
*/ |
function rollback() |
{ |
if ($this->transaction_opcount > 0) { |
if (!@mssql_select_db($this->_db, $this->connection)) { |
return $this->mssqlRaiseError(DB_ERROR_NODBSELECTED); |
} |
$result = @mssql_query('ROLLBACK TRAN', $this->connection); |
$this->transaction_opcount = 0; |
if (!$result) { |
return $this->mssqlRaiseError(); |
} |
} |
return DB_OK; |
} |
// }}} |
// {{{ affectedRows() |
/** |
* Determines the number of rows affected by a data maniuplation query |
* |
* 0 is returned for queries that don't manipulate data. |
* |
* @return int the number of rows. A DB_Error object on failure. |
*/ |
function affectedRows() |
{ |
if ($this->_last_query_manip) { |
$res = @mssql_query('select @@rowcount', $this->connection); |
if (!$res) { |
return $this->mssqlRaiseError(); |
} |
$ar = @mssql_fetch_row($res); |
if (!$ar) { |
$result = 0; |
} else { |
@mssql_free_result($res); |
$result = $ar[0]; |
} |
} else { |
$result = 0; |
} |
return $result; |
} |
// }}} |
// {{{ nextId() |
/** |
* Returns the next free id in a sequence |
* |
* @param string $seq_name name of the sequence |
* @param boolean $ondemand when true, the seqence is automatically |
* created if it does not exist |
* |
* @return int the next id number in the sequence. |
* A DB_Error object on failure. |
* |
* @see DB_common::nextID(), DB_common::getSequenceName(), |
* DB_mssql::createSequence(), DB_mssql::dropSequence() |
*/ |
function nextId($seq_name, $ondemand = true) |
{ |
$seqname = $this->getSequenceName($seq_name); |
if (!@mssql_select_db($this->_db, $this->connection)) { |
return $this->mssqlRaiseError(DB_ERROR_NODBSELECTED); |
} |
$repeat = 0; |
do { |
$this->pushErrorHandling(PEAR_ERROR_RETURN); |
$result = $this->query("INSERT INTO $seqname (vapor) VALUES (0)"); |
$this->popErrorHandling(); |
if ($ondemand && DB::isError($result) && |
($result->getCode() == DB_ERROR || $result->getCode() == DB_ERROR_NOSUCHTABLE)) |
{ |
$repeat = 1; |
$result = $this->createSequence($seq_name); |
if (DB::isError($result)) { |
return $this->raiseError($result); |
} |
} elseif (!DB::isError($result)) { |
$result = $this->query("SELECT IDENT_CURRENT('$seqname')"); |
if (DB::isError($result)) { |
/* Fallback code for MS SQL Server 7.0, which doesn't have |
* IDENT_CURRENT. This is *not* safe for concurrent |
* requests, and really, if you're using it, you're in a |
* world of hurt. Nevertheless, it's here to ensure BC. See |
* bug #181 for the gory details.*/ |
$result = $this->query("SELECT @@IDENTITY FROM $seqname"); |
} |
$repeat = 0; |
} else { |
$repeat = false; |
} |
} while ($repeat); |
if (DB::isError($result)) { |
return $this->raiseError($result); |
} |
$result = $result->fetchRow(DB_FETCHMODE_ORDERED); |
return $result[0]; |
} |
/** |
* Creates a new sequence |
* |
* @param string $seq_name name of the new sequence |
* |
* @return int DB_OK on success. A DB_Error object on failure. |
* |
* @see DB_common::createSequence(), DB_common::getSequenceName(), |
* DB_mssql::nextID(), DB_mssql::dropSequence() |
*/ |
function createSequence($seq_name) |
{ |
return $this->query('CREATE TABLE ' |
. $this->getSequenceName($seq_name) |
. ' ([id] [int] IDENTITY (1, 1) NOT NULL,' |
. ' [vapor] [int] NULL)'); |
} |
// }}} |
// {{{ dropSequence() |
/** |
* Deletes a sequence |
* |
* @param string $seq_name name of the sequence to be deleted |
* |
* @return int DB_OK on success. A DB_Error object on failure. |
* |
* @see DB_common::dropSequence(), DB_common::getSequenceName(), |
* DB_mssql::nextID(), DB_mssql::createSequence() |
*/ |
function dropSequence($seq_name) |
{ |
return $this->query('DROP TABLE ' . $this->getSequenceName($seq_name)); |
} |
// }}} |
// {{{ quoteIdentifier() |
/** |
* Quotes a string so it can be safely used as a table or column name |
* |
* @param string $str identifier name to be quoted |
* |
* @return string quoted identifier string |
* |
* @see DB_common::quoteIdentifier() |
* @since Method available since Release 1.6.0 |
*/ |
function quoteIdentifier($str) |
{ |
return '[' . str_replace(']', ']]', $str) . ']'; |
} |
// }}} |
// {{{ mssqlRaiseError() |
/** |
* Produces a DB_Error object regarding the current problem |
* |
* @param int $errno if the error is being manually raised pass a |
* DB_ERROR* constant here. If this isn't passed |
* the error information gathered from the DBMS. |
* |
* @return object the DB_Error object |
* |
* @see DB_common::raiseError(), |
* DB_mssql::errorNative(), DB_mssql::errorCode() |
*/ |
function mssqlRaiseError($code = null) |
{ |
$message = @mssql_get_last_message(); |
if (!$code) { |
$code = $this->errorNative(); |
} |
return $this->raiseError($this->errorCode($code, $message), |
null, null, null, "$code - $message"); |
} |
// }}} |
// {{{ errorNative() |
/** |
* Gets the DBMS' native error code produced by the last query |
* |
* @return int the DBMS' error code |
*/ |
function errorNative() |
{ |
$res = @mssql_query('select @@ERROR as ErrorCode', $this->connection); |
if (!$res) { |
return DB_ERROR; |
} |
$row = @mssql_fetch_row($res); |
return $row[0]; |
} |
// }}} |
// {{{ errorCode() |
/** |
* Determines PEAR::DB error code from mssql's native codes. |
* |
* If <var>$nativecode</var> isn't known yet, it will be looked up. |
* |
* @param mixed $nativecode mssql error code, if known |
* @return integer an error number from a DB error constant |
* @see errorNative() |
*/ |
function errorCode($nativecode = null, $msg = '') |
{ |
if (!$nativecode) { |
$nativecode = $this->errorNative(); |
} |
if (isset($this->errorcode_map[$nativecode])) { |
if ($nativecode == 3701 |
&& preg_match('/Cannot drop the index/i', $msg)) |
{ |
return DB_ERROR_NOT_FOUND; |
} |
return $this->errorcode_map[$nativecode]; |
} else { |
return DB_ERROR; |
} |
} |
// }}} |
// {{{ tableInfo() |
/** |
* Returns information about a table or a result set |
* |
* NOTE: only supports 'table' and 'flags' if <var>$result</var> |
* is a table name. |
* |
* @param object|string $result DB_result object from a query or a |
* string containing the name of a table. |
* While this also accepts a query result |
* resource identifier, this behavior is |
* deprecated. |
* @param int $mode a valid tableInfo mode |
* |
* @return array an associative array with the information requested. |
* A DB_Error object on failure. |
* |
* @see DB_common::tableInfo() |
*/ |
function tableInfo($result, $mode = null) |
{ |
if (is_string($result)) { |
/* |
* Probably received a table name. |
* Create a result resource identifier. |
*/ |
if (!@mssql_select_db($this->_db, $this->connection)) { |
return $this->mssqlRaiseError(DB_ERROR_NODBSELECTED); |
} |
$id = @mssql_query("SELECT * FROM $result WHERE 1=0", |
$this->connection); |
$got_string = true; |
} elseif (isset($result->result)) { |
/* |
* Probably received a result object. |
* Extract the result resource identifier. |
*/ |
$id = $result->result; |
$got_string = false; |
} else { |
/* |
* Probably received a result resource identifier. |
* Copy it. |
* Deprecated. Here for compatibility only. |
*/ |
$id = $result; |
$got_string = false; |
} |
if (!is_resource($id)) { |
return $this->mssqlRaiseError(DB_ERROR_NEED_MORE_DATA); |
} |
if ($this->options['portability'] & DB_PORTABILITY_LOWERCASE) { |
$case_func = 'strtolower'; |
} else { |
$case_func = 'strval'; |
} |
$count = @mssql_num_fields($id); |
$res = array(); |
if ($mode) { |
$res['num_fields'] = $count; |
} |
for ($i = 0; $i < $count; $i++) { |
if ($got_string) { |
$flags = $this->_mssql_field_flags($result, |
@mssql_field_name($id, $i)); |
if (DB::isError($flags)) { |
return $flags; |
} |
} else { |
$flags = ''; |
} |
$res[$i] = array( |
'table' => $got_string ? $case_func($result) : '', |
'name' => $case_func(@mssql_field_name($id, $i)), |
'type' => @mssql_field_type($id, $i), |
'len' => @mssql_field_length($id, $i), |
'flags' => $flags, |
); |
if ($mode & DB_TABLEINFO_ORDER) { |
$res['order'][$res[$i]['name']] = $i; |
} |
if ($mode & DB_TABLEINFO_ORDERTABLE) { |
$res['ordertable'][$res[$i]['table']][$res[$i]['name']] = $i; |
} |
} |
// free the result only if we were called on a table |
if ($got_string) { |
@mssql_free_result($id); |
} |
return $res; |
} |
// }}} |
// {{{ _mssql_field_flags() |
/** |
* Get a column's flags |
* |
* Supports "not_null", "primary_key", |
* "auto_increment" (mssql identity), "timestamp" (mssql timestamp), |
* "unique_key" (mssql unique index, unique check or primary_key) and |
* "multiple_key" (multikey index) |
* |
* mssql timestamp is NOT similar to the mysql timestamp so this is maybe |
* not useful at all - is the behaviour of mysql_field_flags that primary |
* keys are alway unique? is the interpretation of multiple_key correct? |
* |
* @param string $table the table name |
* @param string $column the field name |
* |
* @return string the flags |
* |
* @access private |
* @author Joern Barthel <j_barthel@web.de> |
*/ |
function _mssql_field_flags($table, $column) |
{ |
static $tableName = null; |
static $flags = array(); |
if ($table != $tableName) { |
$flags = array(); |
$tableName = $table; |
// get unique and primary keys |
$res = $this->getAll("EXEC SP_HELPINDEX $table", DB_FETCHMODE_ASSOC); |
if (DB::isError($res)) { |
return $res; |
} |
foreach ($res as $val) { |
$keys = explode(', ', $val['index_keys']); |
if (sizeof($keys) > 1) { |
foreach ($keys as $key) { |
$this->_add_flag($flags[$key], 'multiple_key'); |
} |
} |
if (strpos($val['index_description'], 'primary key')) { |
foreach ($keys as $key) { |
$this->_add_flag($flags[$key], 'primary_key'); |
} |
} elseif (strpos($val['index_description'], 'unique')) { |
foreach ($keys as $key) { |
$this->_add_flag($flags[$key], 'unique_key'); |
} |
} |
} |
// get auto_increment, not_null and timestamp |
$res = $this->getAll("EXEC SP_COLUMNS $table", DB_FETCHMODE_ASSOC); |
if (DB::isError($res)) { |
return $res; |
} |
foreach ($res as $val) { |
$val = array_change_key_case($val, CASE_LOWER); |
if ($val['nullable'] == '0') { |
$this->_add_flag($flags[$val['column_name']], 'not_null'); |
} |
if (strpos($val['type_name'], 'identity')) { |
$this->_add_flag($flags[$val['column_name']], 'auto_increment'); |
} |
if (strpos($val['type_name'], 'timestamp')) { |
$this->_add_flag($flags[$val['column_name']], 'timestamp'); |
} |
} |
} |
if (array_key_exists($column, $flags)) { |
return(implode(' ', $flags[$column])); |
} |
return ''; |
} |
// }}} |
// {{{ _add_flag() |
/** |
* Adds a string to the flags array if the flag is not yet in there |
* - if there is no flag present the array is created |
* |
* @param array &$array the reference to the flag-array |
* @param string $value the flag value |
* |
* @return void |
* |
* @access private |
* @author Joern Barthel <j_barthel@web.de> |
*/ |
function _add_flag(&$array, $value) |
{ |
if (!is_array($array)) { |
$array = array($value); |
} elseif (!in_array($value, $array)) { |
array_push($array, $value); |
} |
} |
// }}} |
// {{{ getSpecialQuery() |
/** |
* Obtains the query string needed for listing a given type of objects |
* |
* @param string $type the kind of objects you want to retrieve |
* |
* @return string the SQL query string or null if the driver doesn't |
* support the object type requested |
* |
* @access protected |
* @see DB_common::getListOf() |
*/ |
function getSpecialQuery($type) |
{ |
switch ($type) { |
case 'tables': |
return "SELECT name FROM sysobjects WHERE type = 'U'" |
. ' ORDER BY name'; |
case 'views': |
return "SELECT name FROM sysobjects WHERE type = 'V'"; |
default: |
return null; |
} |
} |
// }}} |
} |
/* |
* Local variables: |
* tab-width: 4 |
* c-basic-offset: 4 |
* End: |
*/ |
?> |
/obs_saisons/SPIP-v1-8-3/modules/configuration/DB/sqlite.php |
---|
New file |
0,0 → 1,960 |
<?php |
/* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4: */ |
/** |
* The PEAR DB driver for PHP's sqlite extension |
* for interacting with SQLite databases |
* |
* PHP versions 4 and 5 |
* |
* LICENSE: This source file is subject to version 3.0 of the PHP license |
* that is available through the world-wide-web at the following URI: |
* http://www.php.net/license/3_0.txt. If you did not receive a copy of |
* the PHP License and are unable to obtain it through the web, please |
* send a note to license@php.net so we can mail you a copy immediately. |
* |
* @category Database |
* @package DB |
* @author Urs Gehrig <urs@circle.ch> |
* @author Mika Tuupola <tuupola@appelsiini.net> |
* @author Daniel Convissor <danielc@php.net> |
* @copyright 1997-2007 The PHP Group |
* @license http://www.php.net/license/3_0.txt PHP License 3.0 3.0 |
* @version CVS: $Id: sqlite.php,v 1.1 2008/07/07 18:00:39 mrflos Exp $ |
* @link http://pear.php.net/package/DB |
*/ |
/** |
* Obtain the DB_common class so it can be extended from |
*/ |
require_once 'DB/common.php'; |
/** |
* The methods PEAR DB uses to interact with PHP's sqlite extension |
* for interacting with SQLite databases |
* |
* These methods overload the ones declared in DB_common. |
* |
* NOTICE: This driver needs PHP's track_errors ini setting to be on. |
* It is automatically turned on when connecting to the database. |
* Make sure your scripts don't turn it off. |
* |
* @category Database |
* @package DB |
* @author Urs Gehrig <urs@circle.ch> |
* @author Mika Tuupola <tuupola@appelsiini.net> |
* @author Daniel Convissor <danielc@php.net> |
* @copyright 1997-2007 The PHP Group |
* @license http://www.php.net/license/3_0.txt PHP License 3.0 3.0 |
* @version Release: 1.7.14RC1 |
* @link http://pear.php.net/package/DB |
*/ |
class DB_sqlite extends DB_common |
{ |
// {{{ properties |
/** |
* The DB driver type (mysql, oci8, odbc, etc.) |
* @var string |
*/ |
var $phptype = 'sqlite'; |
/** |
* The database syntax variant to be used (db2, access, etc.), if any |
* @var string |
*/ |
var $dbsyntax = 'sqlite'; |
/** |
* The capabilities of this DB implementation |
* |
* The 'new_link' element contains the PHP version that first provided |
* new_link support for this DBMS. Contains false if it's unsupported. |
* |
* Meaning of the 'limit' element: |
* + 'emulate' = emulate with fetch row by number |
* + 'alter' = alter the query |
* + false = skip rows |
* |
* @var array |
*/ |
var $features = array( |
'limit' => 'alter', |
'new_link' => false, |
'numrows' => true, |
'pconnect' => true, |
'prepare' => false, |
'ssl' => false, |
'transactions' => false, |
); |
/** |
* A mapping of native error codes to DB error codes |
* |
* {@internal Error codes according to sqlite_exec. See the online |
* manual at http://sqlite.org/c_interface.html for info. |
* This error handling based on sqlite_exec is not yet implemented.}} |
* |
* @var array |
*/ |
var $errorcode_map = array( |
); |
/** |
* The raw database connection created by PHP |
* @var resource |
*/ |
var $connection; |
/** |
* The DSN information for connecting to a database |
* @var array |
*/ |
var $dsn = array(); |
/** |
* SQLite data types |
* |
* @link http://www.sqlite.org/datatypes.html |
* |
* @var array |
*/ |
var $keywords = array ( |
'BLOB' => '', |
'BOOLEAN' => '', |
'CHARACTER' => '', |
'CLOB' => '', |
'FLOAT' => '', |
'INTEGER' => '', |
'KEY' => '', |
'NATIONAL' => '', |
'NUMERIC' => '', |
'NVARCHAR' => '', |
'PRIMARY' => '', |
'TEXT' => '', |
'TIMESTAMP' => '', |
'UNIQUE' => '', |
'VARCHAR' => '', |
'VARYING' => '', |
); |
/** |
* The most recent error message from $php_errormsg |
* @var string |
* @access private |
*/ |
var $_lasterror = ''; |
// }}} |
// {{{ constructor |
/** |
* This constructor calls <kbd>$this->DB_common()</kbd> |
* |
* @return void |
*/ |
function DB_sqlite() |
{ |
$this->DB_common(); |
} |
// }}} |
// {{{ connect() |
/** |
* Connect to the database server, log in and open the database |
* |
* Don't call this method directly. Use DB::connect() instead. |
* |
* PEAR DB's sqlite driver supports the following extra DSN options: |
* + mode The permissions for the database file, in four digit |
* chmod octal format (eg "0600"). |
* |
* Example of connecting to a database in read-only mode: |
* <code> |
* require_once 'DB.php'; |
* |
* $dsn = 'sqlite:///path/and/name/of/db/file?mode=0400'; |
* $options = array( |
* 'portability' => DB_PORTABILITY_ALL, |
* ); |
* |
* $db = DB::connect($dsn, $options); |
* if (PEAR::isError($db)) { |
* die($db->getMessage()); |
* } |
* </code> |
* |
* @param array $dsn the data source name |
* @param bool $persistent should the connection be persistent? |
* |
* @return int DB_OK on success. A DB_Error object on failure. |
*/ |
function connect($dsn, $persistent = false) |
{ |
if (!PEAR::loadExtension('sqlite')) { |
return $this->raiseError(DB_ERROR_EXTENSION_NOT_FOUND); |
} |
$this->dsn = $dsn; |
if ($dsn['dbsyntax']) { |
$this->dbsyntax = $dsn['dbsyntax']; |
} |
if (!$dsn['database']) { |
return $this->sqliteRaiseError(DB_ERROR_ACCESS_VIOLATION); |
} |
if ($dsn['database'] !== ':memory:') { |
if (!file_exists($dsn['database'])) { |
if (!touch($dsn['database'])) { |
return $this->sqliteRaiseError(DB_ERROR_NOT_FOUND); |
} |
if (!isset($dsn['mode']) || |
!is_numeric($dsn['mode'])) |
{ |
$mode = 0644; |
} else { |
$mode = octdec($dsn['mode']); |
} |
if (!chmod($dsn['database'], $mode)) { |
return $this->sqliteRaiseError(DB_ERROR_NOT_FOUND); |
} |
if (!file_exists($dsn['database'])) { |
return $this->sqliteRaiseError(DB_ERROR_NOT_FOUND); |
} |
} |
if (!is_file($dsn['database'])) { |
return $this->sqliteRaiseError(DB_ERROR_INVALID); |
} |
if (!is_readable($dsn['database'])) { |
return $this->sqliteRaiseError(DB_ERROR_ACCESS_VIOLATION); |
} |
} |
$connect_function = $persistent ? 'sqlite_popen' : 'sqlite_open'; |
// track_errors must remain on for simpleQuery() |
@ini_set('track_errors', 1); |
$php_errormsg = ''; |
if (!$this->connection = @$connect_function($dsn['database'])) { |
return $this->raiseError(DB_ERROR_NODBSELECTED, |
null, null, null, |
$php_errormsg); |
} |
return DB_OK; |
} |
// }}} |
// {{{ disconnect() |
/** |
* Disconnects from the database server |
* |
* @return bool TRUE on success, FALSE on failure |
*/ |
function disconnect() |
{ |
$ret = @sqlite_close($this->connection); |
$this->connection = null; |
return $ret; |
} |
// }}} |
// {{{ simpleQuery() |
/** |
* Sends a query to the database server |
* |
* NOTICE: This method needs PHP's track_errors ini setting to be on. |
* It is automatically turned on when connecting to the database. |
* Make sure your scripts don't turn it off. |
* |
* @param string the SQL query string |
* |
* @return mixed + a PHP result resrouce for successful SELECT queries |
* + the DB_OK constant for other successful queries |
* + a DB_Error object on failure |
*/ |
function simpleQuery($query) |
{ |
$ismanip = $this->_checkManip($query); |
$this->last_query = $query; |
$query = $this->modifyQuery($query); |
$php_errormsg = ''; |
$result = @sqlite_query($query, $this->connection); |
$this->_lasterror = $php_errormsg ? $php_errormsg : ''; |
$this->result = $result; |
if (!$this->result) { |
return $this->sqliteRaiseError(null); |
} |
// sqlite_query() seems to allways return a resource |
// so cant use that. Using $ismanip instead |
if (!$ismanip) { |
$numRows = $this->numRows($result); |
if (is_object($numRows)) { |
// we've got PEAR_Error |
return $numRows; |
} |
return $result; |
} |
return DB_OK; |
} |
// }}} |
// {{{ nextResult() |
/** |
* Move the internal sqlite result pointer to the next available result |
* |
* @param resource $result the valid sqlite result resource |
* |
* @return bool true if a result is available otherwise return false |
*/ |
function nextResult($result) |
{ |
return false; |
} |
// }}} |
// {{{ fetchInto() |
/** |
* Places a row from the result set into the given array |
* |
* Formating of the array and the data therein are configurable. |
* See DB_result::fetchInto() for more information. |
* |
* This method is not meant to be called directly. Use |
* DB_result::fetchInto() instead. It can't be declared "protected" |
* because DB_result is a separate object. |
* |
* @param resource $result the query result resource |
* @param array $arr the referenced array to put the data in |
* @param int $fetchmode how the resulting array should be indexed |
* @param int $rownum the row number to fetch (0 = first row) |
* |
* @return mixed DB_OK on success, NULL when the end of a result set is |
* reached or on failure |
* |
* @see DB_result::fetchInto() |
*/ |
function fetchInto($result, &$arr, $fetchmode, $rownum = null) |
{ |
if ($rownum !== null) { |
if (!@sqlite_seek($this->result, $rownum)) { |
return null; |
} |
} |
if ($fetchmode & DB_FETCHMODE_ASSOC) { |
$arr = @sqlite_fetch_array($result, SQLITE_ASSOC); |
if ($this->options['portability'] & DB_PORTABILITY_LOWERCASE && $arr) { |
$arr = array_change_key_case($arr, CASE_LOWER); |
} |
/* Remove extraneous " characters from the fields in the result. |
* Fixes bug #11716. */ |
if (is_array($arr) && count($arr) > 0) { |
$strippedArr = array(); |
foreach ($arr as $field => $value) { |
$strippedArr[trim($field, '"')] = $value; |
} |
$arr = $strippedArr; |
} |
} else { |
$arr = @sqlite_fetch_array($result, SQLITE_NUM); |
} |
if (!$arr) { |
return null; |
} |
if ($this->options['portability'] & DB_PORTABILITY_RTRIM) { |
/* |
* Even though this DBMS already trims output, we do this because |
* a field might have intentional whitespace at the end that |
* gets removed by DB_PORTABILITY_RTRIM under another driver. |
*/ |
$this->_rtrimArrayValues($arr); |
} |
if ($this->options['portability'] & DB_PORTABILITY_NULL_TO_EMPTY) { |
$this->_convertNullArrayValuesToEmpty($arr); |
} |
return DB_OK; |
} |
// }}} |
// {{{ freeResult() |
/** |
* Deletes the result set and frees the memory occupied by the result set |
* |
* This method is not meant to be called directly. Use |
* DB_result::free() instead. It can't be declared "protected" |
* because DB_result is a separate object. |
* |
* @param resource $result PHP's query result resource |
* |
* @return bool TRUE on success, FALSE if $result is invalid |
* |
* @see DB_result::free() |
*/ |
function freeResult(&$result) |
{ |
// XXX No native free? |
if (!is_resource($result)) { |
return false; |
} |
$result = null; |
return true; |
} |
// }}} |
// {{{ numCols() |
/** |
* Gets the number of columns in a result set |
* |
* This method is not meant to be called directly. Use |
* DB_result::numCols() instead. It can't be declared "protected" |
* because DB_result is a separate object. |
* |
* @param resource $result PHP's query result resource |
* |
* @return int the number of columns. A DB_Error object on failure. |
* |
* @see DB_result::numCols() |
*/ |
function numCols($result) |
{ |
$cols = @sqlite_num_fields($result); |
if (!$cols) { |
return $this->sqliteRaiseError(); |
} |
return $cols; |
} |
// }}} |
// {{{ numRows() |
/** |
* Gets the number of rows in a result set |
* |
* This method is not meant to be called directly. Use |
* DB_result::numRows() instead. It can't be declared "protected" |
* because DB_result is a separate object. |
* |
* @param resource $result PHP's query result resource |
* |
* @return int the number of rows. A DB_Error object on failure. |
* |
* @see DB_result::numRows() |
*/ |
function numRows($result) |
{ |
$rows = @sqlite_num_rows($result); |
if ($rows === null) { |
return $this->sqliteRaiseError(); |
} |
return $rows; |
} |
// }}} |
// {{{ affected() |
/** |
* Determines the number of rows affected by a data maniuplation query |
* |
* 0 is returned for queries that don't manipulate data. |
* |
* @return int the number of rows. A DB_Error object on failure. |
*/ |
function affectedRows() |
{ |
return @sqlite_changes($this->connection); |
} |
// }}} |
// {{{ dropSequence() |
/** |
* Deletes a sequence |
* |
* @param string $seq_name name of the sequence to be deleted |
* |
* @return int DB_OK on success. A DB_Error object on failure. |
* |
* @see DB_common::dropSequence(), DB_common::getSequenceName(), |
* DB_sqlite::nextID(), DB_sqlite::createSequence() |
*/ |
function dropSequence($seq_name) |
{ |
return $this->query('DROP TABLE ' . $this->getSequenceName($seq_name)); |
} |
/** |
* Creates a new sequence |
* |
* @param string $seq_name name of the new sequence |
* |
* @return int DB_OK on success. A DB_Error object on failure. |
* |
* @see DB_common::createSequence(), DB_common::getSequenceName(), |
* DB_sqlite::nextID(), DB_sqlite::dropSequence() |
*/ |
function createSequence($seq_name) |
{ |
$seqname = $this->getSequenceName($seq_name); |
$query = 'CREATE TABLE ' . $seqname . |
' (id INTEGER UNSIGNED PRIMARY KEY) '; |
$result = $this->query($query); |
if (DB::isError($result)) { |
return($result); |
} |
$query = "CREATE TRIGGER ${seqname}_cleanup AFTER INSERT ON $seqname |
BEGIN |
DELETE FROM $seqname WHERE id<LAST_INSERT_ROWID(); |
END "; |
$result = $this->query($query); |
if (DB::isError($result)) { |
return($result); |
} |
} |
// }}} |
// {{{ nextId() |
/** |
* Returns the next free id in a sequence |
* |
* @param string $seq_name name of the sequence |
* @param boolean $ondemand when true, the seqence is automatically |
* created if it does not exist |
* |
* @return int the next id number in the sequence. |
* A DB_Error object on failure. |
* |
* @see DB_common::nextID(), DB_common::getSequenceName(), |
* DB_sqlite::createSequence(), DB_sqlite::dropSequence() |
*/ |
function nextId($seq_name, $ondemand = true) |
{ |
$seqname = $this->getSequenceName($seq_name); |
do { |
$repeat = 0; |
$this->pushErrorHandling(PEAR_ERROR_RETURN); |
$result = $this->query("INSERT INTO $seqname (id) VALUES (NULL)"); |
$this->popErrorHandling(); |
if ($result === DB_OK) { |
$id = @sqlite_last_insert_rowid($this->connection); |
if ($id != 0) { |
return $id; |
} |
} elseif ($ondemand && DB::isError($result) && |
$result->getCode() == DB_ERROR_NOSUCHTABLE) |
{ |
$result = $this->createSequence($seq_name); |
if (DB::isError($result)) { |
return $this->raiseError($result); |
} else { |
$repeat = 1; |
} |
} |
} while ($repeat); |
return $this->raiseError($result); |
} |
// }}} |
// {{{ getDbFileStats() |
/** |
* Get the file stats for the current database |
* |
* Possible arguments are dev, ino, mode, nlink, uid, gid, rdev, size, |
* atime, mtime, ctime, blksize, blocks or a numeric key between |
* 0 and 12. |
* |
* @param string $arg the array key for stats() |
* |
* @return mixed an array on an unspecified key, integer on a passed |
* arg and false at a stats error |
*/ |
function getDbFileStats($arg = '') |
{ |
$stats = stat($this->dsn['database']); |
if ($stats == false) { |
return false; |
} |
if (is_array($stats)) { |
if (is_numeric($arg)) { |
if (((int)$arg <= 12) & ((int)$arg >= 0)) { |
return false; |
} |
return $stats[$arg ]; |
} |
if (array_key_exists(trim($arg), $stats)) { |
return $stats[$arg ]; |
} |
} |
return $stats; |
} |
// }}} |
// {{{ escapeSimple() |
/** |
* Escapes a string according to the current DBMS's standards |
* |
* In SQLite, this makes things safe for inserts/updates, but may |
* cause problems when performing text comparisons against columns |
* containing binary data. See the |
* {@link http://php.net/sqlite_escape_string PHP manual} for more info. |
* |
* @param string $str the string to be escaped |
* |
* @return string the escaped string |
* |
* @since Method available since Release 1.6.1 |
* @see DB_common::escapeSimple() |
*/ |
function escapeSimple($str) |
{ |
return @sqlite_escape_string($str); |
} |
// }}} |
// {{{ modifyLimitQuery() |
/** |
* Adds LIMIT clauses to a query string according to current DBMS standards |
* |
* @param string $query the query to modify |
* @param int $from the row to start to fetching (0 = the first row) |
* @param int $count the numbers of rows to fetch |
* @param mixed $params array, string or numeric data to be used in |
* execution of the statement. Quantity of items |
* passed must match quantity of placeholders in |
* query: meaning 1 placeholder for non-array |
* parameters or 1 placeholder per array element. |
* |
* @return string the query string with LIMIT clauses added |
* |
* @access protected |
*/ |
function modifyLimitQuery($query, $from, $count, $params = array()) |
{ |
return "$query LIMIT $count OFFSET $from"; |
} |
// }}} |
// {{{ modifyQuery() |
/** |
* Changes a query string for various DBMS specific reasons |
* |
* This little hack lets you know how many rows were deleted |
* when running a "DELETE FROM table" query. Only implemented |
* if the DB_PORTABILITY_DELETE_COUNT portability option is on. |
* |
* @param string $query the query string to modify |
* |
* @return string the modified query string |
* |
* @access protected |
* @see DB_common::setOption() |
*/ |
function modifyQuery($query) |
{ |
if ($this->options['portability'] & DB_PORTABILITY_DELETE_COUNT) { |
if (preg_match('/^\s*DELETE\s+FROM\s+(\S+)\s*$/i', $query)) { |
$query = preg_replace('/^\s*DELETE\s+FROM\s+(\S+)\s*$/', |
'DELETE FROM \1 WHERE 1=1', $query); |
} |
} |
return $query; |
} |
// }}} |
// {{{ sqliteRaiseError() |
/** |
* Produces a DB_Error object regarding the current problem |
* |
* @param int $errno if the error is being manually raised pass a |
* DB_ERROR* constant here. If this isn't passed |
* the error information gathered from the DBMS. |
* |
* @return object the DB_Error object |
* |
* @see DB_common::raiseError(), |
* DB_sqlite::errorNative(), DB_sqlite::errorCode() |
*/ |
function sqliteRaiseError($errno = null) |
{ |
$native = $this->errorNative(); |
if ($errno === null) { |
$errno = $this->errorCode($native); |
} |
$errorcode = @sqlite_last_error($this->connection); |
$userinfo = "$errorcode ** $this->last_query"; |
return $this->raiseError($errno, null, null, $userinfo, $native); |
} |
// }}} |
// {{{ errorNative() |
/** |
* Gets the DBMS' native error message produced by the last query |
* |
* {@internal This is used to retrieve more meaningfull error messages |
* because sqlite_last_error() does not provide adequate info.}} |
* |
* @return string the DBMS' error message |
*/ |
function errorNative() |
{ |
return $this->_lasterror; |
} |
// }}} |
// {{{ errorCode() |
/** |
* Determines PEAR::DB error code from the database's text error message |
* |
* @param string $errormsg the error message returned from the database |
* |
* @return integer the DB error number |
*/ |
function errorCode($errormsg) |
{ |
static $error_regexps; |
// PHP 5.2+ prepends the function name to $php_errormsg, so we need |
// this hack to work around it, per bug #9599. |
$errormsg = preg_replace('/^sqlite[a-z_]+\(\): /', '', $errormsg); |
if (!isset($error_regexps)) { |
$error_regexps = array( |
'/^no such table:/' => DB_ERROR_NOSUCHTABLE, |
'/^no such index:/' => DB_ERROR_NOT_FOUND, |
'/^(table|index) .* already exists$/' => DB_ERROR_ALREADY_EXISTS, |
'/PRIMARY KEY must be unique/i' => DB_ERROR_CONSTRAINT, |
'/is not unique/' => DB_ERROR_CONSTRAINT, |
'/columns .* are not unique/i' => DB_ERROR_CONSTRAINT, |
'/uniqueness constraint failed/' => DB_ERROR_CONSTRAINT, |
'/may not be NULL/' => DB_ERROR_CONSTRAINT_NOT_NULL, |
'/^no such column:/' => DB_ERROR_NOSUCHFIELD, |
'/no column named/' => DB_ERROR_NOSUCHFIELD, |
'/column not present in both tables/i' => DB_ERROR_NOSUCHFIELD, |
'/^near ".*": syntax error$/' => DB_ERROR_SYNTAX, |
'/[0-9]+ values for [0-9]+ columns/i' => DB_ERROR_VALUE_COUNT_ON_ROW, |
); |
} |
foreach ($error_regexps as $regexp => $code) { |
if (preg_match($regexp, $errormsg)) { |
return $code; |
} |
} |
// Fall back to DB_ERROR if there was no mapping. |
return DB_ERROR; |
} |
// }}} |
// {{{ tableInfo() |
/** |
* Returns information about a table |
* |
* @param string $result a string containing the name of a table |
* @param int $mode a valid tableInfo mode |
* |
* @return array an associative array with the information requested. |
* A DB_Error object on failure. |
* |
* @see DB_common::tableInfo() |
* @since Method available since Release 1.7.0 |
*/ |
function tableInfo($result, $mode = null) |
{ |
if (is_string($result)) { |
/* |
* Probably received a table name. |
* Create a result resource identifier. |
*/ |
$id = @sqlite_array_query($this->connection, |
"PRAGMA table_info('$result');", |
SQLITE_ASSOC); |
$got_string = true; |
} else { |
$this->last_query = ''; |
return $this->raiseError(DB_ERROR_NOT_CAPABLE, null, null, null, |
'This DBMS can not obtain tableInfo' . |
' from result sets'); |
} |
if ($this->options['portability'] & DB_PORTABILITY_LOWERCASE) { |
$case_func = 'strtolower'; |
} else { |
$case_func = 'strval'; |
} |
$count = count($id); |
$res = array(); |
if ($mode) { |
$res['num_fields'] = $count; |
} |
for ($i = 0; $i < $count; $i++) { |
if (strpos($id[$i]['type'], '(') !== false) { |
$bits = explode('(', $id[$i]['type']); |
$type = $bits[0]; |
$len = rtrim($bits[1],')'); |
} else { |
$type = $id[$i]['type']; |
$len = 0; |
} |
$flags = ''; |
if ($id[$i]['pk']) { |
$flags .= 'primary_key '; |
} |
if ($id[$i]['notnull']) { |
$flags .= 'not_null '; |
} |
if ($id[$i]['dflt_value'] !== null) { |
$flags .= 'default_' . rawurlencode($id[$i]['dflt_value']); |
} |
$flags = trim($flags); |
$res[$i] = array( |
'table' => $case_func($result), |
'name' => $case_func($id[$i]['name']), |
'type' => $type, |
'len' => $len, |
'flags' => $flags, |
); |
if ($mode & DB_TABLEINFO_ORDER) { |
$res['order'][$res[$i]['name']] = $i; |
} |
if ($mode & DB_TABLEINFO_ORDERTABLE) { |
$res['ordertable'][$res[$i]['table']][$res[$i]['name']] = $i; |
} |
} |
return $res; |
} |
// }}} |
// {{{ getSpecialQuery() |
/** |
* Obtains the query string needed for listing a given type of objects |
* |
* @param string $type the kind of objects you want to retrieve |
* @param array $args SQLITE DRIVER ONLY: a private array of arguments |
* used by the getSpecialQuery(). Do not use |
* this directly. |
* |
* @return string the SQL query string or null if the driver doesn't |
* support the object type requested |
* |
* @access protected |
* @see DB_common::getListOf() |
*/ |
function getSpecialQuery($type, $args = array()) |
{ |
if (!is_array($args)) { |
return $this->raiseError('no key specified', null, null, null, |
'Argument has to be an array.'); |
} |
switch ($type) { |
case 'master': |
return 'SELECT * FROM sqlite_master;'; |
case 'tables': |
return "SELECT name FROM sqlite_master WHERE type='table' " |
. 'UNION ALL SELECT name FROM sqlite_temp_master ' |
. "WHERE type='table' ORDER BY name;"; |
case 'schema': |
return 'SELECT sql FROM (SELECT * FROM sqlite_master ' |
. 'UNION ALL SELECT * FROM sqlite_temp_master) ' |
. "WHERE type!='meta' " |
. 'ORDER BY tbl_name, type DESC, name;'; |
case 'schemax': |
case 'schema_x': |
/* |
* Use like: |
* $res = $db->query($db->getSpecialQuery('schema_x', |
* array('table' => 'table3'))); |
*/ |
return 'SELECT sql FROM (SELECT * FROM sqlite_master ' |
. 'UNION ALL SELECT * FROM sqlite_temp_master) ' |
. "WHERE tbl_name LIKE '{$args['table']}' " |
. "AND type!='meta' " |
. 'ORDER BY type DESC, name;'; |
case 'alter': |
/* |
* SQLite does not support ALTER TABLE; this is a helper query |
* to handle this. 'table' represents the table name, 'rows' |
* the news rows to create, 'save' the row(s) to keep _with_ |
* the data. |
* |
* Use like: |
* $args = array( |
* 'table' => $table, |
* 'rows' => "id INTEGER PRIMARY KEY, firstname TEXT, surname TEXT, datetime TEXT", |
* 'save' => "NULL, titel, content, datetime" |
* ); |
* $res = $db->query( $db->getSpecialQuery('alter', $args)); |
*/ |
$rows = strtr($args['rows'], $this->keywords); |
$q = array( |
'BEGIN TRANSACTION', |
"CREATE TEMPORARY TABLE {$args['table']}_backup ({$args['rows']})", |
"INSERT INTO {$args['table']}_backup SELECT {$args['save']} FROM {$args['table']}", |
"DROP TABLE {$args['table']}", |
"CREATE TABLE {$args['table']} ({$args['rows']})", |
"INSERT INTO {$args['table']} SELECT {$rows} FROM {$args['table']}_backup", |
"DROP TABLE {$args['table']}_backup", |
'COMMIT', |
); |
/* |
* This is a dirty hack, since the above query will not get |
* executed with a single query call so here the query method |
* will be called directly and return a select instead. |
*/ |
foreach ($q as $query) { |
$this->query($query); |
} |
return "SELECT * FROM {$args['table']};"; |
default: |
return null; |
} |
} |
// }}} |
} |
/* |
* Local variables: |
* tab-width: 4 |
* c-basic-offset: 4 |
* End: |
*/ |
?> |
/obs_saisons/SPIP-v1-8-3/modules/configuration/DB/oci8.php |
---|
New file |
0,0 → 1,1156 |
<?php |
/* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4: */ |
/** |
* The PEAR DB driver for PHP's oci8 extension |
* for interacting with Oracle databases |
* |
* PHP versions 4 and 5 |
* |
* LICENSE: This source file is subject to version 3.0 of the PHP license |
* that is available through the world-wide-web at the following URI: |
* http://www.php.net/license/3_0.txt. If you did not receive a copy of |
* the PHP License and are unable to obtain it through the web, please |
* send a note to license@php.net so we can mail you a copy immediately. |
* |
* @category Database |
* @package DB |
* @author James L. Pine <jlp@valinux.com> |
* @author Daniel Convissor <danielc@php.net> |
* @copyright 1997-2007 The PHP Group |
* @license http://www.php.net/license/3_0.txt PHP License 3.0 |
* @version CVS: $Id: oci8.php,v 1.1 2008/07/07 18:00:39 mrflos Exp $ |
* @link http://pear.php.net/package/DB |
*/ |
/** |
* Obtain the DB_common class so it can be extended from |
*/ |
require_once 'DB/common.php'; |
/** |
* The methods PEAR DB uses to interact with PHP's oci8 extension |
* for interacting with Oracle databases |
* |
* Definitely works with versions 8 and 9 of Oracle. |
* |
* These methods overload the ones declared in DB_common. |
* |
* Be aware... OCIError() only appears to return anything when given a |
* statement, so functions return the generic DB_ERROR instead of more |
* useful errors that have to do with feedback from the database. |
* |
* @category Database |
* @package DB |
* @author James L. Pine <jlp@valinux.com> |
* @author Daniel Convissor <danielc@php.net> |
* @copyright 1997-2007 The PHP Group |
* @license http://www.php.net/license/3_0.txt PHP License 3.0 |
* @version Release: 1.7.14RC1 |
* @link http://pear.php.net/package/DB |
*/ |
class DB_oci8 extends DB_common |
{ |
// {{{ properties |
/** |
* The DB driver type (mysql, oci8, odbc, etc.) |
* @var string |
*/ |
var $phptype = 'oci8'; |
/** |
* The database syntax variant to be used (db2, access, etc.), if any |
* @var string |
*/ |
var $dbsyntax = 'oci8'; |
/** |
* The capabilities of this DB implementation |
* |
* The 'new_link' element contains the PHP version that first provided |
* new_link support for this DBMS. Contains false if it's unsupported. |
* |
* Meaning of the 'limit' element: |
* + 'emulate' = emulate with fetch row by number |
* + 'alter' = alter the query |
* + false = skip rows |
* |
* @var array |
*/ |
var $features = array( |
'limit' => 'alter', |
'new_link' => '5.0.0', |
'numrows' => 'subquery', |
'pconnect' => true, |
'prepare' => true, |
'ssl' => false, |
'transactions' => true, |
); |
/** |
* A mapping of native error codes to DB error codes |
* @var array |
*/ |
var $errorcode_map = array( |
1 => DB_ERROR_CONSTRAINT, |
900 => DB_ERROR_SYNTAX, |
904 => DB_ERROR_NOSUCHFIELD, |
913 => DB_ERROR_VALUE_COUNT_ON_ROW, |
921 => DB_ERROR_SYNTAX, |
923 => DB_ERROR_SYNTAX, |
942 => DB_ERROR_NOSUCHTABLE, |
955 => DB_ERROR_ALREADY_EXISTS, |
1400 => DB_ERROR_CONSTRAINT_NOT_NULL, |
1401 => DB_ERROR_INVALID, |
1407 => DB_ERROR_CONSTRAINT_NOT_NULL, |
1418 => DB_ERROR_NOT_FOUND, |
1476 => DB_ERROR_DIVZERO, |
1722 => DB_ERROR_INVALID_NUMBER, |
2289 => DB_ERROR_NOSUCHTABLE, |
2291 => DB_ERROR_CONSTRAINT, |
2292 => DB_ERROR_CONSTRAINT, |
2449 => DB_ERROR_CONSTRAINT, |
12899 => DB_ERROR_INVALID, |
); |
/** |
* The raw database connection created by PHP |
* @var resource |
*/ |
var $connection; |
/** |
* The DSN information for connecting to a database |
* @var array |
*/ |
var $dsn = array(); |
/** |
* Should data manipulation queries be committed automatically? |
* @var bool |
* @access private |
*/ |
var $autocommit = true; |
/** |
* Stores the $data passed to execute() in the oci8 driver |
* |
* Gets reset to array() when simpleQuery() is run. |
* |
* Needed in case user wants to call numRows() after prepare/execute |
* was used. |
* |
* @var array |
* @access private |
*/ |
var $_data = array(); |
/** |
* The result or statement handle from the most recently executed query |
* @var resource |
*/ |
var $last_stmt; |
/** |
* Is the given prepared statement a data manipulation query? |
* @var array |
* @access private |
*/ |
var $manip_query = array(); |
/** |
* Store of prepared SQL queries. |
* @var array |
* @access private |
*/ |
var $_prepared_queries = array(); |
// }}} |
// {{{ constructor |
/** |
* This constructor calls <kbd>$this->DB_common()</kbd> |
* |
* @return void |
*/ |
function DB_oci8() |
{ |
$this->DB_common(); |
} |
// }}} |
// {{{ connect() |
/** |
* Connect to the database server, log in and open the database |
* |
* Don't call this method directly. Use DB::connect() instead. |
* |
* If PHP is at version 5.0.0 or greater: |
* + Generally, oci_connect() or oci_pconnect() are used. |
* + But if the new_link DSN option is set to true, oci_new_connect() |
* is used. |
* |
* When using PHP version 4.x, OCILogon() or OCIPLogon() are used. |
* |
* PEAR DB's oci8 driver supports the following extra DSN options: |
* + charset The character set to be used on the connection. |
* Only used if PHP is at version 5.0.0 or greater |
* and the Oracle server is at 9.2 or greater. |
* Available since PEAR DB 1.7.0. |
* + new_link If set to true, causes subsequent calls to |
* connect() to return a new connection link |
* instead of the existing one. WARNING: this is |
* not portable to other DBMS's. |
* Available since PEAR DB 1.7.0. |
* |
* @param array $dsn the data source name |
* @param bool $persistent should the connection be persistent? |
* |
* @return int DB_OK on success. A DB_Error object on failure. |
*/ |
function connect($dsn, $persistent = false) |
{ |
if (!PEAR::loadExtension('oci8')) { |
return $this->raiseError(DB_ERROR_EXTENSION_NOT_FOUND); |
} |
$this->dsn = $dsn; |
if ($dsn['dbsyntax']) { |
$this->dbsyntax = $dsn['dbsyntax']; |
} |
// Backwards compatibility with DB < 1.7.0 |
if (empty($dsn['database']) && !empty($dsn['hostspec'])) { |
$db = $dsn['hostspec']; |
} else { |
$db = $dsn['database']; |
} |
if (function_exists('oci_connect')) { |
if (isset($dsn['new_link']) |
&& ($dsn['new_link'] == 'true' || $dsn['new_link'] === true)) |
{ |
$connect_function = 'oci_new_connect'; |
} else { |
$connect_function = $persistent ? 'oci_pconnect' |
: 'oci_connect'; |
} |
if (isset($this->dsn['port']) && $this->dsn['port']) { |
$db = '//'.$db.':'.$this->dsn['port']; |
} |
$char = empty($dsn['charset']) ? null : $dsn['charset']; |
$this->connection = @$connect_function($dsn['username'], |
$dsn['password'], |
$db, |
$char); |
$error = OCIError(); |
if (!empty($error) && $error['code'] == 12541) { |
// Couldn't find TNS listener. Try direct connection. |
$this->connection = @$connect_function($dsn['username'], |
$dsn['password'], |
null, |
$char); |
} |
} else { |
$connect_function = $persistent ? 'OCIPLogon' : 'OCILogon'; |
if ($db) { |
$this->connection = @$connect_function($dsn['username'], |
$dsn['password'], |
$db); |
} elseif ($dsn['username'] || $dsn['password']) { |
$this->connection = @$connect_function($dsn['username'], |
$dsn['password']); |
} |
} |
if (!$this->connection) { |
$error = OCIError(); |
$error = (is_array($error)) ? $error['message'] : null; |
return $this->raiseError(DB_ERROR_CONNECT_FAILED, |
null, null, null, |
$error); |
} |
return DB_OK; |
} |
// }}} |
// {{{ disconnect() |
/** |
* Disconnects from the database server |
* |
* @return bool TRUE on success, FALSE on failure |
*/ |
function disconnect() |
{ |
if (function_exists('oci_close')) { |
$ret = @oci_close($this->connection); |
} else { |
$ret = @OCILogOff($this->connection); |
} |
$this->connection = null; |
return $ret; |
} |
// }}} |
// {{{ simpleQuery() |
/** |
* Sends a query to the database server |
* |
* To determine how many rows of a result set get buffered using |
* ocisetprefetch(), see the "result_buffering" option in setOptions(). |
* This option was added in Release 1.7.0. |
* |
* @param string the SQL query string |
* |
* @return mixed + a PHP result resrouce for successful SELECT queries |
* + the DB_OK constant for other successful queries |
* + a DB_Error object on failure |
*/ |
function simpleQuery($query) |
{ |
$this->_data = array(); |
$this->last_parameters = array(); |
$this->last_query = $query; |
$query = $this->modifyQuery($query); |
$result = @OCIParse($this->connection, $query); |
if (!$result) { |
return $this->oci8RaiseError(); |
} |
if ($this->autocommit) { |
$success = @OCIExecute($result,OCI_COMMIT_ON_SUCCESS); |
} else { |
$success = @OCIExecute($result,OCI_DEFAULT); |
} |
if (!$success) { |
return $this->oci8RaiseError($result); |
} |
$this->last_stmt = $result; |
if ($this->_checkManip($query)) { |
return DB_OK; |
} else { |
@ocisetprefetch($result, $this->options['result_buffering']); |
return $result; |
} |
} |
// }}} |
// {{{ nextResult() |
/** |
* Move the internal oracle result pointer to the next available result |
* |
* @param a valid oci8 result resource |
* |
* @access public |
* |
* @return true if a result is available otherwise return false |
*/ |
function nextResult($result) |
{ |
return false; |
} |
// }}} |
// {{{ fetchInto() |
/** |
* Places a row from the result set into the given array |
* |
* Formating of the array and the data therein are configurable. |
* See DB_result::fetchInto() for more information. |
* |
* This method is not meant to be called directly. Use |
* DB_result::fetchInto() instead. It can't be declared "protected" |
* because DB_result is a separate object. |
* |
* @param resource $result the query result resource |
* @param array $arr the referenced array to put the data in |
* @param int $fetchmode how the resulting array should be indexed |
* @param int $rownum the row number to fetch (0 = first row) |
* |
* @return mixed DB_OK on success, NULL when the end of a result set is |
* reached or on failure |
* |
* @see DB_result::fetchInto() |
*/ |
function fetchInto($result, &$arr, $fetchmode, $rownum = null) |
{ |
if ($rownum !== null) { |
return $this->raiseError(DB_ERROR_NOT_CAPABLE); |
} |
if ($fetchmode & DB_FETCHMODE_ASSOC) { |
$moredata = @OCIFetchInto($result,$arr,OCI_ASSOC+OCI_RETURN_NULLS+OCI_RETURN_LOBS); |
if ($this->options['portability'] & DB_PORTABILITY_LOWERCASE && |
$moredata) |
{ |
$arr = array_change_key_case($arr, CASE_LOWER); |
} |
} else { |
$moredata = OCIFetchInto($result,$arr,OCI_RETURN_NULLS+OCI_RETURN_LOBS); |
} |
if (!$moredata) { |
return null; |
} |
if ($this->options['portability'] & DB_PORTABILITY_RTRIM) { |
$this->_rtrimArrayValues($arr); |
} |
if ($this->options['portability'] & DB_PORTABILITY_NULL_TO_EMPTY) { |
$this->_convertNullArrayValuesToEmpty($arr); |
} |
return DB_OK; |
} |
// }}} |
// {{{ freeResult() |
/** |
* Deletes the result set and frees the memory occupied by the result set |
* |
* This method is not meant to be called directly. Use |
* DB_result::free() instead. It can't be declared "protected" |
* because DB_result is a separate object. |
* |
* @param resource $result PHP's query result resource |
* |
* @return bool TRUE on success, FALSE if $result is invalid |
* |
* @see DB_result::free() |
*/ |
function freeResult($result) |
{ |
return is_resource($result) ? OCIFreeStatement($result) : false; |
} |
/** |
* Frees the internal resources associated with a prepared query |
* |
* @param resource $stmt the prepared statement's resource |
* @param bool $free_resource should the PHP resource be freed too? |
* Use false if you need to get data |
* from the result set later. |
* |
* @return bool TRUE on success, FALSE if $result is invalid |
* |
* @see DB_oci8::prepare() |
*/ |
function freePrepared($stmt, $free_resource = true) |
{ |
if (!is_resource($stmt)) { |
return false; |
} |
if ($free_resource) { |
@ocifreestatement($stmt); |
} |
if (isset($this->prepare_types[(int)$stmt])) { |
unset($this->prepare_types[(int)$stmt]); |
unset($this->manip_query[(int)$stmt]); |
} else { |
return false; |
} |
return true; |
} |
// }}} |
// {{{ numRows() |
/** |
* Gets the number of rows in a result set |
* |
* Only works if the DB_PORTABILITY_NUMROWS portability option |
* is turned on. |
* |
* This method is not meant to be called directly. Use |
* DB_result::numRows() instead. It can't be declared "protected" |
* because DB_result is a separate object. |
* |
* @param resource $result PHP's query result resource |
* |
* @return int the number of rows. A DB_Error object on failure. |
* |
* @see DB_result::numRows(), DB_common::setOption() |
*/ |
function numRows($result) |
{ |
// emulate numRows for Oracle. yuck. |
if ($this->options['portability'] & DB_PORTABILITY_NUMROWS && |
$result === $this->last_stmt) |
{ |
$countquery = 'SELECT COUNT(*) FROM ('.$this->last_query.')'; |
$save_query = $this->last_query; |
$save_stmt = $this->last_stmt; |
$count = $this->query($countquery); |
// Restore the last query and statement. |
$this->last_query = $save_query; |
$this->last_stmt = $save_stmt; |
if (DB::isError($count) || |
DB::isError($row = $count->fetchRow(DB_FETCHMODE_ORDERED))) |
{ |
return $this->raiseError(DB_ERROR_NOT_CAPABLE); |
} |
return $row[0]; |
} |
return $this->raiseError(DB_ERROR_NOT_CAPABLE); |
} |
// }}} |
// {{{ numCols() |
/** |
* Gets the number of columns in a result set |
* |
* This method is not meant to be called directly. Use |
* DB_result::numCols() instead. It can't be declared "protected" |
* because DB_result is a separate object. |
* |
* @param resource $result PHP's query result resource |
* |
* @return int the number of columns. A DB_Error object on failure. |
* |
* @see DB_result::numCols() |
*/ |
function numCols($result) |
{ |
$cols = @OCINumCols($result); |
if (!$cols) { |
return $this->oci8RaiseError($result); |
} |
return $cols; |
} |
// }}} |
// {{{ prepare() |
/** |
* Prepares a query for multiple execution with execute(). |
* |
* With oci8, this is emulated. |
* |
* prepare() requires a generic query as string like <code> |
* INSERT INTO numbers VALUES (?, ?, ?) |
* </code>. The <kbd>?</kbd> characters are placeholders. |
* |
* Three types of placeholders can be used: |
* + <kbd>?</kbd> a quoted scalar value, i.e. strings, integers |
* + <kbd>!</kbd> value is inserted 'as is' |
* + <kbd>&</kbd> requires a file name. The file's contents get |
* inserted into the query (i.e. saving binary |
* data in a db) |
* |
* Use backslashes to escape placeholder characters if you don't want |
* them to be interpreted as placeholders. Example: <code> |
* "UPDATE foo SET col=? WHERE col='over \& under'" |
* </code> |
* |
* @param string $query the query to be prepared |
* |
* @return mixed DB statement resource on success. DB_Error on failure. |
* |
* @see DB_oci8::execute() |
*/ |
function prepare($query) |
{ |
$tokens = preg_split('/((?<!\\\)[&?!])/', $query, -1, |
PREG_SPLIT_DELIM_CAPTURE); |
$binds = count($tokens) - 1; |
$token = 0; |
$types = array(); |
$newquery = ''; |
foreach ($tokens as $key => $val) { |
switch ($val) { |
case '?': |
$types[$token++] = DB_PARAM_SCALAR; |
unset($tokens[$key]); |
break; |
case '&': |
$types[$token++] = DB_PARAM_OPAQUE; |
unset($tokens[$key]); |
break; |
case '!': |
$types[$token++] = DB_PARAM_MISC; |
unset($tokens[$key]); |
break; |
default: |
$tokens[$key] = preg_replace('/\\\([&?!])/', "\\1", $val); |
if ($key != $binds) { |
$newquery .= $tokens[$key] . ':bind' . $token; |
} else { |
$newquery .= $tokens[$key]; |
} |
} |
} |
$this->last_query = $query; |
$newquery = $this->modifyQuery($newquery); |
if (!$stmt = @OCIParse($this->connection, $newquery)) { |
return $this->oci8RaiseError(); |
} |
$this->prepare_types[(int)$stmt] = $types; |
$this->manip_query[(int)$stmt] = DB::isManip($query); |
$this->_prepared_queries[(int)$stmt] = $newquery; |
return $stmt; |
} |
// }}} |
// {{{ execute() |
/** |
* Executes a DB statement prepared with prepare(). |
* |
* To determine how many rows of a result set get buffered using |
* ocisetprefetch(), see the "result_buffering" option in setOptions(). |
* This option was added in Release 1.7.0. |
* |
* @param resource $stmt a DB statement resource returned from prepare() |
* @param mixed $data array, string or numeric data to be used in |
* execution of the statement. Quantity of items |
* passed must match quantity of placeholders in |
* query: meaning 1 for non-array items or the |
* quantity of elements in the array. |
* |
* @return mixed returns an oic8 result resource for successful SELECT |
* queries, DB_OK for other successful queries. |
* A DB error object is returned on failure. |
* |
* @see DB_oci8::prepare() |
*/ |
function &execute($stmt, $data = array()) |
{ |
$data = (array)$data; |
$this->last_parameters = $data; |
$this->last_query = $this->_prepared_queries[(int)$stmt]; |
$this->_data = $data; |
$types = $this->prepare_types[(int)$stmt]; |
if (count($types) != count($data)) { |
$tmp = $this->raiseError(DB_ERROR_MISMATCH); |
return $tmp; |
} |
$i = 0; |
foreach ($data as $key => $value) { |
if ($types[$i] == DB_PARAM_MISC) { |
/* |
* Oracle doesn't seem to have the ability to pass a |
* parameter along unchanged, so strip off quotes from start |
* and end, plus turn two single quotes to one single quote, |
* in order to avoid the quotes getting escaped by |
* Oracle and ending up in the database. |
*/ |
$data[$key] = preg_replace("/^'(.*)'$/", "\\1", $data[$key]); |
$data[$key] = str_replace("''", "'", $data[$key]); |
} elseif ($types[$i] == DB_PARAM_OPAQUE) { |
$fp = @fopen($data[$key], 'rb'); |
if (!$fp) { |
$tmp = $this->raiseError(DB_ERROR_ACCESS_VIOLATION); |
return $tmp; |
} |
$data[$key] = fread($fp, filesize($data[$key])); |
fclose($fp); |
} elseif ($types[$i] == DB_PARAM_SCALAR) { |
// Floats have to be converted to a locale-neutral |
// representation. |
if (is_float($data[$key])) { |
$data[$key] = $this->quoteFloat($data[$key]); |
} |
} |
if (!@OCIBindByName($stmt, ':bind' . $i, $data[$key], -1)) { |
$tmp = $this->oci8RaiseError($stmt); |
return $tmp; |
} |
$this->last_query = preg_replace("/:bind$i/",$this->quoteSmart($data[$key]),$this->last_query,1); |
$i++; |
} |
if ($this->autocommit) { |
$success = @OCIExecute($stmt, OCI_COMMIT_ON_SUCCESS); |
} else { |
$success = @OCIExecute($stmt, OCI_DEFAULT); |
} |
if (!$success) { |
$tmp = $this->oci8RaiseError($stmt); |
return $tmp; |
} |
$this->last_stmt = $stmt; |
if ($this->manip_query[(int)$stmt] || $this->_next_query_manip) { |
$this->_last_query_manip = true; |
$this->_next_query_manip = false; |
$tmp = DB_OK; |
} else { |
$this->_last_query_manip = false; |
@ocisetprefetch($stmt, $this->options['result_buffering']); |
$tmp = new DB_result($this, $stmt); |
} |
return $tmp; |
} |
// }}} |
// {{{ autoCommit() |
/** |
* Enables or disables automatic commits |
* |
* @param bool $onoff true turns it on, false turns it off |
* |
* @return int DB_OK on success. A DB_Error object if the driver |
* doesn't support auto-committing transactions. |
*/ |
function autoCommit($onoff = false) |
{ |
$this->autocommit = (bool)$onoff;; |
return DB_OK; |
} |
// }}} |
// {{{ commit() |
/** |
* Commits the current transaction |
* |
* @return int DB_OK on success. A DB_Error object on failure. |
*/ |
function commit() |
{ |
$result = @OCICommit($this->connection); |
if (!$result) { |
return $this->oci8RaiseError(); |
} |
return DB_OK; |
} |
// }}} |
// {{{ rollback() |
/** |
* Reverts the current transaction |
* |
* @return int DB_OK on success. A DB_Error object on failure. |
*/ |
function rollback() |
{ |
$result = @OCIRollback($this->connection); |
if (!$result) { |
return $this->oci8RaiseError(); |
} |
return DB_OK; |
} |
// }}} |
// {{{ affectedRows() |
/** |
* Determines the number of rows affected by a data maniuplation query |
* |
* 0 is returned for queries that don't manipulate data. |
* |
* @return int the number of rows. A DB_Error object on failure. |
*/ |
function affectedRows() |
{ |
if ($this->last_stmt === false) { |
return $this->oci8RaiseError(); |
} |
$result = @OCIRowCount($this->last_stmt); |
if ($result === false) { |
return $this->oci8RaiseError($this->last_stmt); |
} |
return $result; |
} |
// }}} |
// {{{ modifyQuery() |
/** |
* Changes a query string for various DBMS specific reasons |
* |
* "SELECT 2+2" must be "SELECT 2+2 FROM dual" in Oracle. |
* |
* @param string $query the query string to modify |
* |
* @return string the modified query string |
* |
* @access protected |
*/ |
function modifyQuery($query) |
{ |
if (preg_match('/^\s*SELECT/i', $query) && |
!preg_match('/\sFROM\s/i', $query)) { |
$query .= ' FROM dual'; |
} |
return $query; |
} |
// }}} |
// {{{ modifyLimitQuery() |
/** |
* Adds LIMIT clauses to a query string according to current DBMS standards |
* |
* @param string $query the query to modify |
* @param int $from the row to start to fetching (0 = the first row) |
* @param int $count the numbers of rows to fetch |
* @param mixed $params array, string or numeric data to be used in |
* execution of the statement. Quantity of items |
* passed must match quantity of placeholders in |
* query: meaning 1 placeholder for non-array |
* parameters or 1 placeholder per array element. |
* |
* @return string the query string with LIMIT clauses added |
* |
* @access protected |
*/ |
function modifyLimitQuery($query, $from, $count, $params = array()) |
{ |
// Let Oracle return the name of the columns instead of |
// coding a "home" SQL parser |
if (count($params)) { |
$result = $this->prepare("SELECT * FROM ($query) " |
. 'WHERE NULL = NULL'); |
$tmp = $this->execute($result, $params); |
} else { |
$q_fields = "SELECT * FROM ($query) WHERE NULL = NULL"; |
if (!$result = @OCIParse($this->connection, $q_fields)) { |
$this->last_query = $q_fields; |
return $this->oci8RaiseError(); |
} |
if (!@OCIExecute($result, OCI_DEFAULT)) { |
$this->last_query = $q_fields; |
return $this->oci8RaiseError($result); |
} |
} |
$ncols = OCINumCols($result); |
$cols = array(); |
for ( $i = 1; $i <= $ncols; $i++ ) { |
$cols[] = '"' . OCIColumnName($result, $i) . '"'; |
} |
$fields = implode(', ', $cols); |
// XXX Test that (tip by John Lim) |
//if (preg_match('/^\s*SELECT\s+/is', $query, $match)) { |
// // Introduce the FIRST_ROWS Oracle query optimizer |
// $query = substr($query, strlen($match[0]), strlen($query)); |
// $query = "SELECT /* +FIRST_ROWS */ " . $query; |
//} |
// Construct the query |
// more at: http://marc.theaimsgroup.com/?l=php-db&m=99831958101212&w=2 |
// Perhaps this could be optimized with the use of Unions |
$query = "SELECT $fields FROM". |
" (SELECT rownum as linenum, $fields FROM". |
" ($query)". |
' WHERE rownum <= '. ($from + $count) . |
') WHERE linenum >= ' . ++$from; |
return $query; |
} |
// }}} |
// {{{ nextId() |
/** |
* Returns the next free id in a sequence |
* |
* @param string $seq_name name of the sequence |
* @param boolean $ondemand when true, the seqence is automatically |
* created if it does not exist |
* |
* @return int the next id number in the sequence. |
* A DB_Error object on failure. |
* |
* @see DB_common::nextID(), DB_common::getSequenceName(), |
* DB_oci8::createSequence(), DB_oci8::dropSequence() |
*/ |
function nextId($seq_name, $ondemand = true) |
{ |
$seqname = $this->getSequenceName($seq_name); |
$repeat = 0; |
do { |
$this->expectError(DB_ERROR_NOSUCHTABLE); |
$result = $this->query("SELECT ${seqname}.nextval FROM dual"); |
$this->popExpect(); |
if ($ondemand && DB::isError($result) && |
$result->getCode() == DB_ERROR_NOSUCHTABLE) { |
$repeat = 1; |
$result = $this->createSequence($seq_name); |
if (DB::isError($result)) { |
return $this->raiseError($result); |
} |
} else { |
$repeat = 0; |
} |
} while ($repeat); |
if (DB::isError($result)) { |
return $this->raiseError($result); |
} |
$arr = $result->fetchRow(DB_FETCHMODE_ORDERED); |
return $arr[0]; |
} |
/** |
* Creates a new sequence |
* |
* @param string $seq_name name of the new sequence |
* |
* @return int DB_OK on success. A DB_Error object on failure. |
* |
* @see DB_common::createSequence(), DB_common::getSequenceName(), |
* DB_oci8::nextID(), DB_oci8::dropSequence() |
*/ |
function createSequence($seq_name) |
{ |
return $this->query('CREATE SEQUENCE ' |
. $this->getSequenceName($seq_name)); |
} |
// }}} |
// {{{ dropSequence() |
/** |
* Deletes a sequence |
* |
* @param string $seq_name name of the sequence to be deleted |
* |
* @return int DB_OK on success. A DB_Error object on failure. |
* |
* @see DB_common::dropSequence(), DB_common::getSequenceName(), |
* DB_oci8::nextID(), DB_oci8::createSequence() |
*/ |
function dropSequence($seq_name) |
{ |
return $this->query('DROP SEQUENCE ' |
. $this->getSequenceName($seq_name)); |
} |
// }}} |
// {{{ oci8RaiseError() |
/** |
* Produces a DB_Error object regarding the current problem |
* |
* @param int $errno if the error is being manually raised pass a |
* DB_ERROR* constant here. If this isn't passed |
* the error information gathered from the DBMS. |
* |
* @return object the DB_Error object |
* |
* @see DB_common::raiseError(), |
* DB_oci8::errorNative(), DB_oci8::errorCode() |
*/ |
function oci8RaiseError($errno = null) |
{ |
if ($errno === null) { |
$error = @OCIError($this->connection); |
return $this->raiseError($this->errorCode($error['code']), |
null, null, null, $error['message']); |
} elseif (is_resource($errno)) { |
$error = @OCIError($errno); |
return $this->raiseError($this->errorCode($error['code']), |
null, null, null, $error['message']); |
} |
return $this->raiseError($this->errorCode($errno)); |
} |
// }}} |
// {{{ errorNative() |
/** |
* Gets the DBMS' native error code produced by the last query |
* |
* @return int the DBMS' error code. FALSE if the code could not be |
* determined |
*/ |
function errorNative() |
{ |
if (is_resource($this->last_stmt)) { |
$error = @OCIError($this->last_stmt); |
} else { |
$error = @OCIError($this->connection); |
} |
if (is_array($error)) { |
return $error['code']; |
} |
return false; |
} |
// }}} |
// {{{ tableInfo() |
/** |
* Returns information about a table or a result set |
* |
* NOTE: only supports 'table' and 'flags' if <var>$result</var> |
* is a table name. |
* |
* NOTE: flags won't contain index information. |
* |
* @param object|string $result DB_result object from a query or a |
* string containing the name of a table. |
* While this also accepts a query result |
* resource identifier, this behavior is |
* deprecated. |
* @param int $mode a valid tableInfo mode |
* |
* @return array an associative array with the information requested. |
* A DB_Error object on failure. |
* |
* @see DB_common::tableInfo() |
*/ |
function tableInfo($result, $mode = null) |
{ |
if ($this->options['portability'] & DB_PORTABILITY_LOWERCASE) { |
$case_func = 'strtolower'; |
} else { |
$case_func = 'strval'; |
} |
$res = array(); |
if (is_string($result)) { |
/* |
* Probably received a table name. |
* Create a result resource identifier. |
*/ |
$result = strtoupper($result); |
$q_fields = 'SELECT column_name, data_type, data_length, ' |
. 'nullable ' |
. 'FROM user_tab_columns ' |
. "WHERE table_name='$result' ORDER BY column_id"; |
$this->last_query = $q_fields; |
if (!$stmt = @OCIParse($this->connection, $q_fields)) { |
return $this->oci8RaiseError(DB_ERROR_NEED_MORE_DATA); |
} |
if (!@OCIExecute($stmt, OCI_DEFAULT)) { |
return $this->oci8RaiseError($stmt); |
} |
$i = 0; |
while (@OCIFetch($stmt)) { |
$res[$i] = array( |
'table' => $case_func($result), |
'name' => $case_func(@OCIResult($stmt, 1)), |
'type' => @OCIResult($stmt, 2), |
'len' => @OCIResult($stmt, 3), |
'flags' => (@OCIResult($stmt, 4) == 'N') ? 'not_null' : '', |
); |
if ($mode & DB_TABLEINFO_ORDER) { |
$res['order'][$res[$i]['name']] = $i; |
} |
if ($mode & DB_TABLEINFO_ORDERTABLE) { |
$res['ordertable'][$res[$i]['table']][$res[$i]['name']] = $i; |
} |
$i++; |
} |
if ($mode) { |
$res['num_fields'] = $i; |
} |
@OCIFreeStatement($stmt); |
} else { |
if (isset($result->result)) { |
/* |
* Probably received a result object. |
* Extract the result resource identifier. |
*/ |
$result = $result->result; |
} |
$res = array(); |
if ($result === $this->last_stmt) { |
$count = @OCINumCols($result); |
if ($mode) { |
$res['num_fields'] = $count; |
} |
for ($i = 0; $i < $count; $i++) { |
$res[$i] = array( |
'table' => '', |
'name' => $case_func(@OCIColumnName($result, $i+1)), |
'type' => @OCIColumnType($result, $i+1), |
'len' => @OCIColumnSize($result, $i+1), |
'flags' => '', |
); |
if ($mode & DB_TABLEINFO_ORDER) { |
$res['order'][$res[$i]['name']] = $i; |
} |
if ($mode & DB_TABLEINFO_ORDERTABLE) { |
$res['ordertable'][$res[$i]['table']][$res[$i]['name']] = $i; |
} |
} |
} else { |
return $this->raiseError(DB_ERROR_NOT_CAPABLE); |
} |
} |
return $res; |
} |
// }}} |
// {{{ getSpecialQuery() |
/** |
* Obtains the query string needed for listing a given type of objects |
* |
* @param string $type the kind of objects you want to retrieve |
* |
* @return string the SQL query string or null if the driver doesn't |
* support the object type requested |
* |
* @access protected |
* @see DB_common::getListOf() |
*/ |
function getSpecialQuery($type) |
{ |
switch ($type) { |
case 'tables': |
return 'SELECT table_name FROM user_tables'; |
case 'synonyms': |
return 'SELECT synonym_name FROM user_synonyms'; |
case 'views': |
return 'SELECT view_name FROM user_views'; |
default: |
return null; |
} |
} |
// }}} |
// {{{ quoteFloat() |
/** |
* Formats a float value for use within a query in a locale-independent |
* manner. |
* |
* @param float the float value to be quoted. |
* @return string the quoted string. |
* @see DB_common::quoteSmart() |
* @since Method available since release 1.7.8. |
*/ |
function quoteFloat($float) { |
return $this->escapeSimple(str_replace(',', '.', strval(floatval($float)))); |
} |
// }}} |
} |
/* |
* Local variables: |
* tab-width: 4 |
* c-basic-offset: 4 |
* End: |
*/ |
?> |
/obs_saisons/SPIP-v1-8-3/modules/configuration/DB/ibase.php |
---|
New file |
0,0 → 1,1082 |
<?php |
/* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4: */ |
/** |
* The PEAR DB driver for PHP's interbase extension |
* for interacting with Interbase and Firebird databases |
* |
* While this class works with PHP 4, PHP's InterBase extension is |
* unstable in PHP 4. Use PHP 5. |
* |
* PHP versions 4 and 5 |
* |
* LICENSE: This source file is subject to version 3.0 of the PHP license |
* that is available through the world-wide-web at the following URI: |
* http://www.php.net/license/3_0.txt. If you did not receive a copy of |
* the PHP License and are unable to obtain it through the web, please |
* send a note to license@php.net so we can mail you a copy immediately. |
* |
* @category Database |
* @package DB |
* @author Sterling Hughes <sterling@php.net> |
* @author Daniel Convissor <danielc@php.net> |
* @copyright 1997-2007 The PHP Group |
* @license http://www.php.net/license/3_0.txt PHP License 3.0 |
* @version CVS: $Id: ibase.php,v 1.1 2008/07/07 18:00:39 mrflos Exp $ |
* @link http://pear.php.net/package/DB |
*/ |
/** |
* Obtain the DB_common class so it can be extended from |
*/ |
require_once 'DB/common.php'; |
/** |
* The methods PEAR DB uses to interact with PHP's interbase extension |
* for interacting with Interbase and Firebird databases |
* |
* These methods overload the ones declared in DB_common. |
* |
* While this class works with PHP 4, PHP's InterBase extension is |
* unstable in PHP 4. Use PHP 5. |
* |
* NOTICE: limitQuery() only works for Firebird. |
* |
* @category Database |
* @package DB |
* @author Sterling Hughes <sterling@php.net> |
* @author Daniel Convissor <danielc@php.net> |
* @copyright 1997-2007 The PHP Group |
* @license http://www.php.net/license/3_0.txt PHP License 3.0 |
* @version Release: 1.7.14RC1 |
* @link http://pear.php.net/package/DB |
* @since Class became stable in Release 1.7.0 |
*/ |
class DB_ibase extends DB_common |
{ |
// {{{ properties |
/** |
* The DB driver type (mysql, oci8, odbc, etc.) |
* @var string |
*/ |
var $phptype = 'ibase'; |
/** |
* The database syntax variant to be used (db2, access, etc.), if any |
* @var string |
*/ |
var $dbsyntax = 'ibase'; |
/** |
* The capabilities of this DB implementation |
* |
* The 'new_link' element contains the PHP version that first provided |
* new_link support for this DBMS. Contains false if it's unsupported. |
* |
* Meaning of the 'limit' element: |
* + 'emulate' = emulate with fetch row by number |
* + 'alter' = alter the query |
* + false = skip rows |
* |
* NOTE: only firebird supports limit. |
* |
* @var array |
*/ |
var $features = array( |
'limit' => false, |
'new_link' => false, |
'numrows' => 'emulate', |
'pconnect' => true, |
'prepare' => true, |
'ssl' => false, |
'transactions' => true, |
); |
/** |
* A mapping of native error codes to DB error codes |
* @var array |
*/ |
var $errorcode_map = array( |
-104 => DB_ERROR_SYNTAX, |
-150 => DB_ERROR_ACCESS_VIOLATION, |
-151 => DB_ERROR_ACCESS_VIOLATION, |
-155 => DB_ERROR_NOSUCHTABLE, |
-157 => DB_ERROR_NOSUCHFIELD, |
-158 => DB_ERROR_VALUE_COUNT_ON_ROW, |
-170 => DB_ERROR_MISMATCH, |
-171 => DB_ERROR_MISMATCH, |
-172 => DB_ERROR_INVALID, |
// -204 => // Covers too many errors, need to use regex on msg |
-205 => DB_ERROR_NOSUCHFIELD, |
-206 => DB_ERROR_NOSUCHFIELD, |
-208 => DB_ERROR_INVALID, |
-219 => DB_ERROR_NOSUCHTABLE, |
-297 => DB_ERROR_CONSTRAINT, |
-303 => DB_ERROR_INVALID, |
-413 => DB_ERROR_INVALID_NUMBER, |
-530 => DB_ERROR_CONSTRAINT, |
-551 => DB_ERROR_ACCESS_VIOLATION, |
-552 => DB_ERROR_ACCESS_VIOLATION, |
// -607 => // Covers too many errors, need to use regex on msg |
-625 => DB_ERROR_CONSTRAINT_NOT_NULL, |
-803 => DB_ERROR_CONSTRAINT, |
-804 => DB_ERROR_VALUE_COUNT_ON_ROW, |
// -902 => // Covers too many errors, need to use regex on msg |
-904 => DB_ERROR_CONNECT_FAILED, |
-922 => DB_ERROR_NOSUCHDB, |
-923 => DB_ERROR_CONNECT_FAILED, |
-924 => DB_ERROR_CONNECT_FAILED |
); |
/** |
* The raw database connection created by PHP |
* @var resource |
*/ |
var $connection; |
/** |
* The DSN information for connecting to a database |
* @var array |
*/ |
var $dsn = array(); |
/** |
* The number of rows affected by a data manipulation query |
* @var integer |
* @access private |
*/ |
var $affected = 0; |
/** |
* Should data manipulation queries be committed automatically? |
* @var bool |
* @access private |
*/ |
var $autocommit = true; |
/** |
* The prepared statement handle from the most recently executed statement |
* |
* {@internal Mainly here because the InterBase/Firebird API is only |
* able to retrieve data from result sets if the statemnt handle is |
* still in scope.}} |
* |
* @var resource |
*/ |
var $last_stmt; |
/** |
* Is the given prepared statement a data manipulation query? |
* @var array |
* @access private |
*/ |
var $manip_query = array(); |
// }}} |
// {{{ constructor |
/** |
* This constructor calls <kbd>$this->DB_common()</kbd> |
* |
* @return void |
*/ |
function DB_ibase() |
{ |
$this->DB_common(); |
} |
// }}} |
// {{{ connect() |
/** |
* Connect to the database server, log in and open the database |
* |
* Don't call this method directly. Use DB::connect() instead. |
* |
* PEAR DB's ibase driver supports the following extra DSN options: |
* + buffers The number of database buffers to allocate for the |
* server-side cache. |
* + charset The default character set for a database. |
* + dialect The default SQL dialect for any statement |
* executed within a connection. Defaults to the |
* highest one supported by client libraries. |
* Functional only with InterBase 6 and up. |
* + role Functional only with InterBase 5 and up. |
* |
* @param array $dsn the data source name |
* @param bool $persistent should the connection be persistent? |
* |
* @return int DB_OK on success. A DB_Error object on failure. |
*/ |
function connect($dsn, $persistent = false) |
{ |
if (!PEAR::loadExtension('interbase')) { |
return $this->raiseError(DB_ERROR_EXTENSION_NOT_FOUND); |
} |
$this->dsn = $dsn; |
if ($dsn['dbsyntax']) { |
$this->dbsyntax = $dsn['dbsyntax']; |
} |
if ($this->dbsyntax == 'firebird') { |
$this->features['limit'] = 'alter'; |
} |
$params = array( |
$dsn['hostspec'] |
? ($dsn['hostspec'] . ':' . $dsn['database']) |
: $dsn['database'], |
$dsn['username'] ? $dsn['username'] : null, |
$dsn['password'] ? $dsn['password'] : null, |
isset($dsn['charset']) ? $dsn['charset'] : null, |
isset($dsn['buffers']) ? $dsn['buffers'] : null, |
isset($dsn['dialect']) ? $dsn['dialect'] : null, |
isset($dsn['role']) ? $dsn['role'] : null, |
); |
$connect_function = $persistent ? 'ibase_pconnect' : 'ibase_connect'; |
$this->connection = @call_user_func_array($connect_function, $params); |
if (!$this->connection) { |
return $this->ibaseRaiseError(DB_ERROR_CONNECT_FAILED); |
} |
return DB_OK; |
} |
// }}} |
// {{{ disconnect() |
/** |
* Disconnects from the database server |
* |
* @return bool TRUE on success, FALSE on failure |
*/ |
function disconnect() |
{ |
$ret = @ibase_close($this->connection); |
$this->connection = null; |
return $ret; |
} |
// }}} |
// {{{ simpleQuery() |
/** |
* Sends a query to the database server |
* |
* @param string the SQL query string |
* |
* @return mixed + a PHP result resrouce for successful SELECT queries |
* + the DB_OK constant for other successful queries |
* + a DB_Error object on failure |
*/ |
function simpleQuery($query) |
{ |
$ismanip = $this->_checkManip($query); |
$this->last_query = $query; |
$query = $this->modifyQuery($query); |
$result = @ibase_query($this->connection, $query); |
if (!$result) { |
return $this->ibaseRaiseError(); |
} |
if ($this->autocommit && $ismanip) { |
@ibase_commit($this->connection); |
} |
if ($ismanip) { |
$this->affected = $result; |
return DB_OK; |
} else { |
$this->affected = 0; |
return $result; |
} |
} |
// }}} |
// {{{ modifyLimitQuery() |
/** |
* Adds LIMIT clauses to a query string according to current DBMS standards |
* |
* Only works with Firebird. |
* |
* @param string $query the query to modify |
* @param int $from the row to start to fetching (0 = the first row) |
* @param int $count the numbers of rows to fetch |
* @param mixed $params array, string or numeric data to be used in |
* execution of the statement. Quantity of items |
* passed must match quantity of placeholders in |
* query: meaning 1 placeholder for non-array |
* parameters or 1 placeholder per array element. |
* |
* @return string the query string with LIMIT clauses added |
* |
* @access protected |
*/ |
function modifyLimitQuery($query, $from, $count, $params = array()) |
{ |
if ($this->dsn['dbsyntax'] == 'firebird') { |
$query = preg_replace('/^([\s(])*SELECT/i', |
"SELECT FIRST $count SKIP $from", $query); |
} |
return $query; |
} |
// }}} |
// {{{ nextResult() |
/** |
* Move the internal ibase result pointer to the next available result |
* |
* @param a valid fbsql result resource |
* |
* @access public |
* |
* @return true if a result is available otherwise return false |
*/ |
function nextResult($result) |
{ |
return false; |
} |
// }}} |
// {{{ fetchInto() |
/** |
* Places a row from the result set into the given array |
* |
* Formating of the array and the data therein are configurable. |
* See DB_result::fetchInto() for more information. |
* |
* This method is not meant to be called directly. Use |
* DB_result::fetchInto() instead. It can't be declared "protected" |
* because DB_result is a separate object. |
* |
* @param resource $result the query result resource |
* @param array $arr the referenced array to put the data in |
* @param int $fetchmode how the resulting array should be indexed |
* @param int $rownum the row number to fetch (0 = first row) |
* |
* @return mixed DB_OK on success, NULL when the end of a result set is |
* reached or on failure |
* |
* @see DB_result::fetchInto() |
*/ |
function fetchInto($result, &$arr, $fetchmode, $rownum = null) |
{ |
if ($rownum !== null) { |
return $this->ibaseRaiseError(DB_ERROR_NOT_CAPABLE); |
} |
if ($fetchmode & DB_FETCHMODE_ASSOC) { |
if (function_exists('ibase_fetch_assoc')) { |
$arr = @ibase_fetch_assoc($result); |
} else { |
$arr = get_object_vars(ibase_fetch_object($result)); |
} |
if ($this->options['portability'] & DB_PORTABILITY_LOWERCASE && $arr) { |
$arr = array_change_key_case($arr, CASE_LOWER); |
} |
} else { |
$arr = @ibase_fetch_row($result); |
} |
if (!$arr) { |
return null; |
} |
if ($this->options['portability'] & DB_PORTABILITY_RTRIM) { |
$this->_rtrimArrayValues($arr); |
} |
if ($this->options['portability'] & DB_PORTABILITY_NULL_TO_EMPTY) { |
$this->_convertNullArrayValuesToEmpty($arr); |
} |
return DB_OK; |
} |
// }}} |
// {{{ freeResult() |
/** |
* Deletes the result set and frees the memory occupied by the result set |
* |
* This method is not meant to be called directly. Use |
* DB_result::free() instead. It can't be declared "protected" |
* because DB_result is a separate object. |
* |
* @param resource $result PHP's query result resource |
* |
* @return bool TRUE on success, FALSE if $result is invalid |
* |
* @see DB_result::free() |
*/ |
function freeResult($result) |
{ |
return is_resource($result) ? ibase_free_result($result) : false; |
} |
// }}} |
// {{{ freeQuery() |
function freeQuery($query) |
{ |
return is_resource($query) ? ibase_free_query($query) : false; |
} |
// }}} |
// {{{ affectedRows() |
/** |
* Determines the number of rows affected by a data maniuplation query |
* |
* 0 is returned for queries that don't manipulate data. |
* |
* @return int the number of rows. A DB_Error object on failure. |
*/ |
function affectedRows() |
{ |
if (is_integer($this->affected)) { |
return $this->affected; |
} |
return $this->ibaseRaiseError(DB_ERROR_NOT_CAPABLE); |
} |
// }}} |
// {{{ numCols() |
/** |
* Gets the number of columns in a result set |
* |
* This method is not meant to be called directly. Use |
* DB_result::numCols() instead. It can't be declared "protected" |
* because DB_result is a separate object. |
* |
* @param resource $result PHP's query result resource |
* |
* @return int the number of columns. A DB_Error object on failure. |
* |
* @see DB_result::numCols() |
*/ |
function numCols($result) |
{ |
$cols = @ibase_num_fields($result); |
if (!$cols) { |
return $this->ibaseRaiseError(); |
} |
return $cols; |
} |
// }}} |
// {{{ prepare() |
/** |
* Prepares a query for multiple execution with execute(). |
* |
* prepare() requires a generic query as string like <code> |
* INSERT INTO numbers VALUES (?, ?, ?) |
* </code>. The <kbd>?</kbd> characters are placeholders. |
* |
* Three types of placeholders can be used: |
* + <kbd>?</kbd> a quoted scalar value, i.e. strings, integers |
* + <kbd>!</kbd> value is inserted 'as is' |
* + <kbd>&</kbd> requires a file name. The file's contents get |
* inserted into the query (i.e. saving binary |
* data in a db) |
* |
* Use backslashes to escape placeholder characters if you don't want |
* them to be interpreted as placeholders. Example: <code> |
* "UPDATE foo SET col=? WHERE col='over \& under'" |
* </code> |
* |
* @param string $query query to be prepared |
* @return mixed DB statement resource on success. DB_Error on failure. |
*/ |
function prepare($query) |
{ |
$tokens = preg_split('/((?<!\\\)[&?!])/', $query, -1, |
PREG_SPLIT_DELIM_CAPTURE); |
$token = 0; |
$types = array(); |
$newquery = ''; |
foreach ($tokens as $key => $val) { |
switch ($val) { |
case '?': |
$types[$token++] = DB_PARAM_SCALAR; |
break; |
case '&': |
$types[$token++] = DB_PARAM_OPAQUE; |
break; |
case '!': |
$types[$token++] = DB_PARAM_MISC; |
break; |
default: |
$tokens[$key] = preg_replace('/\\\([&?!])/', "\\1", $val); |
$newquery .= $tokens[$key] . '?'; |
} |
} |
$newquery = substr($newquery, 0, -1); |
$this->last_query = $query; |
$newquery = $this->modifyQuery($newquery); |
$stmt = @ibase_prepare($this->connection, $newquery); |
if ($stmt === false) { |
$stmt = $this->ibaseRaiseError(); |
} else { |
$this->prepare_types[(int)$stmt] = $types; |
$this->manip_query[(int)$stmt] = DB::isManip($query); |
} |
return $stmt; |
} |
// }}} |
// {{{ execute() |
/** |
* Executes a DB statement prepared with prepare(). |
* |
* @param resource $stmt a DB statement resource returned from prepare() |
* @param mixed $data array, string or numeric data to be used in |
* execution of the statement. Quantity of items |
* passed must match quantity of placeholders in |
* query: meaning 1 for non-array items or the |
* quantity of elements in the array. |
* @return object a new DB_Result or a DB_Error when fail |
* @see DB_ibase::prepare() |
* @access public |
*/ |
function &execute($stmt, $data = array()) |
{ |
$data = (array)$data; |
$this->last_parameters = $data; |
$types = $this->prepare_types[(int)$stmt]; |
if (count($types) != count($data)) { |
$tmp = $this->raiseError(DB_ERROR_MISMATCH); |
return $tmp; |
} |
$i = 0; |
foreach ($data as $key => $value) { |
if ($types[$i] == DB_PARAM_MISC) { |
/* |
* ibase doesn't seem to have the ability to pass a |
* parameter along unchanged, so strip off quotes from start |
* and end, plus turn two single quotes to one single quote, |
* in order to avoid the quotes getting escaped by |
* ibase and ending up in the database. |
*/ |
$data[$key] = preg_replace("/^'(.*)'$/", "\\1", $data[$key]); |
$data[$key] = str_replace("''", "'", $data[$key]); |
} elseif ($types[$i] == DB_PARAM_OPAQUE) { |
$fp = @fopen($data[$key], 'rb'); |
if (!$fp) { |
$tmp = $this->raiseError(DB_ERROR_ACCESS_VIOLATION); |
return $tmp; |
} |
$data[$key] = fread($fp, filesize($data[$key])); |
fclose($fp); |
} |
$i++; |
} |
array_unshift($data, $stmt); |
$res = call_user_func_array('ibase_execute', $data); |
if (!$res) { |
$tmp = $this->ibaseRaiseError(); |
return $tmp; |
} |
/* XXX need this? |
if ($this->autocommit && $this->manip_query[(int)$stmt]) { |
@ibase_commit($this->connection); |
}*/ |
$this->last_stmt = $stmt; |
if ($this->manip_query[(int)$stmt] || $this->_next_query_manip) { |
$this->_last_query_manip = true; |
$this->_next_query_manip = false; |
$tmp = DB_OK; |
} else { |
$this->_last_query_manip = false; |
$tmp = new DB_result($this, $res); |
} |
return $tmp; |
} |
/** |
* Frees the internal resources associated with a prepared query |
* |
* @param resource $stmt the prepared statement's PHP resource |
* @param bool $free_resource should the PHP resource be freed too? |
* Use false if you need to get data |
* from the result set later. |
* |
* @return bool TRUE on success, FALSE if $result is invalid |
* |
* @see DB_ibase::prepare() |
*/ |
function freePrepared($stmt, $free_resource = true) |
{ |
if (!is_resource($stmt)) { |
return false; |
} |
if ($free_resource) { |
@ibase_free_query($stmt); |
} |
unset($this->prepare_tokens[(int)$stmt]); |
unset($this->prepare_types[(int)$stmt]); |
unset($this->manip_query[(int)$stmt]); |
return true; |
} |
// }}} |
// {{{ autoCommit() |
/** |
* Enables or disables automatic commits |
* |
* @param bool $onoff true turns it on, false turns it off |
* |
* @return int DB_OK on success. A DB_Error object if the driver |
* doesn't support auto-committing transactions. |
*/ |
function autoCommit($onoff = false) |
{ |
$this->autocommit = $onoff ? 1 : 0; |
return DB_OK; |
} |
// }}} |
// {{{ commit() |
/** |
* Commits the current transaction |
* |
* @return int DB_OK on success. A DB_Error object on failure. |
*/ |
function commit() |
{ |
return @ibase_commit($this->connection); |
} |
// }}} |
// {{{ rollback() |
/** |
* Reverts the current transaction |
* |
* @return int DB_OK on success. A DB_Error object on failure. |
*/ |
function rollback() |
{ |
return @ibase_rollback($this->connection); |
} |
// }}} |
// {{{ transactionInit() |
function transactionInit($trans_args = 0) |
{ |
return $trans_args |
? @ibase_trans($trans_args, $this->connection) |
: @ibase_trans(); |
} |
// }}} |
// {{{ nextId() |
/** |
* Returns the next free id in a sequence |
* |
* @param string $seq_name name of the sequence |
* @param boolean $ondemand when true, the seqence is automatically |
* created if it does not exist |
* |
* @return int the next id number in the sequence. |
* A DB_Error object on failure. |
* |
* @see DB_common::nextID(), DB_common::getSequenceName(), |
* DB_ibase::createSequence(), DB_ibase::dropSequence() |
*/ |
function nextId($seq_name, $ondemand = true) |
{ |
$sqn = strtoupper($this->getSequenceName($seq_name)); |
$repeat = 0; |
do { |
$this->pushErrorHandling(PEAR_ERROR_RETURN); |
$result = $this->query("SELECT GEN_ID(${sqn}, 1) " |
. 'FROM RDB$GENERATORS ' |
. "WHERE RDB\$GENERATOR_NAME='${sqn}'"); |
$this->popErrorHandling(); |
if ($ondemand && DB::isError($result)) { |
$repeat = 1; |
$result = $this->createSequence($seq_name); |
if (DB::isError($result)) { |
return $result; |
} |
} else { |
$repeat = 0; |
} |
} while ($repeat); |
if (DB::isError($result)) { |
return $this->raiseError($result); |
} |
$arr = $result->fetchRow(DB_FETCHMODE_ORDERED); |
$result->free(); |
return $arr[0]; |
} |
// }}} |
// {{{ createSequence() |
/** |
* Creates a new sequence |
* |
* @param string $seq_name name of the new sequence |
* |
* @return int DB_OK on success. A DB_Error object on failure. |
* |
* @see DB_common::createSequence(), DB_common::getSequenceName(), |
* DB_ibase::nextID(), DB_ibase::dropSequence() |
*/ |
function createSequence($seq_name) |
{ |
$sqn = strtoupper($this->getSequenceName($seq_name)); |
$this->pushErrorHandling(PEAR_ERROR_RETURN); |
$result = $this->query("CREATE GENERATOR ${sqn}"); |
$this->popErrorHandling(); |
return $result; |
} |
// }}} |
// {{{ dropSequence() |
/** |
* Deletes a sequence |
* |
* @param string $seq_name name of the sequence to be deleted |
* |
* @return int DB_OK on success. A DB_Error object on failure. |
* |
* @see DB_common::dropSequence(), DB_common::getSequenceName(), |
* DB_ibase::nextID(), DB_ibase::createSequence() |
*/ |
function dropSequence($seq_name) |
{ |
return $this->query('DELETE FROM RDB$GENERATORS ' |
. "WHERE RDB\$GENERATOR_NAME='" |
. strtoupper($this->getSequenceName($seq_name)) |
. "'"); |
} |
// }}} |
// {{{ _ibaseFieldFlags() |
/** |
* Get the column's flags |
* |
* Supports "primary_key", "unique_key", "not_null", "default", |
* "computed" and "blob". |
* |
* @param string $field_name the name of the field |
* @param string $table_name the name of the table |
* |
* @return string the flags |
* |
* @access private |
*/ |
function _ibaseFieldFlags($field_name, $table_name) |
{ |
$sql = 'SELECT R.RDB$CONSTRAINT_TYPE CTYPE' |
.' FROM RDB$INDEX_SEGMENTS I' |
.' JOIN RDB$RELATION_CONSTRAINTS R ON I.RDB$INDEX_NAME=R.RDB$INDEX_NAME' |
.' WHERE I.RDB$FIELD_NAME=\'' . $field_name . '\'' |
.' AND UPPER(R.RDB$RELATION_NAME)=\'' . strtoupper($table_name) . '\''; |
$result = @ibase_query($this->connection, $sql); |
if (!$result) { |
return $this->ibaseRaiseError(); |
} |
$flags = ''; |
if ($obj = @ibase_fetch_object($result)) { |
@ibase_free_result($result); |
if (isset($obj->CTYPE) && trim($obj->CTYPE) == 'PRIMARY KEY') { |
$flags .= 'primary_key '; |
} |
if (isset($obj->CTYPE) && trim($obj->CTYPE) == 'UNIQUE') { |
$flags .= 'unique_key '; |
} |
} |
$sql = 'SELECT R.RDB$NULL_FLAG AS NFLAG,' |
.' R.RDB$DEFAULT_SOURCE AS DSOURCE,' |
.' F.RDB$FIELD_TYPE AS FTYPE,' |
.' F.RDB$COMPUTED_SOURCE AS CSOURCE' |
.' FROM RDB$RELATION_FIELDS R ' |
.' JOIN RDB$FIELDS F ON R.RDB$FIELD_SOURCE=F.RDB$FIELD_NAME' |
.' WHERE UPPER(R.RDB$RELATION_NAME)=\'' . strtoupper($table_name) . '\'' |
.' AND R.RDB$FIELD_NAME=\'' . $field_name . '\''; |
$result = @ibase_query($this->connection, $sql); |
if (!$result) { |
return $this->ibaseRaiseError(); |
} |
if ($obj = @ibase_fetch_object($result)) { |
@ibase_free_result($result); |
if (isset($obj->NFLAG)) { |
$flags .= 'not_null '; |
} |
if (isset($obj->DSOURCE)) { |
$flags .= 'default '; |
} |
if (isset($obj->CSOURCE)) { |
$flags .= 'computed '; |
} |
if (isset($obj->FTYPE) && $obj->FTYPE == 261) { |
$flags .= 'blob '; |
} |
} |
return trim($flags); |
} |
// }}} |
// {{{ ibaseRaiseError() |
/** |
* Produces a DB_Error object regarding the current problem |
* |
* @param int $errno if the error is being manually raised pass a |
* DB_ERROR* constant here. If this isn't passed |
* the error information gathered from the DBMS. |
* |
* @return object the DB_Error object |
* |
* @see DB_common::raiseError(), |
* DB_ibase::errorNative(), DB_ibase::errorCode() |
*/ |
function &ibaseRaiseError($errno = null) |
{ |
if ($errno === null) { |
$errno = $this->errorCode($this->errorNative()); |
} |
$tmp = $this->raiseError($errno, null, null, null, @ibase_errmsg()); |
return $tmp; |
} |
// }}} |
// {{{ errorNative() |
/** |
* Gets the DBMS' native error code produced by the last query |
* |
* @return int the DBMS' error code. NULL if there is no error code. |
* |
* @since Method available since Release 1.7.0 |
*/ |
function errorNative() |
{ |
if (function_exists('ibase_errcode')) { |
return @ibase_errcode(); |
} |
if (preg_match('/^Dynamic SQL Error SQL error code = ([0-9-]+)/i', |
@ibase_errmsg(), $m)) { |
return (int)$m[1]; |
} |
return null; |
} |
// }}} |
// {{{ errorCode() |
/** |
* Maps native error codes to DB's portable ones |
* |
* @param int $nativecode the error code returned by the DBMS |
* |
* @return int the portable DB error code. Return DB_ERROR if the |
* current driver doesn't have a mapping for the |
* $nativecode submitted. |
* |
* @since Method available since Release 1.7.0 |
*/ |
function errorCode($nativecode = null) |
{ |
if (isset($this->errorcode_map[$nativecode])) { |
return $this->errorcode_map[$nativecode]; |
} |
static $error_regexps; |
if (!isset($error_regexps)) { |
$error_regexps = array( |
'/generator .* is not defined/' |
=> DB_ERROR_SYNTAX, // for compat. w ibase_errcode() |
'/table.*(not exist|not found|unknown)/i' |
=> DB_ERROR_NOSUCHTABLE, |
'/table .* already exists/i' |
=> DB_ERROR_ALREADY_EXISTS, |
'/unsuccessful metadata update .* failed attempt to store duplicate value/i' |
=> DB_ERROR_ALREADY_EXISTS, |
'/unsuccessful metadata update .* not found/i' |
=> DB_ERROR_NOT_FOUND, |
'/validation error for column .* value "\*\*\* null/i' |
=> DB_ERROR_CONSTRAINT_NOT_NULL, |
'/violation of [\w ]+ constraint/i' |
=> DB_ERROR_CONSTRAINT, |
'/conversion error from string/i' |
=> DB_ERROR_INVALID_NUMBER, |
'/no permission for/i' |
=> DB_ERROR_ACCESS_VIOLATION, |
'/arithmetic exception, numeric overflow, or string truncation/i' |
=> DB_ERROR_INVALID, |
'/feature is not supported/i' |
=> DB_ERROR_NOT_CAPABLE, |
); |
} |
$errormsg = @ibase_errmsg(); |
foreach ($error_regexps as $regexp => $code) { |
if (preg_match($regexp, $errormsg)) { |
return $code; |
} |
} |
return DB_ERROR; |
} |
// }}} |
// {{{ tableInfo() |
/** |
* Returns information about a table or a result set |
* |
* NOTE: only supports 'table' and 'flags' if <var>$result</var> |
* is a table name. |
* |
* @param object|string $result DB_result object from a query or a |
* string containing the name of a table. |
* While this also accepts a query result |
* resource identifier, this behavior is |
* deprecated. |
* @param int $mode a valid tableInfo mode |
* |
* @return array an associative array with the information requested. |
* A DB_Error object on failure. |
* |
* @see DB_common::tableInfo() |
*/ |
function tableInfo($result, $mode = null) |
{ |
if (is_string($result)) { |
/* |
* Probably received a table name. |
* Create a result resource identifier. |
*/ |
$id = @ibase_query($this->connection, |
"SELECT * FROM $result WHERE 1=0"); |
$got_string = true; |
} elseif (isset($result->result)) { |
/* |
* Probably received a result object. |
* Extract the result resource identifier. |
*/ |
$id = $result->result; |
$got_string = false; |
} else { |
/* |
* Probably received a result resource identifier. |
* Copy it. |
* Deprecated. Here for compatibility only. |
*/ |
$id = $result; |
$got_string = false; |
} |
if (!is_resource($id)) { |
return $this->ibaseRaiseError(DB_ERROR_NEED_MORE_DATA); |
} |
if ($this->options['portability'] & DB_PORTABILITY_LOWERCASE) { |
$case_func = 'strtolower'; |
} else { |
$case_func = 'strval'; |
} |
$count = @ibase_num_fields($id); |
$res = array(); |
if ($mode) { |
$res['num_fields'] = $count; |
} |
for ($i = 0; $i < $count; $i++) { |
$info = @ibase_field_info($id, $i); |
$res[$i] = array( |
'table' => $got_string ? $case_func($result) : '', |
'name' => $case_func($info['name']), |
'type' => $info['type'], |
'len' => $info['length'], |
'flags' => ($got_string) |
? $this->_ibaseFieldFlags($info['name'], $result) |
: '', |
); |
if ($mode & DB_TABLEINFO_ORDER) { |
$res['order'][$res[$i]['name']] = $i; |
} |
if ($mode & DB_TABLEINFO_ORDERTABLE) { |
$res['ordertable'][$res[$i]['table']][$res[$i]['name']] = $i; |
} |
} |
// free the result only if we were called on a table |
if ($got_string) { |
@ibase_free_result($id); |
} |
return $res; |
} |
// }}} |
// {{{ getSpecialQuery() |
/** |
* Obtains the query string needed for listing a given type of objects |
* |
* @param string $type the kind of objects you want to retrieve |
* |
* @return string the SQL query string or null if the driver doesn't |
* support the object type requested |
* |
* @access protected |
* @see DB_common::getListOf() |
*/ |
function getSpecialQuery($type) |
{ |
switch ($type) { |
case 'tables': |
return 'SELECT DISTINCT R.RDB$RELATION_NAME FROM ' |
. 'RDB$RELATION_FIELDS R WHERE R.RDB$SYSTEM_FLAG=0'; |
case 'views': |
return 'SELECT DISTINCT RDB$VIEW_NAME from RDB$VIEW_RELATIONS'; |
case 'users': |
return 'SELECT DISTINCT RDB$USER FROM RDB$USER_PRIVILEGES'; |
default: |
return null; |
} |
} |
// }}} |
} |
/* |
* Local variables: |
* tab-width: 4 |
* c-basic-offset: 4 |
* End: |
*/ |
?> |
/obs_saisons/SPIP-v1-8-3/modules/configuration/DB/storage.php |
---|
New file |
0,0 → 1,506 |
<?php |
/* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4: */ |
/** |
* Provides an object interface to a table row |
* |
* PHP versions 4 and 5 |
* |
* LICENSE: This source file is subject to version 3.0 of the PHP license |
* that is available through the world-wide-web at the following URI: |
* http://www.php.net/license/3_0.txt. If you did not receive a copy of |
* the PHP License and are unable to obtain it through the web, please |
* send a note to license@php.net so we can mail you a copy immediately. |
* |
* @category Database |
* @package DB |
* @author Stig Bakken <stig@php.net> |
* @copyright 1997-2007 The PHP Group |
* @license http://www.php.net/license/3_0.txt PHP License 3.0 |
* @version CVS: $Id: storage.php,v 1.1 2008/07/07 18:00:39 mrflos Exp $ |
* @link http://pear.php.net/package/DB |
*/ |
/** |
* Obtain the DB class so it can be extended from |
*/ |
require_once 'DB.php'; |
/** |
* Provides an object interface to a table row |
* |
* It lets you add, delete and change rows using objects rather than SQL |
* statements. |
* |
* @category Database |
* @package DB |
* @author Stig Bakken <stig@php.net> |
* @copyright 1997-2007 The PHP Group |
* @license http://www.php.net/license/3_0.txt PHP License 3.0 |
* @version Release: 1.7.14RC1 |
* @link http://pear.php.net/package/DB |
*/ |
class DB_storage extends PEAR |
{ |
// {{{ properties |
/** the name of the table (or view, if the backend database supports |
updates in views) we hold data from */ |
var $_table = null; |
/** which column(s) in the table contains primary keys, can be a |
string for single-column primary keys, or an array of strings |
for multiple-column primary keys */ |
var $_keycolumn = null; |
/** DB connection handle used for all transactions */ |
var $_dbh = null; |
/** an assoc with the names of database fields stored as properties |
in this object */ |
var $_properties = array(); |
/** an assoc with the names of the properties in this object that |
have been changed since they were fetched from the database */ |
var $_changes = array(); |
/** flag that decides if data in this object can be changed. |
objects that don't have their table's key column in their |
property lists will be flagged as read-only. */ |
var $_readonly = false; |
/** function or method that implements a validator for fields that |
are set, this validator function returns true if the field is |
valid, false if not */ |
var $_validator = null; |
// }}} |
// {{{ constructor |
/** |
* Constructor |
* |
* @param $table string the name of the database table |
* |
* @param $keycolumn mixed string with name of key column, or array of |
* strings if the table has a primary key of more than one column |
* |
* @param $dbh object database connection object |
* |
* @param $validator mixed function or method used to validate |
* each new value, called with three parameters: the name of the |
* field/column that is changing, a reference to the new value and |
* a reference to this object |
* |
*/ |
function DB_storage($table, $keycolumn, &$dbh, $validator = null) |
{ |
$this->PEAR('DB_Error'); |
$this->_table = $table; |
$this->_keycolumn = $keycolumn; |
$this->_dbh = $dbh; |
$this->_readonly = false; |
$this->_validator = $validator; |
} |
// }}} |
// {{{ _makeWhere() |
/** |
* Utility method to build a "WHERE" clause to locate ourselves in |
* the table. |
* |
* XXX future improvement: use rowids? |
* |
* @access private |
*/ |
function _makeWhere($keyval = null) |
{ |
if (is_array($this->_keycolumn)) { |
if ($keyval === null) { |
for ($i = 0; $i < sizeof($this->_keycolumn); $i++) { |
$keyval[] = $this->{$this->_keycolumn[$i]}; |
} |
} |
$whereclause = ''; |
for ($i = 0; $i < sizeof($this->_keycolumn); $i++) { |
if ($i > 0) { |
$whereclause .= ' AND '; |
} |
$whereclause .= $this->_keycolumn[$i]; |
if (is_null($keyval[$i])) { |
// there's not much point in having a NULL key, |
// but we support it anyway |
$whereclause .= ' IS NULL'; |
} else { |
$whereclause .= ' = ' . $this->_dbh->quote($keyval[$i]); |
} |
} |
} else { |
if ($keyval === null) { |
$keyval = @$this->{$this->_keycolumn}; |
} |
$whereclause = $this->_keycolumn; |
if (is_null($keyval)) { |
// there's not much point in having a NULL key, |
// but we support it anyway |
$whereclause .= ' IS NULL'; |
} else { |
$whereclause .= ' = ' . $this->_dbh->quote($keyval); |
} |
} |
return $whereclause; |
} |
// }}} |
// {{{ setup() |
/** |
* Method used to initialize a DB_storage object from the |
* configured table. |
* |
* @param $keyval mixed the key[s] of the row to fetch (string or array) |
* |
* @return int DB_OK on success, a DB error if not |
*/ |
function setup($keyval) |
{ |
$whereclause = $this->_makeWhere($keyval); |
$query = 'SELECT * FROM ' . $this->_table . ' WHERE ' . $whereclause; |
$sth = $this->_dbh->query($query); |
if (DB::isError($sth)) { |
return $sth; |
} |
$row = $sth->fetchRow(DB_FETCHMODE_ASSOC); |
if (DB::isError($row)) { |
return $row; |
} |
if (!$row) { |
return $this->raiseError(null, DB_ERROR_NOT_FOUND, null, null, |
$query, null, true); |
} |
foreach ($row as $key => $value) { |
$this->_properties[$key] = true; |
$this->$key = $value; |
} |
return DB_OK; |
} |
// }}} |
// {{{ insert() |
/** |
* Create a new (empty) row in the configured table for this |
* object. |
*/ |
function insert($newpk) |
{ |
if (is_array($this->_keycolumn)) { |
$primarykey = $this->_keycolumn; |
} else { |
$primarykey = array($this->_keycolumn); |
} |
settype($newpk, "array"); |
for ($i = 0; $i < sizeof($primarykey); $i++) { |
$pkvals[] = $this->_dbh->quote($newpk[$i]); |
} |
$sth = $this->_dbh->query("INSERT INTO $this->_table (" . |
implode(",", $primarykey) . ") VALUES(" . |
implode(",", $pkvals) . ")"); |
if (DB::isError($sth)) { |
return $sth; |
} |
if (sizeof($newpk) == 1) { |
$newpk = $newpk[0]; |
} |
$this->setup($newpk); |
} |
// }}} |
// {{{ toString() |
/** |
* Output a simple description of this DB_storage object. |
* @return string object description |
*/ |
function toString() |
{ |
$info = strtolower(get_class($this)); |
$info .= " (table="; |
$info .= $this->_table; |
$info .= ", keycolumn="; |
if (is_array($this->_keycolumn)) { |
$info .= "(" . implode(",", $this->_keycolumn) . ")"; |
} else { |
$info .= $this->_keycolumn; |
} |
$info .= ", dbh="; |
if (is_object($this->_dbh)) { |
$info .= $this->_dbh->toString(); |
} else { |
$info .= "null"; |
} |
$info .= ")"; |
if (sizeof($this->_properties)) { |
$info .= " [loaded, key="; |
$keyname = $this->_keycolumn; |
if (is_array($keyname)) { |
$info .= "("; |
for ($i = 0; $i < sizeof($keyname); $i++) { |
if ($i > 0) { |
$info .= ","; |
} |
$info .= $this->$keyname[$i]; |
} |
$info .= ")"; |
} else { |
$info .= $this->$keyname; |
} |
$info .= "]"; |
} |
if (sizeof($this->_changes)) { |
$info .= " [modified]"; |
} |
return $info; |
} |
// }}} |
// {{{ dump() |
/** |
* Dump the contents of this object to "standard output". |
*/ |
function dump() |
{ |
foreach ($this->_properties as $prop => $foo) { |
print "$prop = "; |
print htmlentities($this->$prop); |
print "<br />\n"; |
} |
} |
// }}} |
// {{{ &create() |
/** |
* Static method used to create new DB storage objects. |
* @param $data assoc. array where the keys are the names |
* of properties/columns |
* @return object a new instance of DB_storage or a subclass of it |
*/ |
function &create($table, &$data) |
{ |
$classname = strtolower(get_class($this)); |
$obj = new $classname($table); |
foreach ($data as $name => $value) { |
$obj->_properties[$name] = true; |
$obj->$name = &$value; |
} |
return $obj; |
} |
// }}} |
// {{{ loadFromQuery() |
/** |
* Loads data into this object from the given query. If this |
* object already contains table data, changes will be saved and |
* the object re-initialized first. |
* |
* @param $query SQL query |
* |
* @param $params parameter list in case you want to use |
* prepare/execute mode |
* |
* @return int DB_OK on success, DB_WARNING_READ_ONLY if the |
* returned object is read-only (because the object's specified |
* key column was not found among the columns returned by $query), |
* or another DB error code in case of errors. |
*/ |
// XXX commented out for now |
/* |
function loadFromQuery($query, $params = null) |
{ |
if (sizeof($this->_properties)) { |
if (sizeof($this->_changes)) { |
$this->store(); |
$this->_changes = array(); |
} |
$this->_properties = array(); |
} |
$rowdata = $this->_dbh->getRow($query, DB_FETCHMODE_ASSOC, $params); |
if (DB::isError($rowdata)) { |
return $rowdata; |
} |
reset($rowdata); |
$found_keycolumn = false; |
while (list($key, $value) = each($rowdata)) { |
if ($key == $this->_keycolumn) { |
$found_keycolumn = true; |
} |
$this->_properties[$key] = true; |
$this->$key = &$value; |
unset($value); // have to unset, or all properties will |
// refer to the same value |
} |
if (!$found_keycolumn) { |
$this->_readonly = true; |
return DB_WARNING_READ_ONLY; |
} |
return DB_OK; |
} |
*/ |
// }}} |
// {{{ set() |
/** |
* Modify an attriute value. |
*/ |
function set($property, $newvalue) |
{ |
// only change if $property is known and object is not |
// read-only |
if ($this->_readonly) { |
return $this->raiseError(null, DB_WARNING_READ_ONLY, null, |
null, null, null, true); |
} |
if (@isset($this->_properties[$property])) { |
if (empty($this->_validator)) { |
$valid = true; |
} else { |
$valid = @call_user_func($this->_validator, |
$this->_table, |
$property, |
$newvalue, |
$this->$property, |
$this); |
} |
if ($valid) { |
$this->$property = $newvalue; |
if (empty($this->_changes[$property])) { |
$this->_changes[$property] = 0; |
} else { |
$this->_changes[$property]++; |
} |
} else { |
return $this->raiseError(null, DB_ERROR_INVALID, null, |
null, "invalid field: $property", |
null, true); |
} |
return true; |
} |
return $this->raiseError(null, DB_ERROR_NOSUCHFIELD, null, |
null, "unknown field: $property", |
null, true); |
} |
// }}} |
// {{{ &get() |
/** |
* Fetch an attribute value. |
* |
* @param string attribute name |
* |
* @return attribute contents, or null if the attribute name is |
* unknown |
*/ |
function &get($property) |
{ |
// only return if $property is known |
if (isset($this->_properties[$property])) { |
return $this->$property; |
} |
$tmp = null; |
return $tmp; |
} |
// }}} |
// {{{ _DB_storage() |
/** |
* Destructor, calls DB_storage::store() if there are changes |
* that are to be kept. |
*/ |
function _DB_storage() |
{ |
if (sizeof($this->_changes)) { |
$this->store(); |
} |
$this->_properties = array(); |
$this->_changes = array(); |
$this->_table = null; |
} |
// }}} |
// {{{ store() |
/** |
* Stores changes to this object in the database. |
* |
* @return DB_OK or a DB error |
*/ |
function store() |
{ |
$params = array(); |
$vars = array(); |
foreach ($this->_changes as $name => $foo) { |
$params[] = &$this->$name; |
$vars[] = $name . ' = ?'; |
} |
if ($vars) { |
$query = 'UPDATE ' . $this->_table . ' SET ' . |
implode(', ', $vars) . ' WHERE ' . |
$this->_makeWhere(); |
$stmt = $this->_dbh->prepare($query); |
$res = $this->_dbh->execute($stmt, $params); |
if (DB::isError($res)) { |
return $res; |
} |
$this->_changes = array(); |
} |
return DB_OK; |
} |
// }}} |
// {{{ remove() |
/** |
* Remove the row represented by this object from the database. |
* |
* @return mixed DB_OK or a DB error |
*/ |
function remove() |
{ |
if ($this->_readonly) { |
return $this->raiseError(null, DB_WARNING_READ_ONLY, null, |
null, null, null, true); |
} |
$query = 'DELETE FROM ' . $this->_table .' WHERE '. |
$this->_makeWhere(); |
$res = $this->_dbh->query($query); |
if (DB::isError($res)) { |
return $res; |
} |
foreach ($this->_properties as $prop => $foo) { |
unset($this->$prop); |
} |
$this->_properties = array(); |
$this->_changes = array(); |
return DB_OK; |
} |
// }}} |
} |
/* |
* Local variables: |
* tab-width: 4 |
* c-basic-offset: 4 |
* End: |
*/ |
?> |
/obs_saisons/SPIP-v1-8-3/modules/configuration/DB/mysql.php |
---|
New file |
0,0 → 1,1045 |
<?php |
/* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4: */ |
/** |
* The PEAR DB driver for PHP's mysql extension |
* for interacting with MySQL databases |
* |
* PHP versions 4 and 5 |
* |
* LICENSE: This source file is subject to version 3.0 of the PHP license |
* that is available through the world-wide-web at the following URI: |
* http://www.php.net/license/3_0.txt. If you did not receive a copy of |
* the PHP License and are unable to obtain it through the web, please |
* send a note to license@php.net so we can mail you a copy immediately. |
* |
* @category Database |
* @package DB |
* @author Stig Bakken <ssb@php.net> |
* @author Daniel Convissor <danielc@php.net> |
* @copyright 1997-2007 The PHP Group |
* @license http://www.php.net/license/3_0.txt PHP License 3.0 |
* @version CVS: $Id: mysql.php,v 1.1 2008/07/07 18:00:39 mrflos Exp $ |
* @link http://pear.php.net/package/DB |
*/ |
/** |
* Obtain the DB_common class so it can be extended from |
*/ |
require_once 'DB/common.php'; |
/** |
* The methods PEAR DB uses to interact with PHP's mysql extension |
* for interacting with MySQL databases |
* |
* These methods overload the ones declared in DB_common. |
* |
* @category Database |
* @package DB |
* @author Stig Bakken <ssb@php.net> |
* @author Daniel Convissor <danielc@php.net> |
* @copyright 1997-2007 The PHP Group |
* @license http://www.php.net/license/3_0.txt PHP License 3.0 |
* @version Release: 1.7.14RC1 |
* @link http://pear.php.net/package/DB |
*/ |
class DB_mysql extends DB_common |
{ |
// {{{ properties |
/** |
* The DB driver type (mysql, oci8, odbc, etc.) |
* @var string |
*/ |
var $phptype = 'mysql'; |
/** |
* The database syntax variant to be used (db2, access, etc.), if any |
* @var string |
*/ |
var $dbsyntax = 'mysql'; |
/** |
* The capabilities of this DB implementation |
* |
* The 'new_link' element contains the PHP version that first provided |
* new_link support for this DBMS. Contains false if it's unsupported. |
* |
* Meaning of the 'limit' element: |
* + 'emulate' = emulate with fetch row by number |
* + 'alter' = alter the query |
* + false = skip rows |
* |
* @var array |
*/ |
var $features = array( |
'limit' => 'alter', |
'new_link' => '4.2.0', |
'numrows' => true, |
'pconnect' => true, |
'prepare' => false, |
'ssl' => false, |
'transactions' => true, |
); |
/** |
* A mapping of native error codes to DB error codes |
* @var array |
*/ |
var $errorcode_map = array( |
1004 => DB_ERROR_CANNOT_CREATE, |
1005 => DB_ERROR_CANNOT_CREATE, |
1006 => DB_ERROR_CANNOT_CREATE, |
1007 => DB_ERROR_ALREADY_EXISTS, |
1008 => DB_ERROR_CANNOT_DROP, |
1022 => DB_ERROR_ALREADY_EXISTS, |
1044 => DB_ERROR_ACCESS_VIOLATION, |
1046 => DB_ERROR_NODBSELECTED, |
1048 => DB_ERROR_CONSTRAINT, |
1049 => DB_ERROR_NOSUCHDB, |
1050 => DB_ERROR_ALREADY_EXISTS, |
1051 => DB_ERROR_NOSUCHTABLE, |
1054 => DB_ERROR_NOSUCHFIELD, |
1061 => DB_ERROR_ALREADY_EXISTS, |
1062 => DB_ERROR_ALREADY_EXISTS, |
1064 => DB_ERROR_SYNTAX, |
1091 => DB_ERROR_NOT_FOUND, |
1100 => DB_ERROR_NOT_LOCKED, |
1136 => DB_ERROR_VALUE_COUNT_ON_ROW, |
1142 => DB_ERROR_ACCESS_VIOLATION, |
1146 => DB_ERROR_NOSUCHTABLE, |
1216 => DB_ERROR_CONSTRAINT, |
1217 => DB_ERROR_CONSTRAINT, |
1356 => DB_ERROR_DIVZERO, |
1451 => DB_ERROR_CONSTRAINT, |
1452 => DB_ERROR_CONSTRAINT, |
); |
/** |
* The raw database connection created by PHP |
* @var resource |
*/ |
var $connection; |
/** |
* The DSN information for connecting to a database |
* @var array |
*/ |
var $dsn = array(); |
/** |
* Should data manipulation queries be committed automatically? |
* @var bool |
* @access private |
*/ |
var $autocommit = true; |
/** |
* The quantity of transactions begun |
* |
* {@internal While this is private, it can't actually be designated |
* private in PHP 5 because it is directly accessed in the test suite.}} |
* |
* @var integer |
* @access private |
*/ |
var $transaction_opcount = 0; |
/** |
* The database specified in the DSN |
* |
* It's a fix to allow calls to different databases in the same script. |
* |
* @var string |
* @access private |
*/ |
var $_db = ''; |
// }}} |
// {{{ constructor |
/** |
* This constructor calls <kbd>$this->DB_common()</kbd> |
* |
* @return void |
*/ |
function DB_mysql() |
{ |
$this->DB_common(); |
} |
// }}} |
// {{{ connect() |
/** |
* Connect to the database server, log in and open the database |
* |
* Don't call this method directly. Use DB::connect() instead. |
* |
* PEAR DB's mysql driver supports the following extra DSN options: |
* + new_link If set to true, causes subsequent calls to connect() |
* to return a new connection link instead of the |
* existing one. WARNING: this is not portable to |
* other DBMS's. Available since PEAR DB 1.7.0. |
* + client_flags Any combination of MYSQL_CLIENT_* constants. |
* Only used if PHP is at version 4.3.0 or greater. |
* Available since PEAR DB 1.7.0. |
* |
* @param array $dsn the data source name |
* @param bool $persistent should the connection be persistent? |
* |
* @return int DB_OK on success. A DB_Error object on failure. |
*/ |
function connect($dsn, $persistent = false) |
{ |
if (!PEAR::loadExtension('mysql')) { |
return $this->raiseError(DB_ERROR_EXTENSION_NOT_FOUND); |
} |
$this->dsn = $dsn; |
if ($dsn['dbsyntax']) { |
$this->dbsyntax = $dsn['dbsyntax']; |
} |
$params = array(); |
if ($dsn['protocol'] && $dsn['protocol'] == 'unix') { |
$params[0] = ':' . $dsn['socket']; |
} else { |
$params[0] = $dsn['hostspec'] ? $dsn['hostspec'] |
: 'localhost'; |
if ($dsn['port']) { |
$params[0] .= ':' . $dsn['port']; |
} |
} |
$params[] = $dsn['username'] ? $dsn['username'] : null; |
$params[] = $dsn['password'] ? $dsn['password'] : null; |
if (!$persistent) { |
if (isset($dsn['new_link']) |
&& ($dsn['new_link'] == 'true' || $dsn['new_link'] === true)) |
{ |
$params[] = true; |
} else { |
$params[] = false; |
} |
} |
if (version_compare(phpversion(), '4.3.0', '>=')) { |
$params[] = isset($dsn['client_flags']) |
? $dsn['client_flags'] : null; |
} |
$connect_function = $persistent ? 'mysql_pconnect' : 'mysql_connect'; |
$ini = ini_get('track_errors'); |
$php_errormsg = ''; |
if ($ini) { |
$this->connection = @call_user_func_array($connect_function, |
$params); |
} else { |
@ini_set('track_errors', 1); |
$this->connection = @call_user_func_array($connect_function, |
$params); |
@ini_set('track_errors', $ini); |
} |
if (!$this->connection) { |
if (($err = @mysql_error()) != '') { |
return $this->raiseError(DB_ERROR_CONNECT_FAILED, |
null, null, null, |
$err); |
} else { |
return $this->raiseError(DB_ERROR_CONNECT_FAILED, |
null, null, null, |
$php_errormsg); |
} |
} |
if ($dsn['database']) { |
if (!@mysql_select_db($dsn['database'], $this->connection)) { |
return $this->mysqlRaiseError(); |
} |
$this->_db = $dsn['database']; |
} |
return DB_OK; |
} |
// }}} |
// {{{ disconnect() |
/** |
* Disconnects from the database server |
* |
* @return bool TRUE on success, FALSE on failure |
*/ |
function disconnect() |
{ |
$ret = @mysql_close($this->connection); |
$this->connection = null; |
return $ret; |
} |
// }}} |
// {{{ simpleQuery() |
/** |
* Sends a query to the database server |
* |
* Generally uses mysql_query(). If you want to use |
* mysql_unbuffered_query() set the "result_buffering" option to 0 using |
* setOptions(). This option was added in Release 1.7.0. |
* |
* @param string the SQL query string |
* |
* @return mixed + a PHP result resrouce for successful SELECT queries |
* + the DB_OK constant for other successful queries |
* + a DB_Error object on failure |
*/ |
function simpleQuery($query) |
{ |
$ismanip = $this->_checkManip($query); |
$this->last_query = $query; |
$query = $this->modifyQuery($query); |
if ($this->_db) { |
if (!@mysql_select_db($this->_db, $this->connection)) { |
return $this->mysqlRaiseError(DB_ERROR_NODBSELECTED); |
} |
} |
if (!$this->autocommit && $ismanip) { |
if ($this->transaction_opcount == 0) { |
$result = @mysql_query('SET AUTOCOMMIT=0', $this->connection); |
$result = @mysql_query('BEGIN', $this->connection); |
if (!$result) { |
return $this->mysqlRaiseError(); |
} |
} |
$this->transaction_opcount++; |
} |
if (!$this->options['result_buffering']) { |
$result = @mysql_unbuffered_query($query, $this->connection); |
} else { |
$result = @mysql_query($query, $this->connection); |
} |
if (!$result) { |
return $this->mysqlRaiseError(); |
} |
if (is_resource($result)) { |
return $result; |
} |
return DB_OK; |
} |
// }}} |
// {{{ nextResult() |
/** |
* Move the internal mysql result pointer to the next available result |
* |
* This method has not been implemented yet. |
* |
* @param a valid sql result resource |
* |
* @return false |
*/ |
function nextResult($result) |
{ |
return false; |
} |
// }}} |
// {{{ fetchInto() |
/** |
* Places a row from the result set into the given array |
* |
* Formating of the array and the data therein are configurable. |
* See DB_result::fetchInto() for more information. |
* |
* This method is not meant to be called directly. Use |
* DB_result::fetchInto() instead. It can't be declared "protected" |
* because DB_result is a separate object. |
* |
* @param resource $result the query result resource |
* @param array $arr the referenced array to put the data in |
* @param int $fetchmode how the resulting array should be indexed |
* @param int $rownum the row number to fetch (0 = first row) |
* |
* @return mixed DB_OK on success, NULL when the end of a result set is |
* reached or on failure |
* |
* @see DB_result::fetchInto() |
*/ |
function fetchInto($result, &$arr, $fetchmode, $rownum = null) |
{ |
if ($rownum !== null) { |
if (!@mysql_data_seek($result, $rownum)) { |
return null; |
} |
} |
if ($fetchmode & DB_FETCHMODE_ASSOC) { |
$arr = @mysql_fetch_array($result, MYSQL_ASSOC); |
if ($this->options['portability'] & DB_PORTABILITY_LOWERCASE && $arr) { |
$arr = array_change_key_case($arr, CASE_LOWER); |
} |
} else { |
$arr = @mysql_fetch_row($result); |
} |
if (!$arr) { |
return null; |
} |
if ($this->options['portability'] & DB_PORTABILITY_RTRIM) { |
/* |
* Even though this DBMS already trims output, we do this because |
* a field might have intentional whitespace at the end that |
* gets removed by DB_PORTABILITY_RTRIM under another driver. |
*/ |
$this->_rtrimArrayValues($arr); |
} |
if ($this->options['portability'] & DB_PORTABILITY_NULL_TO_EMPTY) { |
$this->_convertNullArrayValuesToEmpty($arr); |
} |
return DB_OK; |
} |
// }}} |
// {{{ freeResult() |
/** |
* Deletes the result set and frees the memory occupied by the result set |
* |
* This method is not meant to be called directly. Use |
* DB_result::free() instead. It can't be declared "protected" |
* because DB_result is a separate object. |
* |
* @param resource $result PHP's query result resource |
* |
* @return bool TRUE on success, FALSE if $result is invalid |
* |
* @see DB_result::free() |
*/ |
function freeResult($result) |
{ |
return is_resource($result) ? mysql_free_result($result) : false; |
} |
// }}} |
// {{{ numCols() |
/** |
* Gets the number of columns in a result set |
* |
* This method is not meant to be called directly. Use |
* DB_result::numCols() instead. It can't be declared "protected" |
* because DB_result is a separate object. |
* |
* @param resource $result PHP's query result resource |
* |
* @return int the number of columns. A DB_Error object on failure. |
* |
* @see DB_result::numCols() |
*/ |
function numCols($result) |
{ |
$cols = @mysql_num_fields($result); |
if (!$cols) { |
return $this->mysqlRaiseError(); |
} |
return $cols; |
} |
// }}} |
// {{{ numRows() |
/** |
* Gets the number of rows in a result set |
* |
* This method is not meant to be called directly. Use |
* DB_result::numRows() instead. It can't be declared "protected" |
* because DB_result is a separate object. |
* |
* @param resource $result PHP's query result resource |
* |
* @return int the number of rows. A DB_Error object on failure. |
* |
* @see DB_result::numRows() |
*/ |
function numRows($result) |
{ |
$rows = @mysql_num_rows($result); |
if ($rows === null) { |
return $this->mysqlRaiseError(); |
} |
return $rows; |
} |
// }}} |
// {{{ autoCommit() |
/** |
* Enables or disables automatic commits |
* |
* @param bool $onoff true turns it on, false turns it off |
* |
* @return int DB_OK on success. A DB_Error object if the driver |
* doesn't support auto-committing transactions. |
*/ |
function autoCommit($onoff = false) |
{ |
// XXX if $this->transaction_opcount > 0, we should probably |
// issue a warning here. |
$this->autocommit = $onoff ? true : false; |
return DB_OK; |
} |
// }}} |
// {{{ commit() |
/** |
* Commits the current transaction |
* |
* @return int DB_OK on success. A DB_Error object on failure. |
*/ |
function commit() |
{ |
if ($this->transaction_opcount > 0) { |
if ($this->_db) { |
if (!@mysql_select_db($this->_db, $this->connection)) { |
return $this->mysqlRaiseError(DB_ERROR_NODBSELECTED); |
} |
} |
$result = @mysql_query('COMMIT', $this->connection); |
$result = @mysql_query('SET AUTOCOMMIT=1', $this->connection); |
$this->transaction_opcount = 0; |
if (!$result) { |
return $this->mysqlRaiseError(); |
} |
} |
return DB_OK; |
} |
// }}} |
// {{{ rollback() |
/** |
* Reverts the current transaction |
* |
* @return int DB_OK on success. A DB_Error object on failure. |
*/ |
function rollback() |
{ |
if ($this->transaction_opcount > 0) { |
if ($this->_db) { |
if (!@mysql_select_db($this->_db, $this->connection)) { |
return $this->mysqlRaiseError(DB_ERROR_NODBSELECTED); |
} |
} |
$result = @mysql_query('ROLLBACK', $this->connection); |
$result = @mysql_query('SET AUTOCOMMIT=1', $this->connection); |
$this->transaction_opcount = 0; |
if (!$result) { |
return $this->mysqlRaiseError(); |
} |
} |
return DB_OK; |
} |
// }}} |
// {{{ affectedRows() |
/** |
* Determines the number of rows affected by a data maniuplation query |
* |
* 0 is returned for queries that don't manipulate data. |
* |
* @return int the number of rows. A DB_Error object on failure. |
*/ |
function affectedRows() |
{ |
if ($this->_last_query_manip) { |
return @mysql_affected_rows($this->connection); |
} else { |
return 0; |
} |
} |
// }}} |
// {{{ nextId() |
/** |
* Returns the next free id in a sequence |
* |
* @param string $seq_name name of the sequence |
* @param boolean $ondemand when true, the seqence is automatically |
* created if it does not exist |
* |
* @return int the next id number in the sequence. |
* A DB_Error object on failure. |
* |
* @see DB_common::nextID(), DB_common::getSequenceName(), |
* DB_mysql::createSequence(), DB_mysql::dropSequence() |
*/ |
function nextId($seq_name, $ondemand = true) |
{ |
$seqname = $this->getSequenceName($seq_name); |
do { |
$repeat = 0; |
$this->pushErrorHandling(PEAR_ERROR_RETURN); |
$result = $this->query("UPDATE ${seqname} ". |
'SET id=LAST_INSERT_ID(id+1)'); |
$this->popErrorHandling(); |
if ($result === DB_OK) { |
// COMMON CASE |
$id = @mysql_insert_id($this->connection); |
if ($id != 0) { |
return $id; |
} |
// EMPTY SEQ TABLE |
// Sequence table must be empty for some reason, so fill |
// it and return 1 and obtain a user-level lock |
$result = $this->getOne("SELECT GET_LOCK('${seqname}_lock',10)"); |
if (DB::isError($result)) { |
return $this->raiseError($result); |
} |
if ($result == 0) { |
// Failed to get the lock |
return $this->mysqlRaiseError(DB_ERROR_NOT_LOCKED); |
} |
// add the default value |
$result = $this->query("REPLACE INTO ${seqname} (id) VALUES (0)"); |
if (DB::isError($result)) { |
return $this->raiseError($result); |
} |
// Release the lock |
$result = $this->getOne('SELECT RELEASE_LOCK(' |
. "'${seqname}_lock')"); |
if (DB::isError($result)) { |
return $this->raiseError($result); |
} |
// We know what the result will be, so no need to try again |
return 1; |
} elseif ($ondemand && DB::isError($result) && |
$result->getCode() == DB_ERROR_NOSUCHTABLE) |
{ |
// ONDEMAND TABLE CREATION |
$result = $this->createSequence($seq_name); |
if (DB::isError($result)) { |
return $this->raiseError($result); |
} else { |
$repeat = 1; |
} |
} elseif (DB::isError($result) && |
$result->getCode() == DB_ERROR_ALREADY_EXISTS) |
{ |
// BACKWARDS COMPAT |
// see _BCsequence() comment |
$result = $this->_BCsequence($seqname); |
if (DB::isError($result)) { |
return $this->raiseError($result); |
} |
$repeat = 1; |
} |
} while ($repeat); |
return $this->raiseError($result); |
} |
// }}} |
// {{{ createSequence() |
/** |
* Creates a new sequence |
* |
* @param string $seq_name name of the new sequence |
* |
* @return int DB_OK on success. A DB_Error object on failure. |
* |
* @see DB_common::createSequence(), DB_common::getSequenceName(), |
* DB_mysql::nextID(), DB_mysql::dropSequence() |
*/ |
function createSequence($seq_name) |
{ |
$seqname = $this->getSequenceName($seq_name); |
$res = $this->query('CREATE TABLE ' . $seqname |
. ' (id INTEGER UNSIGNED AUTO_INCREMENT NOT NULL,' |
. ' PRIMARY KEY(id))'); |
if (DB::isError($res)) { |
return $res; |
} |
// insert yields value 1, nextId call will generate ID 2 |
$res = $this->query("INSERT INTO ${seqname} (id) VALUES (0)"); |
if (DB::isError($res)) { |
return $res; |
} |
// so reset to zero |
return $this->query("UPDATE ${seqname} SET id = 0"); |
} |
// }}} |
// {{{ dropSequence() |
/** |
* Deletes a sequence |
* |
* @param string $seq_name name of the sequence to be deleted |
* |
* @return int DB_OK on success. A DB_Error object on failure. |
* |
* @see DB_common::dropSequence(), DB_common::getSequenceName(), |
* DB_mysql::nextID(), DB_mysql::createSequence() |
*/ |
function dropSequence($seq_name) |
{ |
return $this->query('DROP TABLE ' . $this->getSequenceName($seq_name)); |
} |
// }}} |
// {{{ _BCsequence() |
/** |
* Backwards compatibility with old sequence emulation implementation |
* (clean up the dupes) |
* |
* @param string $seqname the sequence name to clean up |
* |
* @return bool true on success. A DB_Error object on failure. |
* |
* @access private |
*/ |
function _BCsequence($seqname) |
{ |
// Obtain a user-level lock... this will release any previous |
// application locks, but unlike LOCK TABLES, it does not abort |
// the current transaction and is much less frequently used. |
$result = $this->getOne("SELECT GET_LOCK('${seqname}_lock',10)"); |
if (DB::isError($result)) { |
return $result; |
} |
if ($result == 0) { |
// Failed to get the lock, can't do the conversion, bail |
// with a DB_ERROR_NOT_LOCKED error |
return $this->mysqlRaiseError(DB_ERROR_NOT_LOCKED); |
} |
$highest_id = $this->getOne("SELECT MAX(id) FROM ${seqname}"); |
if (DB::isError($highest_id)) { |
return $highest_id; |
} |
// This should kill all rows except the highest |
// We should probably do something if $highest_id isn't |
// numeric, but I'm at a loss as how to handle that... |
$result = $this->query('DELETE FROM ' . $seqname |
. " WHERE id <> $highest_id"); |
if (DB::isError($result)) { |
return $result; |
} |
// If another thread has been waiting for this lock, |
// it will go thru the above procedure, but will have no |
// real effect |
$result = $this->getOne("SELECT RELEASE_LOCK('${seqname}_lock')"); |
if (DB::isError($result)) { |
return $result; |
} |
return true; |
} |
// }}} |
// {{{ quoteIdentifier() |
/** |
* Quotes a string so it can be safely used as a table or column name |
* (WARNING: using names that require this is a REALLY BAD IDEA) |
* |
* WARNING: Older versions of MySQL can't handle the backtick |
* character (<kbd>`</kbd>) in table or column names. |
* |
* @param string $str identifier name to be quoted |
* |
* @return string quoted identifier string |
* |
* @see DB_common::quoteIdentifier() |
* @since Method available since Release 1.6.0 |
*/ |
function quoteIdentifier($str) |
{ |
return '`' . str_replace('`', '``', $str) . '`'; |
} |
// }}} |
// {{{ quote() |
/** |
* @deprecated Deprecated in release 1.6.0 |
*/ |
function quote($str) |
{ |
return $this->quoteSmart($str); |
} |
// }}} |
// {{{ escapeSimple() |
/** |
* Escapes a string according to the current DBMS's standards |
* |
* @param string $str the string to be escaped |
* |
* @return string the escaped string |
* |
* @see DB_common::quoteSmart() |
* @since Method available since Release 1.6.0 |
*/ |
function escapeSimple($str) |
{ |
if (function_exists('mysql_real_escape_string')) { |
return @mysql_real_escape_string($str, $this->connection); |
} else { |
return @mysql_escape_string($str); |
} |
} |
// }}} |
// {{{ modifyQuery() |
/** |
* Changes a query string for various DBMS specific reasons |
* |
* This little hack lets you know how many rows were deleted |
* when running a "DELETE FROM table" query. Only implemented |
* if the DB_PORTABILITY_DELETE_COUNT portability option is on. |
* |
* @param string $query the query string to modify |
* |
* @return string the modified query string |
* |
* @access protected |
* @see DB_common::setOption() |
*/ |
function modifyQuery($query) |
{ |
if ($this->options['portability'] & DB_PORTABILITY_DELETE_COUNT) { |
// "DELETE FROM table" gives 0 affected rows in MySQL. |
// This little hack lets you know how many rows were deleted. |
if (preg_match('/^\s*DELETE\s+FROM\s+(\S+)\s*$/i', $query)) { |
$query = preg_replace('/^\s*DELETE\s+FROM\s+(\S+)\s*$/', |
'DELETE FROM \1 WHERE 1=1', $query); |
} |
} |
return $query; |
} |
// }}} |
// {{{ modifyLimitQuery() |
/** |
* Adds LIMIT clauses to a query string according to current DBMS standards |
* |
* @param string $query the query to modify |
* @param int $from the row to start to fetching (0 = the first row) |
* @param int $count the numbers of rows to fetch |
* @param mixed $params array, string or numeric data to be used in |
* execution of the statement. Quantity of items |
* passed must match quantity of placeholders in |
* query: meaning 1 placeholder for non-array |
* parameters or 1 placeholder per array element. |
* |
* @return string the query string with LIMIT clauses added |
* |
* @access protected |
*/ |
function modifyLimitQuery($query, $from, $count, $params = array()) |
{ |
if (DB::isManip($query) || $this->_next_query_manip) { |
return $query . " LIMIT $count"; |
} else { |
return $query . " LIMIT $from, $count"; |
} |
} |
// }}} |
// {{{ mysqlRaiseError() |
/** |
* Produces a DB_Error object regarding the current problem |
* |
* @param int $errno if the error is being manually raised pass a |
* DB_ERROR* constant here. If this isn't passed |
* the error information gathered from the DBMS. |
* |
* @return object the DB_Error object |
* |
* @see DB_common::raiseError(), |
* DB_mysql::errorNative(), DB_common::errorCode() |
*/ |
function mysqlRaiseError($errno = null) |
{ |
if ($errno === null) { |
if ($this->options['portability'] & DB_PORTABILITY_ERRORS) { |
$this->errorcode_map[1022] = DB_ERROR_CONSTRAINT; |
$this->errorcode_map[1048] = DB_ERROR_CONSTRAINT_NOT_NULL; |
$this->errorcode_map[1062] = DB_ERROR_CONSTRAINT; |
} else { |
// Doing this in case mode changes during runtime. |
$this->errorcode_map[1022] = DB_ERROR_ALREADY_EXISTS; |
$this->errorcode_map[1048] = DB_ERROR_CONSTRAINT; |
$this->errorcode_map[1062] = DB_ERROR_ALREADY_EXISTS; |
} |
$errno = $this->errorCode(mysql_errno($this->connection)); |
} |
return $this->raiseError($errno, null, null, null, |
@mysql_errno($this->connection) . ' ** ' . |
@mysql_error($this->connection)); |
} |
// }}} |
// {{{ errorNative() |
/** |
* Gets the DBMS' native error code produced by the last query |
* |
* @return int the DBMS' error code |
*/ |
function errorNative() |
{ |
return @mysql_errno($this->connection); |
} |
// }}} |
// {{{ tableInfo() |
/** |
* Returns information about a table or a result set |
* |
* @param object|string $result DB_result object from a query or a |
* string containing the name of a table. |
* While this also accepts a query result |
* resource identifier, this behavior is |
* deprecated. |
* @param int $mode a valid tableInfo mode |
* |
* @return array an associative array with the information requested. |
* A DB_Error object on failure. |
* |
* @see DB_common::tableInfo() |
*/ |
function tableInfo($result, $mode = null) |
{ |
if (is_string($result)) { |
// Fix for bug #11580. |
if ($this->_db) { |
if (!@mysql_select_db($this->_db, $this->connection)) { |
return $this->mysqlRaiseError(DB_ERROR_NODBSELECTED); |
} |
} |
/* |
* Probably received a table name. |
* Create a result resource identifier. |
*/ |
$id = @mysql_query("SELECT * FROM $result LIMIT 0", |
$this->connection); |
$got_string = true; |
} elseif (isset($result->result)) { |
/* |
* Probably received a result object. |
* Extract the result resource identifier. |
*/ |
$id = $result->result; |
$got_string = false; |
} else { |
/* |
* Probably received a result resource identifier. |
* Copy it. |
* Deprecated. Here for compatibility only. |
*/ |
$id = $result; |
$got_string = false; |
} |
if (!is_resource($id)) { |
return $this->mysqlRaiseError(DB_ERROR_NEED_MORE_DATA); |
} |
if ($this->options['portability'] & DB_PORTABILITY_LOWERCASE) { |
$case_func = 'strtolower'; |
} else { |
$case_func = 'strval'; |
} |
$count = @mysql_num_fields($id); |
$res = array(); |
if ($mode) { |
$res['num_fields'] = $count; |
} |
for ($i = 0; $i < $count; $i++) { |
$res[$i] = array( |
'table' => $case_func(@mysql_field_table($id, $i)), |
'name' => $case_func(@mysql_field_name($id, $i)), |
'type' => @mysql_field_type($id, $i), |
'len' => @mysql_field_len($id, $i), |
'flags' => @mysql_field_flags($id, $i), |
); |
if ($mode & DB_TABLEINFO_ORDER) { |
$res['order'][$res[$i]['name']] = $i; |
} |
if ($mode & DB_TABLEINFO_ORDERTABLE) { |
$res['ordertable'][$res[$i]['table']][$res[$i]['name']] = $i; |
} |
} |
// free the result only if we were called on a table |
if ($got_string) { |
@mysql_free_result($id); |
} |
return $res; |
} |
// }}} |
// {{{ getSpecialQuery() |
/** |
* Obtains the query string needed for listing a given type of objects |
* |
* @param string $type the kind of objects you want to retrieve |
* |
* @return string the SQL query string or null if the driver doesn't |
* support the object type requested |
* |
* @access protected |
* @see DB_common::getListOf() |
*/ |
function getSpecialQuery($type) |
{ |
switch ($type) { |
case 'tables': |
return 'SHOW TABLES'; |
case 'users': |
return 'SELECT DISTINCT User FROM mysql.user'; |
case 'databases': |
return 'SHOW DATABASES'; |
default: |
return null; |
} |
} |
// }}} |
} |
/* |
* Local variables: |
* tab-width: 4 |
* c-basic-offset: 4 |
* End: |
*/ |
?> |
/obs_saisons/SPIP-v1-8-3/modules/configuration/DB/ifx.php |
---|
New file |
0,0 → 1,683 |
<?php |
/* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4: */ |
/** |
* The PEAR DB driver for PHP's ifx extension |
* for interacting with Informix databases |
* |
* PHP versions 4 and 5 |
* |
* LICENSE: This source file is subject to version 3.0 of the PHP license |
* that is available through the world-wide-web at the following URI: |
* http://www.php.net/license/3_0.txt. If you did not receive a copy of |
* the PHP License and are unable to obtain it through the web, please |
* send a note to license@php.net so we can mail you a copy immediately. |
* |
* @category Database |
* @package DB |
* @author Tomas V.V.Cox <cox@idecnet.com> |
* @author Daniel Convissor <danielc@php.net> |
* @copyright 1997-2007 The PHP Group |
* @license http://www.php.net/license/3_0.txt PHP License 3.0 |
* @version CVS: $Id: ifx.php,v 1.1 2008/07/07 18:00:39 mrflos Exp $ |
* @link http://pear.php.net/package/DB |
*/ |
/** |
* Obtain the DB_common class so it can be extended from |
*/ |
require_once 'DB/common.php'; |
/** |
* The methods PEAR DB uses to interact with PHP's ifx extension |
* for interacting with Informix databases |
* |
* These methods overload the ones declared in DB_common. |
* |
* More info on Informix errors can be found at: |
* http://www.informix.com/answers/english/ierrors.htm |
* |
* TODO: |
* - set needed env Informix vars on connect |
* - implement native prepare/execute |
* |
* @category Database |
* @package DB |
* @author Tomas V.V.Cox <cox@idecnet.com> |
* @author Daniel Convissor <danielc@php.net> |
* @copyright 1997-2007 The PHP Group |
* @license http://www.php.net/license/3_0.txt PHP License 3.0 |
* @version Release: 1.7.14RC1 |
* @link http://pear.php.net/package/DB |
*/ |
class DB_ifx extends DB_common |
{ |
// {{{ properties |
/** |
* The DB driver type (mysql, oci8, odbc, etc.) |
* @var string |
*/ |
var $phptype = 'ifx'; |
/** |
* The database syntax variant to be used (db2, access, etc.), if any |
* @var string |
*/ |
var $dbsyntax = 'ifx'; |
/** |
* The capabilities of this DB implementation |
* |
* The 'new_link' element contains the PHP version that first provided |
* new_link support for this DBMS. Contains false if it's unsupported. |
* |
* Meaning of the 'limit' element: |
* + 'emulate' = emulate with fetch row by number |
* + 'alter' = alter the query |
* + false = skip rows |
* |
* @var array |
*/ |
var $features = array( |
'limit' => 'emulate', |
'new_link' => false, |
'numrows' => 'emulate', |
'pconnect' => true, |
'prepare' => false, |
'ssl' => false, |
'transactions' => true, |
); |
/** |
* A mapping of native error codes to DB error codes |
* @var array |
*/ |
var $errorcode_map = array( |
'-201' => DB_ERROR_SYNTAX, |
'-206' => DB_ERROR_NOSUCHTABLE, |
'-217' => DB_ERROR_NOSUCHFIELD, |
'-236' => DB_ERROR_VALUE_COUNT_ON_ROW, |
'-239' => DB_ERROR_CONSTRAINT, |
'-253' => DB_ERROR_SYNTAX, |
'-268' => DB_ERROR_CONSTRAINT, |
'-292' => DB_ERROR_CONSTRAINT_NOT_NULL, |
'-310' => DB_ERROR_ALREADY_EXISTS, |
'-316' => DB_ERROR_ALREADY_EXISTS, |
'-319' => DB_ERROR_NOT_FOUND, |
'-329' => DB_ERROR_NODBSELECTED, |
'-346' => DB_ERROR_CONSTRAINT, |
'-386' => DB_ERROR_CONSTRAINT_NOT_NULL, |
'-391' => DB_ERROR_CONSTRAINT_NOT_NULL, |
'-554' => DB_ERROR_SYNTAX, |
'-691' => DB_ERROR_CONSTRAINT, |
'-692' => DB_ERROR_CONSTRAINT, |
'-703' => DB_ERROR_CONSTRAINT_NOT_NULL, |
'-1202' => DB_ERROR_DIVZERO, |
'-1204' => DB_ERROR_INVALID_DATE, |
'-1205' => DB_ERROR_INVALID_DATE, |
'-1206' => DB_ERROR_INVALID_DATE, |
'-1209' => DB_ERROR_INVALID_DATE, |
'-1210' => DB_ERROR_INVALID_DATE, |
'-1212' => DB_ERROR_INVALID_DATE, |
'-1213' => DB_ERROR_INVALID_NUMBER, |
); |
/** |
* The raw database connection created by PHP |
* @var resource |
*/ |
var $connection; |
/** |
* The DSN information for connecting to a database |
* @var array |
*/ |
var $dsn = array(); |
/** |
* Should data manipulation queries be committed automatically? |
* @var bool |
* @access private |
*/ |
var $autocommit = true; |
/** |
* The quantity of transactions begun |
* |
* {@internal While this is private, it can't actually be designated |
* private in PHP 5 because it is directly accessed in the test suite.}} |
* |
* @var integer |
* @access private |
*/ |
var $transaction_opcount = 0; |
/** |
* The number of rows affected by a data manipulation query |
* @var integer |
* @access private |
*/ |
var $affected = 0; |
// }}} |
// {{{ constructor |
/** |
* This constructor calls <kbd>$this->DB_common()</kbd> |
* |
* @return void |
*/ |
function DB_ifx() |
{ |
$this->DB_common(); |
} |
// }}} |
// {{{ connect() |
/** |
* Connect to the database server, log in and open the database |
* |
* Don't call this method directly. Use DB::connect() instead. |
* |
* @param array $dsn the data source name |
* @param bool $persistent should the connection be persistent? |
* |
* @return int DB_OK on success. A DB_Error object on failure. |
*/ |
function connect($dsn, $persistent = false) |
{ |
if (!PEAR::loadExtension('informix') && |
!PEAR::loadExtension('Informix')) |
{ |
return $this->raiseError(DB_ERROR_EXTENSION_NOT_FOUND); |
} |
$this->dsn = $dsn; |
if ($dsn['dbsyntax']) { |
$this->dbsyntax = $dsn['dbsyntax']; |
} |
$dbhost = $dsn['hostspec'] ? '@' . $dsn['hostspec'] : ''; |
$dbname = $dsn['database'] ? $dsn['database'] . $dbhost : ''; |
$user = $dsn['username'] ? $dsn['username'] : ''; |
$pw = $dsn['password'] ? $dsn['password'] : ''; |
$connect_function = $persistent ? 'ifx_pconnect' : 'ifx_connect'; |
$this->connection = @$connect_function($dbname, $user, $pw); |
if (!is_resource($this->connection)) { |
return $this->ifxRaiseError(DB_ERROR_CONNECT_FAILED); |
} |
return DB_OK; |
} |
// }}} |
// {{{ disconnect() |
/** |
* Disconnects from the database server |
* |
* @return bool TRUE on success, FALSE on failure |
*/ |
function disconnect() |
{ |
$ret = @ifx_close($this->connection); |
$this->connection = null; |
return $ret; |
} |
// }}} |
// {{{ simpleQuery() |
/** |
* Sends a query to the database server |
* |
* @param string the SQL query string |
* |
* @return mixed + a PHP result resrouce for successful SELECT queries |
* + the DB_OK constant for other successful queries |
* + a DB_Error object on failure |
*/ |
function simpleQuery($query) |
{ |
$ismanip = $this->_checkManip($query); |
$this->last_query = $query; |
$this->affected = null; |
if (preg_match('/(SELECT|EXECUTE)/i', $query)) { //TESTME: Use !DB::isManip()? |
// the scroll is needed for fetching absolute row numbers |
// in a select query result |
$result = @ifx_query($query, $this->connection, IFX_SCROLL); |
} else { |
if (!$this->autocommit && $ismanip) { |
if ($this->transaction_opcount == 0) { |
$result = @ifx_query('BEGIN WORK', $this->connection); |
if (!$result) { |
return $this->ifxRaiseError(); |
} |
} |
$this->transaction_opcount++; |
} |
$result = @ifx_query($query, $this->connection); |
} |
if (!$result) { |
return $this->ifxRaiseError(); |
} |
$this->affected = @ifx_affected_rows($result); |
// Determine which queries should return data, and which |
// should return an error code only. |
if (preg_match('/(SELECT|EXECUTE)/i', $query)) { |
return $result; |
} |
// XXX Testme: free results inside a transaction |
// may cause to stop it and commit the work? |
// Result has to be freed even with a insert or update |
@ifx_free_result($result); |
return DB_OK; |
} |
// }}} |
// {{{ nextResult() |
/** |
* Move the internal ifx result pointer to the next available result |
* |
* @param a valid fbsql result resource |
* |
* @access public |
* |
* @return true if a result is available otherwise return false |
*/ |
function nextResult($result) |
{ |
return false; |
} |
// }}} |
// {{{ affectedRows() |
/** |
* Determines the number of rows affected by a data maniuplation query |
* |
* 0 is returned for queries that don't manipulate data. |
* |
* @return int the number of rows. A DB_Error object on failure. |
*/ |
function affectedRows() |
{ |
if ($this->_last_query_manip) { |
return $this->affected; |
} else { |
return 0; |
} |
} |
// }}} |
// {{{ fetchInto() |
/** |
* Places a row from the result set into the given array |
* |
* Formating of the array and the data therein are configurable. |
* See DB_result::fetchInto() for more information. |
* |
* This method is not meant to be called directly. Use |
* DB_result::fetchInto() instead. It can't be declared "protected" |
* because DB_result is a separate object. |
* |
* @param resource $result the query result resource |
* @param array $arr the referenced array to put the data in |
* @param int $fetchmode how the resulting array should be indexed |
* @param int $rownum the row number to fetch (0 = first row) |
* |
* @return mixed DB_OK on success, NULL when the end of a result set is |
* reached or on failure |
* |
* @see DB_result::fetchInto() |
*/ |
function fetchInto($result, &$arr, $fetchmode, $rownum = null) |
{ |
if (($rownum !== null) && ($rownum < 0)) { |
return null; |
} |
if ($rownum === null) { |
/* |
* Even though fetch_row() should return the next row if |
* $rownum is null, it doesn't in all cases. Bug 598. |
*/ |
$rownum = 'NEXT'; |
} else { |
// Index starts at row 1, unlike most DBMS's starting at 0. |
$rownum++; |
} |
if (!$arr = @ifx_fetch_row($result, $rownum)) { |
return null; |
} |
if ($fetchmode !== DB_FETCHMODE_ASSOC) { |
$i=0; |
$order = array(); |
foreach ($arr as $val) { |
$order[$i++] = $val; |
} |
$arr = $order; |
} elseif ($fetchmode == DB_FETCHMODE_ASSOC && |
$this->options['portability'] & DB_PORTABILITY_LOWERCASE) |
{ |
$arr = array_change_key_case($arr, CASE_LOWER); |
} |
if ($this->options['portability'] & DB_PORTABILITY_RTRIM) { |
$this->_rtrimArrayValues($arr); |
} |
if ($this->options['portability'] & DB_PORTABILITY_NULL_TO_EMPTY) { |
$this->_convertNullArrayValuesToEmpty($arr); |
} |
return DB_OK; |
} |
// }}} |
// {{{ numCols() |
/** |
* Gets the number of columns in a result set |
* |
* This method is not meant to be called directly. Use |
* DB_result::numCols() instead. It can't be declared "protected" |
* because DB_result is a separate object. |
* |
* @param resource $result PHP's query result resource |
* |
* @return int the number of columns. A DB_Error object on failure. |
* |
* @see DB_result::numCols() |
*/ |
function numCols($result) |
{ |
if (!$cols = @ifx_num_fields($result)) { |
return $this->ifxRaiseError(); |
} |
return $cols; |
} |
// }}} |
// {{{ freeResult() |
/** |
* Deletes the result set and frees the memory occupied by the result set |
* |
* This method is not meant to be called directly. Use |
* DB_result::free() instead. It can't be declared "protected" |
* because DB_result is a separate object. |
* |
* @param resource $result PHP's query result resource |
* |
* @return bool TRUE on success, FALSE if $result is invalid |
* |
* @see DB_result::free() |
*/ |
function freeResult($result) |
{ |
return is_resource($result) ? ifx_free_result($result) : false; |
} |
// }}} |
// {{{ autoCommit() |
/** |
* Enables or disables automatic commits |
* |
* @param bool $onoff true turns it on, false turns it off |
* |
* @return int DB_OK on success. A DB_Error object if the driver |
* doesn't support auto-committing transactions. |
*/ |
function autoCommit($onoff = true) |
{ |
// XXX if $this->transaction_opcount > 0, we should probably |
// issue a warning here. |
$this->autocommit = $onoff ? true : false; |
return DB_OK; |
} |
// }}} |
// {{{ commit() |
/** |
* Commits the current transaction |
* |
* @return int DB_OK on success. A DB_Error object on failure. |
*/ |
function commit() |
{ |
if ($this->transaction_opcount > 0) { |
$result = @ifx_query('COMMIT WORK', $this->connection); |
$this->transaction_opcount = 0; |
if (!$result) { |
return $this->ifxRaiseError(); |
} |
} |
return DB_OK; |
} |
// }}} |
// {{{ rollback() |
/** |
* Reverts the current transaction |
* |
* @return int DB_OK on success. A DB_Error object on failure. |
*/ |
function rollback() |
{ |
if ($this->transaction_opcount > 0) { |
$result = @ifx_query('ROLLBACK WORK', $this->connection); |
$this->transaction_opcount = 0; |
if (!$result) { |
return $this->ifxRaiseError(); |
} |
} |
return DB_OK; |
} |
// }}} |
// {{{ ifxRaiseError() |
/** |
* Produces a DB_Error object regarding the current problem |
* |
* @param int $errno if the error is being manually raised pass a |
* DB_ERROR* constant here. If this isn't passed |
* the error information gathered from the DBMS. |
* |
* @return object the DB_Error object |
* |
* @see DB_common::raiseError(), |
* DB_ifx::errorNative(), DB_ifx::errorCode() |
*/ |
function ifxRaiseError($errno = null) |
{ |
if ($errno === null) { |
$errno = $this->errorCode(ifx_error()); |
} |
return $this->raiseError($errno, null, null, null, |
$this->errorNative()); |
} |
// }}} |
// {{{ errorNative() |
/** |
* Gets the DBMS' native error code and message produced by the last query |
* |
* @return string the DBMS' error code and message |
*/ |
function errorNative() |
{ |
return @ifx_error() . ' ' . @ifx_errormsg(); |
} |
// }}} |
// {{{ errorCode() |
/** |
* Maps native error codes to DB's portable ones. |
* |
* Requires that the DB implementation's constructor fills |
* in the <var>$errorcode_map</var> property. |
* |
* @param string $nativecode error code returned by the database |
* @return int a portable DB error code, or DB_ERROR if this DB |
* implementation has no mapping for the given error code. |
*/ |
function errorCode($nativecode) |
{ |
if (ereg('SQLCODE=(.*)]', $nativecode, $match)) { |
$code = $match[1]; |
if (isset($this->errorcode_map[$code])) { |
return $this->errorcode_map[$code]; |
} |
} |
return DB_ERROR; |
} |
// }}} |
// {{{ tableInfo() |
/** |
* Returns information about a table or a result set |
* |
* NOTE: only supports 'table' if <var>$result</var> is a table name. |
* |
* If analyzing a query result and the result has duplicate field names, |
* an error will be raised saying |
* <samp>can't distinguish duplicate field names</samp>. |
* |
* @param object|string $result DB_result object from a query or a |
* string containing the name of a table. |
* While this also accepts a query result |
* resource identifier, this behavior is |
* deprecated. |
* @param int $mode a valid tableInfo mode |
* |
* @return array an associative array with the information requested. |
* A DB_Error object on failure. |
* |
* @see DB_common::tableInfo() |
* @since Method available since Release 1.6.0 |
*/ |
function tableInfo($result, $mode = null) |
{ |
if (is_string($result)) { |
/* |
* Probably received a table name. |
* Create a result resource identifier. |
*/ |
$id = @ifx_query("SELECT * FROM $result WHERE 1=0", |
$this->connection); |
$got_string = true; |
} elseif (isset($result->result)) { |
/* |
* Probably received a result object. |
* Extract the result resource identifier. |
*/ |
$id = $result->result; |
$got_string = false; |
} else { |
/* |
* Probably received a result resource identifier. |
* Copy it. |
*/ |
$id = $result; |
$got_string = false; |
} |
if (!is_resource($id)) { |
return $this->ifxRaiseError(DB_ERROR_NEED_MORE_DATA); |
} |
$flds = @ifx_fieldproperties($id); |
$count = @ifx_num_fields($id); |
if (count($flds) != $count) { |
return $this->raiseError("can't distinguish duplicate field names"); |
} |
if ($this->options['portability'] & DB_PORTABILITY_LOWERCASE) { |
$case_func = 'strtolower'; |
} else { |
$case_func = 'strval'; |
} |
$i = 0; |
$res = array(); |
if ($mode) { |
$res['num_fields'] = $count; |
} |
foreach ($flds as $key => $value) { |
$props = explode(';', $value); |
$res[$i] = array( |
'table' => $got_string ? $case_func($result) : '', |
'name' => $case_func($key), |
'type' => $props[0], |
'len' => $props[1], |
'flags' => $props[4] == 'N' ? 'not_null' : '', |
); |
if ($mode & DB_TABLEINFO_ORDER) { |
$res['order'][$res[$i]['name']] = $i; |
} |
if ($mode & DB_TABLEINFO_ORDERTABLE) { |
$res['ordertable'][$res[$i]['table']][$res[$i]['name']] = $i; |
} |
$i++; |
} |
// free the result only if we were called on a table |
if ($got_string) { |
@ifx_free_result($id); |
} |
return $res; |
} |
// }}} |
// {{{ getSpecialQuery() |
/** |
* Obtains the query string needed for listing a given type of objects |
* |
* @param string $type the kind of objects you want to retrieve |
* |
* @return string the SQL query string or null if the driver doesn't |
* support the object type requested |
* |
* @access protected |
* @see DB_common::getListOf() |
*/ |
function getSpecialQuery($type) |
{ |
switch ($type) { |
case 'tables': |
return 'SELECT tabname FROM systables WHERE tabid >= 100'; |
default: |
return null; |
} |
} |
// }}} |
} |
/* |
* Local variables: |
* tab-width: 4 |
* c-basic-offset: 4 |
* End: |
*/ |
?> |
/obs_saisons/SPIP-v1-8-3/modules/configuration/DB/pgsql.php |
---|
New file |
0,0 → 1,1135 |
<?php |
/* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4: */ |
/** |
* The PEAR DB driver for PHP's pgsql extension |
* for interacting with PostgreSQL databases |
* |
* PHP versions 4 and 5 |
* |
* LICENSE: This source file is subject to version 3.0 of the PHP license |
* that is available through the world-wide-web at the following URI: |
* http://www.php.net/license/3_0.txt. If you did not receive a copy of |
* the PHP License and are unable to obtain it through the web, please |
* send a note to license@php.net so we can mail you a copy immediately. |
* |
* @category Database |
* @package DB |
* @author Rui Hirokawa <hirokawa@php.net> |
* @author Stig Bakken <ssb@php.net> |
* @author Daniel Convissor <danielc@php.net> |
* @copyright 1997-2007 The PHP Group |
* @license http://www.php.net/license/3_0.txt PHP License 3.0 |
* @version CVS: $Id: pgsql.php,v 1.1 2008/07/07 18:00:39 mrflos Exp $ |
* @link http://pear.php.net/package/DB |
*/ |
/** |
* Obtain the DB_common class so it can be extended from |
*/ |
require_once 'DB/common.php'; |
/** |
* The methods PEAR DB uses to interact with PHP's pgsql extension |
* for interacting with PostgreSQL databases |
* |
* These methods overload the ones declared in DB_common. |
* |
* @category Database |
* @package DB |
* @author Rui Hirokawa <hirokawa@php.net> |
* @author Stig Bakken <ssb@php.net> |
* @author Daniel Convissor <danielc@php.net> |
* @copyright 1997-2007 The PHP Group |
* @license http://www.php.net/license/3_0.txt PHP License 3.0 |
* @version Release: 1.7.14RC1 |
* @link http://pear.php.net/package/DB |
*/ |
class DB_pgsql extends DB_common |
{ |
// {{{ properties |
/** |
* The DB driver type (mysql, oci8, odbc, etc.) |
* @var string |
*/ |
var $phptype = 'pgsql'; |
/** |
* The database syntax variant to be used (db2, access, etc.), if any |
* @var string |
*/ |
var $dbsyntax = 'pgsql'; |
/** |
* The capabilities of this DB implementation |
* |
* The 'new_link' element contains the PHP version that first provided |
* new_link support for this DBMS. Contains false if it's unsupported. |
* |
* Meaning of the 'limit' element: |
* + 'emulate' = emulate with fetch row by number |
* + 'alter' = alter the query |
* + false = skip rows |
* |
* @var array |
*/ |
var $features = array( |
'limit' => 'alter', |
'new_link' => '4.3.0', |
'numrows' => true, |
'pconnect' => true, |
'prepare' => false, |
'ssl' => true, |
'transactions' => true, |
); |
/** |
* A mapping of native error codes to DB error codes |
* @var array |
*/ |
var $errorcode_map = array( |
); |
/** |
* The raw database connection created by PHP |
* @var resource |
*/ |
var $connection; |
/** |
* The DSN information for connecting to a database |
* @var array |
*/ |
var $dsn = array(); |
/** |
* Should data manipulation queries be committed automatically? |
* @var bool |
* @access private |
*/ |
var $autocommit = true; |
/** |
* The quantity of transactions begun |
* |
* {@internal While this is private, it can't actually be designated |
* private in PHP 5 because it is directly accessed in the test suite.}} |
* |
* @var integer |
* @access private |
*/ |
var $transaction_opcount = 0; |
/** |
* The number of rows affected by a data manipulation query |
* @var integer |
*/ |
var $affected = 0; |
/** |
* The current row being looked at in fetchInto() |
* @var array |
* @access private |
*/ |
var $row = array(); |
/** |
* The number of rows in a given result set |
* @var array |
* @access private |
*/ |
var $_num_rows = array(); |
// }}} |
// {{{ constructor |
/** |
* This constructor calls <kbd>$this->DB_common()</kbd> |
* |
* @return void |
*/ |
function DB_pgsql() |
{ |
$this->DB_common(); |
} |
// }}} |
// {{{ connect() |
/** |
* Connect to the database server, log in and open the database |
* |
* Don't call this method directly. Use DB::connect() instead. |
* |
* PEAR DB's pgsql driver supports the following extra DSN options: |
* + connect_timeout How many seconds to wait for a connection to |
* be established. Available since PEAR DB 1.7.0. |
* + new_link If set to true, causes subsequent calls to |
* connect() to return a new connection link |
* instead of the existing one. WARNING: this is |
* not portable to other DBMS's. Available only |
* if PHP is >= 4.3.0 and PEAR DB is >= 1.7.0. |
* + options Command line options to be sent to the server. |
* Available since PEAR DB 1.6.4. |
* + service Specifies a service name in pg_service.conf that |
* holds additional connection parameters. |
* Available since PEAR DB 1.7.0. |
* + sslmode How should SSL be used when connecting? Values: |
* disable, allow, prefer or require. |
* Available since PEAR DB 1.7.0. |
* + tty This was used to specify where to send server |
* debug output. Available since PEAR DB 1.6.4. |
* |
* Example of connecting to a new link via a socket: |
* <code> |
* require_once 'DB.php'; |
* |
* $dsn = 'pgsql://user:pass@unix(/tmp)/dbname?new_link=true'; |
* $options = array( |
* 'portability' => DB_PORTABILITY_ALL, |
* ); |
* |
* $db = DB::connect($dsn, $options); |
* if (PEAR::isError($db)) { |
* die($db->getMessage()); |
* } |
* </code> |
* |
* @param array $dsn the data source name |
* @param bool $persistent should the connection be persistent? |
* |
* @return int DB_OK on success. A DB_Error object on failure. |
* |
* @link http://www.postgresql.org/docs/current/static/libpq.html#LIBPQ-CONNECT |
*/ |
function connect($dsn, $persistent = false) |
{ |
if (!PEAR::loadExtension('pgsql')) { |
return $this->raiseError(DB_ERROR_EXTENSION_NOT_FOUND); |
} |
$this->dsn = $dsn; |
if ($dsn['dbsyntax']) { |
$this->dbsyntax = $dsn['dbsyntax']; |
} |
$protocol = $dsn['protocol'] ? $dsn['protocol'] : 'tcp'; |
$params = array(''); |
if ($protocol == 'tcp') { |
if ($dsn['hostspec']) { |
$params[0] .= 'host=' . $dsn['hostspec']; |
} |
if ($dsn['port']) { |
$params[0] .= ' port=' . $dsn['port']; |
} |
} elseif ($protocol == 'unix') { |
// Allow for pg socket in non-standard locations. |
if ($dsn['socket']) { |
$params[0] .= 'host=' . $dsn['socket']; |
} |
if ($dsn['port']) { |
$params[0] .= ' port=' . $dsn['port']; |
} |
} |
if ($dsn['database']) { |
$params[0] .= ' dbname=\'' . addslashes($dsn['database']) . '\''; |
} |
if ($dsn['username']) { |
$params[0] .= ' user=\'' . addslashes($dsn['username']) . '\''; |
} |
if ($dsn['password']) { |
$params[0] .= ' password=\'' . addslashes($dsn['password']) . '\''; |
} |
if (!empty($dsn['options'])) { |
$params[0] .= ' options=' . $dsn['options']; |
} |
if (!empty($dsn['tty'])) { |
$params[0] .= ' tty=' . $dsn['tty']; |
} |
if (!empty($dsn['connect_timeout'])) { |
$params[0] .= ' connect_timeout=' . $dsn['connect_timeout']; |
} |
if (!empty($dsn['sslmode'])) { |
$params[0] .= ' sslmode=' . $dsn['sslmode']; |
} |
if (!empty($dsn['service'])) { |
$params[0] .= ' service=' . $dsn['service']; |
} |
if (isset($dsn['new_link']) |
&& ($dsn['new_link'] == 'true' || $dsn['new_link'] === true)) |
{ |
if (version_compare(phpversion(), '4.3.0', '>=')) { |
$params[] = PGSQL_CONNECT_FORCE_NEW; |
} |
} |
$connect_function = $persistent ? 'pg_pconnect' : 'pg_connect'; |
$ini = ini_get('track_errors'); |
$php_errormsg = ''; |
if ($ini) { |
$this->connection = @call_user_func_array($connect_function, |
$params); |
} else { |
@ini_set('track_errors', 1); |
$this->connection = @call_user_func_array($connect_function, |
$params); |
@ini_set('track_errors', $ini); |
} |
if (!$this->connection) { |
return $this->raiseError(DB_ERROR_CONNECT_FAILED, |
null, null, null, |
$php_errormsg); |
} |
return DB_OK; |
} |
// }}} |
// {{{ disconnect() |
/** |
* Disconnects from the database server |
* |
* @return bool TRUE on success, FALSE on failure |
*/ |
function disconnect() |
{ |
$ret = @pg_close($this->connection); |
$this->connection = null; |
return $ret; |
} |
// }}} |
// {{{ simpleQuery() |
/** |
* Sends a query to the database server |
* |
* @param string the SQL query string |
* |
* @return mixed + a PHP result resrouce for successful SELECT queries |
* + the DB_OK constant for other successful queries |
* + a DB_Error object on failure |
*/ |
function simpleQuery($query) |
{ |
$ismanip = $this->_checkManip($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 whether queries produce affected rows, result or nothing. |
* |
* This logic was introduced in version 1.1 of the file by ssb, |
* though the regex has been modified slightly since then. |
* |
* 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 |
*/ |
if ($ismanip) { |
$this->affected = @pg_affected_rows($result); |
return DB_OK; |
} elseif (preg_match('/^\s*\(*\s*(SELECT|EXPLAIN|FETCH|SHOW)\s/si', |
$query)) |
{ |
$this->row[(int)$result] = 0; // reset the row counter. |
$numrows = $this->numRows($result); |
if (is_object($numrows)) { |
return $numrows; |
} |
$this->_num_rows[(int)$result] = $numrows; |
$this->affected = 0; |
return $result; |
} else { |
$this->affected = 0; |
return DB_OK; |
} |
} |
// }}} |
// {{{ nextResult() |
/** |
* Move the internal pgsql result pointer to the next available result |
* |
* @param a valid fbsql result resource |
* |
* @access public |
* |
* @return true if a result is available otherwise return false |
*/ |
function nextResult($result) |
{ |
return false; |
} |
// }}} |
// {{{ fetchInto() |
/** |
* Places a row from the result set into the given array |
* |
* Formating of the array and the data therein are configurable. |
* See DB_result::fetchInto() for more information. |
* |
* This method is not meant to be called directly. Use |
* DB_result::fetchInto() instead. It can't be declared "protected" |
* because DB_result is a separate object. |
* |
* @param resource $result the query result resource |
* @param array $arr the referenced array to put the data in |
* @param int $fetchmode how the resulting array should be indexed |
* @param int $rownum the row number to fetch (0 = first row) |
* |
* @return mixed DB_OK on success, NULL when the end of a result set is |
* reached or on failure |
* |
* @see DB_result::fetchInto() |
*/ |
function fetchInto($result, &$arr, $fetchmode, $rownum = null) |
{ |
$result_int = (int)$result; |
$rownum = ($rownum !== null) ? $rownum : $this->row[$result_int]; |
if ($rownum >= $this->_num_rows[$result_int]) { |
return null; |
} |
if ($fetchmode & DB_FETCHMODE_ASSOC) { |
$arr = @pg_fetch_array($result, $rownum, PGSQL_ASSOC); |
if ($this->options['portability'] & DB_PORTABILITY_LOWERCASE && $arr) { |
$arr = array_change_key_case($arr, CASE_LOWER); |
} |
} else { |
$arr = @pg_fetch_row($result, $rownum); |
} |
if (!$arr) { |
return null; |
} |
if ($this->options['portability'] & DB_PORTABILITY_RTRIM) { |
$this->_rtrimArrayValues($arr); |
} |
if ($this->options['portability'] & DB_PORTABILITY_NULL_TO_EMPTY) { |
$this->_convertNullArrayValuesToEmpty($arr); |
} |
$this->row[$result_int] = ++$rownum; |
return DB_OK; |
} |
// }}} |
// {{{ freeResult() |
/** |
* Deletes the result set and frees the memory occupied by the result set |
* |
* This method is not meant to be called directly. Use |
* DB_result::free() instead. It can't be declared "protected" |
* because DB_result is a separate object. |
* |
* @param resource $result PHP's query result resource |
* |
* @return bool TRUE on success, FALSE if $result is invalid |
* |
* @see DB_result::free() |
*/ |
function freeResult($result) |
{ |
if (is_resource($result)) { |
unset($this->row[(int)$result]); |
unset($this->_num_rows[(int)$result]); |
$this->affected = 0; |
return @pg_freeresult($result); |
} |
return false; |
} |
// }}} |
// {{{ quote() |
/** |
* @deprecated Deprecated in release 1.6.0 |
* @internal |
*/ |
function quote($str) |
{ |
return $this->quoteSmart($str); |
} |
// }}} |
// {{{ quoteBoolean() |
/** |
* Formats a boolean value for use within a query in a locale-independent |
* manner. |
* |
* @param boolean the boolean value to be quoted. |
* @return string the quoted string. |
* @see DB_common::quoteSmart() |
* @since Method available since release 1.7.8. |
*/ |
function quoteBoolean($boolean) { |
return $boolean ? 'TRUE' : 'FALSE'; |
} |
// }}} |
// {{{ escapeSimple() |
/** |
* Escapes a string according to the current DBMS's standards |
* |
* {@internal PostgreSQL treats a backslash as an escape character, |
* so they are escaped as well. |
* |
* @param string $str the string to be escaped |
* |
* @return string the escaped string |
* |
* @see DB_common::quoteSmart() |
* @since Method available since Release 1.6.0 |
*/ |
function escapeSimple($str) |
{ |
if (function_exists('pg_escape_string')) { |
/* This fixes an undocumented BC break in PHP 5.2.0 which changed |
* the prototype of pg_escape_string. I'm not thrilled about having |
* to sniff the PHP version, quite frankly, but it's the only way |
* to deal with the problem. Revision 1.331.2.13.2.10 on |
* php-src/ext/pgsql/pgsql.c (PHP_5_2 branch) is to blame, for the |
* record. */ |
if (version_compare(PHP_VERSION, '5.2.0', '>=')) { |
return pg_escape_string($this->connection, $str); |
} else { |
return pg_escape_string($str); |
} |
} else { |
return str_replace("'", "''", str_replace('\\', '\\\\', $str)); |
} |
} |
// }}} |
// {{{ numCols() |
/** |
* Gets the number of columns in a result set |
* |
* This method is not meant to be called directly. Use |
* DB_result::numCols() instead. It can't be declared "protected" |
* because DB_result is a separate object. |
* |
* @param resource $result PHP's query result resource |
* |
* @return int the number of columns. A DB_Error object on failure. |
* |
* @see DB_result::numCols() |
*/ |
function numCols($result) |
{ |
$cols = @pg_numfields($result); |
if (!$cols) { |
return $this->pgsqlRaiseError(); |
} |
return $cols; |
} |
// }}} |
// {{{ numRows() |
/** |
* Gets the number of rows in a result set |
* |
* This method is not meant to be called directly. Use |
* DB_result::numRows() instead. It can't be declared "protected" |
* because DB_result is a separate object. |
* |
* @param resource $result PHP's query result resource |
* |
* @return int the number of rows. A DB_Error object on failure. |
* |
* @see DB_result::numRows() |
*/ |
function numRows($result) |
{ |
$rows = @pg_numrows($result); |
if ($rows === null) { |
return $this->pgsqlRaiseError(); |
} |
return $rows; |
} |
// }}} |
// {{{ autoCommit() |
/** |
* Enables or disables automatic commits |
* |
* @param bool $onoff true turns it on, false turns it off |
* |
* @return int DB_OK on success. A DB_Error object if the driver |
* doesn't support auto-committing transactions. |
*/ |
function autoCommit($onoff = false) |
{ |
// XXX if $this->transaction_opcount > 0, we should probably |
// issue a warning here. |
$this->autocommit = $onoff ? true : false; |
return DB_OK; |
} |
// }}} |
// {{{ commit() |
/** |
* Commits the current transaction |
* |
* @return int DB_OK on success. A DB_Error object on failure. |
*/ |
function commit() |
{ |
if ($this->transaction_opcount > 0) { |
// (disabled) hack to shut up error messages from libpq.a |
//@fclose(@fopen("php://stderr", "w")); |
$result = @pg_exec($this->connection, 'end;'); |
$this->transaction_opcount = 0; |
if (!$result) { |
return $this->pgsqlRaiseError(); |
} |
} |
return DB_OK; |
} |
// }}} |
// {{{ rollback() |
/** |
* Reverts the current transaction |
* |
* @return int DB_OK on success. A DB_Error object on failure. |
*/ |
function rollback() |
{ |
if ($this->transaction_opcount > 0) { |
$result = @pg_exec($this->connection, 'abort;'); |
$this->transaction_opcount = 0; |
if (!$result) { |
return $this->pgsqlRaiseError(); |
} |
} |
return DB_OK; |
} |
// }}} |
// {{{ affectedRows() |
/** |
* Determines the number of rows affected by a data maniuplation query |
* |
* 0 is returned for queries that don't manipulate data. |
* |
* @return int the number of rows. A DB_Error object on failure. |
*/ |
function affectedRows() |
{ |
return $this->affected; |
} |
// }}} |
// {{{ nextId() |
/** |
* Returns the next free id in a sequence |
* |
* @param string $seq_name name of the sequence |
* @param boolean $ondemand when true, the seqence is automatically |
* created if it does not exist |
* |
* @return int the next id number in the sequence. |
* A DB_Error object on failure. |
* |
* @see DB_common::nextID(), DB_common::getSequenceName(), |
* DB_pgsql::createSequence(), DB_pgsql::dropSequence() |
*/ |
function nextId($seq_name, $ondemand = true) |
{ |
$seqname = $this->getSequenceName($seq_name); |
$repeat = false; |
do { |
$this->pushErrorHandling(PEAR_ERROR_RETURN); |
$result = $this->query("SELECT NEXTVAL('${seqname}')"); |
$this->popErrorHandling(); |
if ($ondemand && DB::isError($result) && |
$result->getCode() == DB_ERROR_NOSUCHTABLE) { |
$repeat = true; |
$this->pushErrorHandling(PEAR_ERROR_RETURN); |
$result = $this->createSequence($seq_name); |
$this->popErrorHandling(); |
if (DB::isError($result)) { |
return $this->raiseError($result); |
} |
} else { |
$repeat = false; |
} |
} while ($repeat); |
if (DB::isError($result)) { |
return $this->raiseError($result); |
} |
$arr = $result->fetchRow(DB_FETCHMODE_ORDERED); |
$result->free(); |
return $arr[0]; |
} |
// }}} |
// {{{ createSequence() |
/** |
* Creates a new sequence |
* |
* @param string $seq_name name of the new sequence |
* |
* @return int DB_OK on success. A DB_Error object on failure. |
* |
* @see DB_common::createSequence(), DB_common::getSequenceName(), |
* DB_pgsql::nextID(), DB_pgsql::dropSequence() |
*/ |
function createSequence($seq_name) |
{ |
$seqname = $this->getSequenceName($seq_name); |
$result = $this->query("CREATE SEQUENCE ${seqname}"); |
return $result; |
} |
// }}} |
// {{{ dropSequence() |
/** |
* Deletes a sequence |
* |
* @param string $seq_name name of the sequence to be deleted |
* |
* @return int DB_OK on success. A DB_Error object on failure. |
* |
* @see DB_common::dropSequence(), DB_common::getSequenceName(), |
* DB_pgsql::nextID(), DB_pgsql::createSequence() |
*/ |
function dropSequence($seq_name) |
{ |
return $this->query('DROP SEQUENCE ' |
. $this->getSequenceName($seq_name)); |
} |
// }}} |
// {{{ modifyLimitQuery() |
/** |
* Adds LIMIT clauses to a query string according to current DBMS standards |
* |
* @param string $query the query to modify |
* @param int $from the row to start to fetching (0 = the first row) |
* @param int $count the numbers of rows to fetch |
* @param mixed $params array, string or numeric data to be used in |
* execution of the statement. Quantity of items |
* passed must match quantity of placeholders in |
* query: meaning 1 placeholder for non-array |
* parameters or 1 placeholder per array element. |
* |
* @return string the query string with LIMIT clauses added |
* |
* @access protected |
*/ |
function modifyLimitQuery($query, $from, $count, $params = array()) |
{ |
return "$query LIMIT $count OFFSET $from"; |
} |
// }}} |
// {{{ pgsqlRaiseError() |
/** |
* Produces a DB_Error object regarding the current problem |
* |
* @param int $errno if the error is being manually raised pass a |
* DB_ERROR* constant here. If this isn't passed |
* the error information gathered from the DBMS. |
* |
* @return object the DB_Error object |
* |
* @see DB_common::raiseError(), |
* DB_pgsql::errorNative(), DB_pgsql::errorCode() |
*/ |
function pgsqlRaiseError($errno = null) |
{ |
$native = $this->errorNative(); |
if (!$native) { |
$native = 'Database connection has been lost.'; |
$errno = DB_ERROR_CONNECT_FAILED; |
} |
if ($errno === null) { |
$errno = $this->errorCode($native); |
} |
return $this->raiseError($errno, null, null, null, $native); |
} |
// }}} |
// {{{ errorNative() |
/** |
* Gets the DBMS' native error message produced by the last query |
* |
* {@internal Error messages are used instead of error codes |
* in order to support older versions of PostgreSQL.}} |
* |
* @return string the DBMS' error message |
*/ |
function errorNative() |
{ |
return @pg_errormessage($this->connection); |
} |
// }}} |
// {{{ errorCode() |
/** |
* Determines PEAR::DB error code from the database's text error message. |
* |
* @param string $errormsg error message returned from the database |
* @return integer an error number from a DB error constant |
*/ |
function errorCode($errormsg) |
{ |
static $error_regexps; |
if (!isset($error_regexps)) { |
$error_regexps = array( |
'/column .* (of relation .*)?does not exist/i' |
=> DB_ERROR_NOSUCHFIELD, |
'/(relation|sequence|table).*does not exist|class .* not found/i' |
=> DB_ERROR_NOSUCHTABLE, |
'/index .* does not exist/' |
=> DB_ERROR_NOT_FOUND, |
'/relation .* already exists/i' |
=> DB_ERROR_ALREADY_EXISTS, |
'/(divide|division) by zero$/i' |
=> DB_ERROR_DIVZERO, |
'/pg_atoi: error in .*: can\'t parse /i' |
=> DB_ERROR_INVALID_NUMBER, |
'/invalid input syntax for( type)? (integer|numeric)/i' |
=> DB_ERROR_INVALID_NUMBER, |
'/value .* is out of range for type \w*int/i' |
=> DB_ERROR_INVALID_NUMBER, |
'/integer out of range/i' |
=> DB_ERROR_INVALID_NUMBER, |
'/value too long for type character/i' |
=> DB_ERROR_INVALID, |
'/attribute .* not found|relation .* does not have attribute/i' |
=> DB_ERROR_NOSUCHFIELD, |
'/column .* specified in USING clause does not exist in (left|right) table/i' |
=> DB_ERROR_NOSUCHFIELD, |
'/parser: parse error at or near/i' |
=> DB_ERROR_SYNTAX, |
'/syntax error at/' |
=> DB_ERROR_SYNTAX, |
'/column reference .* is ambiguous/i' |
=> DB_ERROR_SYNTAX, |
'/permission denied/' |
=> DB_ERROR_ACCESS_VIOLATION, |
'/violates not-null constraint/' |
=> DB_ERROR_CONSTRAINT_NOT_NULL, |
'/violates [\w ]+ constraint/' |
=> DB_ERROR_CONSTRAINT, |
'/referential integrity violation/' |
=> DB_ERROR_CONSTRAINT, |
'/more expressions than target columns/i' |
=> DB_ERROR_VALUE_COUNT_ON_ROW, |
); |
} |
foreach ($error_regexps as $regexp => $code) { |
if (preg_match($regexp, $errormsg)) { |
return $code; |
} |
} |
// Fall back to DB_ERROR if there was no mapping. |
return DB_ERROR; |
} |
// }}} |
// {{{ tableInfo() |
/** |
* Returns information about a table or a result set |
* |
* NOTE: only supports 'table' and 'flags' if <var>$result</var> |
* is a table name. |
* |
* @param object|string $result DB_result object from a query or a |
* string containing the name of a table. |
* While this also accepts a query result |
* resource identifier, this behavior is |
* deprecated. |
* @param int $mode a valid tableInfo mode |
* |
* @return array an associative array with the information requested. |
* A DB_Error object on failure. |
* |
* @see DB_common::tableInfo() |
*/ |
function tableInfo($result, $mode = null) |
{ |
if (is_string($result)) { |
/* |
* Probably received a table name. |
* Create a result resource identifier. |
*/ |
$id = @pg_exec($this->connection, "SELECT * FROM $result LIMIT 0"); |
$got_string = true; |
} elseif (isset($result->result)) { |
/* |
* Probably received a result object. |
* Extract the result resource identifier. |
*/ |
$id = $result->result; |
$got_string = false; |
} else { |
/* |
* Probably received a result resource identifier. |
* Copy it. |
* Deprecated. Here for compatibility only. |
*/ |
$id = $result; |
$got_string = false; |
} |
if (!is_resource($id)) { |
return $this->pgsqlRaiseError(DB_ERROR_NEED_MORE_DATA); |
} |
if ($this->options['portability'] & DB_PORTABILITY_LOWERCASE) { |
$case_func = 'strtolower'; |
} else { |
$case_func = 'strval'; |
} |
$count = @pg_numfields($id); |
$res = array(); |
if ($mode) { |
$res['num_fields'] = $count; |
} |
for ($i = 0; $i < $count; $i++) { |
$res[$i] = array( |
'table' => $got_string ? $case_func($result) : '', |
'name' => $case_func(@pg_fieldname($id, $i)), |
'type' => @pg_fieldtype($id, $i), |
'len' => @pg_fieldsize($id, $i), |
'flags' => $got_string |
? $this->_pgFieldFlags($id, $i, $result) |
: '', |
); |
if ($mode & DB_TABLEINFO_ORDER) { |
$res['order'][$res[$i]['name']] = $i; |
} |
if ($mode & DB_TABLEINFO_ORDERTABLE) { |
$res['ordertable'][$res[$i]['table']][$res[$i]['name']] = $i; |
} |
} |
// free the result only if we were called on a table |
if ($got_string) { |
@pg_freeresult($id); |
} |
return $res; |
} |
// }}} |
// {{{ _pgFieldFlags() |
/** |
* Get a column's flags |
* |
* Supports "not_null", "default_value", "primary_key", "unique_key" |
* and "multiple_key". The default value is passed through |
* rawurlencode() in case there are spaces in it. |
* |
* @param int $resource the PostgreSQL result identifier |
* @param int $num_field the field number |
* |
* @return string the flags |
* |
* @access private |
*/ |
function _pgFieldFlags($resource, $num_field, $table_name) |
{ |
$field_name = @pg_fieldname($resource, $num_field); |
// Check if there's a schema in $table_name and update things |
// accordingly. |
$from = 'pg_attribute f, pg_class tab, pg_type typ'; |
if (strpos($table_name, '.') !== false) { |
$from .= ', pg_namespace nsp'; |
list($schema, $table) = explode('.', $table_name); |
$tableWhere = "tab.relname = '$table' AND tab.relnamespace = nsp.oid AND nsp.nspname = '$schema'"; |
} else { |
$tableWhere = "tab.relname = '$table_name'"; |
} |
$result = @pg_exec($this->connection, "SELECT f.attnotnull, f.atthasdef |
FROM $from |
WHERE tab.relname = typ.typname |
AND typ.typrelid = f.attrelid |
AND f.attname = '$field_name' |
AND $tableWhere"); |
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 $from, pg_attrdef a |
WHERE tab.relname = typ.typname AND typ.typrelid = f.attrelid |
AND f.attrelid = a.adrelid AND f.attname = '$field_name' |
AND $tableWhere AND f.attnum = a.adnum"); |
$row = @pg_fetch_row($result, 0); |
$num = preg_replace("/'(.*)'::\w+/", "\\1", $row[0]); |
$flags .= 'default_' . rawurlencode($num) . ' '; |
} |
} else { |
$flags = ''; |
} |
$result = @pg_exec($this->connection, "SELECT i.indisunique, i.indisprimary, i.indkey |
FROM $from, pg_index i |
WHERE tab.relname = typ.typname |
AND typ.typrelid = f.attrelid |
AND f.attrelid = i.indrelid |
AND f.attname = '$field_name' |
AND $tableWhere"); |
$count = @pg_numrows($result); |
for ($i = 0; $i < $count ; $i++) { |
$row = @pg_fetch_row($result, $i); |
$keys = explode(' ', $row[2]); |
if (in_array($num_field + 1, $keys)) { |
$flags .= ($row[0] == 't' && $row[1] == 'f') ? 'unique_key ' : ''; |
$flags .= ($row[1] == 't') ? 'primary_key ' : ''; |
if (count($keys) > 1) |
$flags .= 'multiple_key '; |
} |
} |
return trim($flags); |
} |
// }}} |
// {{{ getSpecialQuery() |
/** |
* Obtains the query string needed for listing a given type of objects |
* |
* @param string $type the kind of objects you want to retrieve |
* |
* @return string the SQL query string or null if the driver doesn't |
* support the object type requested |
* |
* @access protected |
* @see DB_common::getListOf() |
*/ |
function getSpecialQuery($type) |
{ |
switch ($type) { |
case 'tables': |
return 'SELECT c.relname AS "Name"' |
. ' FROM pg_class c, pg_user u' |
. ' WHERE c.relowner = u.usesysid' |
. " AND c.relkind = 'r'" |
. ' AND NOT EXISTS' |
. ' (SELECT 1 FROM pg_views' |
. ' WHERE viewname = c.relname)' |
. " AND c.relname !~ '^(pg_|sql_)'" |
. ' UNION' |
. ' SELECT c.relname AS "Name"' |
. ' FROM pg_class c' |
. " WHERE c.relkind = 'r'" |
. ' AND NOT EXISTS' |
. ' (SELECT 1 FROM pg_views' |
. ' WHERE viewname = c.relname)' |
. ' AND NOT EXISTS' |
. ' (SELECT 1 FROM pg_user' |
. ' WHERE usesysid = c.relowner)' |
. " AND c.relname !~ '^pg_'"; |
case 'schema.tables': |
return "SELECT schemaname || '.' || tablename" |
. ' AS "Name"' |
. ' FROM pg_catalog.pg_tables' |
. ' WHERE schemaname NOT IN' |
. " ('pg_catalog', 'information_schema', 'pg_toast')"; |
case 'schema.views': |
return "SELECT schemaname || '.' || viewname from pg_views WHERE schemaname" |
. " NOT IN ('information_schema', 'pg_catalog')"; |
case 'views': |
// Table cols: viewname | viewowner | definition |
return 'SELECT viewname from pg_views WHERE schemaname' |
. " NOT IN ('information_schema', 'pg_catalog')"; |
case 'users': |
// cols: usename |usesysid|usecreatedb|usetrace|usesuper|usecatupd|passwd |valuntil |
return 'SELECT usename FROM pg_user'; |
case 'databases': |
return 'SELECT datname FROM pg_database'; |
case 'functions': |
case 'procedures': |
return 'SELECT proname FROM pg_proc WHERE proowner <> 1'; |
default: |
return null; |
} |
} |
// }}} |
// {{{ _checkManip() |
/** |
* Checks if the given query is a manipulation query. This also takes into |
* account the _next_query_manip flag and sets the _last_query_manip flag |
* (and resets _next_query_manip) according to the result. |
* |
* @param string The query to check. |
* |
* @return boolean true if the query is a manipulation query, false |
* otherwise |
* |
* @access protected |
*/ |
function _checkManip($query) |
{ |
return (preg_match('/^\s*(SAVEPOINT|RELEASE)\s+/i', $query) |
|| parent::_checkManip($query)); |
} |
} |
/* |
* Local variables: |
* tab-width: 4 |
* c-basic-offset: 4 |
* End: |
*/ |
?> |
/obs_saisons/SPIP-v1-8-3/modules/configuration/DB/sybase.php |
---|
New file |
0,0 → 1,942 |
<?php |
/* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4: */ |
/** |
* The PEAR DB driver for PHP's sybase extension |
* for interacting with Sybase databases |
* |
* PHP versions 4 and 5 |
* |
* LICENSE: This source file is subject to version 3.0 of the PHP license |
* that is available through the world-wide-web at the following URI: |
* http://www.php.net/license/3_0.txt. If you did not receive a copy of |
* the PHP License and are unable to obtain it through the web, please |
* send a note to license@php.net so we can mail you a copy immediately. |
* |
* @category Database |
* @package DB |
* @author Sterling Hughes <sterling@php.net> |
* @author Antônio Carlos Venâncio Júnior <floripa@php.net> |
* @author Daniel Convissor <danielc@php.net> |
* @copyright 1997-2007 The PHP Group |
* @license http://www.php.net/license/3_0.txt PHP License 3.0 |
* @version CVS: $Id: sybase.php,v 1.1 2008/07/07 18:00:39 mrflos Exp $ |
* @link http://pear.php.net/package/DB |
*/ |
/** |
* Obtain the DB_common class so it can be extended from |
*/ |
require_once 'DB/common.php'; |
/** |
* The methods PEAR DB uses to interact with PHP's sybase extension |
* for interacting with Sybase databases |
* |
* These methods overload the ones declared in DB_common. |
* |
* WARNING: This driver may fail with multiple connections under the |
* same user/pass/host and different databases. |
* |
* @category Database |
* @package DB |
* @author Sterling Hughes <sterling@php.net> |
* @author Antônio Carlos Venâncio Júnior <floripa@php.net> |
* @author Daniel Convissor <danielc@php.net> |
* @copyright 1997-2007 The PHP Group |
* @license http://www.php.net/license/3_0.txt PHP License 3.0 |
* @version Release: 1.7.14RC1 |
* @link http://pear.php.net/package/DB |
*/ |
class DB_sybase extends DB_common |
{ |
// {{{ properties |
/** |
* The DB driver type (mysql, oci8, odbc, etc.) |
* @var string |
*/ |
var $phptype = 'sybase'; |
/** |
* The database syntax variant to be used (db2, access, etc.), if any |
* @var string |
*/ |
var $dbsyntax = 'sybase'; |
/** |
* The capabilities of this DB implementation |
* |
* The 'new_link' element contains the PHP version that first provided |
* new_link support for this DBMS. Contains false if it's unsupported. |
* |
* Meaning of the 'limit' element: |
* + 'emulate' = emulate with fetch row by number |
* + 'alter' = alter the query |
* + false = skip rows |
* |
* @var array |
*/ |
var $features = array( |
'limit' => 'emulate', |
'new_link' => false, |
'numrows' => true, |
'pconnect' => true, |
'prepare' => false, |
'ssl' => false, |
'transactions' => true, |
); |
/** |
* A mapping of native error codes to DB error codes |
* @var array |
*/ |
var $errorcode_map = array( |
); |
/** |
* The raw database connection created by PHP |
* @var resource |
*/ |
var $connection; |
/** |
* The DSN information for connecting to a database |
* @var array |
*/ |
var $dsn = array(); |
/** |
* Should data manipulation queries be committed automatically? |
* @var bool |
* @access private |
*/ |
var $autocommit = true; |
/** |
* The quantity of transactions begun |
* |
* {@internal While this is private, it can't actually be designated |
* private in PHP 5 because it is directly accessed in the test suite.}} |
* |
* @var integer |
* @access private |
*/ |
var $transaction_opcount = 0; |
/** |
* The database specified in the DSN |
* |
* It's a fix to allow calls to different databases in the same script. |
* |
* @var string |
* @access private |
*/ |
var $_db = ''; |
// }}} |
// {{{ constructor |
/** |
* This constructor calls <kbd>$this->DB_common()</kbd> |
* |
* @return void |
*/ |
function DB_sybase() |
{ |
$this->DB_common(); |
} |
// }}} |
// {{{ connect() |
/** |
* Connect to the database server, log in and open the database |
* |
* Don't call this method directly. Use DB::connect() instead. |
* |
* PEAR DB's sybase driver supports the following extra DSN options: |
* + appname The application name to use on this connection. |
* Available since PEAR DB 1.7.0. |
* + charset The character set to use on this connection. |
* Available since PEAR DB 1.7.0. |
* |
* @param array $dsn the data source name |
* @param bool $persistent should the connection be persistent? |
* |
* @return int DB_OK on success. A DB_Error object on failure. |
*/ |
function connect($dsn, $persistent = false) |
{ |
if (!PEAR::loadExtension('sybase') && |
!PEAR::loadExtension('sybase_ct')) |
{ |
return $this->raiseError(DB_ERROR_EXTENSION_NOT_FOUND); |
} |
$this->dsn = $dsn; |
if ($dsn['dbsyntax']) { |
$this->dbsyntax = $dsn['dbsyntax']; |
} |
$dsn['hostspec'] = $dsn['hostspec'] ? $dsn['hostspec'] : 'localhost'; |
$dsn['password'] = !empty($dsn['password']) ? $dsn['password'] : false; |
$dsn['charset'] = isset($dsn['charset']) ? $dsn['charset'] : false; |
$dsn['appname'] = isset($dsn['appname']) ? $dsn['appname'] : false; |
$connect_function = $persistent ? 'sybase_pconnect' : 'sybase_connect'; |
if ($dsn['username']) { |
$this->connection = @$connect_function($dsn['hostspec'], |
$dsn['username'], |
$dsn['password'], |
$dsn['charset'], |
$dsn['appname']); |
} else { |
return $this->raiseError(DB_ERROR_CONNECT_FAILED, |
null, null, null, |
'The DSN did not contain a username.'); |
} |
if (!$this->connection) { |
return $this->raiseError(DB_ERROR_CONNECT_FAILED, |
null, null, null, |
@sybase_get_last_message()); |
} |
if ($dsn['database']) { |
if (!@sybase_select_db($dsn['database'], $this->connection)) { |
return $this->raiseError(DB_ERROR_NODBSELECTED, |
null, null, null, |
@sybase_get_last_message()); |
} |
$this->_db = $dsn['database']; |
} |
return DB_OK; |
} |
// }}} |
// {{{ disconnect() |
/** |
* Disconnects from the database server |
* |
* @return bool TRUE on success, FALSE on failure |
*/ |
function disconnect() |
{ |
$ret = @sybase_close($this->connection); |
$this->connection = null; |
return $ret; |
} |
// }}} |
// {{{ simpleQuery() |
/** |
* Sends a query to the database server |
* |
* @param string the SQL query string |
* |
* @return mixed + a PHP result resrouce for successful SELECT queries |
* + the DB_OK constant for other successful queries |
* + a DB_Error object on failure |
*/ |
function simpleQuery($query) |
{ |
$ismanip = $this->_checkManip($query); |
$this->last_query = $query; |
if ($this->_db && !@sybase_select_db($this->_db, $this->connection)) { |
return $this->sybaseRaiseError(DB_ERROR_NODBSELECTED); |
} |
$query = $this->modifyQuery($query); |
if (!$this->autocommit && $ismanip) { |
if ($this->transaction_opcount == 0) { |
$result = @sybase_query('BEGIN TRANSACTION', $this->connection); |
if (!$result) { |
return $this->sybaseRaiseError(); |
} |
} |
$this->transaction_opcount++; |
} |
$result = @sybase_query($query, $this->connection); |
if (!$result) { |
return $this->sybaseRaiseError(); |
} |
if (is_resource($result)) { |
return $result; |
} |
// Determine which queries that should return data, and which |
// should return an error code only. |
return $ismanip ? DB_OK : $result; |
} |
// }}} |
// {{{ nextResult() |
/** |
* Move the internal sybase result pointer to the next available result |
* |
* @param a valid sybase result resource |
* |
* @access public |
* |
* @return true if a result is available otherwise return false |
*/ |
function nextResult($result) |
{ |
return false; |
} |
// }}} |
// {{{ fetchInto() |
/** |
* Places a row from the result set into the given array |
* |
* Formating of the array and the data therein are configurable. |
* See DB_result::fetchInto() for more information. |
* |
* This method is not meant to be called directly. Use |
* DB_result::fetchInto() instead. It can't be declared "protected" |
* because DB_result is a separate object. |
* |
* @param resource $result the query result resource |
* @param array $arr the referenced array to put the data in |
* @param int $fetchmode how the resulting array should be indexed |
* @param int $rownum the row number to fetch (0 = first row) |
* |
* @return mixed DB_OK on success, NULL when the end of a result set is |
* reached or on failure |
* |
* @see DB_result::fetchInto() |
*/ |
function fetchInto($result, &$arr, $fetchmode, $rownum = null) |
{ |
if ($rownum !== null) { |
if (!@sybase_data_seek($result, $rownum)) { |
return null; |
} |
} |
if ($fetchmode & DB_FETCHMODE_ASSOC) { |
if (function_exists('sybase_fetch_assoc')) { |
$arr = @sybase_fetch_assoc($result); |
} else { |
if ($arr = @sybase_fetch_array($result)) { |
foreach ($arr as $key => $value) { |
if (is_int($key)) { |
unset($arr[$key]); |
} |
} |
} |
} |
if ($this->options['portability'] & DB_PORTABILITY_LOWERCASE && $arr) { |
$arr = array_change_key_case($arr, CASE_LOWER); |
} |
} else { |
$arr = @sybase_fetch_row($result); |
} |
if (!$arr) { |
return null; |
} |
if ($this->options['portability'] & DB_PORTABILITY_RTRIM) { |
$this->_rtrimArrayValues($arr); |
} |
if ($this->options['portability'] & DB_PORTABILITY_NULL_TO_EMPTY) { |
$this->_convertNullArrayValuesToEmpty($arr); |
} |
return DB_OK; |
} |
// }}} |
// {{{ freeResult() |
/** |
* Deletes the result set and frees the memory occupied by the result set |
* |
* This method is not meant to be called directly. Use |
* DB_result::free() instead. It can't be declared "protected" |
* because DB_result is a separate object. |
* |
* @param resource $result PHP's query result resource |
* |
* @return bool TRUE on success, FALSE if $result is invalid |
* |
* @see DB_result::free() |
*/ |
function freeResult($result) |
{ |
return is_resource($result) ? sybase_free_result($result) : false; |
} |
// }}} |
// {{{ numCols() |
/** |
* Gets the number of columns in a result set |
* |
* This method is not meant to be called directly. Use |
* DB_result::numCols() instead. It can't be declared "protected" |
* because DB_result is a separate object. |
* |
* @param resource $result PHP's query result resource |
* |
* @return int the number of columns. A DB_Error object on failure. |
* |
* @see DB_result::numCols() |
*/ |
function numCols($result) |
{ |
$cols = @sybase_num_fields($result); |
if (!$cols) { |
return $this->sybaseRaiseError(); |
} |
return $cols; |
} |
// }}} |
// {{{ numRows() |
/** |
* Gets the number of rows in a result set |
* |
* This method is not meant to be called directly. Use |
* DB_result::numRows() instead. It can't be declared "protected" |
* because DB_result is a separate object. |
* |
* @param resource $result PHP's query result resource |
* |
* @return int the number of rows. A DB_Error object on failure. |
* |
* @see DB_result::numRows() |
*/ |
function numRows($result) |
{ |
$rows = @sybase_num_rows($result); |
if ($rows === false) { |
return $this->sybaseRaiseError(); |
} |
return $rows; |
} |
// }}} |
// {{{ affectedRows() |
/** |
* Determines the number of rows affected by a data maniuplation query |
* |
* 0 is returned for queries that don't manipulate data. |
* |
* @return int the number of rows. A DB_Error object on failure. |
*/ |
function affectedRows() |
{ |
if ($this->_last_query_manip) { |
$result = @sybase_affected_rows($this->connection); |
} else { |
$result = 0; |
} |
return $result; |
} |
// }}} |
// {{{ nextId() |
/** |
* Returns the next free id in a sequence |
* |
* @param string $seq_name name of the sequence |
* @param boolean $ondemand when true, the seqence is automatically |
* created if it does not exist |
* |
* @return int the next id number in the sequence. |
* A DB_Error object on failure. |
* |
* @see DB_common::nextID(), DB_common::getSequenceName(), |
* DB_sybase::createSequence(), DB_sybase::dropSequence() |
*/ |
function nextId($seq_name, $ondemand = true) |
{ |
$seqname = $this->getSequenceName($seq_name); |
if ($this->_db && !@sybase_select_db($this->_db, $this->connection)) { |
return $this->sybaseRaiseError(DB_ERROR_NODBSELECTED); |
} |
$repeat = 0; |
do { |
$this->pushErrorHandling(PEAR_ERROR_RETURN); |
$result = $this->query("INSERT INTO $seqname (vapor) VALUES (0)"); |
$this->popErrorHandling(); |
if ($ondemand && DB::isError($result) && |
($result->getCode() == DB_ERROR || $result->getCode() == DB_ERROR_NOSUCHTABLE)) |
{ |
$repeat = 1; |
$result = $this->createSequence($seq_name); |
if (DB::isError($result)) { |
return $this->raiseError($result); |
} |
} elseif (!DB::isError($result)) { |
$result = $this->query("SELECT @@IDENTITY FROM $seqname"); |
$repeat = 0; |
} else { |
$repeat = false; |
} |
} while ($repeat); |
if (DB::isError($result)) { |
return $this->raiseError($result); |
} |
$result = $result->fetchRow(DB_FETCHMODE_ORDERED); |
return $result[0]; |
} |
/** |
* Creates a new sequence |
* |
* @param string $seq_name name of the new sequence |
* |
* @return int DB_OK on success. A DB_Error object on failure. |
* |
* @see DB_common::createSequence(), DB_common::getSequenceName(), |
* DB_sybase::nextID(), DB_sybase::dropSequence() |
*/ |
function createSequence($seq_name) |
{ |
return $this->query('CREATE TABLE ' |
. $this->getSequenceName($seq_name) |
. ' (id numeric(10, 0) IDENTITY NOT NULL,' |
. ' vapor int NULL)'); |
} |
// }}} |
// {{{ dropSequence() |
/** |
* Deletes a sequence |
* |
* @param string $seq_name name of the sequence to be deleted |
* |
* @return int DB_OK on success. A DB_Error object on failure. |
* |
* @see DB_common::dropSequence(), DB_common::getSequenceName(), |
* DB_sybase::nextID(), DB_sybase::createSequence() |
*/ |
function dropSequence($seq_name) |
{ |
return $this->query('DROP TABLE ' . $this->getSequenceName($seq_name)); |
} |
// }}} |
// {{{ quoteFloat() |
/** |
* Formats a float value for use within a query in a locale-independent |
* manner. |
* |
* @param float the float value to be quoted. |
* @return string the quoted string. |
* @see DB_common::quoteSmart() |
* @since Method available since release 1.7.8. |
*/ |
function quoteFloat($float) { |
return $this->escapeSimple(str_replace(',', '.', strval(floatval($float)))); |
} |
// }}} |
// {{{ autoCommit() |
/** |
* Enables or disables automatic commits |
* |
* @param bool $onoff true turns it on, false turns it off |
* |
* @return int DB_OK on success. A DB_Error object if the driver |
* doesn't support auto-committing transactions. |
*/ |
function autoCommit($onoff = false) |
{ |
// XXX if $this->transaction_opcount > 0, we should probably |
// issue a warning here. |
$this->autocommit = $onoff ? true : false; |
return DB_OK; |
} |
// }}} |
// {{{ commit() |
/** |
* Commits the current transaction |
* |
* @return int DB_OK on success. A DB_Error object on failure. |
*/ |
function commit() |
{ |
if ($this->transaction_opcount > 0) { |
if ($this->_db && !@sybase_select_db($this->_db, $this->connection)) { |
return $this->sybaseRaiseError(DB_ERROR_NODBSELECTED); |
} |
$result = @sybase_query('COMMIT', $this->connection); |
$this->transaction_opcount = 0; |
if (!$result) { |
return $this->sybaseRaiseError(); |
} |
} |
return DB_OK; |
} |
// }}} |
// {{{ rollback() |
/** |
* Reverts the current transaction |
* |
* @return int DB_OK on success. A DB_Error object on failure. |
*/ |
function rollback() |
{ |
if ($this->transaction_opcount > 0) { |
if ($this->_db && !@sybase_select_db($this->_db, $this->connection)) { |
return $this->sybaseRaiseError(DB_ERROR_NODBSELECTED); |
} |
$result = @sybase_query('ROLLBACK', $this->connection); |
$this->transaction_opcount = 0; |
if (!$result) { |
return $this->sybaseRaiseError(); |
} |
} |
return DB_OK; |
} |
// }}} |
// {{{ sybaseRaiseError() |
/** |
* Produces a DB_Error object regarding the current problem |
* |
* @param int $errno if the error is being manually raised pass a |
* DB_ERROR* constant here. If this isn't passed |
* the error information gathered from the DBMS. |
* |
* @return object the DB_Error object |
* |
* @see DB_common::raiseError(), |
* DB_sybase::errorNative(), DB_sybase::errorCode() |
*/ |
function sybaseRaiseError($errno = null) |
{ |
$native = $this->errorNative(); |
if ($errno === null) { |
$errno = $this->errorCode($native); |
} |
return $this->raiseError($errno, null, null, null, $native); |
} |
// }}} |
// {{{ errorNative() |
/** |
* Gets the DBMS' native error message produced by the last query |
* |
* @return string the DBMS' error message |
*/ |
function errorNative() |
{ |
return @sybase_get_last_message(); |
} |
// }}} |
// {{{ errorCode() |
/** |
* Determines PEAR::DB error code from the database's text error message. |
* |
* @param string $errormsg error message returned from the database |
* @return integer an error number from a DB error constant |
*/ |
function errorCode($errormsg) |
{ |
static $error_regexps; |
// PHP 5.2+ prepends the function name to $php_errormsg, so we need |
// this hack to work around it, per bug #9599. |
$errormsg = preg_replace('/^sybase[a-z_]+\(\): /', '', $errormsg); |
if (!isset($error_regexps)) { |
$error_regexps = array( |
'/Incorrect syntax near/' |
=> DB_ERROR_SYNTAX, |
'/^Unclosed quote before the character string [\"\'].*[\"\']\./' |
=> DB_ERROR_SYNTAX, |
'/Implicit conversion (from datatype|of NUMERIC value)/i' |
=> DB_ERROR_INVALID_NUMBER, |
'/Cannot drop the table [\"\'].+[\"\'], because it doesn\'t exist in the system catalogs\./' |
=> DB_ERROR_NOSUCHTABLE, |
'/Only the owner of object [\"\'].+[\"\'] or a user with System Administrator \(SA\) role can run this command\./' |
=> DB_ERROR_ACCESS_VIOLATION, |
'/^.+ permission denied on object .+, database .+, owner .+/' |
=> DB_ERROR_ACCESS_VIOLATION, |
'/^.* permission denied, database .+, owner .+/' |
=> DB_ERROR_ACCESS_VIOLATION, |
'/[^.*] not found\./' |
=> DB_ERROR_NOSUCHTABLE, |
'/There is already an object named/' |
=> DB_ERROR_ALREADY_EXISTS, |
'/Invalid column name/' |
=> DB_ERROR_NOSUCHFIELD, |
'/does not allow null values/' |
=> DB_ERROR_CONSTRAINT_NOT_NULL, |
'/Command has been aborted/' |
=> DB_ERROR_CONSTRAINT, |
'/^Cannot drop the index .* because it doesn\'t exist/i' |
=> DB_ERROR_NOT_FOUND, |
'/^There is already an index/i' |
=> DB_ERROR_ALREADY_EXISTS, |
'/^There are fewer columns in the INSERT statement than values specified/i' |
=> DB_ERROR_VALUE_COUNT_ON_ROW, |
'/Divide by zero/i' |
=> DB_ERROR_DIVZERO, |
); |
} |
foreach ($error_regexps as $regexp => $code) { |
if (preg_match($regexp, $errormsg)) { |
return $code; |
} |
} |
return DB_ERROR; |
} |
// }}} |
// {{{ tableInfo() |
/** |
* Returns information about a table or a result set |
* |
* NOTE: only supports 'table' and 'flags' if <var>$result</var> |
* is a table name. |
* |
* @param object|string $result DB_result object from a query or a |
* string containing the name of a table. |
* While this also accepts a query result |
* resource identifier, this behavior is |
* deprecated. |
* @param int $mode a valid tableInfo mode |
* |
* @return array an associative array with the information requested. |
* A DB_Error object on failure. |
* |
* @see DB_common::tableInfo() |
* @since Method available since Release 1.6.0 |
*/ |
function tableInfo($result, $mode = null) |
{ |
if (is_string($result)) { |
/* |
* Probably received a table name. |
* Create a result resource identifier. |
*/ |
if ($this->_db && !@sybase_select_db($this->_db, $this->connection)) { |
return $this->sybaseRaiseError(DB_ERROR_NODBSELECTED); |
} |
$id = @sybase_query("SELECT * FROM $result WHERE 1=0", |
$this->connection); |
$got_string = true; |
} elseif (isset($result->result)) { |
/* |
* Probably received a result object. |
* Extract the result resource identifier. |
*/ |
$id = $result->result; |
$got_string = false; |
} else { |
/* |
* Probably received a result resource identifier. |
* Copy it. |
* Deprecated. Here for compatibility only. |
*/ |
$id = $result; |
$got_string = false; |
} |
if (!is_resource($id)) { |
return $this->sybaseRaiseError(DB_ERROR_NEED_MORE_DATA); |
} |
if ($this->options['portability'] & DB_PORTABILITY_LOWERCASE) { |
$case_func = 'strtolower'; |
} else { |
$case_func = 'strval'; |
} |
$count = @sybase_num_fields($id); |
$res = array(); |
if ($mode) { |
$res['num_fields'] = $count; |
} |
for ($i = 0; $i < $count; $i++) { |
$f = @sybase_fetch_field($id, $i); |
// column_source is often blank |
$res[$i] = array( |
'table' => $got_string |
? $case_func($result) |
: $case_func($f->column_source), |
'name' => $case_func($f->name), |
'type' => $f->type, |
'len' => $f->max_length, |
'flags' => '', |
); |
if ($res[$i]['table']) { |
$res[$i]['flags'] = $this->_sybase_field_flags( |
$res[$i]['table'], $res[$i]['name']); |
} |
if ($mode & DB_TABLEINFO_ORDER) { |
$res['order'][$res[$i]['name']] = $i; |
} |
if ($mode & DB_TABLEINFO_ORDERTABLE) { |
$res['ordertable'][$res[$i]['table']][$res[$i]['name']] = $i; |
} |
} |
// free the result only if we were called on a table |
if ($got_string) { |
@sybase_free_result($id); |
} |
return $res; |
} |
// }}} |
// {{{ _sybase_field_flags() |
/** |
* Get the flags for a field |
* |
* Currently supports: |
* + <samp>unique_key</samp> (unique index, unique check or primary_key) |
* + <samp>multiple_key</samp> (multi-key index) |
* |
* @param string $table the table name |
* @param string $column the field name |
* |
* @return string space delimited string of flags. Empty string if none. |
* |
* @access private |
*/ |
function _sybase_field_flags($table, $column) |
{ |
static $tableName = null; |
static $flags = array(); |
if ($table != $tableName) { |
$flags = array(); |
$tableName = $table; |
/* We're running sp_helpindex directly because it doesn't exist in |
* older versions of ASE -- unfortunately, we can't just use |
* DB::isError() because the user may be using callback error |
* handling. */ |
$res = @sybase_query("sp_helpindex $table", $this->connection); |
if ($res === false || $res === true) { |
// Fake a valid response for BC reasons. |
return ''; |
} |
while (($val = sybase_fetch_assoc($res)) !== false) { |
if (!isset($val['index_keys'])) { |
/* No useful information returned. Break and be done with |
* it, which preserves the pre-1.7.9 behaviour. */ |
break; |
} |
$keys = explode(', ', trim($val['index_keys'])); |
if (sizeof($keys) > 1) { |
foreach ($keys as $key) { |
$this->_add_flag($flags[$key], 'multiple_key'); |
} |
} |
if (strpos($val['index_description'], 'unique')) { |
foreach ($keys as $key) { |
$this->_add_flag($flags[$key], 'unique_key'); |
} |
} |
} |
sybase_free_result($res); |
} |
if (array_key_exists($column, $flags)) { |
return(implode(' ', $flags[$column])); |
} |
return ''; |
} |
// }}} |
// {{{ _add_flag() |
/** |
* Adds a string to the flags array if the flag is not yet in there |
* - if there is no flag present the array is created |
* |
* @param array $array reference of flags array to add a value to |
* @param mixed $value value to add to the flag array |
* |
* @return void |
* |
* @access private |
*/ |
function _add_flag(&$array, $value) |
{ |
if (!is_array($array)) { |
$array = array($value); |
} elseif (!in_array($value, $array)) { |
array_push($array, $value); |
} |
} |
// }}} |
// {{{ getSpecialQuery() |
/** |
* Obtains the query string needed for listing a given type of objects |
* |
* @param string $type the kind of objects you want to retrieve |
* |
* @return string the SQL query string or null if the driver doesn't |
* support the object type requested |
* |
* @access protected |
* @see DB_common::getListOf() |
*/ |
function getSpecialQuery($type) |
{ |
switch ($type) { |
case 'tables': |
return "SELECT name FROM sysobjects WHERE type = 'U'" |
. ' ORDER BY name'; |
case 'views': |
return "SELECT name FROM sysobjects WHERE type = 'V'"; |
default: |
return null; |
} |
} |
// }}} |
} |
/* |
* Local variables: |
* tab-width: 4 |
* c-basic-offset: 4 |
* End: |
*/ |
?> |
/obs_saisons/SPIP-v1-8-3/modules/configuration/DB/fbsql.php |
---|
New file |
0,0 → 1,769 |
<?php |
/* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4: */ |
/** |
* The PEAR DB driver for PHP's fbsql extension |
* for interacting with FrontBase databases |
* |
* PHP versions 4 and 5 |
* |
* LICENSE: This source file is subject to version 3.0 of the PHP license |
* that is available through the world-wide-web at the following URI: |
* http://www.php.net/license/3_0.txt. If you did not receive a copy of |
* the PHP License and are unable to obtain it through the web, please |
* send a note to license@php.net so we can mail you a copy immediately. |
* |
* @category Database |
* @package DB |
* @author Frank M. Kromann <frank@frontbase.com> |
* @author Daniel Convissor <danielc@php.net> |
* @copyright 1997-2007 The PHP Group |
* @license http://www.php.net/license/3_0.txt PHP License 3.0 |
* @version CVS: $Id: fbsql.php,v 1.1 2008/07/07 18:00:39 mrflos Exp $ |
* @link http://pear.php.net/package/DB |
*/ |
/** |
* Obtain the DB_common class so it can be extended from |
*/ |
require_once 'DB/common.php'; |
/** |
* The methods PEAR DB uses to interact with PHP's fbsql extension |
* for interacting with FrontBase databases |
* |
* These methods overload the ones declared in DB_common. |
* |
* @category Database |
* @package DB |
* @author Frank M. Kromann <frank@frontbase.com> |
* @author Daniel Convissor <danielc@php.net> |
* @copyright 1997-2007 The PHP Group |
* @license http://www.php.net/license/3_0.txt PHP License 3.0 |
* @version Release: 1.7.14RC1 |
* @link http://pear.php.net/package/DB |
* @since Class functional since Release 1.7.0 |
*/ |
class DB_fbsql extends DB_common |
{ |
// {{{ properties |
/** |
* The DB driver type (mysql, oci8, odbc, etc.) |
* @var string |
*/ |
var $phptype = 'fbsql'; |
/** |
* The database syntax variant to be used (db2, access, etc.), if any |
* @var string |
*/ |
var $dbsyntax = 'fbsql'; |
/** |
* The capabilities of this DB implementation |
* |
* The 'new_link' element contains the PHP version that first provided |
* new_link support for this DBMS. Contains false if it's unsupported. |
* |
* Meaning of the 'limit' element: |
* + 'emulate' = emulate with fetch row by number |
* + 'alter' = alter the query |
* + false = skip rows |
* |
* @var array |
*/ |
var $features = array( |
'limit' => 'alter', |
'new_link' => false, |
'numrows' => true, |
'pconnect' => true, |
'prepare' => false, |
'ssl' => false, |
'transactions' => true, |
); |
/** |
* A mapping of native error codes to DB error codes |
* @var array |
*/ |
var $errorcode_map = array( |
22 => DB_ERROR_SYNTAX, |
85 => DB_ERROR_ALREADY_EXISTS, |
108 => DB_ERROR_SYNTAX, |
116 => DB_ERROR_NOSUCHTABLE, |
124 => DB_ERROR_VALUE_COUNT_ON_ROW, |
215 => DB_ERROR_NOSUCHFIELD, |
217 => DB_ERROR_INVALID_NUMBER, |
226 => DB_ERROR_NOSUCHFIELD, |
231 => DB_ERROR_INVALID, |
239 => DB_ERROR_TRUNCATED, |
251 => DB_ERROR_SYNTAX, |
266 => DB_ERROR_NOT_FOUND, |
357 => DB_ERROR_CONSTRAINT_NOT_NULL, |
358 => DB_ERROR_CONSTRAINT, |
360 => DB_ERROR_CONSTRAINT, |
361 => DB_ERROR_CONSTRAINT, |
); |
/** |
* The raw database connection created by PHP |
* @var resource |
*/ |
var $connection; |
/** |
* The DSN information for connecting to a database |
* @var array |
*/ |
var $dsn = array(); |
// }}} |
// {{{ constructor |
/** |
* This constructor calls <kbd>$this->DB_common()</kbd> |
* |
* @return void |
*/ |
function DB_fbsql() |
{ |
$this->DB_common(); |
} |
// }}} |
// {{{ connect() |
/** |
* Connect to the database server, log in and open the database |
* |
* Don't call this method directly. Use DB::connect() instead. |
* |
* @param array $dsn the data source name |
* @param bool $persistent should the connection be persistent? |
* |
* @return int DB_OK on success. A DB_Error object on failure. |
*/ |
function connect($dsn, $persistent = false) |
{ |
if (!PEAR::loadExtension('fbsql')) { |
return $this->raiseError(DB_ERROR_EXTENSION_NOT_FOUND); |
} |
$this->dsn = $dsn; |
if ($dsn['dbsyntax']) { |
$this->dbsyntax = $dsn['dbsyntax']; |
} |
$params = array( |
$dsn['hostspec'] ? $dsn['hostspec'] : 'localhost', |
$dsn['username'] ? $dsn['username'] : null, |
$dsn['password'] ? $dsn['password'] : null, |
); |
$connect_function = $persistent ? 'fbsql_pconnect' : 'fbsql_connect'; |
$ini = ini_get('track_errors'); |
$php_errormsg = ''; |
if ($ini) { |
$this->connection = @call_user_func_array($connect_function, |
$params); |
} else { |
@ini_set('track_errors', 1); |
$this->connection = @call_user_func_array($connect_function, |
$params); |
@ini_set('track_errors', $ini); |
} |
if (!$this->connection) { |
return $this->raiseError(DB_ERROR_CONNECT_FAILED, |
null, null, null, |
$php_errormsg); |
} |
if ($dsn['database']) { |
if (!@fbsql_select_db($dsn['database'], $this->connection)) { |
return $this->fbsqlRaiseError(); |
} |
} |
return DB_OK; |
} |
// }}} |
// {{{ disconnect() |
/** |
* Disconnects from the database server |
* |
* @return bool TRUE on success, FALSE on failure |
*/ |
function disconnect() |
{ |
$ret = @fbsql_close($this->connection); |
$this->connection = null; |
return $ret; |
} |
// }}} |
// {{{ simpleQuery() |
/** |
* Sends a query to the database server |
* |
* @param string the SQL query string |
* |
* @return mixed + a PHP result resrouce for successful SELECT queries |
* + the DB_OK constant for other successful queries |
* + a DB_Error object on failure |
*/ |
function simpleQuery($query) |
{ |
$this->last_query = $query; |
$query = $this->modifyQuery($query); |
$result = @fbsql_query("$query;", $this->connection); |
if (!$result) { |
return $this->fbsqlRaiseError(); |
} |
// Determine which queries that should return data, and which |
// should return an error code only. |
if ($this->_checkManip($query)) { |
return DB_OK; |
} |
return $result; |
} |
// }}} |
// {{{ nextResult() |
/** |
* Move the internal fbsql result pointer to the next available result |
* |
* @param a valid fbsql result resource |
* |
* @access public |
* |
* @return true if a result is available otherwise return false |
*/ |
function nextResult($result) |
{ |
return @fbsql_next_result($result); |
} |
// }}} |
// {{{ fetchInto() |
/** |
* Places a row from the result set into the given array |
* |
* Formating of the array and the data therein are configurable. |
* See DB_result::fetchInto() for more information. |
* |
* This method is not meant to be called directly. Use |
* DB_result::fetchInto() instead. It can't be declared "protected" |
* because DB_result is a separate object. |
* |
* @param resource $result the query result resource |
* @param array $arr the referenced array to put the data in |
* @param int $fetchmode how the resulting array should be indexed |
* @param int $rownum the row number to fetch (0 = first row) |
* |
* @return mixed DB_OK on success, NULL when the end of a result set is |
* reached or on failure |
* |
* @see DB_result::fetchInto() |
*/ |
function fetchInto($result, &$arr, $fetchmode, $rownum = null) |
{ |
if ($rownum !== null) { |
if (!@fbsql_data_seek($result, $rownum)) { |
return null; |
} |
} |
if ($fetchmode & DB_FETCHMODE_ASSOC) { |
$arr = @fbsql_fetch_array($result, FBSQL_ASSOC); |
if ($this->options['portability'] & DB_PORTABILITY_LOWERCASE && $arr) { |
$arr = array_change_key_case($arr, CASE_LOWER); |
} |
} else { |
$arr = @fbsql_fetch_row($result); |
} |
if (!$arr) { |
return null; |
} |
if ($this->options['portability'] & DB_PORTABILITY_RTRIM) { |
$this->_rtrimArrayValues($arr); |
} |
if ($this->options['portability'] & DB_PORTABILITY_NULL_TO_EMPTY) { |
$this->_convertNullArrayValuesToEmpty($arr); |
} |
return DB_OK; |
} |
// }}} |
// {{{ freeResult() |
/** |
* Deletes the result set and frees the memory occupied by the result set |
* |
* This method is not meant to be called directly. Use |
* DB_result::free() instead. It can't be declared "protected" |
* because DB_result is a separate object. |
* |
* @param resource $result PHP's query result resource |
* |
* @return bool TRUE on success, FALSE if $result is invalid |
* |
* @see DB_result::free() |
*/ |
function freeResult($result) |
{ |
return is_resource($result) ? fbsql_free_result($result) : false; |
} |
// }}} |
// {{{ autoCommit() |
/** |
* Enables or disables automatic commits |
* |
* @param bool $onoff true turns it on, false turns it off |
* |
* @return int DB_OK on success. A DB_Error object if the driver |
* doesn't support auto-committing transactions. |
*/ |
function autoCommit($onoff=false) |
{ |
if ($onoff) { |
$this->query("SET COMMIT TRUE"); |
} else { |
$this->query("SET COMMIT FALSE"); |
} |
} |
// }}} |
// {{{ commit() |
/** |
* Commits the current transaction |
* |
* @return int DB_OK on success. A DB_Error object on failure. |
*/ |
function commit() |
{ |
@fbsql_commit($this->connection); |
} |
// }}} |
// {{{ rollback() |
/** |
* Reverts the current transaction |
* |
* @return int DB_OK on success. A DB_Error object on failure. |
*/ |
function rollback() |
{ |
@fbsql_rollback($this->connection); |
} |
// }}} |
// {{{ numCols() |
/** |
* Gets the number of columns in a result set |
* |
* This method is not meant to be called directly. Use |
* DB_result::numCols() instead. It can't be declared "protected" |
* because DB_result is a separate object. |
* |
* @param resource $result PHP's query result resource |
* |
* @return int the number of columns. A DB_Error object on failure. |
* |
* @see DB_result::numCols() |
*/ |
function numCols($result) |
{ |
$cols = @fbsql_num_fields($result); |
if (!$cols) { |
return $this->fbsqlRaiseError(); |
} |
return $cols; |
} |
// }}} |
// {{{ numRows() |
/** |
* Gets the number of rows in a result set |
* |
* This method is not meant to be called directly. Use |
* DB_result::numRows() instead. It can't be declared "protected" |
* because DB_result is a separate object. |
* |
* @param resource $result PHP's query result resource |
* |
* @return int the number of rows. A DB_Error object on failure. |
* |
* @see DB_result::numRows() |
*/ |
function numRows($result) |
{ |
$rows = @fbsql_num_rows($result); |
if ($rows === null) { |
return $this->fbsqlRaiseError(); |
} |
return $rows; |
} |
// }}} |
// {{{ affectedRows() |
/** |
* Determines the number of rows affected by a data maniuplation query |
* |
* 0 is returned for queries that don't manipulate data. |
* |
* @return int the number of rows. A DB_Error object on failure. |
*/ |
function affectedRows() |
{ |
if ($this->_last_query_manip) { |
$result = @fbsql_affected_rows($this->connection); |
} else { |
$result = 0; |
} |
return $result; |
} |
// }}} |
// {{{ nextId() |
/** |
* Returns the next free id in a sequence |
* |
* @param string $seq_name name of the sequence |
* @param boolean $ondemand when true, the seqence is automatically |
* created if it does not exist |
* |
* @return int the next id number in the sequence. |
* A DB_Error object on failure. |
* |
* @see DB_common::nextID(), DB_common::getSequenceName(), |
* DB_fbsql::createSequence(), DB_fbsql::dropSequence() |
*/ |
function nextId($seq_name, $ondemand = true) |
{ |
$seqname = $this->getSequenceName($seq_name); |
do { |
$repeat = 0; |
$this->pushErrorHandling(PEAR_ERROR_RETURN); |
$result = $this->query('SELECT UNIQUE FROM ' . $seqname); |
$this->popErrorHandling(); |
if ($ondemand && DB::isError($result) && |
$result->getCode() == DB_ERROR_NOSUCHTABLE) { |
$repeat = 1; |
$result = $this->createSequence($seq_name); |
if (DB::isError($result)) { |
return $result; |
} |
} else { |
$repeat = 0; |
} |
} while ($repeat); |
if (DB::isError($result)) { |
return $this->fbsqlRaiseError(); |
} |
$result->fetchInto($tmp, DB_FETCHMODE_ORDERED); |
return $tmp[0]; |
} |
/** |
* Creates a new sequence |
* |
* @param string $seq_name name of the new sequence |
* |
* @return int DB_OK on success. A DB_Error object on failure. |
* |
* @see DB_common::createSequence(), DB_common::getSequenceName(), |
* DB_fbsql::nextID(), DB_fbsql::dropSequence() |
*/ |
function createSequence($seq_name) |
{ |
$seqname = $this->getSequenceName($seq_name); |
$res = $this->query('CREATE TABLE ' . $seqname |
. ' (id INTEGER NOT NULL,' |
. ' PRIMARY KEY(id))'); |
if ($res) { |
$res = $this->query('SET UNIQUE = 0 FOR ' . $seqname); |
} |
return $res; |
} |
// }}} |
// {{{ dropSequence() |
/** |
* Deletes a sequence |
* |
* @param string $seq_name name of the sequence to be deleted |
* |
* @return int DB_OK on success. A DB_Error object on failure. |
* |
* @see DB_common::dropSequence(), DB_common::getSequenceName(), |
* DB_fbsql::nextID(), DB_fbsql::createSequence() |
*/ |
function dropSequence($seq_name) |
{ |
return $this->query('DROP TABLE ' . $this->getSequenceName($seq_name) |
. ' RESTRICT'); |
} |
// }}} |
// {{{ modifyLimitQuery() |
/** |
* Adds LIMIT clauses to a query string according to current DBMS standards |
* |
* @param string $query the query to modify |
* @param int $from the row to start to fetching (0 = the first row) |
* @param int $count the numbers of rows to fetch |
* @param mixed $params array, string or numeric data to be used in |
* execution of the statement. Quantity of items |
* passed must match quantity of placeholders in |
* query: meaning 1 placeholder for non-array |
* parameters or 1 placeholder per array element. |
* |
* @return string the query string with LIMIT clauses added |
* |
* @access protected |
*/ |
function modifyLimitQuery($query, $from, $count, $params = array()) |
{ |
if (DB::isManip($query) || $this->_next_query_manip) { |
return preg_replace('/^([\s(])*SELECT/i', |
"\\1SELECT TOP($count)", $query); |
} else { |
return preg_replace('/([\s(])*SELECT/i', |
"\\1SELECT TOP($from, $count)", $query); |
} |
} |
// }}} |
// {{{ quoteBoolean() |
/** |
* Formats a boolean value for use within a query in a locale-independent |
* manner. |
* |
* @param boolean the boolean value to be quoted. |
* @return string the quoted string. |
* @see DB_common::quoteSmart() |
* @since Method available since release 1.7.8. |
*/ |
function quoteBoolean($boolean) { |
return $boolean ? 'TRUE' : 'FALSE'; |
} |
// }}} |
// {{{ quoteFloat() |
/** |
* Formats a float value for use within a query in a locale-independent |
* manner. |
* |
* @param float the float value to be quoted. |
* @return string the quoted string. |
* @see DB_common::quoteSmart() |
* @since Method available since release 1.7.8. |
*/ |
function quoteFloat($float) { |
return $this->escapeSimple(str_replace(',', '.', strval(floatval($float)))); |
} |
// }}} |
// {{{ fbsqlRaiseError() |
/** |
* Produces a DB_Error object regarding the current problem |
* |
* @param int $errno if the error is being manually raised pass a |
* DB_ERROR* constant here. If this isn't passed |
* the error information gathered from the DBMS. |
* |
* @return object the DB_Error object |
* |
* @see DB_common::raiseError(), |
* DB_fbsql::errorNative(), DB_common::errorCode() |
*/ |
function fbsqlRaiseError($errno = null) |
{ |
if ($errno === null) { |
$errno = $this->errorCode(fbsql_errno($this->connection)); |
} |
return $this->raiseError($errno, null, null, null, |
@fbsql_error($this->connection)); |
} |
// }}} |
// {{{ errorNative() |
/** |
* Gets the DBMS' native error code produced by the last query |
* |
* @return int the DBMS' error code |
*/ |
function errorNative() |
{ |
return @fbsql_errno($this->connection); |
} |
// }}} |
// {{{ tableInfo() |
/** |
* Returns information about a table or a result set |
* |
* @param object|string $result DB_result object from a query or a |
* string containing the name of a table. |
* While this also accepts a query result |
* resource identifier, this behavior is |
* deprecated. |
* @param int $mode a valid tableInfo mode |
* |
* @return array an associative array with the information requested. |
* A DB_Error object on failure. |
* |
* @see DB_common::tableInfo() |
*/ |
function tableInfo($result, $mode = null) |
{ |
if (is_string($result)) { |
/* |
* Probably received a table name. |
* Create a result resource identifier. |
*/ |
$id = @fbsql_list_fields($this->dsn['database'], |
$result, $this->connection); |
$got_string = true; |
} elseif (isset($result->result)) { |
/* |
* Probably received a result object. |
* Extract the result resource identifier. |
*/ |
$id = $result->result; |
$got_string = false; |
} else { |
/* |
* Probably received a result resource identifier. |
* Copy it. |
* Deprecated. Here for compatibility only. |
*/ |
$id = $result; |
$got_string = false; |
} |
if (!is_resource($id)) { |
return $this->fbsqlRaiseError(DB_ERROR_NEED_MORE_DATA); |
} |
if ($this->options['portability'] & DB_PORTABILITY_LOWERCASE) { |
$case_func = 'strtolower'; |
} else { |
$case_func = 'strval'; |
} |
$count = @fbsql_num_fields($id); |
$res = array(); |
if ($mode) { |
$res['num_fields'] = $count; |
} |
for ($i = 0; $i < $count; $i++) { |
$res[$i] = array( |
'table' => $case_func(@fbsql_field_table($id, $i)), |
'name' => $case_func(@fbsql_field_name($id, $i)), |
'type' => @fbsql_field_type($id, $i), |
'len' => @fbsql_field_len($id, $i), |
'flags' => @fbsql_field_flags($id, $i), |
); |
if ($mode & DB_TABLEINFO_ORDER) { |
$res['order'][$res[$i]['name']] = $i; |
} |
if ($mode & DB_TABLEINFO_ORDERTABLE) { |
$res['ordertable'][$res[$i]['table']][$res[$i]['name']] = $i; |
} |
} |
// free the result only if we were called on a table |
if ($got_string) { |
@fbsql_free_result($id); |
} |
return $res; |
} |
// }}} |
// {{{ getSpecialQuery() |
/** |
* Obtains the query string needed for listing a given type of objects |
* |
* @param string $type the kind of objects you want to retrieve |
* |
* @return string the SQL query string or null if the driver doesn't |
* support the object type requested |
* |
* @access protected |
* @see DB_common::getListOf() |
*/ |
function getSpecialQuery($type) |
{ |
switch ($type) { |
case 'tables': |
return 'SELECT "table_name" FROM information_schema.tables' |
. ' t0, information_schema.schemata t1' |
. ' WHERE t0.schema_pk=t1.schema_pk AND' |
. ' "table_type" = \'BASE TABLE\'' |
. ' AND "schema_name" = current_schema'; |
case 'views': |
return 'SELECT "table_name" FROM information_schema.tables' |
. ' t0, information_schema.schemata t1' |
. ' WHERE t0.schema_pk=t1.schema_pk AND' |
. ' "table_type" = \'VIEW\'' |
. ' AND "schema_name" = current_schema'; |
case 'users': |
return 'SELECT "user_name" from information_schema.users'; |
case 'functions': |
return 'SELECT "routine_name" FROM' |
. ' information_schema.psm_routines' |
. ' t0, information_schema.schemata t1' |
. ' WHERE t0.schema_pk=t1.schema_pk' |
. ' AND "routine_kind"=\'FUNCTION\'' |
. ' AND "schema_name" = current_schema'; |
case 'procedures': |
return 'SELECT "routine_name" FROM' |
. ' information_schema.psm_routines' |
. ' t0, information_schema.schemata t1' |
. ' WHERE t0.schema_pk=t1.schema_pk' |
. ' AND "routine_kind"=\'PROCEDURE\'' |
. ' AND "schema_name" = current_schema'; |
default: |
return null; |
} |
} |
// }}} |
} |
/* |
* Local variables: |
* tab-width: 4 |
* c-basic-offset: 4 |
* End: |
*/ |
?> |
/obs_saisons/SPIP-v1-8-3/modules/configuration/DB/odbc.php |
---|
New file |
0,0 → 1,883 |
<?php |
/* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4: */ |
/** |
* The PEAR DB driver for PHP's odbc extension |
* for interacting with databases via ODBC connections |
* |
* PHP versions 4 and 5 |
* |
* LICENSE: This source file is subject to version 3.0 of the PHP license |
* that is available through the world-wide-web at the following URI: |
* http://www.php.net/license/3_0.txt. If you did not receive a copy of |
* the PHP License and are unable to obtain it through the web, please |
* send a note to license@php.net so we can mail you a copy immediately. |
* |
* @category Database |
* @package DB |
* @author Stig Bakken <ssb@php.net> |
* @author Daniel Convissor <danielc@php.net> |
* @copyright 1997-2007 The PHP Group |
* @license http://www.php.net/license/3_0.txt PHP License 3.0 |
* @version CVS: $Id: odbc.php,v 1.1 2008/07/07 18:00:39 mrflos Exp $ |
* @link http://pear.php.net/package/DB |
*/ |
/** |
* Obtain the DB_common class so it can be extended from |
*/ |
require_once 'DB/common.php'; |
/** |
* The methods PEAR DB uses to interact with PHP's odbc extension |
* for interacting with databases via ODBC connections |
* |
* These methods overload the ones declared in DB_common. |
* |
* More info on ODBC errors could be found here: |
* http://msdn.microsoft.com/library/default.asp?url=/library/en-us/trblsql/tr_err_odbc_5stz.asp |
* |
* @category Database |
* @package DB |
* @author Stig Bakken <ssb@php.net> |
* @author Daniel Convissor <danielc@php.net> |
* @copyright 1997-2007 The PHP Group |
* @license http://www.php.net/license/3_0.txt PHP License 3.0 |
* @version Release: 1.7.14RC1 |
* @link http://pear.php.net/package/DB |
*/ |
class DB_odbc extends DB_common |
{ |
// {{{ properties |
/** |
* The DB driver type (mysql, oci8, odbc, etc.) |
* @var string |
*/ |
var $phptype = 'odbc'; |
/** |
* The database syntax variant to be used (db2, access, etc.), if any |
* @var string |
*/ |
var $dbsyntax = 'sql92'; |
/** |
* The capabilities of this DB implementation |
* |
* The 'new_link' element contains the PHP version that first provided |
* new_link support for this DBMS. Contains false if it's unsupported. |
* |
* Meaning of the 'limit' element: |
* + 'emulate' = emulate with fetch row by number |
* + 'alter' = alter the query |
* + false = skip rows |
* |
* NOTE: The feature set of the following drivers are different than |
* the default: |
* + solid: 'transactions' = true |
* + navision: 'limit' = false |
* |
* @var array |
*/ |
var $features = array( |
'limit' => 'emulate', |
'new_link' => false, |
'numrows' => true, |
'pconnect' => true, |
'prepare' => false, |
'ssl' => false, |
'transactions' => false, |
); |
/** |
* A mapping of native error codes to DB error codes |
* @var array |
*/ |
var $errorcode_map = array( |
'01004' => DB_ERROR_TRUNCATED, |
'07001' => DB_ERROR_MISMATCH, |
'21S01' => DB_ERROR_VALUE_COUNT_ON_ROW, |
'21S02' => DB_ERROR_MISMATCH, |
'22001' => DB_ERROR_INVALID, |
'22003' => DB_ERROR_INVALID_NUMBER, |
'22005' => DB_ERROR_INVALID_NUMBER, |
'22008' => DB_ERROR_INVALID_DATE, |
'22012' => DB_ERROR_DIVZERO, |
'23000' => DB_ERROR_CONSTRAINT, |
'23502' => DB_ERROR_CONSTRAINT_NOT_NULL, |
'23503' => DB_ERROR_CONSTRAINT, |
'23504' => DB_ERROR_CONSTRAINT, |
'23505' => DB_ERROR_CONSTRAINT, |
'24000' => DB_ERROR_INVALID, |
'34000' => DB_ERROR_INVALID, |
'37000' => DB_ERROR_SYNTAX, |
'42000' => DB_ERROR_SYNTAX, |
'42601' => DB_ERROR_SYNTAX, |
'IM001' => DB_ERROR_UNSUPPORTED, |
'S0000' => DB_ERROR_NOSUCHTABLE, |
'S0001' => DB_ERROR_ALREADY_EXISTS, |
'S0002' => DB_ERROR_NOSUCHTABLE, |
'S0011' => DB_ERROR_ALREADY_EXISTS, |
'S0012' => DB_ERROR_NOT_FOUND, |
'S0021' => DB_ERROR_ALREADY_EXISTS, |
'S0022' => DB_ERROR_NOSUCHFIELD, |
'S1009' => DB_ERROR_INVALID, |
'S1090' => DB_ERROR_INVALID, |
'S1C00' => DB_ERROR_NOT_CAPABLE, |
); |
/** |
* The raw database connection created by PHP |
* @var resource |
*/ |
var $connection; |
/** |
* The DSN information for connecting to a database |
* @var array |
*/ |
var $dsn = array(); |
/** |
* The number of rows affected by a data manipulation query |
* @var integer |
* @access private |
*/ |
var $affected = 0; |
// }}} |
// {{{ constructor |
/** |
* This constructor calls <kbd>$this->DB_common()</kbd> |
* |
* @return void |
*/ |
function DB_odbc() |
{ |
$this->DB_common(); |
} |
// }}} |
// {{{ connect() |
/** |
* Connect to the database server, log in and open the database |
* |
* Don't call this method directly. Use DB::connect() instead. |
* |
* PEAR DB's odbc driver supports the following extra DSN options: |
* + cursor The type of cursor to be used for this connection. |
* |
* @param array $dsn the data source name |
* @param bool $persistent should the connection be persistent? |
* |
* @return int DB_OK on success. A DB_Error object on failure. |
*/ |
function connect($dsn, $persistent = false) |
{ |
if (!PEAR::loadExtension('odbc')) { |
return $this->raiseError(DB_ERROR_EXTENSION_NOT_FOUND); |
} |
$this->dsn = $dsn; |
if ($dsn['dbsyntax']) { |
$this->dbsyntax = $dsn['dbsyntax']; |
} |
switch ($this->dbsyntax) { |
case 'access': |
case 'db2': |
case 'solid': |
$this->features['transactions'] = true; |
break; |
case 'navision': |
$this->features['limit'] = false; |
} |
/* |
* This is hear for backwards compatibility. Should have been using |
* 'database' all along, but prior to 1.6.0RC3 'hostspec' was used. |
*/ |
if ($dsn['database']) { |
$odbcdsn = $dsn['database']; |
} elseif ($dsn['hostspec']) { |
$odbcdsn = $dsn['hostspec']; |
} else { |
$odbcdsn = 'localhost'; |
} |
$connect_function = $persistent ? 'odbc_pconnect' : 'odbc_connect'; |
if (empty($dsn['cursor'])) { |
$this->connection = @$connect_function($odbcdsn, $dsn['username'], |
$dsn['password']); |
} else { |
$this->connection = @$connect_function($odbcdsn, $dsn['username'], |
$dsn['password'], |
$dsn['cursor']); |
} |
if (!is_resource($this->connection)) { |
return $this->raiseError(DB_ERROR_CONNECT_FAILED, |
null, null, null, |
$this->errorNative()); |
} |
return DB_OK; |
} |
// }}} |
// {{{ disconnect() |
/** |
* Disconnects from the database server |
* |
* @return bool TRUE on success, FALSE on failure |
*/ |
function disconnect() |
{ |
$err = @odbc_close($this->connection); |
$this->connection = null; |
return $err; |
} |
// }}} |
// {{{ simpleQuery() |
/** |
* Sends a query to the database server |
* |
* @param string the SQL query string |
* |
* @return mixed + a PHP result resrouce for successful SELECT queries |
* + the DB_OK constant for other successful queries |
* + a DB_Error object on failure |
*/ |
function simpleQuery($query) |
{ |
$this->last_query = $query; |
$query = $this->modifyQuery($query); |
$result = @odbc_exec($this->connection, $query); |
if (!$result) { |
return $this->odbcRaiseError(); // XXX ERRORMSG |
} |
// Determine which queries that should return data, and which |
// should return an error code only. |
if ($this->_checkManip($query)) { |
$this->affected = $result; // For affectedRows() |
return DB_OK; |
} |
$this->affected = 0; |
return $result; |
} |
// }}} |
// {{{ nextResult() |
/** |
* Move the internal odbc result pointer to the next available result |
* |
* @param a valid fbsql result resource |
* |
* @access public |
* |
* @return true if a result is available otherwise return false |
*/ |
function nextResult($result) |
{ |
return @odbc_next_result($result); |
} |
// }}} |
// {{{ fetchInto() |
/** |
* Places a row from the result set into the given array |
* |
* Formating of the array and the data therein are configurable. |
* See DB_result::fetchInto() for more information. |
* |
* This method is not meant to be called directly. Use |
* DB_result::fetchInto() instead. It can't be declared "protected" |
* because DB_result is a separate object. |
* |
* @param resource $result the query result resource |
* @param array $arr the referenced array to put the data in |
* @param int $fetchmode how the resulting array should be indexed |
* @param int $rownum the row number to fetch (0 = first row) |
* |
* @return mixed DB_OK on success, NULL when the end of a result set is |
* reached or on failure |
* |
* @see DB_result::fetchInto() |
*/ |
function fetchInto($result, &$arr, $fetchmode, $rownum = null) |
{ |
$arr = array(); |
if ($rownum !== null) { |
$rownum++; // ODBC first row is 1 |
if (version_compare(phpversion(), '4.2.0', 'ge')) { |
$cols = @odbc_fetch_into($result, $arr, $rownum); |
} else { |
$cols = @odbc_fetch_into($result, $rownum, $arr); |
} |
} else { |
$cols = @odbc_fetch_into($result, $arr); |
} |
if (!$cols) { |
return null; |
} |
if ($fetchmode !== DB_FETCHMODE_ORDERED) { |
for ($i = 0; $i < count($arr); $i++) { |
$colName = @odbc_field_name($result, $i+1); |
$a[$colName] = $arr[$i]; |
} |
if ($this->options['portability'] & DB_PORTABILITY_LOWERCASE) { |
$a = array_change_key_case($a, CASE_LOWER); |
} |
$arr = $a; |
} |
if ($this->options['portability'] & DB_PORTABILITY_RTRIM) { |
$this->_rtrimArrayValues($arr); |
} |
if ($this->options['portability'] & DB_PORTABILITY_NULL_TO_EMPTY) { |
$this->_convertNullArrayValuesToEmpty($arr); |
} |
return DB_OK; |
} |
// }}} |
// {{{ freeResult() |
/** |
* Deletes the result set and frees the memory occupied by the result set |
* |
* This method is not meant to be called directly. Use |
* DB_result::free() instead. It can't be declared "protected" |
* because DB_result is a separate object. |
* |
* @param resource $result PHP's query result resource |
* |
* @return bool TRUE on success, FALSE if $result is invalid |
* |
* @see DB_result::free() |
*/ |
function freeResult($result) |
{ |
return is_resource($result) ? odbc_free_result($result) : false; |
} |
// }}} |
// {{{ numCols() |
/** |
* Gets the number of columns in a result set |
* |
* This method is not meant to be called directly. Use |
* DB_result::numCols() instead. It can't be declared "protected" |
* because DB_result is a separate object. |
* |
* @param resource $result PHP's query result resource |
* |
* @return int the number of columns. A DB_Error object on failure. |
* |
* @see DB_result::numCols() |
*/ |
function numCols($result) |
{ |
$cols = @odbc_num_fields($result); |
if (!$cols) { |
return $this->odbcRaiseError(); |
} |
return $cols; |
} |
// }}} |
// {{{ affectedRows() |
/** |
* Determines the number of rows affected by a data maniuplation query |
* |
* 0 is returned for queries that don't manipulate data. |
* |
* @return int the number of rows. A DB_Error object on failure. |
*/ |
function affectedRows() |
{ |
if (empty($this->affected)) { // In case of SELECT stms |
return 0; |
} |
$nrows = @odbc_num_rows($this->affected); |
if ($nrows == -1) { |
return $this->odbcRaiseError(); |
} |
return $nrows; |
} |
// }}} |
// {{{ numRows() |
/** |
* Gets the number of rows in a result set |
* |
* Not all ODBC drivers support this functionality. If they don't |
* a DB_Error object for DB_ERROR_UNSUPPORTED is returned. |
* |
* This method is not meant to be called directly. Use |
* DB_result::numRows() instead. It can't be declared "protected" |
* because DB_result is a separate object. |
* |
* @param resource $result PHP's query result resource |
* |
* @return int the number of rows. A DB_Error object on failure. |
* |
* @see DB_result::numRows() |
*/ |
function numRows($result) |
{ |
$nrows = @odbc_num_rows($result); |
if ($nrows == -1) { |
return $this->odbcRaiseError(DB_ERROR_UNSUPPORTED); |
} |
if ($nrows === false) { |
return $this->odbcRaiseError(); |
} |
return $nrows; |
} |
// }}} |
// {{{ quoteIdentifier() |
/** |
* Quotes a string so it can be safely used as a table or column name |
* |
* Use 'mssql' as the dbsyntax in the DB DSN only if you've unchecked |
* "Use ANSI quoted identifiers" when setting up the ODBC data source. |
* |
* @param string $str identifier name to be quoted |
* |
* @return string quoted identifier string |
* |
* @see DB_common::quoteIdentifier() |
* @since Method available since Release 1.6.0 |
*/ |
function quoteIdentifier($str) |
{ |
switch ($this->dsn['dbsyntax']) { |
case 'access': |
return '[' . $str . ']'; |
case 'mssql': |
case 'sybase': |
return '[' . str_replace(']', ']]', $str) . ']'; |
case 'mysql': |
case 'mysqli': |
return '`' . $str . '`'; |
default: |
return '"' . str_replace('"', '""', $str) . '"'; |
} |
} |
// }}} |
// {{{ quote() |
/** |
* @deprecated Deprecated in release 1.6.0 |
* @internal |
*/ |
function quote($str) |
{ |
return $this->quoteSmart($str); |
} |
// }}} |
// {{{ nextId() |
/** |
* Returns the next free id in a sequence |
* |
* @param string $seq_name name of the sequence |
* @param boolean $ondemand when true, the seqence is automatically |
* created if it does not exist |
* |
* @return int the next id number in the sequence. |
* A DB_Error object on failure. |
* |
* @see DB_common::nextID(), DB_common::getSequenceName(), |
* DB_odbc::createSequence(), DB_odbc::dropSequence() |
*/ |
function nextId($seq_name, $ondemand = true) |
{ |
$seqname = $this->getSequenceName($seq_name); |
$repeat = 0; |
do { |
$this->pushErrorHandling(PEAR_ERROR_RETURN); |
$result = $this->query("update ${seqname} set id = id + 1"); |
$this->popErrorHandling(); |
if ($ondemand && DB::isError($result) && |
$result->getCode() == DB_ERROR_NOSUCHTABLE) { |
$repeat = 1; |
$this->pushErrorHandling(PEAR_ERROR_RETURN); |
$result = $this->createSequence($seq_name); |
$this->popErrorHandling(); |
if (DB::isError($result)) { |
return $this->raiseError($result); |
} |
$result = $this->query("insert into ${seqname} (id) values(0)"); |
} else { |
$repeat = 0; |
} |
} while ($repeat); |
if (DB::isError($result)) { |
return $this->raiseError($result); |
} |
$result = $this->query("select id from ${seqname}"); |
if (DB::isError($result)) { |
return $result; |
} |
$row = $result->fetchRow(DB_FETCHMODE_ORDERED); |
if (DB::isError($row || !$row)) { |
return $row; |
} |
return $row[0]; |
} |
/** |
* Creates a new sequence |
* |
* @param string $seq_name name of the new sequence |
* |
* @return int DB_OK on success. A DB_Error object on failure. |
* |
* @see DB_common::createSequence(), DB_common::getSequenceName(), |
* DB_odbc::nextID(), DB_odbc::dropSequence() |
*/ |
function createSequence($seq_name) |
{ |
return $this->query('CREATE TABLE ' |
. $this->getSequenceName($seq_name) |
. ' (id integer NOT NULL,' |
. ' PRIMARY KEY(id))'); |
} |
// }}} |
// {{{ dropSequence() |
/** |
* Deletes a sequence |
* |
* @param string $seq_name name of the sequence to be deleted |
* |
* @return int DB_OK on success. A DB_Error object on failure. |
* |
* @see DB_common::dropSequence(), DB_common::getSequenceName(), |
* DB_odbc::nextID(), DB_odbc::createSequence() |
*/ |
function dropSequence($seq_name) |
{ |
return $this->query('DROP TABLE ' . $this->getSequenceName($seq_name)); |
} |
// }}} |
// {{{ autoCommit() |
/** |
* Enables or disables automatic commits |
* |
* @param bool $onoff true turns it on, false turns it off |
* |
* @return int DB_OK on success. A DB_Error object if the driver |
* doesn't support auto-committing transactions. |
*/ |
function autoCommit($onoff = false) |
{ |
if (!@odbc_autocommit($this->connection, $onoff)) { |
return $this->odbcRaiseError(); |
} |
return DB_OK; |
} |
// }}} |
// {{{ commit() |
/** |
* Commits the current transaction |
* |
* @return int DB_OK on success. A DB_Error object on failure. |
*/ |
function commit() |
{ |
if (!@odbc_commit($this->connection)) { |
return $this->odbcRaiseError(); |
} |
return DB_OK; |
} |
// }}} |
// {{{ rollback() |
/** |
* Reverts the current transaction |
* |
* @return int DB_OK on success. A DB_Error object on failure. |
*/ |
function rollback() |
{ |
if (!@odbc_rollback($this->connection)) { |
return $this->odbcRaiseError(); |
} |
return DB_OK; |
} |
// }}} |
// {{{ odbcRaiseError() |
/** |
* Produces a DB_Error object regarding the current problem |
* |
* @param int $errno if the error is being manually raised pass a |
* DB_ERROR* constant here. If this isn't passed |
* the error information gathered from the DBMS. |
* |
* @return object the DB_Error object |
* |
* @see DB_common::raiseError(), |
* DB_odbc::errorNative(), DB_common::errorCode() |
*/ |
function odbcRaiseError($errno = null) |
{ |
if ($errno === null) { |
switch ($this->dbsyntax) { |
case 'access': |
if ($this->options['portability'] & DB_PORTABILITY_ERRORS) { |
$this->errorcode_map['07001'] = DB_ERROR_NOSUCHFIELD; |
} else { |
// Doing this in case mode changes during runtime. |
$this->errorcode_map['07001'] = DB_ERROR_MISMATCH; |
} |
$native_code = odbc_error($this->connection); |
// S1000 is for "General Error." Let's be more specific. |
if ($native_code == 'S1000') { |
$errormsg = odbc_errormsg($this->connection); |
static $error_regexps; |
if (!isset($error_regexps)) { |
$error_regexps = array( |
'/includes related records.$/i' => DB_ERROR_CONSTRAINT, |
'/cannot contain a Null value/i' => DB_ERROR_CONSTRAINT_NOT_NULL, |
); |
} |
foreach ($error_regexps as $regexp => $code) { |
if (preg_match($regexp, $errormsg)) { |
return $this->raiseError($code, |
null, null, null, |
$native_code . ' ' . $errormsg); |
} |
} |
$errno = DB_ERROR; |
} else { |
$errno = $this->errorCode($native_code); |
} |
break; |
default: |
$errno = $this->errorCode(odbc_error($this->connection)); |
} |
} |
return $this->raiseError($errno, null, null, null, |
$this->errorNative()); |
} |
// }}} |
// {{{ errorNative() |
/** |
* Gets the DBMS' native error code and message produced by the last query |
* |
* @return string the DBMS' error code and message |
*/ |
function errorNative() |
{ |
if (!is_resource($this->connection)) { |
return @odbc_error() . ' ' . @odbc_errormsg(); |
} |
return @odbc_error($this->connection) . ' ' . @odbc_errormsg($this->connection); |
} |
// }}} |
// {{{ tableInfo() |
/** |
* Returns information about a table or a result set |
* |
* @param object|string $result DB_result object from a query or a |
* string containing the name of a table. |
* While this also accepts a query result |
* resource identifier, this behavior is |
* deprecated. |
* @param int $mode a valid tableInfo mode |
* |
* @return array an associative array with the information requested. |
* A DB_Error object on failure. |
* |
* @see DB_common::tableInfo() |
* @since Method available since Release 1.7.0 |
*/ |
function tableInfo($result, $mode = null) |
{ |
if (is_string($result)) { |
/* |
* Probably received a table name. |
* Create a result resource identifier. |
*/ |
$id = @odbc_exec($this->connection, "SELECT * FROM $result"); |
if (!$id) { |
return $this->odbcRaiseError(); |
} |
$got_string = true; |
} elseif (isset($result->result)) { |
/* |
* Probably received a result object. |
* Extract the result resource identifier. |
*/ |
$id = $result->result; |
$got_string = false; |
} else { |
/* |
* Probably received a result resource identifier. |
* Copy it. |
* Deprecated. Here for compatibility only. |
*/ |
$id = $result; |
$got_string = false; |
} |
if (!is_resource($id)) { |
return $this->odbcRaiseError(DB_ERROR_NEED_MORE_DATA); |
} |
if ($this->options['portability'] & DB_PORTABILITY_LOWERCASE) { |
$case_func = 'strtolower'; |
} else { |
$case_func = 'strval'; |
} |
$count = @odbc_num_fields($id); |
$res = array(); |
if ($mode) { |
$res['num_fields'] = $count; |
} |
for ($i = 0; $i < $count; $i++) { |
$col = $i + 1; |
$res[$i] = array( |
'table' => $got_string ? $case_func($result) : '', |
'name' => $case_func(@odbc_field_name($id, $col)), |
'type' => @odbc_field_type($id, $col), |
'len' => @odbc_field_len($id, $col), |
'flags' => '', |
); |
if ($mode & DB_TABLEINFO_ORDER) { |
$res['order'][$res[$i]['name']] = $i; |
} |
if ($mode & DB_TABLEINFO_ORDERTABLE) { |
$res['ordertable'][$res[$i]['table']][$res[$i]['name']] = $i; |
} |
} |
// free the result only if we were called on a table |
if ($got_string) { |
@odbc_free_result($id); |
} |
return $res; |
} |
// }}} |
// {{{ getSpecialQuery() |
/** |
* Obtains the query string needed for listing a given type of objects |
* |
* Thanks to symbol1@gmail.com and Philippe.Jausions@11abacus.com. |
* |
* @param string $type the kind of objects you want to retrieve |
* |
* @return string the list of objects requested |
* |
* @access protected |
* @see DB_common::getListOf() |
* @since Method available since Release 1.7.0 |
*/ |
function getSpecialQuery($type) |
{ |
switch ($type) { |
case 'databases': |
if (!function_exists('odbc_data_source')) { |
return null; |
} |
$res = @odbc_data_source($this->connection, SQL_FETCH_FIRST); |
if (is_array($res)) { |
$out = array($res['server']); |
while($res = @odbc_data_source($this->connection, |
SQL_FETCH_NEXT)) |
{ |
$out[] = $res['server']; |
} |
return $out; |
} else { |
return $this->odbcRaiseError(); |
} |
break; |
case 'tables': |
case 'schema.tables': |
$keep = 'TABLE'; |
break; |
case 'views': |
$keep = 'VIEW'; |
break; |
default: |
return null; |
} |
/* |
* Removing non-conforming items in the while loop rather than |
* in the odbc_tables() call because some backends choke on this: |
* odbc_tables($this->connection, '', '', '', 'TABLE') |
*/ |
$res = @odbc_tables($this->connection); |
if (!$res) { |
return $this->odbcRaiseError(); |
} |
$out = array(); |
while ($row = odbc_fetch_array($res)) { |
if ($row['TABLE_TYPE'] != $keep) { |
continue; |
} |
if ($type == 'schema.tables') { |
$out[] = $row['TABLE_SCHEM'] . '.' . $row['TABLE_NAME']; |
} else { |
$out[] = $row['TABLE_NAME']; |
} |
} |
return $out; |
} |
// }}} |
} |
/* |
* Local variables: |
* tab-width: 4 |
* c-basic-offset: 4 |
* End: |
*/ |
?> |
/obs_saisons/SPIP-v1-8-3/modules/configuration/DB/common.php |
---|
New file |
0,0 → 1,2262 |
<?php |
/* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4: */ |
/** |
* Contains the DB_common base class |
* |
* PHP versions 4 and 5 |
* |
* LICENSE: This source file is subject to version 3.0 of the PHP license |
* that is available through the world-wide-web at the following URI: |
* http://www.php.net/license/3_0.txt. If you did not receive a copy of |
* the PHP License and are unable to obtain it through the web, please |
* send a note to license@php.net so we can mail you a copy immediately. |
* |
* @category Database |
* @package DB |
* @author Stig Bakken <ssb@php.net> |
* @author Tomas V.V. Cox <cox@idecnet.com> |
* @author Daniel Convissor <danielc@php.net> |
* @copyright 1997-2007 The PHP Group |
* @license http://www.php.net/license/3_0.txt PHP License 3.0 |
* @version CVS: $Id: common.php,v 1.1 2008/07/07 18:00:39 mrflos Exp $ |
* @link http://pear.php.net/package/DB |
*/ |
/** |
* Obtain the PEAR class so it can be extended from |
*/ |
require_once 'PEAR.php'; |
/** |
* DB_common is the base class from which each database driver class extends |
* |
* All common methods are declared here. If a given DBMS driver contains |
* a particular method, that method will overload the one here. |
* |
* @category Database |
* @package DB |
* @author Stig Bakken <ssb@php.net> |
* @author Tomas V.V. Cox <cox@idecnet.com> |
* @author Daniel Convissor <danielc@php.net> |
* @copyright 1997-2007 The PHP Group |
* @license http://www.php.net/license/3_0.txt PHP License 3.0 |
* @version Release: 1.7.14RC1 |
* @link http://pear.php.net/package/DB |
*/ |
class DB_common extends PEAR |
{ |
// {{{ properties |
/** |
* The current default fetch mode |
* @var integer |
*/ |
var $fetchmode = DB_FETCHMODE_ORDERED; |
/** |
* The name of the class into which results should be fetched when |
* DB_FETCHMODE_OBJECT is in effect |
* |
* @var string |
*/ |
var $fetchmode_object_class = 'stdClass'; |
/** |
* Was a connection present when the object was serialized()? |
* @var bool |
* @see DB_common::__sleep(), DB_common::__wake() |
*/ |
var $was_connected = null; |
/** |
* The most recently executed query |
* @var string |
*/ |
var $last_query = ''; |
/** |
* Run-time configuration options |
* |
* The 'optimize' option has been deprecated. Use the 'portability' |
* option instead. |
* |
* @var array |
* @see DB_common::setOption() |
*/ |
var $options = array( |
'result_buffering' => 500, |
'persistent' => false, |
'ssl' => false, |
'debug' => 0, |
'seqname_format' => '%s_seq', |
'autofree' => false, |
'portability' => DB_PORTABILITY_NONE, |
'optimize' => 'performance', // Deprecated. Use 'portability'. |
); |
/** |
* The parameters from the most recently executed query |
* @var array |
* @since Property available since Release 1.7.0 |
*/ |
var $last_parameters = array(); |
/** |
* The elements from each prepared statement |
* @var array |
*/ |
var $prepare_tokens = array(); |
/** |
* The data types of the various elements in each prepared statement |
* @var array |
*/ |
var $prepare_types = array(); |
/** |
* The prepared queries |
* @var array |
*/ |
var $prepared_queries = array(); |
/** |
* Flag indicating that the last query was a manipulation query. |
* @access protected |
* @var boolean |
*/ |
var $_last_query_manip = false; |
/** |
* Flag indicating that the next query <em>must</em> be a manipulation |
* query. |
* @access protected |
* @var boolean |
*/ |
var $_next_query_manip = false; |
// }}} |
// {{{ DB_common |
/** |
* This constructor calls <kbd>$this->PEAR('DB_Error')</kbd> |
* |
* @return void |
*/ |
function DB_common() |
{ |
$this->PEAR('DB_Error'); |
} |
// }}} |
// {{{ __sleep() |
/** |
* Automatically indicates which properties should be saved |
* when PHP's serialize() function is called |
* |
* @return array the array of properties names that should be saved |
*/ |
function __sleep() |
{ |
if ($this->connection) { |
// Don't disconnect(), people use serialize() for many reasons |
$this->was_connected = true; |
} else { |
$this->was_connected = false; |
} |
if (isset($this->autocommit)) { |
return array('autocommit', |
'dbsyntax', |
'dsn', |
'features', |
'fetchmode', |
'fetchmode_object_class', |
'options', |
'was_connected', |
); |
} else { |
return array('dbsyntax', |
'dsn', |
'features', |
'fetchmode', |
'fetchmode_object_class', |
'options', |
'was_connected', |
); |
} |
} |
// }}} |
// {{{ __wakeup() |
/** |
* Automatically reconnects to the database when PHP's unserialize() |
* function is called |
* |
* The reconnection attempt is only performed if the object was connected |
* at the time PHP's serialize() function was run. |
* |
* @return void |
*/ |
function __wakeup() |
{ |
if ($this->was_connected) { |
$this->connect($this->dsn, $this->options); |
} |
} |
// }}} |
// {{{ __toString() |
/** |
* Automatic string conversion for PHP 5 |
* |
* @return string a string describing the current PEAR DB object |
* |
* @since Method available since Release 1.7.0 |
*/ |
function __toString() |
{ |
$info = strtolower(get_class($this)); |
$info .= ': (phptype=' . $this->phptype . |
', dbsyntax=' . $this->dbsyntax . |
')'; |
if ($this->connection) { |
$info .= ' [connected]'; |
} |
return $info; |
} |
// }}} |
// {{{ toString() |
/** |
* DEPRECATED: String conversion method |
* |
* @return string a string describing the current PEAR DB object |
* |
* @deprecated Method deprecated in Release 1.7.0 |
*/ |
function toString() |
{ |
return $this->__toString(); |
} |
// }}} |
// {{{ quoteString() |
/** |
* DEPRECATED: Quotes a string so it can be safely used within string |
* delimiters in a query |
* |
* @param string $string the string to be quoted |
* |
* @return string the quoted string |
* |
* @see DB_common::quoteSmart(), DB_common::escapeSimple() |
* @deprecated Method deprecated some time before Release 1.2 |
*/ |
function quoteString($string) |
{ |
$string = $this->quote($string); |
if ($string{0} == "'") { |
return substr($string, 1, -1); |
} |
return $string; |
} |
// }}} |
// {{{ quote() |
/** |
* DEPRECATED: Quotes a string so it can be safely used in a query |
* |
* @param string $string the string to quote |
* |
* @return string the quoted string or the string <samp>NULL</samp> |
* if the value submitted is <kbd>null</kbd>. |
* |
* @see DB_common::quoteSmart(), DB_common::escapeSimple() |
* @deprecated Deprecated in release 1.6.0 |
*/ |
function quote($string = null) |
{ |
return ($string === null) ? 'NULL' |
: "'" . str_replace("'", "''", $string) . "'"; |
} |
// }}} |
// {{{ quoteIdentifier() |
/** |
* Quotes a string so it can be safely used as a table or column name |
* |
* Delimiting style depends on which database driver is being used. |
* |
* NOTE: just because you CAN use delimited identifiers doesn't mean |
* you SHOULD use them. In general, they end up causing way more |
* problems than they solve. |
* |
* Portability is broken by using the following characters inside |
* delimited identifiers: |
* + backtick (<kbd>`</kbd>) -- due to MySQL |
* + double quote (<kbd>"</kbd>) -- due to Oracle |
* + brackets (<kbd>[</kbd> or <kbd>]</kbd>) -- due to Access |
* |
* Delimited identifiers are known to generally work correctly under |
* the following drivers: |
* + mssql |
* + mysql |
* + mysqli |
* + oci8 |
* + odbc(access) |
* + odbc(db2) |
* + pgsql |
* + sqlite |
* + sybase (must execute <kbd>set quoted_identifier on</kbd> sometime |
* prior to use) |
* |
* InterBase doesn't seem to be able to use delimited identifiers |
* via PHP 4. They work fine under PHP 5. |
* |
* @param string $str the identifier name to be quoted |
* |
* @return string the quoted identifier |
* |
* @since Method available since Release 1.6.0 |
*/ |
function quoteIdentifier($str) |
{ |
return '"' . str_replace('"', '""', $str) . '"'; |
} |
// }}} |
// {{{ quoteSmart() |
/** |
* Formats input so it can be safely used in a query |
* |
* The output depends on the PHP data type of input and the database |
* type being used. |
* |
* @param mixed $in the data to be formatted |
* |
* @return mixed the formatted data. The format depends on the input's |
* PHP type: |
* <ul> |
* <li> |
* <kbd>input</kbd> -> <samp>returns</samp> |
* </li> |
* <li> |
* <kbd>null</kbd> -> the string <samp>NULL</samp> |
* </li> |
* <li> |
* <kbd>integer</kbd> or <kbd>double</kbd> -> the unquoted number |
* </li> |
* <li> |
* <kbd>bool</kbd> -> output depends on the driver in use |
* Most drivers return integers: <samp>1</samp> if |
* <kbd>true</kbd> or <samp>0</samp> if |
* <kbd>false</kbd>. |
* Some return strings: <samp>TRUE</samp> if |
* <kbd>true</kbd> or <samp>FALSE</samp> if |
* <kbd>false</kbd>. |
* Finally one returns strings: <samp>T</samp> if |
* <kbd>true</kbd> or <samp>F</samp> if |
* <kbd>false</kbd>. Here is a list of each DBMS, |
* the values returned and the suggested column type: |
* <ul> |
* <li> |
* <kbd>dbase</kbd> -> <samp>T/F</samp> |
* (<kbd>Logical</kbd>) |
* </li> |
* <li> |
* <kbd>fbase</kbd> -> <samp>TRUE/FALSE</samp> |
* (<kbd>BOOLEAN</kbd>) |
* </li> |
* <li> |
* <kbd>ibase</kbd> -> <samp>1/0</samp> |
* (<kbd>SMALLINT</kbd>) [1] |
* </li> |
* <li> |
* <kbd>ifx</kbd> -> <samp>1/0</samp> |
* (<kbd>SMALLINT</kbd>) [1] |
* </li> |
* <li> |
* <kbd>msql</kbd> -> <samp>1/0</samp> |
* (<kbd>INTEGER</kbd>) |
* </li> |
* <li> |
* <kbd>mssql</kbd> -> <samp>1/0</samp> |
* (<kbd>BIT</kbd>) |
* </li> |
* <li> |
* <kbd>mysql</kbd> -> <samp>1/0</samp> |
* (<kbd>TINYINT(1)</kbd>) |
* </li> |
* <li> |
* <kbd>mysqli</kbd> -> <samp>1/0</samp> |
* (<kbd>TINYINT(1)</kbd>) |
* </li> |
* <li> |
* <kbd>oci8</kbd> -> <samp>1/0</samp> |
* (<kbd>NUMBER(1)</kbd>) |
* </li> |
* <li> |
* <kbd>odbc</kbd> -> <samp>1/0</samp> |
* (<kbd>SMALLINT</kbd>) [1] |
* </li> |
* <li> |
* <kbd>pgsql</kbd> -> <samp>TRUE/FALSE</samp> |
* (<kbd>BOOLEAN</kbd>) |
* </li> |
* <li> |
* <kbd>sqlite</kbd> -> <samp>1/0</samp> |
* (<kbd>INTEGER</kbd>) |
* </li> |
* <li> |
* <kbd>sybase</kbd> -> <samp>1/0</samp> |
* (<kbd>TINYINT(1)</kbd>) |
* </li> |
* </ul> |
* [1] Accommodate the lowest common denominator because not all |
* versions of have <kbd>BOOLEAN</kbd>. |
* </li> |
* <li> |
* other (including strings and numeric strings) -> |
* the data with single quotes escaped by preceeding |
* single quotes, backslashes are escaped by preceeding |
* backslashes, then the whole string is encapsulated |
* between single quotes |
* </li> |
* </ul> |
* |
* @see DB_common::escapeSimple() |
* @since Method available since Release 1.6.0 |
*/ |
function quoteSmart($in) |
{ |
if (is_int($in)) { |
return $in; |
} elseif (is_float($in)) { |
return $this->quoteFloat($in); |
} elseif (is_bool($in)) { |
return $this->quoteBoolean($in); |
} elseif (is_null($in)) { |
return 'NULL'; |
} else { |
if ($this->dbsyntax == 'access' |
&& preg_match('/^#.+#$/', $in)) |
{ |
return $this->escapeSimple($in); |
} |
return "'" . $this->escapeSimple($in) . "'"; |
} |
} |
// }}} |
// {{{ quoteBoolean() |
/** |
* Formats a boolean value for use within a query in a locale-independent |
* manner. |
* |
* @param boolean the boolean value to be quoted. |
* @return string the quoted string. |
* @see DB_common::quoteSmart() |
* @since Method available since release 1.7.8. |
*/ |
function quoteBoolean($boolean) { |
return $boolean ? '1' : '0'; |
} |
// }}} |
// {{{ quoteFloat() |
/** |
* Formats a float value for use within a query in a locale-independent |
* manner. |
* |
* @param float the float value to be quoted. |
* @return string the quoted string. |
* @see DB_common::quoteSmart() |
* @since Method available since release 1.7.8. |
*/ |
function quoteFloat($float) { |
return "'".$this->escapeSimple(str_replace(',', '.', strval(floatval($float))))."'"; |
} |
// }}} |
// {{{ escapeSimple() |
/** |
* Escapes a string according to the current DBMS's standards |
* |
* In SQLite, this makes things safe for inserts/updates, but may |
* cause problems when performing text comparisons against columns |
* containing binary data. See the |
* {@link http://php.net/sqlite_escape_string PHP manual} for more info. |
* |
* @param string $str the string to be escaped |
* |
* @return string the escaped string |
* |
* @see DB_common::quoteSmart() |
* @since Method available since Release 1.6.0 |
*/ |
function escapeSimple($str) |
{ |
return str_replace("'", "''", $str); |
} |
// }}} |
// {{{ provides() |
/** |
* Tells whether the present driver supports a given feature |
* |
* @param string $feature the feature you're curious about |
* |
* @return bool whether this driver supports $feature |
*/ |
function provides($feature) |
{ |
return $this->features[$feature]; |
} |
// }}} |
// {{{ setFetchMode() |
/** |
* Sets the fetch mode that should be used by default for query results |
* |
* @param integer $fetchmode DB_FETCHMODE_ORDERED, DB_FETCHMODE_ASSOC |
* or DB_FETCHMODE_OBJECT |
* @param string $object_class the class name of the object to be returned |
* by the fetch methods when the |
* DB_FETCHMODE_OBJECT mode is selected. |
* If no class is specified by default a cast |
* to object from the assoc array row will be |
* done. There is also the posibility to use |
* and extend the 'DB_row' class. |
* |
* @see DB_FETCHMODE_ORDERED, DB_FETCHMODE_ASSOC, DB_FETCHMODE_OBJECT |
*/ |
function setFetchMode($fetchmode, $object_class = 'stdClass') |
{ |
switch ($fetchmode) { |
case DB_FETCHMODE_OBJECT: |
$this->fetchmode_object_class = $object_class; |
case DB_FETCHMODE_ORDERED: |
case DB_FETCHMODE_ASSOC: |
$this->fetchmode = $fetchmode; |
break; |
default: |
return $this->raiseError('invalid fetchmode mode'); |
} |
} |
// }}} |
// {{{ setOption() |
/** |
* Sets run-time configuration options for PEAR DB |
* |
* Options, their data types, default values and description: |
* <ul> |
* <li> |
* <var>autofree</var> <kbd>boolean</kbd> = <samp>false</samp> |
* <br />should results be freed automatically when there are no |
* more rows? |
* </li><li> |
* <var>result_buffering</var> <kbd>integer</kbd> = <samp>500</samp> |
* <br />how many rows of the result set should be buffered? |
* <br />In mysql: mysql_unbuffered_query() is used instead of |
* mysql_query() if this value is 0. (Release 1.7.0) |
* <br />In oci8: this value is passed to ocisetprefetch(). |
* (Release 1.7.0) |
* </li><li> |
* <var>debug</var> <kbd>integer</kbd> = <samp>0</samp> |
* <br />debug level |
* </li><li> |
* <var>persistent</var> <kbd>boolean</kbd> = <samp>false</samp> |
* <br />should the connection be persistent? |
* </li><li> |
* <var>portability</var> <kbd>integer</kbd> = <samp>DB_PORTABILITY_NONE</samp> |
* <br />portability mode constant (see below) |
* </li><li> |
* <var>seqname_format</var> <kbd>string</kbd> = <samp>%s_seq</samp> |
* <br />the sprintf() format string used on sequence names. This |
* format is applied to sequence names passed to |
* createSequence(), nextID() and dropSequence(). |
* </li><li> |
* <var>ssl</var> <kbd>boolean</kbd> = <samp>false</samp> |
* <br />use ssl to connect? |
* </li> |
* </ul> |
* |
* ----------------------------------------- |
* |
* PORTABILITY MODES |
* |
* These modes are bitwised, so they can be combined using <kbd>|</kbd> |
* and removed using <kbd>^</kbd>. See the examples section below on how |
* to do this. |
* |
* <samp>DB_PORTABILITY_NONE</samp> |
* turn off all portability features |
* |
* This mode gets automatically turned on if the deprecated |
* <var>optimize</var> option gets set to <samp>performance</samp>. |
* |
* |
* <samp>DB_PORTABILITY_LOWERCASE</samp> |
* convert names of tables and fields to lower case when using |
* <kbd>get*()</kbd>, <kbd>fetch*()</kbd> and <kbd>tableInfo()</kbd> |
* |
* This mode gets automatically turned on in the following databases |
* if the deprecated option <var>optimize</var> gets set to |
* <samp>portability</samp>: |
* + oci8 |
* |
* |
* <samp>DB_PORTABILITY_RTRIM</samp> |
* right trim the data output by <kbd>get*()</kbd> <kbd>fetch*()</kbd> |
* |
* |
* <samp>DB_PORTABILITY_DELETE_COUNT</samp> |
* force reporting the number of rows deleted |
* |
* Some DBMS's don't count the number of rows deleted when performing |
* simple <kbd>DELETE FROM tablename</kbd> queries. This portability |
* mode tricks such DBMS's into telling the count by adding |
* <samp>WHERE 1=1</samp> to the end of <kbd>DELETE</kbd> queries. |
* |
* This mode gets automatically turned on in the following databases |
* if the deprecated option <var>optimize</var> gets set to |
* <samp>portability</samp>: |
* + fbsql |
* + mysql |
* + mysqli |
* + sqlite |
* |
* |
* <samp>DB_PORTABILITY_NUMROWS</samp> |
* enable hack that makes <kbd>numRows()</kbd> work in Oracle |
* |
* This mode gets automatically turned on in the following databases |
* if the deprecated option <var>optimize</var> gets set to |
* <samp>portability</samp>: |
* + oci8 |
* |
* |
* <samp>DB_PORTABILITY_ERRORS</samp> |
* makes certain error messages in certain drivers compatible |
* with those from other DBMS's |
* |
* + mysql, mysqli: change unique/primary key constraints |
* DB_ERROR_ALREADY_EXISTS -> DB_ERROR_CONSTRAINT |
* |
* + odbc(access): MS's ODBC driver reports 'no such field' as code |
* 07001, which means 'too few parameters.' When this option is on |
* that code gets mapped to DB_ERROR_NOSUCHFIELD. |
* DB_ERROR_MISMATCH -> DB_ERROR_NOSUCHFIELD |
* |
* <samp>DB_PORTABILITY_NULL_TO_EMPTY</samp> |
* convert null values to empty strings in data output by get*() and |
* fetch*(). Needed because Oracle considers empty strings to be null, |
* while most other DBMS's know the difference between empty and null. |
* |
* |
* <samp>DB_PORTABILITY_ALL</samp> |
* turn on all portability features |
* |
* ----------------------------------------- |
* |
* Example 1. Simple setOption() example |
* <code> |
* $db->setOption('autofree', true); |
* </code> |
* |
* Example 2. Portability for lowercasing and trimming |
* <code> |
* $db->setOption('portability', |
* DB_PORTABILITY_LOWERCASE | DB_PORTABILITY_RTRIM); |
* </code> |
* |
* Example 3. All portability options except trimming |
* <code> |
* $db->setOption('portability', |
* DB_PORTABILITY_ALL ^ DB_PORTABILITY_RTRIM); |
* </code> |
* |
* @param string $option option name |
* @param mixed $value value for the option |
* |
* @return int DB_OK on success. A DB_Error object on failure. |
* |
* @see DB_common::$options |
*/ |
function setOption($option, $value) |
{ |
if (isset($this->options[$option])) { |
$this->options[$option] = $value; |
/* |
* Backwards compatibility check for the deprecated 'optimize' |
* option. Done here in case settings change after connecting. |
*/ |
if ($option == 'optimize') { |
if ($value == 'portability') { |
switch ($this->phptype) { |
case 'oci8': |
$this->options['portability'] = |
DB_PORTABILITY_LOWERCASE | |
DB_PORTABILITY_NUMROWS; |
break; |
case 'fbsql': |
case 'mysql': |
case 'mysqli': |
case 'sqlite': |
$this->options['portability'] = |
DB_PORTABILITY_DELETE_COUNT; |
break; |
} |
} else { |
$this->options['portability'] = DB_PORTABILITY_NONE; |
} |
} |
return DB_OK; |
} |
return $this->raiseError("unknown option $option"); |
} |
// }}} |
// {{{ getOption() |
/** |
* Returns the value of an option |
* |
* @param string $option the option name you're curious about |
* |
* @return mixed the option's value |
*/ |
function getOption($option) |
{ |
if (isset($this->options[$option])) { |
return $this->options[$option]; |
} |
return $this->raiseError("unknown option $option"); |
} |
// }}} |
// {{{ prepare() |
/** |
* Prepares a query for multiple execution with execute() |
* |
* Creates a query that can be run multiple times. Each time it is run, |
* the placeholders, if any, will be replaced by the contents of |
* execute()'s $data argument. |
* |
* Three types of placeholders can be used: |
* + <kbd>?</kbd> scalar value (i.e. strings, integers). The system |
* will automatically quote and escape the data. |
* + <kbd>!</kbd> value is inserted 'as is' |
* + <kbd>&</kbd> requires a file name. The file's contents get |
* inserted into the query (i.e. saving binary |
* data in a db) |
* |
* Example 1. |
* <code> |
* $sth = $db->prepare('INSERT INTO tbl (a, b, c) VALUES (?, !, &)'); |
* $data = array( |
* "John's text", |
* "'it''s good'", |
* 'filename.txt' |
* ); |
* $res = $db->execute($sth, $data); |
* </code> |
* |
* Use backslashes to escape placeholder characters if you don't want |
* them to be interpreted as placeholders: |
* <pre> |
* "UPDATE foo SET col=? WHERE col='over \& under'" |
* </pre> |
* |
* With some database backends, this is emulated. |
* |
* {@internal ibase and oci8 have their own prepare() methods.}} |
* |
* @param string $query the query to be prepared |
* |
* @return mixed DB statement resource on success. A DB_Error object |
* on failure. |
* |
* @see DB_common::execute() |
*/ |
function prepare($query) |
{ |
$tokens = preg_split('/((?<!\\\)[&?!])/', $query, -1, |
PREG_SPLIT_DELIM_CAPTURE); |
$token = 0; |
$types = array(); |
$newtokens = array(); |
foreach ($tokens as $val) { |
switch ($val) { |
case '?': |
$types[$token++] = DB_PARAM_SCALAR; |
break; |
case '&': |
$types[$token++] = DB_PARAM_OPAQUE; |
break; |
case '!': |
$types[$token++] = DB_PARAM_MISC; |
break; |
default: |
$newtokens[] = preg_replace('/\\\([&?!])/', "\\1", $val); |
} |
} |
$this->prepare_tokens[] = &$newtokens; |
end($this->prepare_tokens); |
$k = key($this->prepare_tokens); |
$this->prepare_types[$k] = $types; |
$this->prepared_queries[$k] = implode(' ', $newtokens); |
return $k; |
} |
// }}} |
// {{{ autoPrepare() |
/** |
* Automaticaly generates an insert or update query and pass it to prepare() |
* |
* @param string $table the table name |
* @param array $table_fields the array of field names |
* @param int $mode a type of query to make: |
* DB_AUTOQUERY_INSERT or DB_AUTOQUERY_UPDATE |
* @param string $where for update queries: the WHERE clause to |
* append to the SQL statement. Don't |
* include the "WHERE" keyword. |
* |
* @return resource the query handle |
* |
* @uses DB_common::prepare(), DB_common::buildManipSQL() |
*/ |
function autoPrepare($table, $table_fields, $mode = DB_AUTOQUERY_INSERT, |
$where = false) |
{ |
$query = $this->buildManipSQL($table, $table_fields, $mode, $where); |
if (DB::isError($query)) { |
return $query; |
} |
return $this->prepare($query); |
} |
// }}} |
// {{{ autoExecute() |
/** |
* Automaticaly generates an insert or update query and call prepare() |
* and execute() with it |
* |
* @param string $table the table name |
* @param array $fields_values the associative array where $key is a |
* field name and $value its value |
* @param int $mode a type of query to make: |
* DB_AUTOQUERY_INSERT or DB_AUTOQUERY_UPDATE |
* @param string $where for update queries: the WHERE clause to |
* append to the SQL statement. Don't |
* include the "WHERE" keyword. |
* |
* @return mixed a new DB_result object for successful SELECT queries |
* or DB_OK for successul data manipulation queries. |
* A DB_Error object on failure. |
* |
* @uses DB_common::autoPrepare(), DB_common::execute() |
*/ |
function autoExecute($table, $fields_values, $mode = DB_AUTOQUERY_INSERT, |
$where = false) |
{ |
$sth = $this->autoPrepare($table, array_keys($fields_values), $mode, |
$where); |
if (DB::isError($sth)) { |
return $sth; |
} |
$ret = $this->execute($sth, array_values($fields_values)); |
$this->freePrepared($sth); |
return $ret; |
} |
// }}} |
// {{{ buildManipSQL() |
/** |
* Produces an SQL query string for autoPrepare() |
* |
* Example: |
* <pre> |
* buildManipSQL('table_sql', array('field1', 'field2', 'field3'), |
* DB_AUTOQUERY_INSERT); |
* </pre> |
* |
* That returns |
* <samp> |
* INSERT INTO table_sql (field1,field2,field3) VALUES (?,?,?) |
* </samp> |
* |
* NOTES: |
* - This belongs more to a SQL Builder class, but this is a simple |
* facility. |
* - Be carefull! If you don't give a $where param with an UPDATE |
* query, all the records of the table will be updated! |
* |
* @param string $table the table name |
* @param array $table_fields the array of field names |
* @param int $mode a type of query to make: |
* DB_AUTOQUERY_INSERT or DB_AUTOQUERY_UPDATE |
* @param string $where for update queries: the WHERE clause to |
* append to the SQL statement. Don't |
* include the "WHERE" keyword. |
* |
* @return string the sql query for autoPrepare() |
*/ |
function buildManipSQL($table, $table_fields, $mode, $where = false) |
{ |
if (count($table_fields) == 0) { |
return $this->raiseError(DB_ERROR_NEED_MORE_DATA); |
} |
$first = true; |
switch ($mode) { |
case DB_AUTOQUERY_INSERT: |
$values = ''; |
$names = ''; |
foreach ($table_fields as $value) { |
if ($first) { |
$first = false; |
} else { |
$names .= ','; |
$values .= ','; |
} |
$names .= $value; |
$values .= '?'; |
} |
return "INSERT INTO $table ($names) VALUES ($values)"; |
case DB_AUTOQUERY_UPDATE: |
$set = ''; |
foreach ($table_fields as $value) { |
if ($first) { |
$first = false; |
} else { |
$set .= ','; |
} |
$set .= "$value = ?"; |
} |
$sql = "UPDATE $table SET $set"; |
if ($where) { |
$sql .= " WHERE $where"; |
} |
return $sql; |
default: |
return $this->raiseError(DB_ERROR_SYNTAX); |
} |
} |
// }}} |
// {{{ execute() |
/** |
* Executes a DB statement prepared with prepare() |
* |
* Example 1. |
* <code> |
* $sth = $db->prepare('INSERT INTO tbl (a, b, c) VALUES (?, !, &)'); |
* $data = array( |
* "John's text", |
* "'it''s good'", |
* 'filename.txt' |
* ); |
* $res = $db->execute($sth, $data); |
* </code> |
* |
* @param resource $stmt a DB statement resource returned from prepare() |
* @param mixed $data array, string or numeric data to be used in |
* execution of the statement. Quantity of items |
* passed must match quantity of placeholders in |
* query: meaning 1 placeholder for non-array |
* parameters or 1 placeholder per array element. |
* |
* @return mixed a new DB_result object for successful SELECT queries |
* or DB_OK for successul data manipulation queries. |
* A DB_Error object on failure. |
* |
* {@internal ibase and oci8 have their own execute() methods.}} |
* |
* @see DB_common::prepare() |
*/ |
function &execute($stmt, $data = array()) |
{ |
$realquery = $this->executeEmulateQuery($stmt, $data); |
if (DB::isError($realquery)) { |
return $realquery; |
} |
$result = $this->simpleQuery($realquery); |
if ($result === DB_OK || DB::isError($result)) { |
return $result; |
} else { |
$tmp = new DB_result($this, $result); |
return $tmp; |
} |
} |
// }}} |
// {{{ executeEmulateQuery() |
/** |
* Emulates executing prepared statements if the DBMS not support them |
* |
* @param resource $stmt a DB statement resource returned from execute() |
* @param mixed $data array, string or numeric data to be used in |
* execution of the statement. Quantity of items |
* passed must match quantity of placeholders in |
* query: meaning 1 placeholder for non-array |
* parameters or 1 placeholder per array element. |
* |
* @return mixed a string containing the real query run when emulating |
* prepare/execute. A DB_Error object on failure. |
* |
* @access protected |
* @see DB_common::execute() |
*/ |
function executeEmulateQuery($stmt, $data = array()) |
{ |
$stmt = (int)$stmt; |
$data = (array)$data; |
$this->last_parameters = $data; |
if (count($this->prepare_types[$stmt]) != count($data)) { |
$this->last_query = $this->prepared_queries[$stmt]; |
return $this->raiseError(DB_ERROR_MISMATCH); |
} |
$realquery = $this->prepare_tokens[$stmt][0]; |
$i = 0; |
foreach ($data as $value) { |
if ($this->prepare_types[$stmt][$i] == DB_PARAM_SCALAR) { |
$realquery .= $this->quoteSmart($value); |
} elseif ($this->prepare_types[$stmt][$i] == DB_PARAM_OPAQUE) { |
$fp = @fopen($value, 'rb'); |
if (!$fp) { |
return $this->raiseError(DB_ERROR_ACCESS_VIOLATION); |
} |
$realquery .= $this->quoteSmart(fread($fp, filesize($value))); |
fclose($fp); |
} else { |
$realquery .= $value; |
} |
$realquery .= $this->prepare_tokens[$stmt][++$i]; |
} |
return $realquery; |
} |
// }}} |
// {{{ executeMultiple() |
/** |
* Performs several execute() calls on the same statement handle |
* |
* $data must be an array indexed numerically |
* from 0, one execute call is done for every "row" in the array. |
* |
* If an error occurs during execute(), executeMultiple() does not |
* execute the unfinished rows, but rather returns that error. |
* |
* @param resource $stmt query handle from prepare() |
* @param array $data numeric array containing the |
* data to insert into the query |
* |
* @return int DB_OK on success. A DB_Error object on failure. |
* |
* @see DB_common::prepare(), DB_common::execute() |
*/ |
function executeMultiple($stmt, $data) |
{ |
foreach ($data as $value) { |
$res = $this->execute($stmt, $value); |
if (DB::isError($res)) { |
return $res; |
} |
} |
return DB_OK; |
} |
// }}} |
// {{{ freePrepared() |
/** |
* Frees the internal resources associated with a prepared query |
* |
* @param resource $stmt the prepared statement's PHP resource |
* @param bool $free_resource should the PHP resource be freed too? |
* Use false if you need to get data |
* from the result set later. |
* |
* @return bool TRUE on success, FALSE if $result is invalid |
* |
* @see DB_common::prepare() |
*/ |
function freePrepared($stmt, $free_resource = true) |
{ |
$stmt = (int)$stmt; |
if (isset($this->prepare_tokens[$stmt])) { |
unset($this->prepare_tokens[$stmt]); |
unset($this->prepare_types[$stmt]); |
unset($this->prepared_queries[$stmt]); |
return true; |
} |
return false; |
} |
// }}} |
// {{{ modifyQuery() |
/** |
* Changes a query string for various DBMS specific reasons |
* |
* It is defined here to ensure all drivers have this method available. |
* |
* @param string $query the query string to modify |
* |
* @return string the modified query string |
* |
* @access protected |
* @see DB_mysql::modifyQuery(), DB_oci8::modifyQuery(), |
* DB_sqlite::modifyQuery() |
*/ |
function modifyQuery($query) |
{ |
return $query; |
} |
// }}} |
// {{{ modifyLimitQuery() |
/** |
* Adds LIMIT clauses to a query string according to current DBMS standards |
* |
* It is defined here to assure that all implementations |
* have this method defined. |
* |
* @param string $query the query to modify |
* @param int $from the row to start to fetching (0 = the first row) |
* @param int $count the numbers of rows to fetch |
* @param mixed $params array, string or numeric data to be used in |
* execution of the statement. Quantity of items |
* passed must match quantity of placeholders in |
* query: meaning 1 placeholder for non-array |
* parameters or 1 placeholder per array element. |
* |
* @return string the query string with LIMIT clauses added |
* |
* @access protected |
*/ |
function modifyLimitQuery($query, $from, $count, $params = array()) |
{ |
return $query; |
} |
// }}} |
// {{{ query() |
/** |
* Sends a query to the database server |
* |
* The query string can be either a normal statement to be sent directly |
* to the server OR if <var>$params</var> are passed the query can have |
* placeholders and it will be passed through prepare() and execute(). |
* |
* @param string $query the SQL query or the statement to prepare |
* @param mixed $params array, string or numeric data to be used in |
* execution of the statement. Quantity of items |
* passed must match quantity of placeholders in |
* query: meaning 1 placeholder for non-array |
* parameters or 1 placeholder per array element. |
* |
* @return mixed a new DB_result object for successful SELECT queries |
* or DB_OK for successul data manipulation queries. |
* A DB_Error object on failure. |
* |
* @see DB_result, DB_common::prepare(), DB_common::execute() |
*/ |
function &query($query, $params = array()) |
{ |
if (sizeof($params) > 0) { |
$sth = $this->prepare($query); |
if (DB::isError($sth)) { |
return $sth; |
} |
$ret = $this->execute($sth, $params); |
$this->freePrepared($sth, false); |
return $ret; |
} else { |
$this->last_parameters = array(); |
$result = $this->simpleQuery($query); |
if ($result === DB_OK || DB::isError($result)) { |
return $result; |
} else { |
$tmp = new DB_result($this, $result); |
return $tmp; |
} |
} |
} |
// }}} |
// {{{ limitQuery() |
/** |
* Generates and executes a LIMIT query |
* |
* @param string $query the query |
* @param intr $from the row to start to fetching (0 = the first row) |
* @param int $count the numbers of rows to fetch |
* @param mixed $params array, string or numeric data to be used in |
* execution of the statement. Quantity of items |
* passed must match quantity of placeholders in |
* query: meaning 1 placeholder for non-array |
* parameters or 1 placeholder per array element. |
* |
* @return mixed a new DB_result object for successful SELECT queries |
* or DB_OK for successul data manipulation queries. |
* A DB_Error object on failure. |
*/ |
function &limitQuery($query, $from, $count, $params = array()) |
{ |
$query = $this->modifyLimitQuery($query, $from, $count, $params); |
if (DB::isError($query)){ |
return $query; |
} |
$result = $this->query($query, $params); |
if (is_a($result, 'DB_result')) { |
$result->setOption('limit_from', $from); |
$result->setOption('limit_count', $count); |
} |
return $result; |
} |
// }}} |
// {{{ getOne() |
/** |
* Fetches the first column of the first row from a query result |
* |
* Takes care of doing the query and freeing the results when finished. |
* |
* @param string $query the SQL query |
* @param mixed $params array, string or numeric data to be used in |
* execution of the statement. Quantity of items |
* passed must match quantity of placeholders in |
* query: meaning 1 placeholder for non-array |
* parameters or 1 placeholder per array element. |
* |
* @return mixed the returned value of the query. |
* A DB_Error object on failure. |
*/ |
function &getOne($query, $params = array()) |
{ |
$params = (array)$params; |
// modifyLimitQuery() would be nice here, but it causes BC issues |
if (sizeof($params) > 0) { |
$sth = $this->prepare($query); |
if (DB::isError($sth)) { |
return $sth; |
} |
$res = $this->execute($sth, $params); |
$this->freePrepared($sth); |
} else { |
$res = $this->query($query); |
} |
if (DB::isError($res)) { |
return $res; |
} |
$err = $res->fetchInto($row, DB_FETCHMODE_ORDERED); |
$res->free(); |
if ($err !== DB_OK) { |
return $err; |
} |
return $row[0]; |
} |
// }}} |
// {{{ getRow() |
/** |
* Fetches the first row of data returned from a query result |
* |
* Takes care of doing the query and freeing the results when finished. |
* |
* @param string $query the SQL query |
* @param mixed $params array, string or numeric data to be used in |
* execution of the statement. Quantity of items |
* passed must match quantity of placeholders in |
* query: meaning 1 placeholder for non-array |
* parameters or 1 placeholder per array element. |
* @param int $fetchmode the fetch mode to use |
* |
* @return array the first row of results as an array. |
* A DB_Error object on failure. |
*/ |
function &getRow($query, $params = array(), |
$fetchmode = DB_FETCHMODE_DEFAULT) |
{ |
// compat check, the params and fetchmode parameters used to |
// have the opposite order |
if (!is_array($params)) { |
if (is_array($fetchmode)) { |
if ($params === null) { |
$tmp = DB_FETCHMODE_DEFAULT; |
} else { |
$tmp = $params; |
} |
$params = $fetchmode; |
$fetchmode = $tmp; |
} elseif ($params !== null) { |
$fetchmode = $params; |
$params = array(); |
} |
} |
// modifyLimitQuery() would be nice here, but it causes BC issues |
if (sizeof($params) > 0) { |
$sth = $this->prepare($query); |
if (DB::isError($sth)) { |
return $sth; |
} |
$res = $this->execute($sth, $params); |
$this->freePrepared($sth); |
} else { |
$res = $this->query($query); |
} |
if (DB::isError($res)) { |
return $res; |
} |
$err = $res->fetchInto($row, $fetchmode); |
$res->free(); |
if ($err !== DB_OK) { |
return $err; |
} |
return $row; |
} |
// }}} |
// {{{ getCol() |
/** |
* Fetches a single column from a query result and returns it as an |
* indexed array |
* |
* @param string $query the SQL query |
* @param mixed $col which column to return (integer [column number, |
* starting at 0] or string [column name]) |
* @param mixed $params array, string or numeric data to be used in |
* execution of the statement. Quantity of items |
* passed must match quantity of placeholders in |
* query: meaning 1 placeholder for non-array |
* parameters or 1 placeholder per array element. |
* |
* @return array the results as an array. A DB_Error object on failure. |
* |
* @see DB_common::query() |
*/ |
function &getCol($query, $col = 0, $params = array()) |
{ |
$params = (array)$params; |
if (sizeof($params) > 0) { |
$sth = $this->prepare($query); |
if (DB::isError($sth)) { |
return $sth; |
} |
$res = $this->execute($sth, $params); |
$this->freePrepared($sth); |
} else { |
$res = $this->query($query); |
} |
if (DB::isError($res)) { |
return $res; |
} |
$fetchmode = is_int($col) ? DB_FETCHMODE_ORDERED : DB_FETCHMODE_ASSOC; |
if (!is_array($row = $res->fetchRow($fetchmode))) { |
$ret = array(); |
} else { |
if (!array_key_exists($col, $row)) { |
$ret = $this->raiseError(DB_ERROR_NOSUCHFIELD); |
} else { |
$ret = array($row[$col]); |
while (is_array($row = $res->fetchRow($fetchmode))) { |
$ret[] = $row[$col]; |
} |
} |
} |
$res->free(); |
if (DB::isError($row)) { |
$ret = $row; |
} |
return $ret; |
} |
// }}} |
// {{{ getAssoc() |
/** |
* Fetches an entire query result and returns it as an |
* associative array using the first column as the key |
* |
* If the result set contains more than two columns, the value |
* will be an array of the values from column 2-n. If the result |
* set contains only two columns, the returned value will be a |
* scalar with the value of the second column (unless forced to an |
* array with the $force_array parameter). A DB error code is |
* returned on errors. If the result set contains fewer than two |
* columns, a DB_ERROR_TRUNCATED error is returned. |
* |
* For example, if the table "mytable" contains: |
* |
* <pre> |
* ID TEXT DATE |
* -------------------------------- |
* 1 'one' 944679408 |
* 2 'two' 944679408 |
* 3 'three' 944679408 |
* </pre> |
* |
* Then the call getAssoc('SELECT id,text FROM mytable') returns: |
* <pre> |
* array( |
* '1' => 'one', |
* '2' => 'two', |
* '3' => 'three', |
* ) |
* </pre> |
* |
* ...while the call getAssoc('SELECT id,text,date FROM mytable') returns: |
* <pre> |
* array( |
* '1' => array('one', '944679408'), |
* '2' => array('two', '944679408'), |
* '3' => array('three', '944679408') |
* ) |
* </pre> |
* |
* If the more than one row occurs with the same value in the |
* first column, the last row overwrites all previous ones by |
* default. Use the $group parameter if you don't want to |
* overwrite like this. Example: |
* |
* <pre> |
* getAssoc('SELECT category,id,name FROM mytable', false, null, |
* DB_FETCHMODE_ASSOC, true) returns: |
* |
* array( |
* '1' => array(array('id' => '4', 'name' => 'number four'), |
* array('id' => '6', 'name' => 'number six') |
* ), |
* '9' => array(array('id' => '4', 'name' => 'number four'), |
* array('id' => '6', 'name' => 'number six') |
* ) |
* ) |
* </pre> |
* |
* Keep in mind that database functions in PHP usually return string |
* values for results regardless of the database's internal type. |
* |
* @param string $query the SQL query |
* @param bool $force_array used only when the query returns |
* exactly two columns. If true, the values |
* of the returned array will be one-element |
* arrays instead of scalars. |
* @param mixed $params array, string or numeric data to be used in |
* execution of the statement. Quantity of |
* items passed must match quantity of |
* placeholders in query: meaning 1 |
* placeholder for non-array parameters or |
* 1 placeholder per array element. |
* @param int $fetchmode the fetch mode to use |
* @param bool $group if true, the values of the returned array |
* is wrapped in another array. If the same |
* key value (in the first column) repeats |
* itself, the values will be appended to |
* this array instead of overwriting the |
* existing values. |
* |
* @return array the associative array containing the query results. |
* A DB_Error object on failure. |
*/ |
function &getAssoc($query, $force_array = false, $params = array(), |
$fetchmode = DB_FETCHMODE_DEFAULT, $group = false) |
{ |
$params = (array)$params; |
if (sizeof($params) > 0) { |
$sth = $this->prepare($query); |
if (DB::isError($sth)) { |
return $sth; |
} |
$res = $this->execute($sth, $params); |
$this->freePrepared($sth); |
} else { |
$res = $this->query($query); |
} |
if (DB::isError($res)) { |
return $res; |
} |
if ($fetchmode == DB_FETCHMODE_DEFAULT) { |
$fetchmode = $this->fetchmode; |
} |
$cols = $res->numCols(); |
if ($cols < 2) { |
$tmp = $this->raiseError(DB_ERROR_TRUNCATED); |
return $tmp; |
} |
$results = array(); |
if ($cols > 2 || $force_array) { |
// return array values |
// XXX this part can be optimized |
if ($fetchmode == DB_FETCHMODE_ASSOC) { |
while (is_array($row = $res->fetchRow(DB_FETCHMODE_ASSOC))) { |
reset($row); |
$key = current($row); |
unset($row[key($row)]); |
if ($group) { |
$results[$key][] = $row; |
} else { |
$results[$key] = $row; |
} |
} |
} elseif ($fetchmode == DB_FETCHMODE_OBJECT) { |
while ($row = $res->fetchRow(DB_FETCHMODE_OBJECT)) { |
$arr = get_object_vars($row); |
$key = current($arr); |
if ($group) { |
$results[$key][] = $row; |
} else { |
$results[$key] = $row; |
} |
} |
} else { |
while (is_array($row = $res->fetchRow(DB_FETCHMODE_ORDERED))) { |
// we shift away the first element to get |
// indices running from 0 again |
$key = array_shift($row); |
if ($group) { |
$results[$key][] = $row; |
} else { |
$results[$key] = $row; |
} |
} |
} |
if (DB::isError($row)) { |
$results = $row; |
} |
} else { |
// return scalar values |
while (is_array($row = $res->fetchRow(DB_FETCHMODE_ORDERED))) { |
if ($group) { |
$results[$row[0]][] = $row[1]; |
} else { |
$results[$row[0]] = $row[1]; |
} |
} |
if (DB::isError($row)) { |
$results = $row; |
} |
} |
$res->free(); |
return $results; |
} |
// }}} |
// {{{ getAll() |
/** |
* Fetches all of the rows from a query result |
* |
* @param string $query the SQL query |
* @param mixed $params array, string or numeric data to be used in |
* execution of the statement. Quantity of |
* items passed must match quantity of |
* placeholders in query: meaning 1 |
* placeholder for non-array parameters or |
* 1 placeholder per array element. |
* @param int $fetchmode the fetch mode to use: |
* + DB_FETCHMODE_ORDERED |
* + DB_FETCHMODE_ASSOC |
* + DB_FETCHMODE_ORDERED | DB_FETCHMODE_FLIPPED |
* + DB_FETCHMODE_ASSOC | DB_FETCHMODE_FLIPPED |
* |
* @return array the nested array. A DB_Error object on failure. |
*/ |
function &getAll($query, $params = array(), |
$fetchmode = DB_FETCHMODE_DEFAULT) |
{ |
// compat check, the params and fetchmode parameters used to |
// have the opposite order |
if (!is_array($params)) { |
if (is_array($fetchmode)) { |
if ($params === null) { |
$tmp = DB_FETCHMODE_DEFAULT; |
} else { |
$tmp = $params; |
} |
$params = $fetchmode; |
$fetchmode = $tmp; |
} elseif ($params !== null) { |
$fetchmode = $params; |
$params = array(); |
} |
} |
if (sizeof($params) > 0) { |
$sth = $this->prepare($query); |
if (DB::isError($sth)) { |
return $sth; |
} |
$res = $this->execute($sth, $params); |
$this->freePrepared($sth); |
} else { |
$res = $this->query($query); |
} |
if ($res === DB_OK || DB::isError($res)) { |
return $res; |
} |
$results = array(); |
while (DB_OK === $res->fetchInto($row, $fetchmode)) { |
if ($fetchmode & DB_FETCHMODE_FLIPPED) { |
foreach ($row as $key => $val) { |
$results[$key][] = $val; |
} |
} else { |
$results[] = $row; |
} |
} |
$res->free(); |
if (DB::isError($row)) { |
$tmp = $this->raiseError($row); |
return $tmp; |
} |
return $results; |
} |
// }}} |
// {{{ autoCommit() |
/** |
* Enables or disables automatic commits |
* |
* @param bool $onoff true turns it on, false turns it off |
* |
* @return int DB_OK on success. A DB_Error object if the driver |
* doesn't support auto-committing transactions. |
*/ |
function autoCommit($onoff = false) |
{ |
return $this->raiseError(DB_ERROR_NOT_CAPABLE); |
} |
// }}} |
// {{{ commit() |
/** |
* Commits the current transaction |
* |
* @return int DB_OK on success. A DB_Error object on failure. |
*/ |
function commit() |
{ |
return $this->raiseError(DB_ERROR_NOT_CAPABLE); |
} |
// }}} |
// {{{ rollback() |
/** |
* Reverts the current transaction |
* |
* @return int DB_OK on success. A DB_Error object on failure. |
*/ |
function rollback() |
{ |
return $this->raiseError(DB_ERROR_NOT_CAPABLE); |
} |
// }}} |
// {{{ numRows() |
/** |
* Determines the number of rows in a query result |
* |
* @param resource $result the query result idenifier produced by PHP |
* |
* @return int the number of rows. A DB_Error object on failure. |
*/ |
function numRows($result) |
{ |
return $this->raiseError(DB_ERROR_NOT_CAPABLE); |
} |
// }}} |
// {{{ affectedRows() |
/** |
* Determines the number of rows affected by a data maniuplation query |
* |
* 0 is returned for queries that don't manipulate data. |
* |
* @return int the number of rows. A DB_Error object on failure. |
*/ |
function affectedRows() |
{ |
return $this->raiseError(DB_ERROR_NOT_CAPABLE); |
} |
// }}} |
// {{{ getSequenceName() |
/** |
* Generates the name used inside the database for a sequence |
* |
* The createSequence() docblock contains notes about storing sequence |
* names. |
* |
* @param string $sqn the sequence's public name |
* |
* @return string the sequence's name in the backend |
* |
* @access protected |
* @see DB_common::createSequence(), DB_common::dropSequence(), |
* DB_common::nextID(), DB_common::setOption() |
*/ |
function getSequenceName($sqn) |
{ |
return sprintf($this->getOption('seqname_format'), |
preg_replace('/[^a-z0-9_.]/i', '_', $sqn)); |
} |
// }}} |
// {{{ nextId() |
/** |
* Returns the next free id in a sequence |
* |
* @param string $seq_name name of the sequence |
* @param boolean $ondemand when true, the seqence is automatically |
* created if it does not exist |
* |
* @return int the next id number in the sequence. |
* A DB_Error object on failure. |
* |
* @see DB_common::createSequence(), DB_common::dropSequence(), |
* DB_common::getSequenceName() |
*/ |
function nextId($seq_name, $ondemand = true) |
{ |
return $this->raiseError(DB_ERROR_NOT_CAPABLE); |
} |
// }}} |
// {{{ createSequence() |
/** |
* Creates a new sequence |
* |
* The name of a given sequence is determined by passing the string |
* provided in the <var>$seq_name</var> argument through PHP's sprintf() |
* function using the value from the <var>seqname_format</var> option as |
* the sprintf()'s format argument. |
* |
* <var>seqname_format</var> is set via setOption(). |
* |
* @param string $seq_name name of the new sequence |
* |
* @return int DB_OK on success. A DB_Error object on failure. |
* |
* @see DB_common::dropSequence(), DB_common::getSequenceName(), |
* DB_common::nextID() |
*/ |
function createSequence($seq_name) |
{ |
return $this->raiseError(DB_ERROR_NOT_CAPABLE); |
} |
// }}} |
// {{{ dropSequence() |
/** |
* Deletes a sequence |
* |
* @param string $seq_name name of the sequence to be deleted |
* |
* @return int DB_OK on success. A DB_Error object on failure. |
* |
* @see DB_common::createSequence(), DB_common::getSequenceName(), |
* DB_common::nextID() |
*/ |
function dropSequence($seq_name) |
{ |
return $this->raiseError(DB_ERROR_NOT_CAPABLE); |
} |
// }}} |
// {{{ raiseError() |
/** |
* Communicates an error and invoke error callbacks, etc |
* |
* Basically a wrapper for PEAR::raiseError without the message string. |
* |
* @param mixed integer error code, or a PEAR error object (all |
* other parameters are ignored if this parameter is |
* an object |
* @param int error mode, see PEAR_Error docs |
* @param mixed if error mode is PEAR_ERROR_TRIGGER, this is the |
* error level (E_USER_NOTICE etc). If error mode is |
* PEAR_ERROR_CALLBACK, this is the callback function, |
* either as a function name, or as an array of an |
* object and method name. For other error modes this |
* parameter is ignored. |
* @param string extra debug information. Defaults to the last |
* query and native error code. |
* @param mixed native error code, integer or string depending the |
* backend |
* @param mixed dummy parameter for E_STRICT compatibility with |
* PEAR::raiseError |
* @param mixed dummy parameter for E_STRICT compatibility with |
* PEAR::raiseError |
* |
* @return object the PEAR_Error object |
* |
* @see PEAR_Error |
*/ |
function &raiseError($code = DB_ERROR, $mode = null, $options = null, |
$userinfo = null, $nativecode = null, $dummy1 = null, |
$dummy2 = null) |
{ |
// The error is yet a DB error object |
if (is_object($code)) { |
// because we the static PEAR::raiseError, our global |
// handler should be used if it is set |
if ($mode === null && !empty($this->_default_error_mode)) { |
$mode = $this->_default_error_mode; |
$options = $this->_default_error_options; |
} |
$tmp = PEAR::raiseError($code, null, $mode, $options, |
null, null, true); |
return $tmp; |
} |
if ($userinfo === null) { |
$userinfo = $this->last_query; |
} |
if ($nativecode) { |
$userinfo .= ' [nativecode=' . trim($nativecode) . ']'; |
} else { |
$userinfo .= ' [DB Error: ' . DB::errorMessage($code) . ']'; |
} |
$tmp = PEAR::raiseError(null, $code, $mode, $options, $userinfo, |
'DB_Error', true); |
return $tmp; |
} |
// }}} |
// {{{ errorNative() |
/** |
* Gets the DBMS' native error code produced by the last query |
* |
* @return mixed the DBMS' error code. A DB_Error object on failure. |
*/ |
function errorNative() |
{ |
return $this->raiseError(DB_ERROR_NOT_CAPABLE); |
} |
// }}} |
// {{{ errorCode() |
/** |
* Maps native error codes to DB's portable ones |
* |
* Uses the <var>$errorcode_map</var> property defined in each driver. |
* |
* @param string|int $nativecode the error code returned by the DBMS |
* |
* @return int the portable DB error code. Return DB_ERROR if the |
* current driver doesn't have a mapping for the |
* $nativecode submitted. |
*/ |
function errorCode($nativecode) |
{ |
if (isset($this->errorcode_map[$nativecode])) { |
return $this->errorcode_map[$nativecode]; |
} |
// Fall back to DB_ERROR if there was no mapping. |
return DB_ERROR; |
} |
// }}} |
// {{{ errorMessage() |
/** |
* Maps a DB error code to a textual message |
* |
* @param integer $dbcode the DB error code |
* |
* @return string the error message corresponding to the error code |
* submitted. FALSE if the error code is unknown. |
* |
* @see DB::errorMessage() |
*/ |
function errorMessage($dbcode) |
{ |
return DB::errorMessage($this->errorcode_map[$dbcode]); |
} |
// }}} |
// {{{ tableInfo() |
/** |
* Returns information about a table or a result set |
* |
* The format of the resulting array depends on which <var>$mode</var> |
* you select. The sample output below is based on this query: |
* <pre> |
* SELECT tblFoo.fldID, tblFoo.fldPhone, tblBar.fldId |
* FROM tblFoo |
* JOIN tblBar ON tblFoo.fldId = tblBar.fldId |
* </pre> |
* |
* <ul> |
* <li> |
* |
* <kbd>null</kbd> (default) |
* <pre> |
* [0] => Array ( |
* [table] => tblFoo |
* [name] => fldId |
* [type] => int |
* [len] => 11 |
* [flags] => primary_key not_null |
* ) |
* [1] => Array ( |
* [table] => tblFoo |
* [name] => fldPhone |
* [type] => string |
* [len] => 20 |
* [flags] => |
* ) |
* [2] => Array ( |
* [table] => tblBar |
* [name] => fldId |
* [type] => int |
* [len] => 11 |
* [flags] => primary_key not_null |
* ) |
* </pre> |
* |
* </li><li> |
* |
* <kbd>DB_TABLEINFO_ORDER</kbd> |
* |
* <p>In addition to the information found in the default output, |
* a notation of the number of columns is provided by the |
* <samp>num_fields</samp> element while the <samp>order</samp> |
* element provides an array with the column names as the keys and |
* their location index number (corresponding to the keys in the |
* the default output) as the values.</p> |
* |
* <p>If a result set has identical field names, the last one is |
* used.</p> |
* |
* <pre> |
* [num_fields] => 3 |
* [order] => Array ( |
* [fldId] => 2 |
* [fldTrans] => 1 |
* ) |
* </pre> |
* |
* </li><li> |
* |
* <kbd>DB_TABLEINFO_ORDERTABLE</kbd> |
* |
* <p>Similar to <kbd>DB_TABLEINFO_ORDER</kbd> but adds more |
* dimensions to the array in which the table names are keys and |
* the field names are sub-keys. This is helpful for queries that |
* join tables which have identical field names.</p> |
* |
* <pre> |
* [num_fields] => 3 |
* [ordertable] => Array ( |
* [tblFoo] => Array ( |
* [fldId] => 0 |
* [fldPhone] => 1 |
* ) |
* [tblBar] => Array ( |
* [fldId] => 2 |
* ) |
* ) |
* </pre> |
* |
* </li> |
* </ul> |
* |
* The <samp>flags</samp> element contains a space separated list |
* of extra information about the field. This data is inconsistent |
* between DBMS's due to the way each DBMS works. |
* + <samp>primary_key</samp> |
* + <samp>unique_key</samp> |
* + <samp>multiple_key</samp> |
* + <samp>not_null</samp> |
* |
* Most DBMS's only provide the <samp>table</samp> and <samp>flags</samp> |
* elements if <var>$result</var> is a table name. The following DBMS's |
* provide full information from queries: |
* + fbsql |
* + mysql |
* |
* If the 'portability' option has <samp>DB_PORTABILITY_LOWERCASE</samp> |
* turned on, the names of tables and fields will be lowercased. |
* |
* @param object|string $result DB_result object from a query or a |
* string containing the name of a table. |
* While this also accepts a query result |
* resource identifier, this behavior is |
* deprecated. |
* @param int $mode either unused or one of the tableInfo modes: |
* <kbd>DB_TABLEINFO_ORDERTABLE</kbd>, |
* <kbd>DB_TABLEINFO_ORDER</kbd> or |
* <kbd>DB_TABLEINFO_FULL</kbd> (which does both). |
* These are bitwise, so the first two can be |
* combined using <kbd>|</kbd>. |
* |
* @return array an associative array with the information requested. |
* A DB_Error object on failure. |
* |
* @see DB_common::setOption() |
*/ |
function tableInfo($result, $mode = null) |
{ |
/* |
* If the DB_<driver> class has a tableInfo() method, that one |
* overrides this one. But, if the driver doesn't have one, |
* this method runs and tells users about that fact. |
*/ |
return $this->raiseError(DB_ERROR_NOT_CAPABLE); |
} |
// }}} |
// {{{ getTables() |
/** |
* Lists the tables in the current database |
* |
* @return array the list of tables. A DB_Error object on failure. |
* |
* @deprecated Method deprecated some time before Release 1.2 |
*/ |
function getTables() |
{ |
return $this->getListOf('tables'); |
} |
// }}} |
// {{{ getListOf() |
/** |
* Lists internal database information |
* |
* @param string $type type of information being sought. |
* Common items being sought are: |
* tables, databases, users, views, functions |
* Each DBMS's has its own capabilities. |
* |
* @return array an array listing the items sought. |
* A DB DB_Error object on failure. |
*/ |
function getListOf($type) |
{ |
$sql = $this->getSpecialQuery($type); |
if ($sql === null) { |
$this->last_query = ''; |
return $this->raiseError(DB_ERROR_UNSUPPORTED); |
} elseif (is_int($sql) || DB::isError($sql)) { |
// Previous error |
return $this->raiseError($sql); |
} elseif (is_array($sql)) { |
// Already the result |
return $sql; |
} |
// Launch this query |
return $this->getCol($sql); |
} |
// }}} |
// {{{ getSpecialQuery() |
/** |
* Obtains the query string needed for listing a given type of objects |
* |
* @param string $type the kind of objects you want to retrieve |
* |
* @return string the SQL query string or null if the driver doesn't |
* support the object type requested |
* |
* @access protected |
* @see DB_common::getListOf() |
*/ |
function getSpecialQuery($type) |
{ |
return $this->raiseError(DB_ERROR_UNSUPPORTED); |
} |
// }}} |
// {{{ nextQueryIsManip() |
/** |
* Sets (or unsets) a flag indicating that the next query will be a |
* manipulation query, regardless of the usual DB::isManip() heuristics. |
* |
* @param boolean true to set the flag overriding the isManip() behaviour, |
* false to clear it and fall back onto isManip() |
* |
* @return void |
* |
* @access public |
*/ |
function nextQueryIsManip($manip) |
{ |
$this->_next_query_manip = $manip; |
} |
// }}} |
// {{{ _checkManip() |
/** |
* Checks if the given query is a manipulation query. This also takes into |
* account the _next_query_manip flag and sets the _last_query_manip flag |
* (and resets _next_query_manip) according to the result. |
* |
* @param string The query to check. |
* |
* @return boolean true if the query is a manipulation query, false |
* otherwise |
* |
* @access protected |
*/ |
function _checkManip($query) |
{ |
if ($this->_next_query_manip || DB::isManip($query)) { |
$this->_last_query_manip = true; |
} else { |
$this->_last_query_manip = false; |
} |
$this->_next_query_manip = false; |
return $this->_last_query_manip; |
$manip = $this->_next_query_manip; |
} |
// }}} |
// {{{ _rtrimArrayValues() |
/** |
* Right-trims all strings in an array |
* |
* @param array $array the array to be trimmed (passed by reference) |
* |
* @return void |
* |
* @access protected |
*/ |
function _rtrimArrayValues(&$array) |
{ |
foreach ($array as $key => $value) { |
if (is_string($value)) { |
$array[$key] = rtrim($value); |
} |
} |
} |
// }}} |
// {{{ _convertNullArrayValuesToEmpty() |
/** |
* Converts all null values in an array to empty strings |
* |
* @param array $array the array to be de-nullified (passed by reference) |
* |
* @return void |
* |
* @access protected |
*/ |
function _convertNullArrayValuesToEmpty(&$array) |
{ |
foreach ($array as $key => $value) { |
if (is_null($value)) { |
$array[$key] = ''; |
} |
} |
} |
// }}} |
} |
/* |
* Local variables: |
* tab-width: 4 |
* c-basic-offset: 4 |
* End: |
*/ |
?> |
/obs_saisons/SPIP-v1-8-3/modules/configuration/Auth.php |
---|
New file |
0,0 → 1,1365 |
<?php |
/* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4 foldmethod=marker: */ |
/** |
* The main include file for Auth package |
* |
* PHP versions 4 and 5 |
* |
* LICENSE: This source file is subject to version 3.01 of the PHP license |
* that is available through the world-wide-web at the following URI: |
* http://www.php.net/license/3_01.txt. If you did not receive a copy of |
* the PHP License and are unable to obtain it through the web, please |
* send a note to license@php.net so we can mail you a copy immediately. |
* |
* @category Authentication |
* @package Auth |
* @author Martin Jansen <mj@php.net> |
* @author Adam Ashley <aashley@php.net> |
* @copyright 2001-2006 The PHP Group |
* @license http://www.php.net/license/3_01.txt PHP License 3.01 |
* @version CVS: $Id: Auth.php,v 1.123 2008/04/04 03:50:26 aashley Exp $ |
* @link http://pear.php.net/package/Auth |
*/ |
/** |
* Returned if session exceeds idle time |
*/ |
define('AUTH_IDLED', -1); |
/** |
* Returned if session has expired |
*/ |
define('AUTH_EXPIRED', -2); |
/** |
* Returned if container is unable to authenticate user/password pair |
*/ |
define('AUTH_WRONG_LOGIN', -3); |
/** |
* Returned if a container method is not supported. |
*/ |
define('AUTH_METHOD_NOT_SUPPORTED', -4); |
/** |
* Returned if new Advanced security system detects a breach |
*/ |
define('AUTH_SECURITY_BREACH', -5); |
/** |
* Returned if checkAuthCallback says session should not continue. |
*/ |
define('AUTH_CALLBACK_ABORT', -6); |
/** |
* Auth Log level - INFO |
*/ |
define('AUTH_LOG_INFO', 6); |
/** |
* Auth Log level - DEBUG |
*/ |
define('AUTH_LOG_DEBUG', 7); |
/** |
* Auth Advanced Security - IP Checks |
*/ |
define('AUTH_ADV_IPCHECK', 1); |
/** |
* Auth Advanced Security - User Agent Checks |
*/ |
define('AUTH_ADV_USERAGENT', 2); |
/** |
* Auth Advanced Security - Challenge Response |
*/ |
define('AUTH_ADV_CHALLENGE', 3); |
/** |
* PEAR::Auth |
* |
* The PEAR::Auth class provides methods for creating an |
* authentication system using PHP. |
* |
* @category Authentication |
* @package Auth |
* @author Martin Jansen <mj@php.net> |
* @author Adam Ashley <aashley@php.net> |
* @copyright 2001-2006 The PHP Group |
* @license http://www.php.net/license/3_01.txt PHP License 3.01 |
* @version Release: 1.6.1 File: $Revision: 1.123 $ |
* @link http://pear.php.net/package/Auth |
*/ |
class Auth { |
// {{{ properties |
/** |
* Auth lifetime in seconds |
* |
* If this variable is set to 0, auth never expires |
* |
* @var integer |
* @see setExpire(), checkAuth() |
*/ |
var $expire = 0; |
/** |
* Has the auth session expired? |
* |
* @var bool |
* @see checkAuth() |
*/ |
var $expired = false; |
/** |
* Maximum idletime in seconds |
* |
* The difference to $expire is, that the idletime gets |
* refreshed each time checkAuth() is called. If this |
* variable is set to 0, idletime is never checked. |
* |
* @var integer |
* @see setIdle(), checkAuth() |
*/ |
var $idle = 0; |
/** |
* Is the maximum idletime over? |
* |
* @var boolean |
* @see checkAuth() |
*/ |
var $idled = false; |
/** |
* Storage object |
* |
* @var object |
* @see Auth(), validateLogin() |
*/ |
var $storage = ''; |
/** |
* User-defined function that creates the login screen |
* |
* @var string |
*/ |
var $loginFunction = ''; |
/** |
* Should the login form be displayed |
* |
* @var bool |
* @see setShowlogin() |
*/ |
var $showLogin = true; |
/** |
* Is Login Allowed from this page |
* |
* @var bool |
* @see setAllowLogin |
*/ |
var $allowLogin = true; |
/** |
* Current authentication status |
* |
* @var string |
*/ |
var $status = ''; |
/** |
* Username |
* |
* @var string |
*/ |
var $username = ''; |
/** |
* Password |
* |
* @var string |
*/ |
var $password = ''; |
/** |
* checkAuth callback function name |
* |
* @var string |
* @see setCheckAuthCallback() |
*/ |
var $checkAuthCallback = ''; |
/** |
* Login callback function name |
* |
* @var string |
* @see setLoginCallback() |
*/ |
var $loginCallback = ''; |
/** |
* Failed Login callback function name |
* |
* @var string |
* @see setFailedLoginCallback() |
*/ |
var $loginFailedCallback = ''; |
/** |
* Logout callback function name |
* |
* @var string |
* @see setLogoutCallback() |
*/ |
var $logoutCallback = ''; |
/** |
* Auth session-array name |
* |
* @var string |
*/ |
var $_sessionName = '_authsession'; |
/** |
* Package Version |
* |
* @var string |
*/ |
var $version = "@version@"; |
/** |
* Flag to use advanced security |
* When set extra checks will be made to see if the |
* user's IP or useragent have changed across requests. |
* Turned off by default to preserve BC. |
* |
* @var mixed Boolean to turn all advanced security options on or off |
* Array containing named values turning specific advanced |
* security features on or off individually |
* array( |
* AUTH_ADV_IPCHECK => true, |
* AUTH_ADV_USERAGENT => true, |
* AUTH_ADV_CHALLENGE => true, |
* ); |
*/ |
var $advancedsecurity = false; |
/** |
* Username key in POST array |
* |
* @var string |
*/ |
var $_postUsername = 'username'; |
/** |
* Password key in POST array |
* |
* @var string |
*/ |
var $_postPassword = 'password'; |
/** |
* Holds a reference to the session auth variable |
* @var array |
*/ |
var $session; |
/** |
* Holds a reference to the global server variable |
* @var array |
*/ |
var $server; |
/** |
* Holds a reference to the global post variable |
* @var array |
*/ |
var $post; |
/** |
* Holds a reference to the global cookie variable |
* @var array |
*/ |
var $cookie; |
/** |
* A hash to hold various superglobals as reference |
* @var array |
*/ |
var $authdata; |
/** |
* How many times has checkAuth been called |
* @var int |
*/ |
var $authChecks = 0; |
/** |
* PEAR::Log object |
* |
* @var object Log |
*/ |
var $logger = null; |
/** |
* Whether to enable logging of behaviour |
* |
* @var boolean |
*/ |
var $enableLogging = false; |
/** |
* Whether to regenerate session id everytime start is called |
* |
* @var boolean |
*/ |
var $regenerateSessionId = false; |
// }}} |
// {{{ Auth() [constructor] |
/** |
* Constructor |
* |
* Set up the storage driver. |
* |
* @param string Type of the storage driver |
* @param mixed Additional options for the storage driver |
* (example: if you are using DB as the storage |
* driver, you have to pass the dsn string here) |
* |
* @param string Name of the function that creates the login form |
* @param boolean Should the login form be displayed if neccessary? |
* @return void |
*/ |
function Auth($storageDriver, $options = '', $loginFunction = '', $showLogin = true) |
{ |
$this->applyAuthOptions($options); |
// Start the session suppress error if already started |
if(!session_id()){ |
@session_start(); |
if(!session_id()) { |
// Throw error |
include_once 'PEAR.php'; |
PEAR::throwError('Session could not be started by Auth, ' |
.'possibly headers are already sent, try putting ' |
.'ob_start in the beginning of your script'); |
} |
} |
// Make Sure Auth session variable is there |
if(!isset($_SESSION[$this->_sessionName])) { |
$_SESSION[$this->_sessionName] = array(); |
} |
// Assign Some globals to internal references, this will replace _importGlobalVariable |
$this->session =& $_SESSION[$this->_sessionName]; |
$this->server =& $_SERVER; |
$this->post =& $_POST; |
$this->cookie =& $_COOKIE; |
if ($loginFunction != '' && is_callable($loginFunction)) { |
$this->loginFunction = $loginFunction; |
} |
if (is_bool($showLogin)) { |
$this->showLogin = $showLogin; |
} |
if (is_object($storageDriver)) { |
$this->storage =& $storageDriver; |
// Pass a reference to auth to the container, ugly but works |
// this is used by the DB container to use method setAuthData not staticaly. |
$this->storage->_auth_obj =& $this; |
} else { |
// $this->storage = $this->_factory($storageDriver, $options); |
// |
$this->storage_driver = $storageDriver; |
$this->storage_options =& $options; |
} |
} |
// }}} |
// {{{ applyAuthOptions() |
/** |
* Set the Auth options |
* |
* Some options which are Auth specific will be applied |
* the rest will be left for usage by the container |
* |
* @param array An array of Auth options |
* @return array The options which were not applied |
* @access private |
*/ |
function &applyAuthOptions(&$options) |
{ |
if(is_array($options)){ |
if (!empty($options['sessionName'])) { |
$this->_sessionName = $options['sessionName']; |
unset($options['sessionName']); |
} |
if (isset($options['allowLogin'])) { |
$this->allowLogin = $options['allowLogin']; |
unset($options['allowLogin']); |
} |
if (!empty($options['postUsername'])) { |
$this->_postUsername = $options['postUsername']; |
unset($options['postUsername']); |
} |
if (!empty($options['postPassword'])) { |
$this->_postPassword = $options['postPassword']; |
unset($options['postPassword']); |
} |
if (isset($options['advancedsecurity'])) { |
$this->advancedsecurity = $options['advancedsecurity']; |
unset($options['advancedsecurity']); |
} |
if (isset($options['enableLogging'])) { |
$this->enableLogging = $options['enableLogging']; |
unset($options['enableLogging']); |
} |
if (isset($options['regenerateSessionId']) && is_bool($options['regenerateSessionId'])) { |
$this->regenerateSessionId = $options['regenerateSessionId']; |
} |
} |
return($options); |
} |
// }}} |
// {{{ _loadStorage() |
/** |
* Load Storage Driver if not already loaded |
* |
* Suspend storage instantiation to make Auth lighter to use |
* for calls which do not require login |
* |
* @return bool True if the conainer is loaded, false if the container |
* is already loaded |
* @access private |
*/ |
function _loadStorage() |
{ |
if(!is_object($this->storage)) { |
$this->storage =& $this->_factory($this->storage_driver, |
$this->storage_options); |
$this->storage->_auth_obj =& $this; |
$this->log('Loaded storage container ('.$this->storage_driver.')', AUTH_LOG_DEBUG); |
return(true); |
} |
return(false); |
} |
// }}} |
// {{{ _factory() |
/** |
* Return a storage driver based on $driver and $options |
* |
* @static |
* @param string $driver Type of storage class to return |
* @param string $options Optional parameters for the storage class |
* @return object Object Storage object |
* @access private |
*/ |
function &_factory($driver, $options = '') |
{ |
$storage_class = 'Auth_Container_' . $driver; |
include_once 'Auth/Container/' . $driver . '.php'; |
$obj =& new $storage_class($options); |
return $obj; |
} |
// }}} |
// {{{ assignData() |
/** |
* Assign data from login form to internal values |
* |
* This function takes the values for username and password |
* from $HTTP_POST_VARS/$_POST and assigns them to internal variables. |
* If you wish to use another source apart from $HTTP_POST_VARS/$_POST, |
* you have to derive this function. |
* |
* @global $HTTP_POST_VARS, $_POST |
* @see Auth |
* @return void |
* @access private |
*/ |
function assignData() |
{ |
$this->log('Auth::assignData() called.', AUTH_LOG_DEBUG); |
if ( isset($this->post[$this->_postUsername]) |
&& $this->post[$this->_postUsername] != '') { |
$this->username = (get_magic_quotes_gpc() == 1 |
? stripslashes($this->post[$this->_postUsername]) |
: $this->post[$this->_postUsername]); |
} |
if ( isset($this->post[$this->_postPassword]) |
&& $this->post[$this->_postPassword] != '') { |
$this->password = (get_magic_quotes_gpc() == 1 |
? stripslashes($this->post[$this->_postPassword]) |
: $this->post[$this->_postPassword] ); |
} |
} |
// }}} |
// {{{ start() |
/** |
* Start new auth session |
* |
* @return void |
* @access public |
*/ |
function start() |
{ |
$this->log('Auth::start() called.', AUTH_LOG_DEBUG); |
// #10729 - Regenerate session id here if we are generating it on every |
// page load. |
if ($this->regenerateSessionId) { |
session_regenerate_id(true); |
} |
$this->assignData(); |
if (!$this->checkAuth() && $this->allowLogin) { |
$this->login(); |
} |
} |
// }}} |
// {{{ login() |
/** |
* Login function |
* |
* @return void |
* @access private |
*/ |
function login() |
{ |
$this->log('Auth::login() called.', AUTH_LOG_DEBUG); |
$login_ok = false; |
$this->_loadStorage(); |
// Check if using challenge response |
(isset($this->post['authsecret']) && $this->post['authsecret'] == 1) |
? $usingChap = true |
: $usingChap = false; |
// When the user has already entered a username, we have to validate it. |
if (!empty($this->username)) { |
if (true === $this->storage->fetchData($this->username, $this->password, $usingChap)) { |
$this->session['challengekey'] = md5($this->username.$this->password); |
$login_ok = true; |
$this->log('Successful login.', AUTH_LOG_INFO); |
} |
} |
if (!empty($this->username) && $login_ok) { |
$this->setAuth($this->username); |
if (is_callable($this->loginCallback)) { |
$this->log('Calling loginCallback ('.$this->loginCallback.').', AUTH_LOG_DEBUG); |
call_user_func_array($this->loginCallback, array($this->username, &$this)); |
} |
} |
// If the login failed or the user entered no username, |
// output the login screen again. |
if (!empty($this->username) && !$login_ok) { |
$this->log('Incorrect login.', AUTH_LOG_INFO); |
$this->status = AUTH_WRONG_LOGIN; |
if (is_callable($this->loginFailedCallback)) { |
$this->log('Calling loginFailedCallback ('.$this->loginFailedCallback.').', AUTH_LOG_DEBUG); |
call_user_func_array($this->loginFailedCallback, array($this->username, &$this)); |
} |
} |
if ((empty($this->username) || !$login_ok) && $this->showLogin) { |
$this->log('Rendering Login Form.', AUTH_LOG_INFO); |
if (is_callable($this->loginFunction)) { |
$this->log('Calling loginFunction ('.$this->loginFunction.').', AUTH_LOG_DEBUG); |
call_user_func_array($this->loginFunction, array($this->username, $this->status, &$this)); |
} else { |
// BC fix Auth used to use drawLogin for this |
// call is sub classes implement this |
if (is_callable(array($this, 'drawLogin'))) { |
$this->log('Calling Auth::drawLogin()', AUTH_LOG_DEBUG); |
return $this->drawLogin($this->username, $this); |
} |
$this->log('Using default Auth_Frontend_Html', AUTH_LOG_DEBUG); |
// New Login form |
include_once 'Auth/Frontend/Html.php'; |
return Auth_Frontend_Html::render($this, $this->username); |
} |
} else { |
return; |
} |
} |
// }}} |
// {{{ setExpire() |
/** |
* Set the maximum expire time |
* |
* @param integer time in seconds |
* @param bool add time to current expire time or not |
* @return void |
* @access public |
*/ |
function setExpire($time, $add = false) |
{ |
$add ? $this->expire += $time : $this->expire = $time; |
} |
// }}} |
// {{{ setIdle() |
/** |
* Set the maximum idle time |
* |
* @param integer time in seconds |
* @param bool add time to current maximum idle time or not |
* @return void |
* @access public |
*/ |
function setIdle($time, $add = false) |
{ |
$add ? $this->idle += $time : $this->idle = $time; |
} |
// }}} |
// {{{ setSessionName() |
/** |
* Set name of the session to a customized value. |
* |
* If you are using multiple instances of PEAR::Auth |
* on the same domain, you can change the name of |
* session per application via this function. |
* This will chnage the name of the session variable |
* auth uses to store it's data in the session |
* |
* @param string New name for the session |
* @return void |
* @access public |
*/ |
function setSessionName($name = 'session') |
{ |
$this->_sessionName = '_auth_'.$name; |
// Make Sure Auth session variable is there |
if(!isset($_SESSION[$this->_sessionName])) { |
$_SESSION[$this->_sessionName] = array(); |
} |
$this->session =& $_SESSION[$this->_sessionName]; |
} |
// }}} |
// {{{ setShowLogin() |
/** |
* Should the login form be displayed if neccessary? |
* |
* @param bool show login form or not |
* @return void |
* @access public |
*/ |
function setShowLogin($showLogin = true) |
{ |
$this->showLogin = $showLogin; |
} |
// }}} |
// {{{ setAllowLogin() |
/** |
* Should the login form be displayed if neccessary? |
* |
* @param bool show login form or not |
* @return void |
* @access public |
*/ |
function setAllowLogin($allowLogin = true) |
{ |
$this->allowLogin = $allowLogin; |
} |
// }}} |
// {{{ setCheckAuthCallback() |
/** |
* Register a callback function to be called whenever the validity of the login is checked |
* The function will receive two parameters, the username and a reference to the auth object. |
* |
* @param string callback function name |
* @return void |
* @access public |
* @since Method available since Release 1.4.3 |
*/ |
function setCheckAuthCallback($checkAuthCallback) |
{ |
$this->checkAuthCallback = $checkAuthCallback; |
} |
// }}} |
// {{{ setLoginCallback() |
/** |
* Register a callback function to be called on user login. |
* The function will receive two parameters, the username and a reference to the auth object. |
* |
* @param string callback function name |
* @return void |
* @see setLogoutCallback() |
* @access public |
*/ |
function setLoginCallback($loginCallback) |
{ |
$this->loginCallback = $loginCallback; |
} |
// }}} |
// {{{ setFailedLoginCallback() |
/** |
* Register a callback function to be called on failed user login. |
* The function will receive two parameters, the username and a reference to the auth object. |
* |
* @param string callback function name |
* @return void |
* @access public |
*/ |
function setFailedLoginCallback($loginFailedCallback) |
{ |
$this->loginFailedCallback = $loginFailedCallback; |
} |
// }}} |
// {{{ setLogoutCallback() |
/** |
* Register a callback function to be called on user logout. |
* The function will receive three parameters, the username and a reference to the auth object. |
* |
* @param string callback function name |
* @return void |
* @see setLoginCallback() |
* @access public |
*/ |
function setLogoutCallback($logoutCallback) |
{ |
$this->logoutCallback = $logoutCallback; |
} |
// }}} |
// {{{ setAuthData() |
/** |
* Register additional information that is to be stored |
* in the session. |
* |
* @param string Name of the data field |
* @param mixed Value of the data field |
* @param boolean Should existing data be overwritten? (default |
* is true) |
* @return void |
* @access public |
*/ |
function setAuthData($name, $value, $overwrite = true) |
{ |
if (!empty($this->session['data'][$name]) && $overwrite == false) { |
return; |
} |
$this->session['data'][$name] = $value; |
} |
// }}} |
// {{{ getAuthData() |
/** |
* Get additional information that is stored in the session. |
* |
* If no value for the first parameter is passed, the method will |
* return all data that is currently stored. |
* |
* @param string Name of the data field |
* @return mixed Value of the data field. |
* @access public |
*/ |
function getAuthData($name = null) |
{ |
if (!isset($this->session['data'])) { |
return null; |
} |
if(!isset($name)) { |
return $this->session['data']; |
} |
if (isset($name) && isset($this->session['data'][$name])) { |
return $this->session['data'][$name]; |
} |
return null; |
} |
// }}} |
// {{{ setAuth() |
/** |
* Register variable in a session telling that the user |
* has logged in successfully |
* |
* @param string Username |
* @return void |
* @access public |
*/ |
function setAuth($username) |
{ |
$this->log('Auth::setAuth() called.', AUTH_LOG_DEBUG); |
// #10729 - Regenerate session id here only if generating at login only |
// Don't do it if we are regenerating on every request so we don't |
// regenerate it twice in one request. |
if (!$this->regenerateSessionId) { |
// #2021 - Change the session id to avoid session fixation attacks php 4.3.3 > |
//session_regenerate_id(true); |
} |
if (!isset($this->session) || !is_array($this->session)) { |
$this->session = array(); |
} |
if (!isset($this->session['data'])) { |
$this->session['data'] = array(); |
} |
$this->session['sessionip'] = isset($this->server['REMOTE_ADDR']) |
? $this->server['REMOTE_ADDR'] |
: ''; |
$this->session['sessionuseragent'] = isset($this->server['HTTP_USER_AGENT']) |
? $this->server['HTTP_USER_AGENT'] |
: ''; |
$this->session['sessionforwardedfor'] = isset($this->server['HTTP_X_FORWARDED_FOR']) |
? $this->server['HTTP_X_FORWARDED_FOR'] |
: ''; |
// This should be set by the container to something more safe |
// Like md5(passwd.microtime) |
if(empty($this->session['challengekey'])) { |
$this->session['challengekey'] = md5($username.microtime()); |
} |
$this->session['challengecookie'] = md5($this->session['challengekey'].microtime()); |
//setcookie('authchallenge', $this->session['challengecookie'], 0, '/'); |
$this->session['registered'] = true; |
$this->session['username'] = $username; |
$this->session['timestamp'] = time(); |
$this->session['idle'] = time(); |
} |
// }}} |
// {{{ setAdvancedSecurity() |
/** |
* Enables advanced security checks |
* |
* Currently only ip change and useragent change |
* are detected |
* @todo Add challenge cookies - Create a cookie which changes every time |
* and contains some challenge key which the server can verify with |
* a session var cookie might need to be crypted (user pass) |
* @param bool Enable or disable |
* @return void |
* @access public |
*/ |
function setAdvancedSecurity($flag=true) |
{ |
$this->advancedsecurity = $flag; |
} |
// }}} |
// {{{ checkAuth() |
/** |
* Checks if there is a session with valid auth information. |
* |
* @access public |
* @return boolean Whether or not the user is authenticated. |
*/ |
function checkAuth() |
{ |
$this->log('Auth::checkAuth() called.', AUTH_LOG_DEBUG); |
$this->authChecks++; |
if (isset($this->session)) { |
// Check if authentication session is expired |
if ( $this->expire > 0 |
&& isset($this->session['timestamp']) |
&& ($this->session['timestamp'] + $this->expire) < time()) { |
$this->log('Session Expired', AUTH_LOG_INFO); |
$this->expired = true; |
$this->status = AUTH_EXPIRED; |
$this->logout(); |
return false; |
} |
// Check if maximum idle time is reached |
if ( $this->idle > 0 |
&& isset($this->session['idle']) |
&& ($this->session['idle'] + $this->idle) < time()) { |
$this->log('Session Idle Time Reached', AUTH_LOG_INFO); |
$this->idled = true; |
$this->status = AUTH_IDLED; |
$this->logout(); |
return false; |
} |
if ( isset($this->session['registered']) |
&& isset($this->session['username']) |
&& $this->session['registered'] == true |
&& $this->session['username'] != '') { |
Auth::updateIdle(); |
if ($this->_isAdvancedSecurityEnabled()) { |
$this->log('Advanced Security Mode Enabled.', AUTH_LOG_DEBUG); |
// Only Generate the challenge once |
if ( $this->authChecks == 1 |
&& $this->_isAdvancedSecurityEnabled(AUTH_ADV_CHALLENGE)) { |
$this->log('Generating new Challenge Cookie.', AUTH_LOG_DEBUG); |
$this->session['challengecookieold'] = $this->session['challengecookie']; |
$this->session['challengecookie'] = md5($this->session['challengekey'].microtime()); |
setcookie('authchallenge', $this->session['challengecookie'], 0, '/'); |
} |
// Check for ip change |
if ( $this->_isAdvancedSecurityEnabled(AUTH_ADV_IPCHECK) |
&& isset($this->server['REMOTE_ADDR']) |
&& $this->session['sessionip'] != $this->server['REMOTE_ADDR']) { |
$this->log('Security Breach. Remote IP Address changed.', AUTH_LOG_INFO); |
// Check if the IP of the user has changed, if so we |
// assume a man in the middle attack and log him out |
$this->expired = true; |
$this->status = AUTH_SECURITY_BREACH; |
$this->logout(); |
return false; |
} |
// Check for ip change (if connected via proxy) |
if ( $this->_isAdvancedSecurityEnabled(AUTH_ADV_IPCHECK) |
&& isset($this->server['HTTP_X_FORWARDED_FOR']) |
&& $this->session['sessionforwardedfor'] != $this->server['HTTP_X_FORWARDED_FOR']) { |
$this->log('Security Breach. Forwarded For IP Address changed.', AUTH_LOG_INFO); |
// Check if the IP of the user connecting via proxy has |
// changed, if so we assume a man in the middle attack |
// and log him out. |
$this->expired = true; |
$this->status = AUTH_SECURITY_BREACH; |
$this->logout(); |
return false; |
} |
// Check for useragent change |
if ( $this->_isAdvancedSecurityEnabled(AUTH_ADV_USERAGENT) |
&& isset($this->server['HTTP_USER_AGENT']) |
&& $this->session['sessionuseragent'] != $this->server['HTTP_USER_AGENT']) { |
$this->log('Security Breach. User Agent changed.', AUTH_LOG_INFO); |
// Check if the User-Agent of the user has changed, if |
// so we assume a man in the middle attack and log him out |
$this->expired = true; |
$this->status = AUTH_SECURITY_BREACH; |
$this->logout(); |
return false; |
} |
// Check challenge cookie here, if challengecookieold is not set |
// this is the first time and check is skipped |
// TODO when user open two pages similtaneuly (open in new window,open |
// in tab) auth breach is caused find out a way around that if possible |
if ( $this->_isAdvancedSecurityEnabled(AUTH_ADV_CHALLENGE) |
&& isset($this->session['challengecookieold']) |
&& $this->session['challengecookieold'] != $this->cookie['authchallenge']) { |
$this->log('Security Breach. Challenge Cookie mismatch.', AUTH_LOG_INFO); |
$this->expired = true; |
$this->status = AUTH_SECURITY_BREACH; |
$this->logout(); |
$this->login(); |
return false; |
} |
} |
if (is_callable($this->checkAuthCallback)) { |
$this->log('Calling checkAuthCallback ('.$this->checkAuthCallback.').', AUTH_LOG_DEBUG); |
$checkCallback = call_user_func_array($this->checkAuthCallback, array($this->username, &$this)); |
if ($checkCallback == false) { |
$this->log('checkAuthCallback failed.', AUTH_LOG_INFO); |
$this->expired = true; |
$this->status = AUTH_CALLBACK_ABORT; |
$this->logout(); |
return false; |
} |
} |
$this->log('Session OK.', AUTH_LOG_INFO); |
return true; |
} |
} else { |
$this->log('Unable to locate session storage.', AUTH_LOG_DEBUG); |
return false; |
} |
$this->log('No login session.', AUTH_LOG_DEBUG); |
return false; |
} |
// }}} |
// {{{ staticCheckAuth() [static] |
/** |
* Statically checks if there is a session with valid auth information. |
* |
* @access public |
* @see checkAuth |
* @return boolean Whether or not the user is authenticated. |
* @static |
*/ |
function staticCheckAuth($options = null) |
{ |
static $staticAuth; |
if(!isset($staticAuth)) { |
$staticAuth = new Auth('null', $options); |
} |
$staticAuth->log('Auth::staticCheckAuth() called', AUTH_LOG_DEBUG); |
return $staticAuth->checkAuth(); |
} |
// }}} |
// {{{ getAuth() |
/** |
* Has the user been authenticated? |
* |
* Is there a valid login session. Previously this was different from |
* checkAuth() but now it is just an alias. |
* |
* @access public |
* @return bool True if the user is logged in, otherwise false. |
*/ |
function getAuth() |
{ |
$this->log('Auth::getAuth() called.', AUTH_LOG_DEBUG); |
return $this->checkAuth(); |
} |
// }}} |
// {{{ logout() |
/** |
* Logout function |
* |
* This function clears any auth tokens in the currently |
* active session and executes the logout callback function, |
* if any |
* |
* @access public |
* @return void |
*/ |
function logout() |
{ |
$this->log('Auth::logout() called.', AUTH_LOG_DEBUG); |
if (is_callable($this->logoutCallback) && isset($this->session['username'])) { |
$this->log('Calling logoutCallback ('.$this->logoutCallback.').', AUTH_LOG_DEBUG); |
call_user_func_array($this->logoutCallback, array($this->session['username'], &$this)); |
} |
$this->username = ''; |
$this->password = ''; |
$this->session = null; |
} |
// }}} |
// {{{ updateIdle() |
/** |
* Update the idletime |
* |
* @access private |
* @return void |
*/ |
function updateIdle() |
{ |
$this->session['idle'] = time(); |
} |
// }}} |
// {{{ getUsername() |
/** |
* Get the username |
* |
* @return string |
* @access public |
*/ |
function getUsername() |
{ |
if (isset($this->session['username'])) { |
return($this->session['username']); |
} |
return(''); |
} |
// }}} |
// {{{ getStatus() |
/** |
* Get the current status |
* |
* @return string |
* @access public |
*/ |
function getStatus() |
{ |
return $this->status; |
} |
// }}} |
// {{{ getPostUsernameField() |
/** |
* Gets the post varible used for the username |
* |
* @return string |
* @access public |
*/ |
function getPostUsernameField() |
{ |
return($this->_postUsername); |
} |
// }}} |
// {{{ getPostPasswordField() |
/** |
* Gets the post varible used for the username |
* |
* @return string |
* @access public |
*/ |
function getPostPasswordField() |
{ |
return($this->_postPassword); |
} |
// }}} |
// {{{ sessionValidThru() |
/** |
* Returns the time up to the session is valid |
* |
* @access public |
* @return integer |
*/ |
function sessionValidThru() |
{ |
if (!isset($this->session['idle'])) { |
return 0; |
} |
if ($this->idle == 0) { |
return 0; |
} |
return ($this->session['idle'] + $this->idle); |
} |
// }}} |
// {{{ listUsers() |
/** |
* List all users that are currently available in the storage |
* container |
* |
* @access public |
* @return array |
*/ |
function listUsers() |
{ |
$this->log('Auth::listUsers() called.', AUTH_LOG_DEBUG); |
$this->_loadStorage(); |
return $this->storage->listUsers(); |
} |
// }}} |
// {{{ addUser() |
/** |
* Add user to the storage container |
* |
* @access public |
* @param string Username |
* @param string Password |
* @param mixed Additional parameters |
* @return mixed True on success, PEAR error object on error |
* and AUTH_METHOD_NOT_SUPPORTED otherwise. |
*/ |
function addUser($username, $password, $additional = '') |
{ |
$this->log('Auth::addUser() called.', AUTH_LOG_DEBUG); |
$this->_loadStorage(); |
return $this->storage->addUser($username, $password, $additional); |
} |
// }}} |
// {{{ removeUser() |
/** |
* Remove user from the storage container |
* |
* @access public |
* @param string Username |
* @return mixed True on success, PEAR error object on error |
* and AUTH_METHOD_NOT_SUPPORTED otherwise. |
*/ |
function removeUser($username) |
{ |
$this->log('Auth::removeUser() called.', AUTH_LOG_DEBUG); |
$this->_loadStorage(); |
return $this->storage->removeUser($username); |
} |
// }}} |
// {{{ changePassword() |
/** |
* Change password for user in the storage container |
* |
* @access public |
* @param string Username |
* @param string The new password |
* @return mixed True on success, PEAR error object on error |
* and AUTH_METHOD_NOT_SUPPORTED otherwise. |
*/ |
function changePassword($username, $password) |
{ |
$this->log('Auth::changePassword() called', AUTH_LOG_DEBUG); |
$this->_loadStorage(); |
return $this->storage->changePassword($username, $password); |
} |
// }}} |
// {{{ log() |
/** |
* Log a message from the Auth system |
* |
* @access public |
* @param string The message to log |
* @param string The log level to log the message under. See the Log documentation for more info. |
* @return boolean |
*/ |
function log($message, $level = AUTH_LOG_DEBUG) |
{ |
if (!$this->enableLogging) return false; |
$this->_loadLogger(); |
$this->logger->log('AUTH: '.$message, $level); |
} |
// }}} |
// {{{ _loadLogger() |
/** |
* Load Log object if not already loaded |
* |
* Suspend logger instantiation to make Auth lighter to use |
* for calls which do not require logging |
* |
* @return bool True if the logger is loaded, false if the logger |
* is already loaded |
* @access private |
*/ |
function _loadLogger() |
{ |
if(is_null($this->logger)) { |
if (!class_exists('Log')) { |
include_once 'Log.php'; |
} |
$this->logger =& Log::singleton('null', |
null, |
'auth['.getmypid().']', |
array(), |
AUTH_LOG_DEBUG); |
return(true); |
} |
return(false); |
} |
// }}} |
// {{{ attachLogObserver() |
/** |
* Attach an Observer to the Auth Log Source |
* |
* @param object Log_Observer A Log Observer instance |
* @return boolean |
*/ |
function attachLogObserver(&$observer) { |
$this->_loadLogger(); |
return $this->logger->attach($observer); |
} |
// }}} |
// {{{ _isAdvancedSecurityEnabled() |
/** |
* Is advanced security enabled? |
* |
* Pass one of the Advanced Security constants as the first parameter |
* to check if that advanced security check is enabled. |
* |
* @param integer |
* @return boolean |
*/ |
function _isAdvancedSecurityEnabled($feature = null) { |
if (is_null($feature)) { |
if ($this->advancedsecurity === true) |
return true; |
if ( is_array($this->advancedsecurity) |
&& in_array(true, $this->advancedsecurity, true)) |
return true; |
return false; |
} else { |
if (is_array($this->advancedsecurity)) { |
if ( isset($this->advancedsecurity[$feature]) |
&& $this->advancedsecurity[$feature] == true) |
return true; |
return false; |
} |
return (bool)$this->advancedsecurity; |
} |
} |
// }}} |
} |
?> |
/obs_saisons/SPIP-v1-8-3/modules/configuration/Container.php |
---|
New file |
0,0 → 1,262 |
<?php |
/* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4 foldmethod=marker: */ |
/** |
* Auth_Container Base Class |
* |
* PHP versions 4 and 5 |
* |
* LICENSE: This source file is subject to version 3.01 of the PHP license |
* that is available through the world-wide-web at the following URI: |
* http://www.php.net/license/3_01.txt. If you did not receive a copy of |
* the PHP License and are unable to obtain it through the web, please |
* send a note to license@php.net so we can mail you a copy immediately. |
* |
* @category Authentication |
* @package Auth |
* @author Martin Jansen <mj@php.net> |
* @author Adam Ashley <aashley@php.net> |
* @copyright 2001-2006 The PHP Group |
* @license http://www.php.net/license/3_01.txt PHP License 3.01 |
* @version CVS: $Id: Container.php,v 1.28 2007/06/12 03:11:26 aashley Exp $ |
* @link http://pear.php.net/package/Auth |
*/ |
/** |
* Storage class for fetching login data |
* |
* @category Authentication |
* @package Auth |
* @author Martin Jansen <mj@php.net> |
* @author Adam Ashley <aashley@php.net> |
* @copyright 2001-2006 The PHP Group |
* @license http://www.php.net/license/3_01.txt PHP License 3.01 |
* @version Release: 1.6.1 File: $Revision: 1.28 $ |
* @link http://pear.php.net/package/Auth |
*/ |
class Auth_Container |
{ |
// {{{ properties |
/** |
* User that is currently selected from the storage container. |
* |
* @access public |
*/ |
var $activeUser = ""; |
/** |
* The Auth object this container is attached to. |
* |
* @access public |
*/ |
var $_auth_obj = null; |
// }}} |
// {{{ Auth_Container() [constructor] |
/** |
* Constructor |
* |
* Has to be overwritten by each storage class |
* |
* @access public |
*/ |
function Auth_Container() |
{ |
} |
// }}} |
// {{{ fetchData() |
/** |
* Fetch data from storage container |
* |
* Has to be overwritten by each storage class |
* |
* @access public |
*/ |
function fetchData($username, $password, $isChallengeResponse=false) |
{ |
$this->log('Auth_Container::fetchData() called.', AUTH_LOG_DEBUG); |
} |
// }}} |
// {{{ verifyPassword() |
/** |
* Crypt and verfiy the entered password |
* |
* @param string Entered password |
* @param string Password from the data container (usually this password |
* is already encrypted. |
* @param string Type of algorithm with which the password from |
* the container has been crypted. (md5, crypt etc.) |
* Defaults to "md5". |
* @return bool True, if the passwords match |
*/ |
function verifyPassword($password1, $password2, $cryptType = "md5") |
{ |
$this->log('Auth_Container::verifyPassword() called.', AUTH_LOG_DEBUG); |
switch ($cryptType) { |
case "crypt" : |
return ((string)crypt($password1, $password2) === (string)$password2); |
break; |
case "none" : |
case "" : |
return ((string)$password1 === (string)$password2); |
break; |
case "md5" : |
return ((string)md5($password1) === (string)$password2); |
break; |
default : |
if (function_exists($cryptType)) { |
return ((string)$cryptType($password1) === (string)$password2); |
} elseif (method_exists($this,$cryptType)) { |
return ((string)$this->$cryptType($password1) === (string)$password2); |
} else { |
return false; |
} |
break; |
} |
} |
// }}} |
// {{{ supportsChallengeResponse() |
/** |
* Returns true if the container supports Challenge Response |
* password authentication |
*/ |
function supportsChallengeResponse() |
{ |
return(false); |
} |
// }}} |
// {{{ getCryptType() |
/** |
* Returns the crypt current crypt type of the container |
* |
* @return string |
*/ |
function getCryptType() |
{ |
return(''); |
} |
// }}} |
// {{{ listUsers() |
/** |
* List all users that are available from the storage container |
*/ |
function listUsers() |
{ |
$this->log('Auth_Container::listUsers() called.', AUTH_LOG_DEBUG); |
return AUTH_METHOD_NOT_SUPPORTED; |
} |
// }}} |
// {{{ getUser() |
/** |
* Returns a user assoc array |
* |
* Containers which want should overide this |
* |
* @param string The username |
*/ |
function getUser($username) |
{ |
$this->log('Auth_Container::getUser() called.', AUTH_LOG_DEBUG); |
$users = $this->listUsers(); |
if ($users === AUTH_METHOD_NOT_SUPPORTED) { |
return AUTH_METHOD_NOT_SUPPORTED; |
} |
for ($i=0; $c = count($users), $i<$c; $i++) { |
if ($users[$i]['username'] == $username) { |
return $users[$i]; |
} |
} |
return false; |
} |
// }}} |
// {{{ addUser() |
/** |
* Add a new user to the storage container |
* |
* @param string Username |
* @param string Password |
* @param array Additional information |
* |
* @return boolean |
*/ |
function addUser($username, $password, $additional=null) |
{ |
$this->log('Auth_Container::addUser() called.', AUTH_LOG_DEBUG); |
return AUTH_METHOD_NOT_SUPPORTED; |
} |
// }}} |
// {{{ removeUser() |
/** |
* Remove user from the storage container |
* |
* @param string Username |
*/ |
function removeUser($username) |
{ |
$this->log('Auth_Container::removeUser() called.', AUTH_LOG_DEBUG); |
return AUTH_METHOD_NOT_SUPPORTED; |
} |
// }}} |
// {{{ changePassword() |
/** |
* Change password for user in the storage container |
* |
* @param string Username |
* @param string The new password |
*/ |
function changePassword($username, $password) |
{ |
$this->log('Auth_Container::changePassword() called.', AUTH_LOG_DEBUG); |
return AUTH_METHOD_NOT_SUPPORTED; |
} |
// }}} |
// {{{ log() |
/** |
* Log a message to the Auth log |
* |
* @param string The message |
* @param int |
* @return boolean |
*/ |
function log($message, $level = AUTH_LOG_DEBUG) { |
if (is_null($this->_auth_obj)) { |
return false; |
} else { |
return $this->_auth_obj->log($message, $level); |
} |
} |
// }}} |
} |
?> |
/obs_saisons/SPIP-v1-8-3/modules/configuration/URL.php |
---|
New file |
0,0 → 1,485 |
<?php |
// +-----------------------------------------------------------------------+ |
// | Copyright (c) 2002-2004, Richard Heyes | |
// | All rights reserved. | |
// | | |
// | Redistribution and use in source and binary forms, with or without | |
// | modification, are permitted provided that the following conditions | |
// | are met: | |
// | | |
// | o Redistributions of source code must retain the above copyright | |
// | notice, this list of conditions and the following disclaimer. | |
// | o Redistributions in binary form must reproduce the above copyright | |
// | notice, this list of conditions and the following disclaimer in the | |
// | documentation and/or other materials provided with the distribution.| |
// | o The names of the authors may not be used to endorse or promote | |
// | products derived from this software without specific prior written | |
// | permission. | |
// | | |
// | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS | |
// | "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT | |
// | LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR | |
// | A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT | |
// | OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, | |
// | SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT | |
// | LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, | |
// | DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY | |
// | THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | |
// | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE | |
// | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | |
// | | |
// +-----------------------------------------------------------------------+ |
// | Author: Richard Heyes <richard at php net> | |
// +-----------------------------------------------------------------------+ |
// |
// $Id: URL.php,v 1.2.6.1 2007-11-19 14:06:14 alexandre_tb Exp $ |
// |
// Net_URL Class |
class Net_URL |
{ |
var $options = array('encode_query_keys' => false); |
/** |
* Full url |
* @var string |
*/ |
var $url; |
/** |
* Protocol |
* @var string |
*/ |
var $protocol; |
/** |
* Username |
* @var string |
*/ |
var $username; |
/** |
* Password |
* @var string |
*/ |
var $password; |
/** |
* Host |
* @var string |
*/ |
var $host; |
/** |
* Port |
* @var integer |
*/ |
var $port; |
/** |
* Path |
* @var string |
*/ |
var $path; |
/** |
* Query string |
* @var array |
*/ |
var $querystring; |
/** |
* Anchor |
* @var string |
*/ |
var $anchor; |
/** |
* Whether to use [] |
* @var bool |
*/ |
var $useBrackets; |
/** |
* PHP4 Constructor |
* |
* @see __construct() |
*/ |
function Net_URL($url = null, $useBrackets = true) |
{ |
$this->__construct($url, $useBrackets); |
} |
/** |
* PHP5 Constructor |
* |
* Parses the given url and stores the various parts |
* Defaults are used in certain cases |
* |
* @param string $url Optional URL |
* @param bool $useBrackets Whether to use square brackets when |
* multiple querystrings with the same name |
* exist |
*/ |
function __construct($url = null, $useBrackets = true) |
{ |
$this->url = $url; |
$this->useBrackets = $useBrackets; |
$this->initialize(); |
} |
function initialize() |
{ |
$HTTP_SERVER_VARS = !empty($_SERVER) ? $_SERVER : $GLOBALS['HTTP_SERVER_VARS']; |
$this->user = ''; |
$this->pass = ''; |
$this->host = ''; |
$this->port = 80; |
$this->path = ''; |
$this->querystring = array(); |
$this->anchor = ''; |
// Only use defaults if not an absolute URL given |
if (!preg_match('/^[a-z0-9]+:\/\//i', $this->url)) { |
$this->protocol = (!empty($_SERVER['HTTPS']) && $_SERVER['HTTPS'] == 'on' ? 'https' : 'http'); |
/** |
* Figure out host/port |
*/ |
if (!empty($HTTP_SERVER_VARS['HTTP_HOST']) && |
preg_match('/^(.*)(:([0-9]+))?$/U', $HTTP_SERVER_VARS['HTTP_HOST'], $matches)) |
{ |
$host = $matches[1]; |
if (!empty($matches[3])) { |
$port = $matches[3]; |
} else { |
$port = $this->getStandardPort($this->protocol); |
} |
} |
$this->user = ''; |
$this->pass = ''; |
$this->host = !empty($host) ? $host : (isset($HTTP_SERVER_VARS['SERVER_NAME']) ? $HTTP_SERVER_VARS['SERVER_NAME'] : 'localhost'); |
$this->port = !empty($port) ? $port : (isset($HTTP_SERVER_VARS['SERVER_PORT']) ? $HTTP_SERVER_VARS['SERVER_PORT'] : $this->getStandardPort($this->protocol)); |
$this->path = !empty($HTTP_SERVER_VARS['PHP_SELF']) ? $HTTP_SERVER_VARS['PHP_SELF'] : '/'; |
$this->querystring = isset($HTTP_SERVER_VARS['QUERY_STRING']) ? $this->_parseRawQuerystring($HTTP_SERVER_VARS['QUERY_STRING']) : null; |
$this->anchor = ''; |
} |
// Parse the url and store the various parts |
if (!empty($this->url)) { |
$urlinfo = parse_url($this->url); |
// Default querystring |
$this->querystring = array(); |
foreach ($urlinfo as $key => $value) { |
switch ($key) { |
case 'scheme': |
$this->protocol = $value; |
$this->port = $this->getStandardPort($value); |
break; |
case 'user': |
case 'pass': |
case 'host': |
case 'port': |
$this->$key = $value; |
break; |
case 'path': |
if ($value{0} == '/') { |
$this->path = $value; |
} else { |
$path = dirname($this->path) == DIRECTORY_SEPARATOR ? '' : dirname($this->path); |
$this->path = sprintf('%s/%s', $path, $value); |
} |
break; |
case 'query': |
$this->querystring = $this->_parseRawQueryString($value); |
break; |
case 'fragment': |
$this->anchor = $value; |
break; |
} |
} |
} |
} |
/** |
* Returns full url |
* |
* @return string Full url |
* @access public |
*/ |
function getURL() |
{ |
$querystring = $this->getQueryString(); |
$this->url = $this->protocol . '://' |
. $this->user . (!empty($this->pass) ? ':' : '') |
. $this->pass . (!empty($this->user) ? '@' : '') |
. $this->host . ($this->port == $this->getStandardPort($this->protocol) ? '' : ':' . $this->port) |
. $this->path |
. (!empty($querystring) ? '?' . $querystring : '') |
. (!empty($this->anchor) ? '#' . $this->anchor : ''); |
return $this->url; |
} |
/** |
* Adds or updates a querystring item (URL parameter). |
* Automatically encodes parameters with rawurlencode() if $preencoded |
* is false. |
* You can pass an array to $value, it gets mapped via [] in the URL if |
* $this->useBrackets is activated. |
* |
* @param string $name Name of item |
* @param string $value Value of item |
* @param bool $preencoded Whether value is urlencoded or not, default = not |
* @access public |
*/ |
function addQueryString($name, $value, $preencoded = false) |
{ |
if ($this->getOption('encode_query_keys')) { |
$name = rawurlencode($name); |
} |
if ($preencoded) { |
$this->querystring[$name] = $value; |
} else { |
$this->querystring[$name] = is_array($value) ? array_map('rawurlencode', $value): rawurlencode($value); |
} |
} |
/** |
* Removes a querystring item |
* |
* @param string $name Name of item |
* @access public |
*/ |
function removeQueryString($name) |
{ |
if ($this->getOption('encode_query_keys')) { |
$name = rawurlencode($name); |
} |
if (isset($this->querystring[$name])) { |
unset($this->querystring[$name]); |
} |
} |
/** |
* Sets the querystring to literally what you supply |
* |
* @param string $querystring The querystring data. Should be of the format foo=bar&x=y etc |
* @access public |
*/ |
function addRawQueryString($querystring) |
{ |
$this->querystring = $this->_parseRawQueryString($querystring); |
} |
/** |
* Returns flat querystring |
* |
* @return string Querystring |
* @access public |
*/ |
function getQueryString() |
{ |
if (!empty($this->querystring)) { |
foreach ($this->querystring as $name => $value) { |
// Encode var name |
$name = rawurlencode($name); |
if (is_array($value)) { |
foreach ($value as $k => $v) { |
$querystring[] = $this->useBrackets ? sprintf('%s[%s]=%s', $name, $k, $v) : ($name . '=' . $v); |
} |
} elseif (!is_null($value)) { |
$querystring[] = $name . '=' . $value; |
} else { |
$querystring[] = $name; |
} |
} |
$querystring = implode(ini_get('arg_separator.output'), $querystring); |
} else { |
$querystring = ''; |
} |
return $querystring; |
} |
/** |
* Parses raw querystring and returns an array of it |
* |
* @param string $querystring The querystring to parse |
* @return array An array of the querystring data |
* @access private |
*/ |
function _parseRawQuerystring($querystring) |
{ |
$parts = preg_split('/[' . preg_quote(ini_get('arg_separator.input'), '/') . ']/', $querystring, -1, PREG_SPLIT_NO_EMPTY); |
$return = array(); |
foreach ($parts as $part) { |
if (strpos($part, '=') !== false) { |
$value = substr($part, strpos($part, '=') + 1); |
$key = substr($part, 0, strpos($part, '=')); |
} else { |
$value = null; |
$key = $part; |
} |
if (!$this->getOption('encode_query_keys')) { |
$key = rawurldecode($key); |
} |
if (preg_match('#^(.*)\[([0-9a-z_-]*)\]#i', $key, $matches)) { |
$key = $matches[1]; |
$idx = $matches[2]; |
// Ensure is an array |
if (empty($return[$key]) || !is_array($return[$key])) { |
$return[$key] = array(); |
} |
// Add data |
if ($idx === '') { |
$return[$key][] = $value; |
} else { |
$return[$key][$idx] = $value; |
} |
} elseif (!$this->useBrackets AND !empty($return[$key])) { |
$return[$key] = (array)$return[$key]; |
$return[$key][] = $value; |
} else { |
$return[$key] = $value; |
} |
} |
return $return; |
} |
/** |
* Resolves //, ../ and ./ from a path and returns |
* the result. Eg: |
* |
* /foo/bar/../boo.php => /foo/boo.php |
* /foo/bar/../../boo.php => /boo.php |
* /foo/bar/.././/boo.php => /foo/boo.php |
* |
* This method can also be called statically. |
* |
* @param string $path URL path to resolve |
* @return string The result |
*/ |
function resolvePath($path) |
{ |
$path = explode('/', str_replace('//', '/', $path)); |
for ($i=0; $i<count($path); $i++) { |
if ($path[$i] == '.') { |
unset($path[$i]); |
$path = array_values($path); |
$i--; |
} elseif ($path[$i] == '..' AND ($i > 1 OR ($i == 1 AND $path[0] != '') ) ) { |
unset($path[$i]); |
unset($path[$i-1]); |
$path = array_values($path); |
$i -= 2; |
} elseif ($path[$i] == '..' AND $i == 1 AND $path[0] == '') { |
unset($path[$i]); |
$path = array_values($path); |
$i--; |
} else { |
continue; |
} |
} |
return implode('/', $path); |
} |
/** |
* Returns the standard port number for a protocol |
* |
* @param string $scheme The protocol to lookup |
* @return integer Port number or NULL if no scheme matches |
* |
* @author Philippe Jausions <Philippe.Jausions@11abacus.com> |
*/ |
function getStandardPort($scheme) |
{ |
switch (strtolower($scheme)) { |
case 'http': return 80; |
case 'https': return 443; |
case 'ftp': return 21; |
case 'imap': return 143; |
case 'imaps': return 993; |
case 'pop3': return 110; |
case 'pop3s': return 995; |
default: return null; |
} |
} |
/** |
* Forces the URL to a particular protocol |
* |
* @param string $protocol Protocol to force the URL to |
* @param integer $port Optional port (standard port is used by default) |
*/ |
function setProtocol($protocol, $port = null) |
{ |
$this->protocol = $protocol; |
$this->port = is_null($port) ? $this->getStandardPort($protocol) : $port; |
} |
/** |
* Set an option |
* |
* This function set an option |
* to be used thorough the script. |
* |
* @access public |
* @param string $optionName The optionname to set |
* @param string $value The value of this option. |
*/ |
function setOption($optionName, $value) |
{ |
if (!array_key_exists($optionName, $this->options)) { |
return false; |
} |
$this->options[$optionName] = $value; |
$this->initialize(); |
} |
/** |
* Get an option |
* |
* This function gets an option |
* from the $this->options array |
* and return it's value. |
* |
* @access public |
* @param string $opionName The name of the option to retrieve |
* @see $this->options |
*/ |
function getOption($optionName) |
{ |
if (!isset($this->options[$optionName])) { |
return false; |
} |
return $this->options[$optionName]; |
} |
} |
?> |
/obs_saisons/SPIP-v1-8-3/modules/configuration/car_config.inc.php |
---|
New file |
0,0 → 1,164 |
<?php |
// +----------------------------------------------------------------------------+ |
// |car_config.inc.php | |
// +----------------------------------------------------------------------------+ |
// | Copyright (c) 2004 Tela Botanica | |
// +----------------------------------------------------------------------------+ |
// | Le module d'inscription amélioré, configuration | |
// +----------------------------------------------------------------------------+ |
// | Auteur : Alexandre Granier <alexandre@tela-botanica.org> | |
// +----------------------------------------------------------------------------+ |
// |
// $Id: car_config.inc.php,v 1.1 2004/11/30 13:37:13 tam Exp $ |
// Paramêtres indiquant que l'on est en français pourpermettre la mise en majuscule des caractères accentués |
setlocale(LC_CTYPE, "fr_FR"); |
//chemin relatif d'acces a la carto |
define ('CAR_CHEMIN_APPLI', 'modules'.DIRECTORY_SEPARATOR); |
//bouh! c'est pas propre! c'est a cause de PEAR et de ses includes |
set_include_path(CAR_CHEMIN_APPLI.'configuration/'.PATH_SEPARATOR.get_include_path()); |
//librairies PEAR |
require_once CAR_CHEMIN_APPLI.'configuration/DB.php' ; |
require_once CAR_CHEMIN_APPLI.'configuration/URL.php' ; |
include_once CAR_CHEMIN_APPLI.'configuration/Auth.php' ; |
//langues |
if (isset($lang)) { |
include_once CAR_CHEMIN_APPLI.'langues/car_langue_$lang.inc.php' ; |
} else { |
include_once CAR_CHEMIN_APPLI.'langues/car_langue_fr.inc.php' ; |
} |
//url du chemin de la librairie de fichier php |
define("CAR_CHEMIN_LIBRAIRIE", 'http://obs-saisons.fr/modules/bibliotheque/'); |
//define("CAR_CHEMIN_LIBRAIRIE", 'http://localhost/david/ods/modules/bibliotheque/'); |
//url de l'inscription |
define("CAR_CHEMIN_INSCRIPTION","http://obs-saisons.fr/article.php3?id_article=1"); |
//define("CAR_CHEMIN_INSCRIPTION","http://localhost/david/ods/article.php3?id_article=1"); |
/** |
//=========================DEFINITION DE VARIABLES ================================= |
* Définition des variables globales |
//================================================================================== |
*/ |
//==================================== LES URLS ==================================== |
/** Variable globale contenant l'objet d'accès à l'URL de base de l'application, un objet Net_URL*/ |
//$GLOBALS['car_url'] = new Net_URL('http://obs-saisons.fr/article.php3?id_article='.$_GET['id_article']); |
//$GLOBALS['car_url'] = new Net_URL('http://localhost/david/ods/article.php3?id_article='.$_GET['id_article']); |
$GLOBALS['car_url'] = new Net_URL($_SERVER['REQUEST_URI']); |
//=============================== LA BASE DE DONNEES =============================== |
// Connection a la base de donnee |
$dsn='mysql://'.$login.':'.$pass.'@'.$hote.'/'.$db; |
$GLOBALS['car_db'] =& DB::connect($dsn) ; |
//=============================== AUTHENTIFICATION ================================= |
// Fonction d'identification par PEAR Auth |
function loginFunction($username = null, $status = null, $auth = null) |
{ |
$url = $GLOBALS['car_url']; |
if (isset($GLOBALS['historique_cartes'])) $url->addQueryString('historique_cartes', $GLOBALS['historique_cartes']); |
$res = "<h3 class=\"titre2_cartographie\">".CAR_TEXTE_IDENTIFICATION_1."</h3>"; |
$res .= "<form method=\"post\" action=\"".$GLOBALS['car_url']->getURL()."\">\n"; |
$res .= "<table border=\"0\">"; |
$res .= "<tr><td colspan=\"2\"> </td></tr>"; |
$res .= "<tr><td colspan=\"2\"> </td></tr>"; |
$res .= "<tr><td>Identifiant</td><td><input type=\"text\" name=\"username\"></td></tr>"; |
$res .= "<tr><td>Mot de passe </td><td><input type=\"password\" name=\"password\"></td></tr>"; |
$res .= "<tr><td colspan=\"2\" align=\"right\"><input type=\"submit\" class=\"submit\" value=\"Je me connecte\"></td></tr>"; |
$res .= "<tr><td colspan=\"2\"><a href=\"".$GLOBALS['car_url']->getURL()."\">J'ai oublié mon mot de passe</a></td></tr>"; |
$res .= "<tr><td><a href=\"inscription\">S'inscrire</a></td></tr>"; |
$res .= "</form>\n"; |
return $res; |
} |
$params = array( |
"dsn" => $dsn , |
"table" => 'PARTICIPANT' , |
"usernamecol" => 'PARTICIPANT_PSEUDO' , |
"passwordcol" => 'PARTICIPANT_MOTDEPASSE', |
"cryptType" => 'none', |
"db_fields"=>'*' |
); |
if (isset($_GET['act']) && $_GET['act'] == "login") { |
$optional = true; |
} else { |
$optional = false; |
} |
$GLOBALS['car_auth'] = new Auth("DB", $params, "loginFunction", $optional); |
/** |
//==================================== CONSTANTES ================================== |
* Constantes des noms de tables et de champs dans l'annuaire |
//================================================================================== |
*/ |
define ("CAR_ANNUAIRE", "PARTICIPANT") ; |
define ("CAR_CHAMPS_NOM", "PARTICIPANT_NOM") ; // Nom du champs nom |
define ("CAR_CHAMPS_MAIL", "PARTICIPANT_EMAIL") ; // Nom du champs mail |
define ("CAR_CHAMPS_PRENOM", "PARTICIPANT_PRENOM") ; // Nom du champs prénom |
define ("CAR_CHAMPS_CE_PAYS", "PAYS_ID") ; |
define ("CAR_CHAMPS_DPT", " DEPARTEMENT_ID") ; |
define ("CAR_CHAMPS_ID", "PARTICIPANT_ID") ; |
define ("CAR_CHAMPS_DATE_INS", "PARTICIPANT_DATE_INSCRIPTION") ; |
define ("CAR_CHAMPS_CODE_POSTAL", "PARTICIPANT_CODE_POSTAL") ; |
define ("CAR_CHAMPS_VILLE", "PARTICIPANT_VILLE") ; |
define ("CAR_CHAMPS_ADRESSE", "PARTICIPANT_ADRESSE") ; |
define ('CAR_CHAMPS_LETTRE', 'PARTICIPANT_RECEVOIR_NEWSLETTER'); |
define ('CAR_CHAMPS_VISIBLE', 'PARTICIPANT_NOM_PRENOM_VISIBLE'); |
define ("CAR_TABLE_DPT", "carto_DEPARTEMENT") ; // Nom de la table département |
define ('CAR_CHAMPS_CARTO_DEP', 'CD_ID_Departement'); |
define ('CAR_CHAMPS_NOM_DEP', 'CD_Intitule_departement'); |
define ("CAR_TABLE_PAYS", "carto_PAYS") ; // Nom de la table pays |
define ("CAR_CHAMPS_ID_PAYS", "CP_ID_Pays"); |
define ("CAR_CHAMPS_NOM_PAYS", "CP_Intitule_pays"); |
/** |
//==================================== CONSTANTES ================================== |
* Constantes |
//================================================================================== |
**/ |
/** Constante de préfixe des mails envoyés */ |
define('CAR_PREFIXE_MAIL','[Observatoire des Saisons] '); |
/** Variable définissant la lettre par défaut du parcour alphabétique.*/ |
define('CAR_LETTRE_DEFAUT', 'a') ;// une lettre de l'aphabet ou "tous" |
/** Variable définissant si oui ou non on affiche l'entrée "tous" dans le parcour alphabétique.*/ |
define('CAR_TOUS_BOOL', true) ;// true ou false |
/** Variable definissant le niveau de zoom de depart */ |
define('CAR_ECHELLE_DEPART', "continent*europe*france") ;// ex : continent ou continent*europe ou continent*europe*france |
/** Tableau global contenant les mails des administrateurs. */ |
// Liste des personne recevant le mail après envoie de courriel par l'annuaire |
$GLOBALS['mail_admin'] = array ('david.delon@clapas.net, carto@obs-saisons.fr'); |
// Liste des personne pouvant se connecter à l'annuaire general |
$GLOBALS['pseudo_annu'] = array ('david.delon','violette'); |
/** Constante spécifique à l'ODS : choisir entre inscription adulte et inscription junior. */ |
// Pour l'ODS : les participants sont'ils des adultes (1) ou des enfants (0) |
define ('PARTICIPANT_EST_ADULTE',1); |
/** Requete personnalisée supplémentaire pour l'annuaire et la carto. */ |
// Bout supplémentaire de requète MySQL pour préciser des options pour l'affichage |
define ('SQL_SUPPLEMENTAIRE',' PARTICIPANT_ADULTE='.PARTICIPANT_EST_ADULTE.' '); |
?> |