init php7 branch after svn-crash

Dieser Commit ist enthalten in:
oldperl 2017-03-09 10:26:54 +00:00
Ursprung c78fbec2fa
Commit ba252159d2
17 geänderte Dateien mit 5624 neuen und 0 gelöschten Zeilen

338
branches/php7/conlib/auth.inc Normale Datei
Datei anzeigen

@ -0,0 +1,338 @@
<?php
/**
* Project:
* Contenido Content Management System
*
* Description:
* Session Management for PHP3
* Internet Images srl
*
* Requirements:
* @con_php_req 5
* @con_template <Templatefiles>
* @con_notice <Notice>
*
*
* @package ContenidoBackendArea
* @version <version>
* @author Boris Erdmann, Kristian Koehntopp, Massimiliano Masserelli
* @copyright four for business AG <www.4fb.de>
* @license http://www.contenido.org/license/LIZENZ.txt
* @link http://www.4fb.de
* @link http://www.contenido.org
* @since file available since contenido release <Contenido Version>
* @deprecated file deprecated in contenido release <Contenido Version>
*
* {@internal
* created 2002-07-21
* modified 2008-07-03, bilal arslan, added security fix
*
* $Id: auth.inc 1315 2011-03-03 00:02:52Z xmurrix $:
* }}
*
*/
if(!defined('CON_FRAMEWORK')) {
die('Illegal call');
}
class Auth {
var $classname = "Auth";
var $persistent_slots = array("auth");
var $lifetime = 15; ## Max allowed idle time before
## reauthentication is necessary.
## If set to 0, auth never expires.
var $refresh = 0; ## Refresh interval in minutes.
## When expires auth data is refreshed
## from db using auth_refreshlogin()
## method. Set to 0 to disable refresh
var $mode = "log"; ## "log" for login only systems,
## "reg" for user self registration
var $magic = ""; ## Used in uniqid() generation
var $nobody = false; ## If true, a default auth is created...
var $cancel_login = "cancel_login"; ## The name of a button that can be
## used to cancel a login form
## End of user qualifiable settings.
var $auth = array(); ## Data array
var $in = false;
var $db;
##
## Initialization
##
function start() {
$cl = $this->cancel_login;
global $sess, $$cl;
## This is for performance, I guess but I'm not sure if it could
## be safely removed -- negro
if (! $this->in) {
$sess->register("auth");
$this->in = true;
}
## back compatibility: if d_c is set, create db object
if(isset($this->database_class)) {
$class = $this->database_class;
$this->db = new $class;
}
# Check current auth state. Should be one of
# 1) Not logged in (no valid auth info or auth expired)
# 2) Logged in (valid auth info)
# 3) Login in progress (if $$cl, revert to state 1)
if ($this->is_authenticated()) {
$uid = $this->auth["uid"];
switch ($uid) {
case "form":
# Login in progress
if ($$cl) {
# If $$cl is set, delete all auth info
# and set state to "Not logged in", so eventually
# default or automatic authentication may take place
$this->unauth();
$state = 1;
} else {
# Set state to "Login in progress"
$state = 3;
}
break;
default:
# User is authenticated and auth not expired
$state = 2;
break;
}
} else {
# User is not (yet) authenticated
$this->unauth();
$state = 1;
}
switch ($state) {
case 1:
# No valid auth info or auth is expired
# Check for user supplied automatic login procedure
if ( $uid = $this->auth_preauth() ) {
$this->auth["uid"] = $uid;
$this->auth["exp"] = time() + (60 * $this->lifetime);
$this->auth["refresh"] = time() + (60 * $this->refresh);
return true;
}
# Check for "log" vs. "reg" mode
switch ($this->mode) {
case "yes":
case "log":
if ($this->nobody) {
# Authenticate as nobody
$this->auth["uid"] = "nobody";
# $this->auth["uname"] = "nobody";
$this->auth["exp"] = 0x7fffffff;
$this->auth["refresh"] = 0x7fffffff;
return true;
} else {
# Show the login form
$this->auth_loginform();
$this->auth["uid"] = "form";
$this->auth["exp"] = 0x7fffffff;
$this->auth["refresh"] = 0x7fffffff;
$sess->freeze();
exit;
}
break;
case "reg":
if ($this->nobody) {
# Authenticate as nobody
$this->auth["uid"] = "nobody";
# $this->auth["uname"] = "nobody";
$this->auth["exp"] = 0x7fffffff;
$this->auth["refresh"] = 0x7fffffff;
return true;
} else {
# Show the registration form
$this->auth_registerform();
$this->auth["uid"] = "form";
$this->auth["exp"] = 0x7fffffff;
$this->auth["refresh"] = 0x7fffffff;
$sess->freeze();
exit;
}
break;
default:
# This should never happen. Complain.
echo "Error in auth handling: no valid mode specified.\n";
$sess->freeze();
exit;
}
break;
case 2:
# Valid auth info
# Refresh expire info
## DEFAUTH handling: do not update exp for nobody.
if ($uid != "nobody")
$this->auth["exp"] = time() + (60 * $this->lifetime);
break;
case 3:
# Login in progress, check results and act accordingly
switch ($this->mode) {
case "yes":
case "log":
#if ( $uid = $this->auth_preauth() ) {
# $this->auth["uid"] = $uid;
# $this->auth["exp"] = time() + (60 * $this->lifetime);
# $this->auth["refresh"] = time() + (60 * $this->refresh);
# return true;
#}
if ( $uid = $this->auth_validatelogin() ) {
$this->auth["uid"] = $uid;
$this->auth["exp"] = time() + (60 * $this->lifetime);
$this->auth["refresh"] = time() + (60 * $this->refresh);
return true;
} else {
$this->auth_loginform();
$this->auth["uid"] = "form";
$this->auth["exp"] = 0x7fffffff;
$this->auth["refresh"] = 0x7fffffff;
$sess->freeze();
exit;
}
break;
case "reg":
if ($uid = $this->auth_doregister()) {
$this->auth["uid"] = $uid;
$this->auth["exp"] = time() + (60 * $this->lifetime);
$this->auth["refresh"] = time() + (60 * $this->refresh);
return true;
} else {
$this->auth_registerform();
$this->auth["uid"] = "form";
$this->auth["exp"] = 0x7fffffff;
$this->auth["refresh"] = 0x7fffffff;
$sess->freeze();
exit;
}
break;
default:
# This should never happen. Complain.
echo "Error in auth handling: no valid mode specified.\n";
$sess->freeze();
exit;
break;
}
break;
default:
# This should never happen. Complain.
echo "Error in auth handling: invalid state reached.\n";
$sess->freeze();
exit;
break;
}
}
function login_if( $t ) {
if ( $t ) {
$this->unauth(); # We have to relogin, so clear current auth info
$this->nobody = false; # We are forcing login, so default auth is
# disabled
$this->start(); # Call authentication code
}
}
function unauth($nobody = false) {
$this->auth["uid"] = "";
$this->auth["perm"] = "";
$this->auth["exp"] = 0;
## Back compatibility: passing $nobody to this method is
## deprecated
if ($nobody) {
$this->auth["uid"] = "nobody";
$this->auth["perm"] = "";
$this->auth["exp"] = 0x7fffffff;
}
}
function logout($nobody = "") {
global $sess;
$sess->unregister("auth");
unset($this->auth["uname"]);
$this->unauth($nobody == "" ? $this->nobody : $nobody);
$sess->freeze();
return true;
}
function is_authenticated() {
if (
isset($this->auth["uid"])
&&
$this->auth["uid"]
&&
(($this->lifetime <= 0) || (time() < $this->auth["exp"]))
) {
# If more than $this->refresh minutes are passed since last check,
# perform auth data refreshing. Refresh is only done when current
# session is valid (registered, not expired).
if (
($this->refresh > 0)
&&
($this->auth["refresh"])
&&
($this->auth["refresh"] < time())
) {
if ( $this->auth_refreshlogin() ) {
$this->auth["refresh"] = time() + (60 * $this->refresh);
} else {
return false;
}
}
return $this->auth["uid"];
} else {
return false;
}
}
########################################################################
##
## Helper functions
##
function url() {
return $GLOBALS["sess"]->self_url();
}
function purl() {
print $GLOBALS["sess"]->self_url();
}
## This method can authenticate a user before the loginform
## is being displayed. If it does, it must set a valid uid
## (i.e. nobody IS NOT a valid uid) just like auth_validatelogin,
## else it shall return false.
function auth_preauth() { return false; }
##
## Authentication dummies. Must be overridden by user.
##
function auth_loginform() { ; }
function auth_validatelogin() { ; }
function auth_refreshlogin() { ; }
function auth_registerform() { ; }
function auth_doregister() { ; }
}
?>

Datei anzeigen

@ -0,0 +1,107 @@
<?php
/**
* Project:
* Contenido Content Management System
*
* Description:
* PHPLIB Data Storage Container using DBM Files
* Code inspired by ct_shm.inc v 1.1
*
* Requirements:
* @con_php_req 5
* @con_template <Templatefiles>
* @con_notice <Notice>
*
*
* @package ContenidoBackendArea
* @version 1.1
* @author Oliver Teuber <oliver@teuber.com>
* @copyright four for business AG <www.4fb.de>
* @license http://www.contenido.org/license/LIZENZ.txt
* @link http://www.4fb.de
* @link http://www.contenido.org
* @since file available since contenido release <Contenido Version>
* @deprecated file deprecated in contenido release <Contenido Version>
*
* {@internal
* created 2000-01-01
* modified 2008-07-03, bilal arslan, added security fix
*
* $Id: ct_file.inc 740 2008-08-27 10:45:04Z timo.trautmann $:
* }}
*
*/
if(!defined('CON_FRAMEWORK')) {
die('Illegal call');
}
class CT_File {
##
## Define these parameters by overwriting or by
## deriving your own class from it (recommened)
##
var $file_path = ""; ## Path where to store the session files
## writable by the web server UID
## end of configuration
function ac_start() {
# Not needed in this instance
}
function ac_get_lock() {
# Not needed in this instance
}
function ac_release_lock() {
# Not needed in this instance
}
function ac_newid($str, $name) {
return $str;
}
function ac_store($id, $name, $str) {
$f=fopen($this->file_path . "$id$name",'w+');
if($f<0)
{
return false;
}
fputs($f,urlencode($str));
fclose($f);
return true;
}
function ac_delete($id, $name) {
unlink($this->file_path."$id$name");
}
function ac_gc($gc_time, $name) {
}
function ac_halt($s) {
echo "<b>$s</b>";
exit;
}
function ac_get_value($id, $name) {
if(file_exists($this->file_path."$id$name"))
{
$f=fopen($this->file_path."$id$name",'r');
if($f<0)
return '';
$s=fgets($f,10240);
fclose($f);
return urldecode($s);
}
else
return '';
}
}
?>

Datei anzeigen

@ -0,0 +1,118 @@
<?php
/**
* Project:
* Contenido Content Management System
*
* Description:
* PHPLIB Data Storage Container a LDAP database
*
* Requirements:
* @con_php_req 5
*
*
* @package ContenidoBackendArea
* @version 1.1
* @author Sascha Schumann <sascha@schumann.cx>
* @copyright four for business AG <www.4fb.de>
* @license http://www.contenido.org/license/LIZENZ.txt
* @link http://www.4fb.de
* @link http://www.contenido.org
* @since file available since contenido release <Contenido Version>
* @deprecated file deprecated in contenido release <Contenido Version>
*
* {@internal
* created 2000-01-01
* modified 2008-07-03, bilal arslan, added security fix
*
* $Id: ct_ldap.inc 1315 2011-03-03 00:02:52Z xmurrix $:
* }}
*
*/
if(!defined('CON_FRAMEWORK')) {
die('Illegal call');
}
class CT_Ldap {
##
## Configurable parameters
##
var $ldap_host = "localhost";
var $ldap_port = 389;
var $basedn = "dc=your-domain, dc=com";
var $rootdn = "cn=root, dc=your-domain, dc=com";
var $rootpw = "secret";
var $objclass = "phplibdata";
## end of configuration
var $ds;
function ac_start() {
$this->ds = ldap_connect($this->ldap_host, $this->ldap_port);
if(!$this->ds) {
$this->ac_halt("LDAP connect failed");
}
if(!ldap_bind($this->ds, $this->rootdn, $this->rootpw)) {
$this->ac_halt("LDAP bind failed");
}
}
function ac_halt($msg="") {
echo "Session_ldap failed: <b>".htmlentities($msg)."</b><p>\n";
exit;
}
function ac_store($id, $name, $str) {
$dn = "cn=$id_$name, ".$this->basedn;
$entry = array(
"cn" => "$id_$name",
"str" => $str,
"objectclass" => $this->objclass
);
if(!@ldap_modify($this->ds, $dn, $entry)) {
if(!ldap_add($this->ds, $dn, $entry)) {
$this->ac_halt("LDAP add failed");
}
}
}
function ac_delete($id, $name) {
ldap_delete($this->ds, "cn=$id_$name, ".$this->basedn);
}
function ac_get_value($id, $name) {
$sr = ldap_search($this->ds, $this->basedn, "cn=$id_$name");
$inf = ldap_get_entries($this->ds, $sr);
$str = $inf[0]["str"][0];
ldap_free_result($sr);
return $str;
}
function ac_release_lock() {
}
function ac_get_lock() {
}
function ac_newid($str, $name) {
return $str;
}
function ac_auth($username, $password) {
## we need a username and a md5() encrypted password
$sr = ldap_search($this->ds, $this->basedn, "username=$username");
if(ldap_count_entries($this->ds, $sr) > 0) {
$inf = ldap_get_entries($this->ds, $sr);
$passmd5 = $inf[0]["password"][0];
if(md5($password) == $passmd5) {
return array($inf[0]["uid"][0],
$inf[0]["perms"][0]);
}
}
return array();
}
};
?>

Datei anzeigen

@ -0,0 +1,72 @@
<?php
/**
* Project:
* Contenido Content Management System
*
* Description:
* PHPLIB Data Storage Container using nothing
*
* Requirements:
* @con_php_req 5
* @con_notice
* I wrote this for a quickie test of a website on a server
* where I could not use any other container
* It's also a good skeleton for writing a new container
*
*
* @package ContenidoBackendArea
* @version <version>
* @author Sascha Schumann <sascha@schumann.cx>
* @copyright four for business AG <www.4fb.de>
* @license http://www.contenido.org/license/LIZENZ.txt
* @link http://www.4fb.de
* @link http://www.contenido.org
* @since file available since contenido release <Contenido Version>
* @deprecated file deprecated in contenido release <Contenido Version>
*
* {@internal
* created 2000-01-01
* modified 2008-07-03, bilal arslan, added security fix
*
* $Id: ct_null.inc 1315 2011-03-03 00:02:52Z xmurrix $:
* }}
*
*/
if(!defined('CON_FRAMEWORK')) {
die('Illegal call');
}
class CT_Null {
function ac_start() {
}
function ac_get_lock() {
}
function ac_release_lock() {
}
function ac_newid($str, $name) {
return $str;
}
function ac_store($id, $name, $str) {
return true;
}
function ac_delete($id, $name) {
}
function ac_gc($gc_time, $name) {
}
function ac_halt($s) {
echo "<b>$s</b>";
exit;
}
function ac_get_value($id, $name) {
return "";
}
}
?>

Datei anzeigen

@ -0,0 +1,122 @@
<?php
/**
* Project:
* Contenido Content Management System
*
* Description:
* PHPLIB Data storage container using PHPs session feature.
* Session data will persist in superglobal $_SESSION.
*
* Requirements:
* @con_php_req 5
*
* @package Contenido Backend Session
* @version 0.1
* @author Murat Purc <murat@purc.de>
* @copyright four for business AG <www.4fb.de>
* @license http://www.contenido.org/license/LIZENZ.txt
* @link http://www.4fb.de
* @link http://www.contenido.org
* @since file available since contenido release 4.8.15
*
* {@internal
* created 2011-03-18
*
* $Id: $:
* }}
*
*/
if (!defined('CON_FRAMEWORK')) {
die('Illegal call');
}
class CT_Session
{
/**
* Namespace in superglobal $_SESSION
* @var string
*/
protected $_sNameSpace = 'ct_session_ns';
/**
* Session container's intialize method, configures PHP session and starts
* it, if not done before.
*
* @param array $aOptions Session container configuration as follows:
* - $aOptions['namespace'] (string) Namespace to use
* - $aOptions['session.*'] (string) Each possible session configuration
* see php.ini
*/
public function ac_start(array $aOptions = array())
{
// set namespace
if (isset($aOptions['namespace'])) {
$this->_sNameSpace = $aOptions['namespace'];
}
// configure session
foreach ($aOptions as $k => $v) {
if (strpos($k, 'session.') === 0) {
@ini_set($k, $v);
}
}
if (!isset($_SESSION)) {
session_start();
}
if (!isset($_SESSION[$this->_sNameSpace])) {
$_SESSION[$this->_sNameSpace] = array();
}
}
public function ac_get_lock()
{
// no need to lock session
}
public function ac_release_lock()
{
// no need to release lock session
}
public function ac_gc($gc_time, $name)
{
// no need for garbace collection, will be done by PHP's gc
}
public function ac_store($id, $name, $str)
{
$_SESSION[$this->_sNameSpace][$name] = $str;
return true;
}
public function ac_get_value($id, $name)
{
return isset($_SESSION[$this->_sNameSpace][$name]) ? $_SESSION[$this->_sNameSpace][$name] : '';
}
public function ac_delete($id, $name)
{
// don't destroy session, untill backend and frontend uses it
#session_destroy();
if (isset($_SESSION[$this->_sNameSpace][$name])) {
$_SESSION[$this->_sNameSpace][$name] = '';
}
}
public function ac_newid($str, $name)
{
session_regenerate_id(false);
return session_id();
}
public function ac_halt($s)
{
die($s);
}
}
?>

Datei anzeigen

@ -0,0 +1,117 @@
<?php
/**
* Project:
* Contenido Content Management System
*
* Description:
* PHPLIB Data Storage Container using Shared Memory
*
* Requirements:
* @con_php_req 5
* @con_template <Templatefiles>
* @con_notice <Notice>
*
*
* @package ContenidoBackendArea
* @version 1.2
* @author Sascha Schumann <sascha@schumann.cx>
* @copyright four for business AG <www.4fb.de>
* @license http://www.contenido.org/license/LIZENZ.txt
* @link http://www.4fb.de
* @link http://www.contenido.org
* @since file available since contenido release <Contenido Version>
* @deprecated file deprecated in contenido release <Contenido Version>
*
* {@internal
* created 2000-01-01
* modified 2008-07-03, bilal arslan, added security fix
*
* $Id: ct_shm.inc 1315 2011-03-03 00:02:52Z xmurrix $:
* }}
*
*/
if(!defined('CON_FRAMEWORK')) {
die('Illegal call');
}
class CT_Shm {
##
## Define these parameters by overwriting or by
## deriving your own class from it (recommened)
##
var $max_sessions = 500; ## maximum supported sessions
var $shm_key = 900000; ## key of shared memory segment (unique)
var $shm_size = 64000; ## size in bytes
## end of configuration
var $shmid; ## our shared memory handle
var $semid; ## our semaphore handle
function extract($id) {
return substr($id, 0, strpos($id, "_"));
}
function ac_start() {
$this->shmid = shm_attach($this->shm_key, $this->shm_size, 0600);
}
function ac_get_lock() {
$this->semid = sem_get($this->shm_key + 1);
sem_acquire($this->semid);
}
function ac_release_lock() {
shm_detach($this->shmid);
sem_release($this->semid);
}
function ac_newid($str, $name) {
for($i = 1; $i <= $this->max_sessions &&
(@shm_get_var($this->shmid, $i) != false); $i++);
$id = $i."_".$str;
$this->ac_store($id, $name, "");
return $id;
}
function ac_store($id, $name, $str) {
$val = "$id;".urlencode($name).";".urlencode($str).";".time();
shm_put_var($this->shmid, $this->extract($id), $val);
return true;
}
function ac_delete($id, $name) {
shm_remove_var($this->shmid, $this->extract($id));
}
function ac_gc($gc_time, $name) {
$cmp = time() - $gc_time * 60;
for($i = 1; $i <= $this->max_sessions; $i++) {
if(($val = @shm_get_var($this->shmid, $i)) != false) {
$dat = explode(";", $val);
if($name == $dat[1] && intval($dat[3]) < $cmp) {
shm_remove_var($this->shmid, $i);
}
}
}
}
function ac_halt($s) {
echo "<b>$s</b>";
exit;
}
function ac_get_value($id, $name) {
$i = $this->extract($id);
$var = shm_get_var($this->shmid, $i);
if($var == "") return("");
$dat = explode(";", $var);
## if classname or md5 id does not match...
if($name != urldecode($dat[1]) || $dat[0] != $id)
$this->ac_halt("security stop");
return urldecode($dat[2]);
}
}
?>

Datei anzeigen

@ -0,0 +1,204 @@
<?php
/**
* Project:
* Contenido Content Management System
*
* Description:
* PHPLIB Data Storage Container using a SQL database
*
* Requirements:
* @con_php_req 5
*
* @package ContenidoBackendArea
* @version 1.1.1
* @author Boris Erdmann, Kristian Koehntopp, Sascha Schumann <sascha@schumann.cx>
* @copyright four for business AG <www.4fb.de>
* @license http://www.contenido.org/license/LIZENZ.txt
* @link http://www.4fb.de
* @link http://www.contenido.org
* @since file available since contenido release <Contenido Version>
* @deprecated file deprecated in contenido release <Contenido Version>
*
* {@internal
* created 2002-07-21
* modified 2008-07-03, bilal arslan, added security fix
* modified 2009-11-06, Murat Purc, replaced deprecated functions (PHP 5.3 ready)
*
* $Id: ct_sql.inc 1094 2009-11-06 01:22:13Z xmurrix $:
* }}
*
*/
if(!defined('CON_FRAMEWORK')) {
die('Illegal call');
}
class CT_Sql {
##
## Define these parameters by overwriting or by
## deriving your own class from it (recommened)
##
var $database_lock_semaphore = "";
var $encoding_mode = "base64";
## end of configuration
var $db;
function ac_start() {
$name = $this->database_class;
$this->db = new $name;
}
function ac_get_lock() {
if ( "" != $this->database_lock_semaphore ) {
$query = sprintf("SELECT get_lock('%s')", $this->database_lock_semaphore);
while ( ! $this->db->query($query)) {
$t = 1 + time(); while ( $t > time() ) { ; }
}
}
}
function ac_release_lock() {
if ( "" != $this->database_lock_semaphore ) {
$query = sprintf("SELECT release_lock('%s')", $this->database_lock_semaphore);
$this->db->query($query);
}
}
function ac_gc($gc_time, $name) {
// Security Fix
$timeout = time();
$sqldate = date("YmdHis", $timeout - (Contenido_Security::escapeDB($gc_time, $this->db) * 60));
$this->db->query(sprintf("DELETE FROM %s WHERE changed < '%s' AND name = '%s'",
$this->database_table,
$sqldate,
Contenido_Security::escapeDB($name, $this->db)));
}
function ac_store($id, $name, $str) {
// Security Fix
$ret = true;
switch ( $this->encoding_mode ) {
case "slashes":
$str = addslashes($name . ":" . $str);
break;
case "base64":
default:
$str = base64_encode($name . ":" . $str);
};
$name = addslashes($name);
## update duration of visit
global $HTTP_REFERER, $HTTP_USER_AGENT, $REMOTE_ADDR;
$now = date("YmdHis", time());
$uquery = sprintf("update %s set val='%s', changed='%s' where sid='%s' and name='%s'",
$this->database_table,
$str,
$now,
Contenido_Security::escapeDB($id, $this->db),
Contenido_Security::escapeDB($name, $this->db));
$squery = sprintf("select count(*) from %s where val='%s' and changed='%s' and sid='%s' and name='%s'",
$this->database_table,
$str,
$now,
Contenido_Security::escapeDB($id, $this->db),
Contenido_Security::escapeDB($name, $this->db));
$iquery = sprintf("insert into %s ( sid, name, val, changed ) values ('%s', '%s', '%s', '%s')",
$this->database_table,
Contenido_Security::escapeDB($id, $this->db),
Contenido_Security::escapeDB($name, $this->db),
$str,
$now);
$this->db->lock($this->database_table);
$this->db->query($uquery);
# FIRST test to see if any rows were affected.
# Zero rows affected could mean either there were no matching rows
# whatsoever, OR that the update statement did match a row but made
# no changes to the table data (i.e. UPDATE tbl SET col = 'x', when
# "col" is _already_ set to 'x') so then,
# SECOND, query(SELECT...) on the sid to determine if the row is in
# fact there,
# THIRD, verify that there is at least one row present, and if there
# is not, then
# FOURTH, insert the row as we've determined that it does not exist.
if ( $this->db->affected_rows() == 0
&& $this->db->query($squery)
&& $this->db->next_record() && $this->db->f(0) == 0
&& !$this->db->query($iquery)) {
$ret = false;
}
$this->db->unlock();
return $ret;
}
function ac_delete($id, $name) {
// Security Fix
$this->db->query(sprintf("delete from %s where name = '%s' and sid = '%s'",
$this->database_table,
Contenido_Security::escapeDB($name, $this->db),
Contenido_Security::escapeDB($id, $this->db)));
}
function ac_get_value($id, $name) {
// Security Fix
$this->db->query(sprintf("select val from %s where sid = '%s' and name = '%s'",
$this->database_table,
Contenido_Security::escapeDB($id, $this->db),
Contenido_Security::escapeDB($name, $this->db)));
if ($this->db->next_record()) {
$str = $this->db->f("val");
$str2 = base64_decode( $str );
if (preg_match('/^' . $name . ':.*/', $str2)) {
$str = preg_replace('/^' . $name . ':/', '', $str2);
} else {
$str3 = stripslashes( $str );
if (preg_match('/^' . $name . ':.*/', $str3)) {
$str = preg_replace('/^' . $name . ':/', '', $str3);
} else {
switch ( $this->encoding_mode ) {
case "slashes":
$str = stripslashes($str);
break;
case "base64":
default:
$str = base64_decode($str);
}
}
};
return $str;
};
return "";
}
function ac_newid($str, $name) {
return $str;
}
function ac_halt($s) {
$this->db->halt($s);
}
}
?>

Datei anzeigen

@ -0,0 +1,436 @@
<?php
/**
* Project:
* Contenido Content Management System
*
* Description:
* MySQL database driver
*
* Requirements:
* @con_php_req 5
*
*
* @package Contenido database
* @version 0.2.2
* @author Boris Erdmann, Kristian Koehntopp
* @copyright four for business AG <www.4fb.de>
* @license http://www.contenido.org/license/LIZENZ.txt
* @link http://www.4fb.de
* @link http://www.contenido.org
* @since file available since contenido release <Contenido Version>
*
* {@internal
* created 2002-07-21
* modified 2008-07-04, bilal arslan, added security fix
* modified 2009-10-29, Murat Purc, removed deprecated functions (PHP 5.3 ready) extended DB_Sql_Abstract, added/optimized some functioms and some formatting
* modified 2009-12-18, Murat Purc, Replaced mysql_list_fields() against a SQL statement, see [#CON-262]
* modified 2011-03-03, Murat Purc, Some redesign and improvements (partial adaption to PHP 5 and extending DB_Sql_Abstract).
* modified 2011-03-13, Murat Purc, Cleanup and documentation.
* modified 2011-04-22, Murat Purc, Connect to DB server without database and more
* readable connection settings.
* modified 2011-05-17, Ortwin Pinke, bugfix in methode nextid().
*
* $Id: db_mysql.inc 1359 2011-05-17 13:24:24Z oldperl $:
* }}
*
*/
if (!defined('CON_FRAMEWORK')) {
die('Illegal call');
}
class DB_Sql extends DB_Sql_Abstract {
/**
* Constructor.
*
* @param array $options Optional assoziative options
*/
public function __construct(array $options = array()) {
$options = array_merge($options, array(
'type' => 'mysql'
));
parent::__construct($options);
}
/**
* @see DB_Sql_Abstract::_connect()
*/
protected function _connect() {
$aCon = $this->_aDbCfg['connection'];
if (!isset($aCon['host']) || !isset($aCon['user']) || !isset($aCon['password'])) {
$this->halt('MySQL _connect() Connection settings not complete');
return null;
}
// establish connection, select database
$dbh = @mysql_connect($aCon['host'], $aCon['user'], $aCon['password']);
if (!$dbh || !is_resource($dbh)) {
$this->halt('MySQL _connect() Failed');
return null;
}
// set charset, default utf8
if (isset($aCon['charset'])) {
@mysql_set_charset($aCon['charset'], $dbh);
} else {
@mysql_set_charset($aCon['charset'], 'utf8');
}
//echo mysql_client_encoding($dbh);
if (isset($aCon['database'])) {
if (!@mysql_select_db($aCon['database'], $dbh)) {
$this->halt('MySQL _connect() Cannot use database ' . $aCon['database']);
return null;
}
$this->Database = $aCon['database'];
}
$this->User = $aCon['user'];
return $dbh;
}
/**
* Discard the query result
*/
public function free() {
@mysql_free_result($this->Query_ID);
$this->Query_ID = 0;
}
/**
* @see DB_Sql_Abstract::_query()
*/
protected function _query($sQuery) {
$this->Query_ID = @mysql_query($sQuery, $this->Link_ID);
$this->Row = 0;
$this->Error = $this->_getErrorMessage();
$this->Errno = $this->_getErrorNumber();
if (!$this->Query_ID) {
$this->halt($sQuery);
}
}
/**
* @see DB_Sql_Abstract::next_record()
*/
public function next_record() {
$this->Record = @mysql_fetch_array($this->Query_ID);
$this->Row += 1;
$this->Error = $this->_getErrorMessage();
$this->Errno = $this->_getErrorNumber();
$stat = is_array($this->Record);
if (!$stat && $this->Auto_Free) {
$this->free();
}
return $stat;
}
/**
* @see DB_Sql_Abstract::seek()
*/
public function seek($pos = 0) {
$status = @mysql_data_seek($this->Query_ID, $pos);
if ($status) {
$this->Row = $pos;
} else {
$this->halt("seek($pos) failed: result has " . $this->num_rows() . " rows.");
// half assed attempt to save the day, but do not consider this
// documented or even desireable behaviour.
@mysql_data_seek($this->Query_ID, $this->num_rows());
$this->Row = $this->num_rows();
return 0;
}
return 1;
}
/**
* @see DB_Sql_Abstract::lock()
*/
public function lock($table, $mode = 'write') {
if ($this->_bNolock == true) {
return true;
}
$query = 'LOCK TABLES ';
if (is_array($table)) {
while (list($key, $value) = each($table)) {
if (!is_int($key)) {
// texts key are "read", "read local", "write", "low priority write"
$query .= "$value $key, ";
} else {
$query .= "$value $mode, ";
}
}
$query = substr($query, 0, -2);
} else {
$query .= "$table $mode";
}
$res = $this->query($query);
if (!$res) {
$this->halt('lock() failed.');
return 0;
}
return $res;
}
/**
* @see DB_Sql_Abstract::unlock()
*/
public function unlock() {
if ($this->_bNolock == true) {
return true;
}
$res = $this->query('UNLOCK TABLES');
if (!$res) {
$this->halt('unlock() failed.');
}
return $res;
}
/**
* @see DB_Sql_Abstract::affected_rows()
*/
public function affected_rows() {
return ($this->Link_ID) ? mysql_affected_rows($this->Link_ID) : 0;
}
/**
* @see DB_Sql_Abstract::num_rows()
*/
public function num_rows() {
return ($this->Query_ID) ? mysql_num_rows($this->Query_ID) : 0;
}
/**
* @see DB_Sql_Abstract::num_fields()
*/
public function num_fields() {
return ($this->Query_ID) ? mysql_num_fields($this->Query_ID) : 0;
}
/**
* get next possible id for requested db-table and update sequence table
*
* @param string $seq_name name of db-table to get nextid
* @return int nextid for requested table or 0 if an error occured
*/
public function nextid($seq_name) {
$this->connect();
if ($this->lock($this->Seq_Table)) {
/* get sequence number (locked) and increment */
$q = sprintf("SELECT nextid FROM `%s` WHERE seq_name = '%s'", $this->Seq_Table, $seq_name);
$id = @mysql_query($q, $this->Link_ID);
$res = @mysql_fetch_array($id);
/* No current value, make one */
if (!is_array($res)) {
$currentid = 0;
$q = sprintf("INSERT INTO `%s` VALUES('%s', %s)", $this->Seq_Table, $seq_name, $currentid);
$id = @mysql_query($q, $this->Link_ID);
} else {
$currentid = $res['nextid'];
}
$nextid = $currentid + 1;
$q = sprintf("UPDATE `%s` SET nextid = '%s' WHERE seq_name = '%s'", $this->Seq_Table, $nextid, $seq_name);
$id = @mysql_query($q, $this->Link_ID);
$this->unlock();
} else {
$this->halt('Cannot lock ' . $this->Seq_Table . ' - has it been created?');
return 0;
}
return $nextid;
}
/**
* @see DB_Sql_Abstract::disconnect()
*/
public function disconnect() {
$this->_debug("Debug: Disconnecting $this->Link_ID...");
if (is_resource($this->Link_ID)) {
mysql_close($this->Link_ID);
$this->_removeConnection($this->Link_ID);
}
$this->Link_ID = 0;
$this->Query_ID = 0;
}
/**
* @see DB_Sql_Abstract::_metaData()
*/
protected function _metaData($table = '', $full = false) {
$count = 0;
$id = 0;
$res = array();
/*
* Due to compatibility problems with Table we changed the behavior
* of metadata();
* depending on $full, metadata returns the following values:
*
* - full is false (default):
* $result[]:
* [0]["table"] table name
* [0]["name"] field name
* [0]["type"] field type
* [0]["len"] field length
* [0]["flags"] field flags
*
* - full is true
* $result[]:
* ["num_fields"] number of metadata records
* [0]["table"] table name
* [0]["name"] field name
* [0]["type"] field type
* [0]["len"] field length
* [0]["flags"] field flags
* ["meta"][field name] index of field named "field name"
* This last one could be used if you have a field name, but no index.
* Test: if (isset($result['meta']['myfield'])) { ...
*/
// if no $table specified, assume that we are working with a query
// result
if (!empty($table)) {
$this->connect();
$id = mysql_query(sprintf('SELECT * FROM `%s` LIMIT 1', $table), $this->Link_ID); // PHP 5.3 fix 07.2009 O.Pinke, PHP 5.3 crashes with deprecated mysql_list_fields()
if (!$id) {
$this->halt('Metadata query failed.');
return false;
}
} else {
$id = $this->Query_ID;
if (!$id) {
$this->halt('No query specified.');
return false;
}
}
$count = @mysql_num_fields($id);
// made this IF due to performance (one if is faster than $count if's)
for ($i = 0; $i < $count; $i++) {
$res[$i]['table'] = @mysql_field_table($id, $i);
$res[$i]['name'] = @mysql_field_name($id, $i);
$res[$i]['type'] = @mysql_field_type($id, $i);
$res[$i]['len'] = @mysql_field_len($id, $i);
$res[$i]['flags'] = @mysql_field_flags($id, $i);
if ($full) {
$res['meta'][$res[$i]['name']] = $i;
}
}
if ($full) {
$res['num_fields'] = $count;
}
// free the result only if we were called on a table
if ($table) {
@mysql_free_result($id);
}
return $res;
}
/**
* @see DB_Sql_Abstract::_tableNames()
*/
protected function _tableNames() {
$return = array();
$this->connect();
$h = @mysql_query('SHOW TABLES', $this->Link_ID);
$i = 0;
if (isset($h) && @mysql_num_rows($h) > 0) {
while ($info = @mysql_fetch_row($h)) {
$return[$i]['table_name'] = $info[0];
$return[$i]['tablespace_name'] = $this->Database;
$return[$i]['database'] = $this->Database;
$i++;
}
@mysql_free_result($h);
}
return $return;
}
/**
* @see DB_Sql_Abstract::escape()
*/
public function escape($sString) {
if (!is_string($sString))
return $sString;
$sResult = '';
if (is_resource($this->Link_ID) || $this->connect()) {
$sResult = mysql_real_escape_string($sString, $this->Link_ID);
}
return $sResult;
}
/**
* @see DB_Sql_Abstract::_serverInfo()
*/
protected function _serverInfo() {
$arr['description'] = mysql_get_server_info($this->Link_ID);
return $arr;
}
/**
* @see DB_Sql_Abstract::_getErrorMessage()
*/
protected function _getErrorMessage() {
if (is_resource($this->Link_ID)) {
return mysql_error($this->Link_ID);
} else {
return mysql_error();
}
}
/**
* @see DB_Sql_Abstract::_getErrorNumber()
*/
protected function _getErrorNumber() {
if (is_resource($this->Link_ID)) {
return mysql_errno($this->Link_ID);
} else {
return mysql_errno();
}
}
/**
* This method equates to mysql_fetch_object(). It returns the current
* result set as object or null if no result set is left. If optional
* param $sClassName is set, the result object is an instance of class
* $sClassName.
*
* @return object
*
* @author Holger Librenz <holger.librenz@4fb.de>
* @version 1.0
*/
public function getResultObject($sClassName = null) {
$oResult = null;
if (is_resource($this->Link_ID) && is_resource($this->Query_ID)) {
if ($sClassName == null) {
$oResult = mysql_fetch_object($this->Query_ID);
} else {
$oResult = mysql_fetch_object($this->Query_ID, $sClassName);
}
}
return $oResult;
}
public function getServerInfo() {
return mysql_get_server_info($this->Link_ID);
}
public function getClientEncoding() {
return mysql_client_encoding($this->Link_ID);
}
public function getClientInfo() {
return mysql_get_client_info();
}
}

Datei anzeigen

@ -0,0 +1,500 @@
<?php
/**
* Project:
* Contenido Content Management System
*
* Description:
* MySQLi database driver
*
* Requirements:
* @con_php_req 5
*
*
* @package Contenido database
* @version 0.3.1
* @author Boris Erdmann, Kristian Koehntopp
* @copyright four for business AG <www.4fb.de>
* @license http://www.contenido.org/license/LIZENZ.txt
* @link http://www.4fb.de
* @link http://www.contenido.org
* @since file available since contenido release <Contenido Version>
*
* {@internal
* created 2000-01-01
* modified 2008-07-04, bilal arslan, added security fix
* modified 2009-10-29, Murat Purc, removed deprecated functions (PHP 5.3 ready) extended DB_Sql_Abstract, added/optimized some functioms and some formatting
* modified 2009-12-29, Murat Purc, replaced is_resource() against mysqli compatible check [#CON-290]
* modified 2011-03-03, Murat Purc, Some redesign and improvements (partial adaption to PHP 5 and extending DB_Sql_Abstract).
* modified 2011-03-13, Murat Purc, Cleanup and documentation.
* modified 2011-04-22, Murat Purc, Connect to DB server without database and more
* readable connection settings.
*
* $Id: db_mysqli.inc 1350 2011-04-22 15:53:39Z xmurrix $:
* }}
*
*/
if (!defined('CON_FRAMEWORK')) {
die('Illegal call');
}
class DB_Sql extends DB_Sql_Abstract {
protected $_aDataTypes = array(
0 => 'decimal',
1 => 'tinyint',
2 => 'smallint',
3 => 'int',
4 => 'float',
5 => 'double',
7 => 'timestamp',
8 => 'bigint',
9 => 'mediumint',
10 => 'date',
11 => 'time',
12 => 'datetime',
13 => 'year',
252 => 'blob', // text, blob, tinyblob,mediumblob, etc...
253 => 'string', // varchar and char
254 => 'enum',
);
/**
* Constructor.
*
* @param array $options Optional assoziative options
*/
public function __construct(array $options = array()) {
$options = array_merge($options, array(
'type' => 'mysqli',
));
parent::__construct($options);
}
/**
* @see DB_Sql_Abstract::_connect()
*/
protected function _connect() {
// feasible connection values are:
// - $options['connection']['host'] (string) Hostname or ip
// - $options['connection']['database'] (string) Database name
// - $options['connection']['user'] (string) User name
// - $options['connection']['password'] (string) User password
// - $options['connection']['options'] (array) Optional, MySQLi options array
// - $options['connection']['socket'] (int) Optional, socket
// - $options['connection']['port'] (int) Optional, port
// - $options['connection']['flags'] (int) Optional, flags
// see http://www.php.net/manual/en/mysqli.real-connect.php
// extract($this->_aDbCfg['connection']);
if (!extension_loaded('mysqli')) {
$this->halt('MySQLi _connect() extension not loaded!');
return null;
}
$dbh = mysqli_init();
//print_r($dbh);
if (!$dbh) {
$this->halt('MySQLi _connect() Init failed');
return null;
}
$aCon = $this->_aDbCfg['connection'];
if (!isset($aCon['host']) || !isset($aCon['user']) || !isset($aCon['password'])) {
$this->halt('MySQLi _connect() Connection settings not complete');
return null;
}
// set existing option flags
if (isset($aCon['options']) && is_array($aCon['options'])) {
foreach ($aCon['options'] as $optKey => $optVal) {
mysqli_options($dbh, $optKey, $optVal);
}
}
if (($iPos = strpos($aCon['host'], ':')) !== false) {
list($aCon['host'], $aCon['port']) = explode(':', $aCon['host']);
} else {
$aCon['port'] = null;
}
if (!isset($aCon['socket'])) {
$aCon['socket'] = null;
}
if (!isset($aCon['flags'])) {
$aCon['flags'] = null;
}
if (!isset($aCon['database'])) {
$aCon['database'] = null;
}
$res = mysqli_real_connect(
$dbh, $aCon['host'], $aCon['user'], $aCon['password'], $aCon['database'], $aCon['port'], $aCon['socket'], $aCon['flags']
);
if (isset($aCon['charset'])) {
@mysqli_set_charset($dbh, $aCon['charset']);
} else {
@mysqli_set_charset($dbh, 'utf8');
}
//echo mysqli_character_set_name($dbh);
if ($res && $dbh && $aCon['database']) {
if (!@mysqli_select_db($dbh, $aCon['database'])) {
$this->halt('MySQLi _connect() Cannot use database ' . $aCon['database']);
return null;
}
$this->Database = $aCon['database'];
}
$this->User = $aCon['user'];
return $dbh;
}
/**
* Discard the query result
*/
public function free() {
if (is_object($this->Query_ID)) {
mysqli_free_result($this->Query_ID);
}
$this->Query_ID = 0;
}
/**
* @see DB_Sql_Abstract::_query()
*/
protected function _query($sQuery) {
$this->Query_ID = mysqli_query($this->Link_ID, $sQuery);
$this->Row = 0;
$this->Errno = $this->_getErrorNumber();
$this->Error = $this->_getErrorMessage();
if (!$this->Query_ID) {
$this->halt($sQuery);
}
}
/**
* @see DB_Sql_Abstract::next_record()
*/
public function next_record() {
$this->Record = mysqli_fetch_array($this->Query_ID, MYSQLI_BOTH);
$this->Row += 1;
$this->Errno = $this->_getErrorNumber();
$this->Error = $this->_getErrorMessage();
$stat = is_array($this->Record);
if (!$stat && $this->Auto_Free) {
$this->free();
}
return $stat;
}
/**
* @see DB_Sql_Abstract::seek()
*/
public function seek($pos = 0) {
$status = mysqli_data_seek($this->Query_ID, $pos);
if ($status) {
$this->Row = $pos;
} else {
$this->halt("seek($pos) failed: result has " . $this->num_rows() . " rows.");
// half assed attempt to save the day, but do not consider this
// documented or even desireable behaviour.
mysqli_data_seek($this->Query_ID, $this->num_rows());
$this->Row = $this->num_rows();
return 0;
}
return 1;
}
/**
* @see DB_Sql_Abstract::lock()
*/
public function lock($table, $mode = 'write') {
if ($this->_bNolock == true) {
return true;
}
$query = 'LOCK TABLES ';
if (is_array($table)) {
while (list ($key, $value) = each($table)) {
if (!is_int($key)) {
// texts key are "read", "read local", "write", "low priority write"
$query .= "$value $key, ";
} else {
$query .= "$value $mode, ";
}
}
$query = substr($query, 0, -2);
} else {
$query .= "$table $mode";
}
$res = $this->query($query);
if (!$res) {
$this->halt('lock() failed.');
return 0;
}
return $res;
}
/**
* @see DB_Sql_Abstract::unlock()
*/
public function unlock() {
if ($this->_bNolock == true) {
return true;
}
$res = $this->query('UNLOCK TABLES');
if (!$res) {
$this->halt('unlock() failed.');
}
return $res;
}
/**
* @see DB_Sql_Abstract::affected_rows()
*/
public function affected_rows() {
return ($this->Link_ID) ? mysqli_affected_rows($this->Link_ID) : 0;
}
/**
* @see DB_Sql_Abstract::num_rows()
*/
public function num_rows() {
return ($this->Query_ID) ? mysqli_num_rows($this->Query_ID) : 0;
}
/**
* @see DB_Sql_Abstract::num_fields()
*/
public function num_fields() {
return ($this->Query_ID) ? mysqli_num_fields($this->Query_ID) : 0;
}
/**
* @see DB_Sql_Abstract::nextid()
*/
public function nextid($seq_name) {
$this->connect();
if ($this->lock($this->Seq_Table)) {
/* get sequence number (locked) and increment */
$q = sprintf("SELECT nextid FROM `%s` WHERE seq_name = '%s'", $this->Seq_Table, $seq_name);
$id = mysqli_query($this->Link_ID, $q);
$res = mysqli_fetch_array($id, MYSQLI_BOTH);
/* No current value, make one */
if (!is_array($res)) {
$currentid = 0;
$q = sprintf("INSERT INTO `%s` VALUES('%s', %s)", $this->Seq_Table, $seq_name, $currentid);
$id = mysqli_query($this->Link_ID, $q);
} else {
$currentid = $res["nextid"];
}
$nextid = $currentid + 1;
$q = sprintf("UPDATE `%s` set nextid = '%s' WHERE seq_name = '%s'", $this->Seq_Table, $nextid, $seq_name);
$id = mysqli_query($this->Link_ID, $q);
$this->unlock();
} else {
$this->halt('Cannot lock ' . $this->Seq_Table . ' - has it been created?');
return 0;
}
return $nextid;
}
/**
* @see DB_Sql_Abstract::disconnect()
*/
public function disconnect() {
//$this->_debug("Debug: Disconnecting $this->Link_ID...");
if (is_resource($this->Link_ID)) {
mysqli_close($this->Link_ID);
$this->_removeConnection($this->Link_ID);
}
$this->Link_ID = 0;
$this->Query_ID = 0;
}
/**
* @see DB_Sql_Abstract::_metaData()
*/
protected function _metaData($table = '', $full = false) {
$count = 0;
$id = 0;
$res = array();
/*
* Due to compatibility problems with Table we changed the behavior
* of metadata();
* depending on $full, metadata returns the following values:
*
* - full is false (default):
* $result[]:
* [0]["table"] table name
* [0]["name"] field name
* [0]["type"] field type
* [0]["len"] field length
* [0]["flags"] field flags
*
* - full is true
* $result[]:
* ["num_fields"] number of metadata records
* [0]["table"] table name
* [0]["name"] field name
* [0]["type"] field type
* [0]["len"] field length
* [0]["flags"] field flags
* ["meta"][field name] index of field named "field name"
* This last one could be used if you have a field name, but no index.
* Test: if (isset($result['meta']['myfield'])) { ...
*/
// if no $table specified, assume that we are working with a query
// result
if ($table) {
$this->connect();
$id = mysqli_query($this->Link_ID, sprintf("SELECT * FROM `%s` LIMIT 1", $table));
if (!$id) {
$this->halt('Metadata query failed.');
return false;
}
} else {
$id = $this->Query_ID;
if (!$id) {
$this->halt('No query specified.');
return false;
}
}
$count = mysqli_num_fields($id);
// made this IF due to performance (one if is faster than $count if's)
for ($i = 0; $i < $count; $i ++) {
$finfo = mysqli_fetch_field($id);
$res[$i]['table'] = $finfo->table;
$res[$i]['name'] = $finfo->name;
$res[$i]['type'] = $this->_aDataTypes[$finfo->type];
$res[$i]['len'] = $finfo->max_length;
$res[$i]['flags'] = $finfo->flags;
if ($full) {
$res['meta'][$res[$i]['name']] = $i;
}
}
if ($full) {
$res['num_fields'] = $count;
}
// free the result only if we were called on a table
if ($table) {
mysqli_free_result($id);
}
return $res;
}
/**
* @see DB_Sql_Abstract::escape()
*/
public function escape($sString) {
$sResult = '';
if (is_resource($this->Link_ID) || $this->connect()) {
$sResult = mysqli_real_escape_string($this->Link_ID, $sString);
};
return $sResult;
}
/**
* @see DB_Sql_Abstract::_tableNames()
*/
protected function _tableNames() {
$return = array();
$this->connect();
$h = @mysqli_query($this->Link_ID, 'SHOW TABLES');
$i = 0;
if (isset($h) && @mysqli_num_rows($h) > 0) {
while ($info = mysqli_fetch_row($h)) {
$return[$i]['table_name'] = $info[0];
$return[$i]['tablespace_name'] = $this->Database;
$return[$i]['database'] = $this->Database;
$i ++;
}
mysqli_free_result($h);
}
return $return;
}
/**
* @see DB_Sql_Abstract::_serverInfo()
*/
protected function _serverInfo() {
$arr['description'] = mysqli_get_server_info($this->Link_ID);
return $arr;
}
/**
* @see DB_Sql_Abstract::_getErrorMessage()
*/
protected function _getErrorMessage() {
if ($this->Link_ID) {
return @mysqli_error($this->Link_ID);
} else {
return @mysqli_connect_error();
}
}
/**
* @see DB_Sql_Abstract::_getErrorNumber()
*/
protected function _getErrorNumber() {
if ($this->Link_ID) {
return @mysqli_errno($this->Link_ID);
} else {
return @mysqli_connect_errno();
}
}
/**
* This method equates to mysqli_fetch_object(). It returns the current
* result set as object or null if no result set is left. If optional
* param $sClassName is set, the result object is an instance of class
* $sClassName.
*
* @return object|null
*
* @author Holger Librenz <holger.librenz@4fb.de>
* @version 1.0
*/
public function getResultObject($sClassName = null) {
$oResult = null;
if (is_resource($this->Link_ID) && is_resource($this->Query_ID)) {
if ($sClassName == null) {
$oResult = mysqli_fetch_object($this->Query_ID);
} else {
$oResult = mysqli_fetch_object($this->Query_ID, $sClassName);
}
}
return $oResult;
}
public function getServerInfo() {
return mysqli_get_server_info($this->Link_ID);
}
public function getClientEncoding() {
$oCharSet = mysqli_get_charset($this->Link_ID);
return $oCharSet->charset;
}
public function getClientInfo() {
return mysqli_get_client_info();
}
}

Datei anzeigen

@ -0,0 +1,513 @@
<?php
/**
* Project:
* Contenido Content Management System
*
* Description:
* PDO MySQL database driver
*
* NOTE: Is still in development state, don't use it!
*
* Requirements:
* @con_php_req 5
*
*
* @package Contenido database
* @version 0.1.1
* @author Murat Purc <murat@purc.de>
* @copyright four for business AG <www.4fb.de>
* @license http://www.contenido.org/license/LIZENZ.txt
* @link http://www.4fb.de
* @link http://www.contenido.org
* @since file available since contenido release 4.8.15
*
* {@internal
* created 2011-02-28
* modified 2011-03-13, Murat Purc, Cleanup and documentation.
* modified 2011-04-22, Murat Purc, Connect to DB server without database and more
* readable connection settings.
*
* $Id: $:
* }}
*
*/
if (!defined('CON_FRAMEWORK')) {
die('Illegal call');
}
class DB_Sql extends DB_Sql_Abstract
{
/**
* PDO connection
* @var PDO
*/
public $Query_ID;
/**
* PDO statement
* @var PDOStatement
*/
public $Link_ID;
protected $_aDataTypes = array(
PDO::PARAM_BOOL => 'bool',
PDO::PARAM_NULL => 'null',
PDO::PARAM_INT => 'int',
PDO::PARAM_STR => 'string',
PDO::PARAM_LOB => 'blob',
PDO::PARAM_STMT => 'statement'
);
/**
* Constructor.
*
* @param array $options Optional assoziative options
*/
public function __construct(array $options = array())
{
$options = array_merge($options, array(
'type' => 'pdo_mysql',
));
parent::__construct($options);
}
/**
* @see DB_Sql_Abstract::_connect()
*/
protected function _connect()
{
$aCon = $this->_aDbCfg['connection'];
if (!isset($aCon['host']) || !isset($aCon['user']) || !isset($aCon['password'])) {
$this->halt('MySQL _connect() Connection settings not complete');
return null;
}
$dsn = 'mysql:';
if (isset($aCon['database'])) {
$dsn .= 'dbname=' . $aCon['database'] . ';';
}
$dsn .= 'host=' . $aCon['host'];
if (!isset($aCon['driver_options']) || !is_array($aCon['driver_options'])) {
$aCon['driver_options'] = array();
}
try {
// Create a new PDO connection
$dbh = new PDO($dsn, $aCon['user'], $aCon['password'], $aCon['driver_options']);
} catch (PDOException $e) {
$this->Errno = $e->getCode();
$this->Error = $e->getMessage();
}
if (!$dbh) {
$this->halt('PDO_MySQL _connect() Failed');
return null;
}
if (isset($aCon['database'])) {
$this->Database = $aCon['database'];
}
$this->User = $aCon['user'];
return $dbh;
}
/**
* Discard the query result
*/
public function free()
{
if ($this->Query_ID) {
$this->Query_ID->closeCursor();
unset($this->Query_ID);
}
}
/**
* @see DB_Sql_Abstract::_query()
*/
protected function _query($sQuery)
{
$this->Query_ID = $this->Link_ID->query($sQuery);
$this->Row = 0;
$this->Errno = $this->_getErrorNumber();
$this->Error = $this->_getErrorMessage();
if (!$this->Query_ID) {
$this->halt($sQuery);
}
}
/**
* @see DB_Sql_Abstract::next_record()
*/
public function next_record()
{
$this->Record = $this->Query_ID->fetch(PDO::FETCH_BOTH);
$this->Row += 1;
$this->Errno = $this->_getErrorNumber();
$this->Error = $this->_getErrorMessage();
$stat = is_array($this->Record);
if (!$stat && $this->Auto_Free) {
$this->free();
}
return $stat;
}
/**
* @see DB_Sql_Abstract::seek()
*/
public function seek($pos = 0)
{
throw new Exception('seek not supported');
}
/**
* @see DB_Sql_Abstract::lock()
*/
public function lock($table, $mode = 'write')
{
if ($this->_bNolock == true) {
return true;
}
$query = 'LOCK TABLES ';
if (is_array($table)) {
while (list ($key, $value) = each($table)) {
if (!is_int($key)) {
// texts key are "read", "read local", "write", "low priority write"
$query .= "$value $key, ";
} else {
$query .= "$value $mode, ";
}
}
$query = substr($query, 0, -2);
} else {
$query .= "$table $mode";
}
$res = $this->query($query);
if (!$res) {
$this->halt('lock() failed.');
return 0;
}
return $res;
}
/**
* @see DB_Sql_Abstract::unlock()
*/
public function unlock()
{
if ($this->_bNolock == true) {
return true;
}
$res = $this->query('UNLOCK TABLES');
if (!$res) {
$this->halt('unlock() failed.');
}
return $res;
}
/**
* @see DB_Sql_Abstract::affected_rows()
*/
public function affected_rows()
{
return ($this->Query_ID) ? $this->Query_ID->rowCount() : 0;
}
/**
* @see DB_Sql_Abstract::num_rows()
*/
public function num_rows()
{
if ($this->Query_ID) {
// clone statement and get count by using fetchAll
$stmt = clone $this->Query_ID;
$res = $stmt->fetchAll();
return (is_array($res)) ? count($stmt->fetchAll()) : 0;
} else {
return 0;
}
}
/**
* @see DB_Sql_Abstract::num_fields()
*/
public function num_fields()
{
return count($this->Record / 2);
}
/**
* @see DB_Sql_Abstract::nextid()
*/
public function nextid($seq_name)
{
$this->connect();
if ($this->lock($this->Seq_Table)) {
/* get sequence number (locked) and increment */
$q = sprintf("SELECT nextid FROM `%s` WHERE seq_name = '%s'", $this->Seq_Table, $seq_name);
$stmt = $this->Link_ID->query($q);
$res = ($stmt) ? $stmt->fetch(PDO::FETCH_BOTH) : null;
/* No current value, make one */
if (!is_array($res)) {
$currentid = 0;
$q = sprintf("INSERT INTO `%s` VALUES('%s', %s)", $this->Seq_Table, $seq_name, $currentid);
$stmt = $this->Link_ID->query($q);
} else {
$currentid = $res['nextid'];
}
$nextid = $currentid + 1;
$q = sprintf("UPDATE `%s` set nextid = '%s' WHERE seq_name = '%s'", $this->Seq_Table, $nextid, $seq_name);
$stmt = $this->Link_ID->query($q);
$this->unlock();
} else {
$this->halt('Cannot lock ' . $this->Seq_Table . ' - has it been created?');
return 0;
}
return $nextid;
}
/**
* @see DB_Sql_Abstract::disconnect()
*/
public function disconnect()
{
$this->_debug("Debug: Disconnecting $this->Link_ID...");
// Destroy the PDO and PDOStatement object
$this->_removeConnection($this->Link_ID);
$this->Link_ID = null;
$this->Query_ID = null;
}
/**
* @see DB_Sql_Abstract::_metaData()
*/
protected function _metaData($table = '', $full = false)
{
$count = 0;
$id = 0;
$res = array();
/*
* Due to compatibility problems with Table we changed the behavior
* of metadata();
* depending on $full, metadata returns the following values:
*
* - full is false (default):
* $result[]:
* [0]["table"] table name
* [0]["name"] field name
* [0]["type"] field type
* [0]["len"] field length
* [0]["flags"] field flags
*
* - full is true
* $result[]:
* ["num_fields"] number of metadata records
* [0]["table"] table name
* [0]["name"] field name
* [0]["type"] field type
* [0]["len"] field length
* [0]["flags"] field flags
* ["meta"][field name] index of field named "field name"
* This last one could be used if you have a field name, but no index.
* Test: if (isset($result['meta']['myfield'])) { ...
*/
// if no $table specified, assume that we are working with a query
// result
if ($table) {
$this->connect();
$stmt = $this->Link_ID->query(sprintf("DESCRIBE `%s`", $table));
if (!$stmt) {
$this->halt('Metadata query failed.');
return false;
}
} else {
$stmt = $this->Query_ID;
if (!$stmt) {
$this->halt('No query specified.');
return false;
}
}
// loop thru the result and collect meta data
$res = array();
while ($rs = $stmt->fetch(PDO::FETCH_ASSOC)) {
$field = $this->_getFieldTypeDetails($rs['Type']);
$item = array();
$item['table'] = $table;
$item['name'] = $rs['Field'];
$item['type'] = $field['type'];
$item['len'] = $field['size'];
$item['flags'] = null; // @todo detect field flags
$res[$count] = $item;
if ($full) {
$res['meta'][$item['name']] = $count;
}
$count++;
}
if ($full) {
$res['num_fields'] = $count;
}
unset($stmt);
return $res;
}
/**
* @see DB_Sql_Abstract::escape()
*/
public function escape($sString)
{
$sResult = '';
$sResult = str_replace("'", "''", $sString);
// @todo adapt pdo quote method to own requirements
# if ($this->connect()) {
# $sResult = $this->Link_ID->quote($sString);
# }
return $sResult;
}
/**
* @see DB_Sql_Abstract::_tableNames()
*/
protected function _tableNames()
{
$return = array();
$stmt = $this->Link_ID->query('SHOW TABLES');
$i = 0;
while ($rs = $stmt->fetch(PDO::FETCH_NUM)) {
$return[$i]['table_name'] = $rs[0];
$return[$i]['tablespace_name'] = $this->Database;
$return[$i]['database'] = $this->Database;
$i ++;
}
unset($stmt);
return $return;
}
/**
* @see DB_Sql_Abstract::_serverInfo()
*/
protected function _serverInfo()
{
$arr['description'] = $this->Link_ID->getAttribute(PDO::ATTR_SERVER_INFO);
$arr['version'] = $this->Link_ID->getAttribute(PDO::ATTR_SERVER_VERSION);
return $arr;
}
/**
* @see DB_Sql_Abstract::_getErrorMessage()
*/
protected function _getErrorMessage()
{
$err = null;
if ($this->Query_ID) {
$err = $this->Query_ID->errorInfo();
} elseif ($this->Link_ID) {
$err = $this->Link_ID->errorInfo();
}
if (null !== $err && (int) $err[0] > 0) {
return $err[2];
}
}
/**
* @see DB_Sql_Abstract::_getErrorNumber()
*/
protected function _getErrorNumber()
{
$err = null;
if ($this->Query_ID) {
$err = $this->Query_ID->errorCode();
} elseif ($this->Link_ID) {
$err = $this->Link_ID->errorCode();
}
if (null !== $err && (int) $err[0] > 0) {
return $err[0];
}
}
protected function _getFieldTypeDetails($field)
{
$ret = array('type' => null, 'size' => null);
if (!$field) {
return $ret;
}
if (preg_match('/^([a-z].*)\(([0-9].*)\)/', $field, $matches)) {
$ret = array('type' => $matches[1], 'size' => (int) $matches[2]);
} else {
$ret['type'] = $field;
}
return $ret;
}
/**
* This method festches the current result set and returns the it as object or
* null if no result set is left. If optional param $sClassName is set, the
* result object is an instance of class $sClassName.
*
* @param string sClassName Optional the classname to instantiate.
* @return object|null
*/
public function getResultObject($sClassName = null)
{
$oResult = null;
if ($this->Link_ID && $this->Query_ID) {
if ($rs = $this->Query_ID->fetch(PDO::FETCH_ASSOC)) {
if ($sClassName == null) {
$oResult = (object) $rs;
} else {
$oResult = new $sClassName();
foreach ($rs as $key => $value) {
$oResult->{$key} = $value;
}
}
}
}
return $oResult;
}
public function getServerInfo() {
return '';
}
public function getClientEncoding() {
return '';
}
}

Datei anzeigen

@ -0,0 +1,804 @@
<?php
/**
* Project:
* Contenido Content Management System
*
* Description:
* Base (abstract) database class. Each database driver file should extend this!
* @todo Better error handling, use exceptions!
*
* Requirements:
* @con_php_req 5
*
*
* @package Contenido Database
* @version 0.1.2
* @author Murat Purc <murat@purc.de>
* @copyright four for business AG <www.4fb.de>
* @license http://www.contenido.org/license/LIZENZ.txt
* @link http://www.4fb.de
* @link http://www.contenido.org
* @since file available since Contenido release 4.8.15
*
* {@internal
* created 2011-03-03
* modified 2011-03-13, Murat Purc, Added FETCH_* constants, extended toArray(),
* moved close(), table_names() and server_info()
* from child implementations.
*
* $Id:$:
* }}
*
*/
if (!defined('CON_FRAMEWORK')) {
die('Illegal call');
}
abstract class DB_Sql_Abstract {
const HALT_YES = 'yes';
const HALT_NO = 'no';
const HALT_REPORT = 'report';
const FETCH_NUMERIC = 'numeric';
const FETCH_ASSOC = 'assoc';
const FETCH_BOTH = 'both';
/**
* Assoziative list of database connections
* @array
*/
protected static $_connectionCache = array();
/**
* Assoziative list of database tables metadata
* @array
*/
protected static $_metaCache = array();
/**
* Sequence table name
* @var string
*/
public $Seq_Table = '';
/**
* Flag to print debug messages
* @var bool
*/
public $Debug = false;
/**
* Database name
* @var string
*/
public $Database = '';
/**
* Database connection user name
* @var string
*/
public $User = '';
/**
* Database connection password
* @var string
*/
public $Password = '';
/**
* Database connection resource
* @var resource|int
*/
public $Link_ID = 0;
/**
* Resource identifier of last executed query
* @var resource
*/
public $Query_ID = 0;
/**
* Recordset data array. Could contain either indexed or assoziative result set (or both)
* @var array
*/
public $Record = array();
/**
* The row position inside last executed select result
* @var int
*/
public $Row;
/**
* Database error number
* @var int
*/
public $Errno = 0;
/**
* Database error message
* @var string
*/
public $Error = '';
/**
* Flag to automatic free results
* @var int
*/
public $Auto_Free = 0;
/**
* Database identification string.
* @var string
*/
public $type = '';
/**
* Revision. This is an api revision, not a CVS revision
* @var string
*/
public $revision = '1.3';
/**
* Halt status during occured errors. Feasible values are
* - "yes" (halt with message)
* - "no" (ignore errors quietly)
* - "report" (ignore errror, but spit a warning)
* @var string
*/
public $Halt_On_Error = 'no';
/**
* Text to prepend to the halt message
* @var string
*/
protected $_sHaltMsgPrefix = '';
/**
* Default database connection for all instances
* @var array
*/
protected static $_aDefaultDbCfg = array();
/**
* Database connection configuration for current instance
* @var array
*/
protected $_aDbCfg;
/**
* Enable profiling
* @var bool
*/
protected $_bProfile = false;
/**
* Don't lock tables
* @var bool
*/
protected $_bNolock = false;
/**
* Profile data array
* @var array
*/
protected static $_aProfileData = array();
// @todo intended to map new protected properties against old public
// properties by using magic __call method
protected $_oldProperties = array(
'Seq_Table' => '_sSeqTable',
'Debug' => '_bDebug',
'Database' => '_sDatabase',
'User' => '_sUser',
'Password' => '_sPassword',
'Link_ID' => '_mLinkId',
'Query_ID' => '_mQueryId',
'Auto_Free' => '_iAutoFree',
'type' => '_sType',
'revision' => '_sRevision',
'Halt_On_Error' => '_sHaltOnError',
);
/**
* Constructor, sets passed options and connects to the DBMS, if not done before.
*
* Uses default connection settings, passed $options['db_connection'] settings
* will overwrite connection settings for current instance.
*
* @param array $options Assoziative options as follows:
* - $options['sequenceTable'] (string) Optional, the sequence table name
* - $options['nolock'] (bool) Optional, not lock table
* - $options['haltBehavior'] (string) Optional, halt behavior on occured errors
* - $options['haltMsgPrefix'] (string) Optional, Text to prepend to the halt message
* - $options['type'] (string) Database driver name
* - $options['enableProfiling'] (bool) Optional, flag to enable profiling
* - $options['connection'] (array) Optional, assoziative connection settings
* @return void
*/
protected function __construct(array $options) {
// use default connection configuration, but overwrite it by passed options
$this->_aDbCfg = array_merge(self::$_aDefaultDbCfg, $options);
if (isset($this->_aDbCfg['sequenceTable']) && is_string($this->_aDbCfg['sequenceTable'])) {
$this->Seq_Table = $this->_aDbCfg['sequenceTable'];
}
if (isset($this->_aDbCfg['haltBehavior'])) {
switch ($this->_aDbCfg['haltBehavior']) {
case self::HALT_YES:
$this->Halt_On_Error = self::HALT_YES;
break;
case self::HALT_NO:
$this->Halt_On_Error = self::HALT_NO;
break;
case self::HALT_REPORT:
$this->Halt_On_Error = self::HALT_REPORT;
break;
}
}
if (isset($this->_aDbCfg['haltMsgPrefix']) && is_string($this->_aDbCfg['haltMsgPrefix'])) {
$this->_sHaltMsgPrefix = $this->_aDbCfg['haltMsgPrefix'];
}
if (isset($this->_aDbCfg['type']) && is_string($this->_aDbCfg['type'])) {
$this->type = $this->_aDbCfg['type'];
}
if (isset($this->_aDbCfg['nolock']) && is_bool($this->_aDbCfg['nolock'])) {
$this->_bNolock = (bool) $this->_aDbCfg['nolock'];
}
if (isset($this->_aDbCfg['enableProfiling']) && is_bool($this->_aDbCfg['enableProfiling'])) {
$this->_bProfile = (bool) $this->_aDbCfg['enableProfiling'];
}
$this->connect();
}
/**
* Setter for default database configuration, the connection values.
*
* @param array $defaultDbCfg
*/
public static function setDefaultConfiguration(array $defaultDbCfg) {
self::$_aDefaultDbCfg = $defaultDbCfg;
}
/**
* Establishes a connection to the database server.
*
* @return object|resource|int|null Connection handler. Return value depends on
* used driver and is null in case of an error.
*/
public function connect() {
if ($this->Link_ID = $this->_getConnection($this->_aDbCfg['connection'])) {
return $this->Link_ID;
} else {
if ($this->Link_ID = $this->_connect()) {
$this->_setConnection($this->_aDbCfg['connection'], $this->Link_ID);
return $this->Link_ID;
}
}
return null;
}
/**
* Resource id/object of current connection
*
* @return mixed The resource id/object of current connection
*/
public function link_id() {
return $this->Link_ID;
}
/**
* Returns connection from connection cache
*
* @param mixed $data Connection data array
* @return mixed Either The connection (object, resource, integer) or null
*/
protected function _getConnection($data) {
$hash = md5($this->type . '-' . (is_array($data) ? implode('-', $data) : (string) $data));
return (isset(self::$_connectionCache[$hash])) ? self::$_connectionCache[$hash] : null;
}
/**
* Stores connection in connection cache
*
* @param mixed $data Connection data array
* @param mixed $connection The connection to store in cache
* @return void
*/
protected function _setConnection($data, $connection) {
$hash = md5($this->type . '-' . (is_array($data) ? implode('-', $data) : (string) $data));
self::$_connectionCache[$hash] = $connection;
}
/**
* Removes connection from cache
*
* @param mixed $connection The connection to remove in cache
* @return void
*/
protected function _removeConnection($connection) {
foreach (self::$_connectionCache as $hash => $res) {
if ($res == $connection) {
unset(self::$_connectionCache[$hash]);
return;
}
}
}
/**
* Returns the current cursor
*
* @return resource Current cursor
*/
public function query_id() {
return $this->Query_ID;
}
/**
* Connects to the database.
*
* @return object|resource|int|null Connection handler. Return value depends on
* used driver and is null in case of an error.
*/
abstract protected function _connect();
/**
* Executes the query.
*
* @param string $sQuery The query to execute.
* @param mixed Accepts additional unlimited parameter, where the parameter
* will be replaced against format definitions in query.
* @return resource|int|object|bool Depends on used database driver, false on error
*/
public function query($sQuery) {
// No empty queries, please, since PHP4 chokes on them
if ($sQuery == '') {
// The empty query string is passed on from the constructor, when calling
// the class without a query, e.g. in situations '$db = new DB_Sql_Subclass;'
return false;
}
$aArgs = func_get_args();
if (count($aArgs) > 1) {
array_shift($aArgs);
$sQuery = $this->_prepareQueryf($sQuery, $aArgs);
}
if (!$this->connect()) {
return false;
}
// new query, discard previous result
if ($this->Query_ID) {
$this->free();
}
$this->_debug('Debug: query = ' . $sQuery);
if ($this->_bProfile) {
$fStart = microtime(true);
}
$this->_query($sQuery);
if ($this->_bProfile) {
$fEnd = microtime(true);
$this->_addProfileData($fStart, $fEnd, $sQuery);
}
// Will return nada if it fails. That's fine.
return $this->Query_ID;
}
/**
* Executes the query.
*
* @param string $sQuery The query to execute
* @return void
*/
abstract protected function _query($sQuery);
/**
* Prepares a query with parameter for execution.
*
* @param string $sQuery
* @param array $aArgs Arguments array containing the query with formatting
* signs and the entries.
* Examples:
* <pre>
* $obj->_prepareQueryf('SELECT * FROM `%s` WHERE id = %d', 'tablename', 123);
* $obj->_prepareQueryf('SELECT * FROM `%s` WHERE id = %d AND user = %d', 'tablename', 123, 3);
* </pre>
* @return string
*/
protected function _prepareQueryf($sQuery, array $aArgs) {
if (count($aArgs) > 0) {
$aArgs = array_map(array($this, 'escape'), $aArgs);
array_unshift($aArgs, $sQuery);
$sQuery = call_user_func_array('sprintf', $aArgs);
}
return $sQuery;
}
/**
* Moves the result to the next record, if exists and returns the status of the movement
*
* @return int Flag about move status 1 on success or 0
*/
abstract public function next_record();
/**
* Moves the cursor (position inside current result sets).
*
* @param int $pos The positon to move to inside the current result set
* @return void
*/
abstract public function seek($pos = 0);
/**
* Locks the desired table.
*
* @param string $table The table to lock
* @param string $mode The lock mode. Only mode 'write' is supported!
* @return int Status of lock success (1 or 0)
*/
abstract public function lock($table, $mode = 'write');
/**
* Frees a previous locked result.
*
* @return int Status of lock success (1 or 0)
*/
abstract public function unlock();
/**
* Parses te table structure and generates a metadata from it.
*
* @param string $table The table to get metadata or empty string to retrieve
* metadata of all tables
* @param bool $full Flag to load full metada
* @return array Depends on used database and on parameter $full
*/
public function metadata($table = '', $full = false) {
$key = (string) $this->Database . '_' . $table . '_' . (($full) ? '1' : '0');
if (!isset(self::$_metaCache[$key])) {
// get meta data
self::$_metaCache[$key] = $this->_metaData($table, $full);
}
return self::$_metaCache[$key];
}
/**
* Parses te table structure and generates a metadata from it.
*
* @param string $table The table to get metadata or empty string to retrieve
* metadata of all tables
* @param bool $full Flag to load full metada
* @return array Depends on used database and on parameter $full
*/
abstract protected function _metaData($table = '', $full = false);
/**
* Returns number of affected rows from last executed query (update, delete)
*
* @return int Number of affected rows
*/
abstract public function affected_rows();
/**
* Returns the number of rows from last executed select query.
*
* @return int The number of rows from last select query result
*/
abstract public function num_rows();
/**
* Returns the number of fields (colums) from current record set
*
* @return int Number of fields
*/
abstract public function num_fields();
/**
* Returns the number of rows (record set).
* Shortcut for function num_rows().
*
* @return int Number of rows
*/
public function nf() {
return $this->num_rows();
}
/**
* Displays the number of rows (record set) using print.
*
* @return void
*/
public function np() {
print $this->num_rows();
}
/**
* Returns the desired field value from current record set.
*
* @param mixed The field name or index position
* @param mixed The default value to return
* @return mixed The value of field
*/
public function f($Name, $default = null) {
return (isset($this->Record[$Name])) ? $this->Record[$Name] : $default;
}
/**
* Displays the desired field value from current record set using print.
*
* @param mixed The field name or index position
* @return void
*/
public function p($Name) {
if (isset($this->Record[$Name])) {
print $this->Record[$Name];
}
}
/**
* Returns current recordset as a assoziative and/or indexed array.
*
* @param string $fetchMode One of DB_SQL_Abstract::FETCH_* constants
* @return array
*/
public function toArray($fetchMode = DB_SQL_Abstract::FETCH_ASSOC) {
switch ($fetchMode) {
case self::FETCH_NUMERIC:
case self::FETCH_ASSOC:
case self::FETCH_BOTH:
// donut
break;
default:
$fetchMode = DB_SQL_Abstract::FETCH_ASSOC;
break;
}
$aResult = array();
if (is_array($this->Record)) {
foreach ($this->Record as $key => $value) {
if ($fetchMode == self::FETCH_ASSOC && !is_numeric($key)) {
$aResult[$key] = $value;
} elseif ($fetchMode == self::FETCH_NUMERIC && is_numeric($key)) {
$aResult[$key] = $value;
} else {
$aResult[$key] = $value;
}
}
}
return $aResult;
}
/**
* Returns current recordset as a object
*
* @return stdClass
*/
public function toObject() {
return (object) $this->toArray(self::FETCH_ASSOC);
}
/**
* Returns the next id (sequence number).
*
* @param string $seq_name The sequence name to get the next id from
* @return int The next id or 0 on error
*/
abstract public function nextid($seq_name);
/**
* Wrapper method for disconnect()
* @see DB_Sql_Abstract::disconnect()
*/
public function close() {
$this->disconnect();
}
/**
* Closes the connection and frees the query id.
*
* @return void
*/
abstract public function disconnect();
/**
* Error handling
*
* Error handler function, delegates passed message to the function haltmsg() if propery
* $this->Halt_On_Error is not set to self::HALT_REPORT.
*
* Terminates further script execution if $this->Halt_On_Error is set to self::HALT_YES
*
* @param string $sMsg The message to use for error handling
* @return void
*/
public function halt($sMsg) {
if ($this->Halt_On_Error == self::HALT_REPORT) {
$this->haltmsg($this->_sHaltMsgPrefix . $sMsg);
}
if ($this->Halt_On_Error == self::HALT_YES) {
die('Session halted.');
}
}
/**
* Logs passed message, basically the last db error to the error log.
* Concatenates a detailed error message and invokey PHP's error_log() method.
*
* @param string $sMsg
* @return void
*/
public function haltmsg($sMsg) {
$sName = 'ConLite DB';
if (!$this->Error) {
$this->Error = $this->_getErrorMessage();
}
if (!$this->Errno) {
$this->Errno = $this->_getErrorNumber();
}
$sMsg = sprintf("%s error: %s (%s) - info: %s\n", $sName, $this->Errno, $this->Error, $sMsg);
error_log($sMsg);
}
/**
* Returns names of existing tables.
*
* @return array|null Indexed array containing assoziative table data as
* follows or null:
* - $info[$i]['table_name']
* - $info[$i]['tablespace_name']
* - $info[$i]['database']
*/
public function table_names() {
if (!$this->connect()) {
return null;
}
if (method_exists($this, '_tableNames')) {
return $this->_tableNames();
}
return null;
}
/**
* Implemetation for table_names() in child classes
* @see DB_Sql_Abstract::table_names()
*/
abstract protected function _tableNames();
/**
* Escape string for using in SQL-Statement.
*
* @param string $sString The string to escape
* @return string Escaped string
*/
abstract public function escape($sString);
/**
* Returns information about DB server. The return value depends allways on
* used DBMS.
*
* @return array|null Assoziative array as follows or null:
* - $arr['description'] (string) Optional, server description
* - $arr['version'] (string) Optional, server version
*/
public function server_info() {
if (!$this->connect()) {
return null;
}
if (method_exists($this, '_serverInfo')) {
return $this->_serverInfo();
}
return null;
}
/**
* Implemetation for server_info() in child classes.
* @see DB_Sql_Abstract::server_info()
*/
abstract protected function _serverInfo();
/**
* Returns error message of last occured error.
*
* @return string
*/
public function getErrorMessage() {
return $this->Error;
}
/**
* Returns error message of last occured error by using databases interface.
*
* @return string
*/
abstract protected function _getErrorMessage();
/**
* Returns error code of last occured error by using databases interface.
*
* @return int
*/
public function getErrorNumber() {
return $this->Errno;
}
/**
* Returns error code of last occured error by using databases interface.
*
* @return int
*/
abstract protected function _getErrorNumber();
/**
* Adds a entry to the profile data.
*
* @param float $fStartTime
* @param float $fEndTime
* @param string $sQuery
* @return void
*/
protected static function _addProfileData($fStartTime, $fEndTime, $sQuery) {
self::$_aProfileData[] = array(
'time' => $fEndTime - $fStartTime,
'query' => $sQuery
);
}
/**
* Returns collected profile data.
*
* @return array Profile data array like:
* - $arr[$i]['time'] (float) Elapsed time to execute the query
* - $arr[$i]['query'] (string) The query itself
*/
public static function getProfileData() {
return self::$_aProfileData;
}
/**
* Displays the passed message, if debug is enabled (see $this->Debug)
*
* @param string $sMsg The message to display
* @return void
*/
protected function _debug($sMsg) {
if ($this->Debug) {
printf("<pre>" . $sMsg . "</pre>\n");
}
}
/**
* returns info about db-server
*
* return string
*/
abstract public function getServerInfo();
/**
* returns client encoding
*
* return string
*/
abstract public function getClientEncoding();
/**
* returns client info
*
* return string
*/
abstract public function getClientInfo();
}

Datei anzeigen

@ -0,0 +1,4 @@
<?php
header("Location:/index.php");
exit;
?>

896
branches/php7/conlib/local.php Normale Datei
Datei anzeigen

@ -0,0 +1,896 @@
<?php
/**
* Project:
* Contenido Content Management System
*
* Description:
* Contenido daabase, session and authentication classes
*
* Requirements:
* @con_php_req 5
*
* @package Contenido core
* @version 1.7
* @author Boris Erdmann, Kristian Koehntopp
* @copyright four for business AG <www.4fb.de>
* @license http://www.contenido.org/license/LIZENZ.txt
* @link http://www.4fb.de
* @link http://www.contenido.org
*
*
* {@internal
* created 2000-01-01
* modified 2008-07-04, bilal arslan, added security fix
* modified 2010-02-02, Ingo van Peeren, added local method connect() in order
* to allow only one database connection, see [CON-300]
* modified 2010-02-17, Ingo van Peeren, only one connection for mysqli too
* modified 2011-03-03, Murat Purc, some redesign/improvements (partial adaption to PHP 5)
* modified 2011-03-18, Murat Purc, Fixed occuring "Duplicated entry" errors by using CT_Sql, see [CON-370]
* modified 2011-03-21, Murat Purc, added Contenido_CT_Session to uses PHP's session implementation
*
* $Id: local.php 300 2014-01-30 14:28:53Z oldperl $:
* }}
*
*/
if (!defined('CON_FRAMEWORK')) {
die('Illegal call');
}
/**
* DB-class for all DB handling
*/
class DB_ConLite extends DB_Sql
{
/**
* Constructor of database class.
*
* @param array $options Optional assoziative options. The value depends
* on used DBMS, but is generally as follows:
* - $options['connection']['host'] (string) Hostname or ip
* - $options['connection']['database'] (string) Database name
* - $options['connection']['user'] (string) User name
* - $options['connection']['password'] (string) User password
* - $options['nolock'] (bool) Optional, not lock table
* - $options['sequenceTable'] (string) Optional, sequesnce table
* - $options['haltBehavior'] (string) Optional, halt behavior on occured errors
* - $options['haltMsgPrefix'] (string) Optional, Text to prepend to the halt message
* - $options['enableProfiling'] (bool) Optional, flag to enable profiling
* @return void
*/
public function __construct(array $options = array())
{
global $cachemeta;
parent::__construct($options);
if (!is_array($cachemeta)) {
$cachemeta = array();
}
// TODO check this out
// HerrB: Checked and disabled. Kills umlauts, if tables are latin1_general.
// try to use the new connection and get the needed encryption
//$this->query("SET NAMES 'utf8'");
}
/**
* Fetches the next recordset from result set
*
* @param bool
*/
public function next_record()
{
global $cCurrentModule;
// FIXME For what reason is NoRecord used???
$this->NoRecord = false;
if (!$this->Query_ID) {
$this->NoRecord = true;
if ($cCurrentModule > 0) {
$this->halt("next_record called with no query pending in Module ID $cCurrentModule.");
} else {
$this->halt("next_record called with no query pending.");
}
return false;
}
return parent::next_record();
}
/**
* Returns the metada of passed table
*
* @param string $sTable The tablename of empty string to retrieve metadata of all tables!
* @return array|bool Assoziative metadata array (result depends on used db driver)
* or false in case of an error
* @deprecated Use db drivers toArray() method instead
*/
public function copyResultToArray($sTable = '')
{
global $cachemeta;
$aValues = array();
if ($sTable != '') {
if (array_key_exists($sTable, $cachemeta)) {
$aMetadata = $cachemeta[$sTable];
} else {
$cachemeta[$sTable] = $this->metadata($sTable);
$aMetadata = $cachemeta[$sTable];
}
} else {
$aMetadata = $this->metadata($sTable);
}
if (!is_array($aMetadata) || count($aMetadata) == 0) {
return false;
}
foreach ($aMetadata as $entry) {
$aValues[$entry['name']] = $this->f($entry['name']);
}
return $aValues;
}
}
/**
* Wrapper class for old contenido class
*
* @deprecated since version 2.0.0, use DB_ConLite instead
*/
class DB_Contenido extends DB_ConLite {
/**
*
* @deprecated since version 2.0.0
* @param array $options
*/
public function __construct(array $options = array()) {
parent::__construct($options);
}
}
class Contenido_CT_Sql extends CT_Sql
{
/**
* Database class name
* @var string
*/
public $database_class = 'DB_Contenido';
/**
* And find our session data in this table.
* @var string
*/
public $database_table = '';
public function __construct()
{
global $cfg;
$this->database_table = $cfg['tab']['phplib_active_sessions'];
}
/**
* Stores the session data in database table.
*
* Overwrites parents and uses MySQLs REPLACE statement, to prevent race
* conditions while executing INSERT statements by multiple frames in backend.
*
* - Existing entry will be overwritten
* - Non existing entry will be added
*
* @param string $id The session id (hash)
* @param string $name Name of the session
* @param string $str The value to store
* @return bool
*/
public function ac_store($id, $name, $str)
{
switch ($this->encoding_mode) {
case 'slashes':
$str = addslashes($name . ':' . $str);
break;
case 'base64':
default:
$str = base64_encode($name . ':' . $str);
}
$name = addslashes($name);
$now = date('YmdHis', time());
$iquery = sprintf(
"REPLACE INTO %s (sid, name, val, changed) VALUES ('%s', '%s', '%s', '%s')",
$this->database_table, $id, $name, $str, $now
);
return ($this->db->query($iquery)) ? true : false;
}
}
/**
* Implements the interface class for storing session data to disk using file
* session container of phplib.
*/
class Contenido_CT_File extends CT_File
{
/**
* The maximum length for one line in session file.
* @var int
*/
public $iLineLength = 999999;
/**
* Overrides standard constructor for setting up file path to the one which is
* configured in php.ini
*
* @return Contenido_CT_File
*
* @author Holger Librenz <holger.librenz@4fb.de>
*/
public function __construct()
{
global $cfg;
if (isset($cfg['session_line_length']) && !empty($cfg['session_line_length'])) {
$this->iLineLength = (int) $cfg['session_line_length'];
}
// get php.ini value for session path
$this->file_path = session_save_path() . '/';
}
/**
* Overrides get method, because standard byte count is not really senseful for
* contenido!
*
* @param string $sId
* @param string $sName
* @return mixed
*/
public function ac_get_value($sId, $sName)
{
if (file_exists($this->file_path . "$sId$sName")) {
$f = fopen($this->file_path . "$sId$sName", 'r');
if ($f<0) {
return '';
}
$s = fgets($f, $this->iLineLength);
fclose($f);
return urldecode($s);
} else {
return '';
}
}
}
class Contenido_CT_Shm extends CT_Shm
{
public function __construct()
{
$this->ac_start();
}
}
/**
* Contenido session container, uses PHP's session implementation.
*
* NOTE: Is experimental, so don't use this in a production environment.
*
* To use this, set session container in contenido/includes/config.misc.php to
* $cfg["session_container"] = 'session';
*
* @todo Make session container configurable
*
* @author Murat Purc <murat@purc.de>
*/
class Contenido_CT_Session extends CT_Session
{
public function __construct()
{
$this->ac_start(array(
'namespace' => 'contenido_ct_session_ns',
'session.hash_function' => '1', // use sha-1 function
'session.hash_bits_per_character' => '5', // and set 5 character to achieve 32 chars
# 'session.save_path' => 'your path',
# 'session.name' => 'your session name',
# 'session.gc_maxlifetime' => 'your lifetime in seconds',
));
}
}
class Contenido_Session extends Session
{
public $classname = 'Contenido_Session';
public $cookiename = 'contenido'; ## defaults to classname
public $magic = '934ComeOnEileen'; ## ID seed
public $mode = 'get'; ## We propagate session IDs with cookies
public $fallback_mode = 'cookie';
public $lifetime = 0; ## 0 = do session cookies, else minutes
public $that_class = 'Contenido_CT_Sql'; ## name of data storage container
public $gc_probability = 5;
public function __construct()
{
global $cfg;
$sFallback = 'sql';
$sClassPrefix = 'Contenido_CT_';
$sStorageContainer = strtolower($cfg['session_container']);
if (class_exists ($sClassPrefix . ucfirst($sStorageContainer))) {
$sClass = $sClassPrefix . ucfirst($sStorageContainer);
} else {
$sClass = $sClassPrefix . ucfirst($sFallback);
}
$this->that_class = $sClass;
}
public function delete()
{
$oCol = new InUseCollection();
$oCol->removeSessionMarks($this->id);
parent::delete();
}
}
class Contenido_Frontend_Session extends Session
{
public $classname = 'Contenido_Frontend_Session';
public $cookiename = 'sid'; ## defaults to classname
public $magic = 'Phillipip'; ## ID seed
public $mode = 'cookie'; ## We propagate session IDs with cookies
public $fallback_mode = 'cookie';
public $lifetime = 0; ## 0 = do session cookies, else minutes
public $that_class = 'Contenido_CT_Sql'; ## name of data storage container
public $gc_probability = 5;
public function __construct()
{
global $load_lang, $load_client, $cfg;
$this->cookiename = 'sid_' . $load_client . '_' . $load_lang;
$this->setExpires(time()+3600);
// added 2007-10-11, H. Librenz
// bugfix (found by dodger77): we need alternative session containers
// also in frontend
$sFallback = 'sql';
$sClassPrefix = 'Contenido_CT_';
$sStorageContainer = strtolower($cfg['session_container']);
if (class_exists($sClassPrefix . ucfirst($sStorageContainer))) {
$sClass = $sClassPrefix . ucfirst($sStorageContainer);
} else {
$sClass = $sClassPrefix . ucfirst($sFallback);
}
$this->that_class = $sClass;
}
}
class Contenido_Auth extends Auth
{
public $classname = 'Contenido_Auth';
public $lifetime = 15;
public $database_class = 'DB_Contenido';
public $database_table = 'con_phplib_auth_user';
public function auth_loginform()
{
global $sess, $_PHPLIB;
include($_PHPLIB['libdir'] . 'loginform.ihtml');
}
public function auth_validatelogin()
{
global $username, $password;
if ($password == '') {
return false;
}
if (isset($username)) {
$this->auth['uname'] = $username; ## This provides access for 'loginform.ihtml'
} elseif ($this->nobody){ ## provides for 'default login cancel'
$uid = $this->auth['uname'] = $this->auth['uid'] = 'nobody';
return $uid;
}
$uid = false;
$this->db->query(
sprintf("SELECT user_id, perms FROM %s WHERE username = '%s' AND password = '%s'",
$this->database_table, addslashes($username), addslashes($password))
);
while ($this->db->next_record()) {
$uid = $this->db->f('user_id');
$this->auth['perm'] = $this->db->f('perms');
}
return $uid;
}
}
class Contenido_Default_Auth extends Contenido_Auth
{
public $classname = 'Contenido_Default_Auth';
public $lifetime = 1;
public $nobody = true;
public function auth_loginform()
{
global $sess, $_PHPLIB;
include($_PHPLIB['libdir'] . 'defloginform.ihtml');
}
}
class Contenido_Challenge_Auth extends Auth
{
public $classname = 'Contenido_Challenge_Auth';
public $lifetime = 1;
public $magic = 'Simsalabim'; ## Challenge seed
public $database_class = 'DB_Contenido';
public $database_table = 'con_phplib_auth_user';
public function auth_loginform()
{
global $sess, $challenge, $_PHPLIB;
$challenge = md5(uniqid($this->magic));
$sess->register('challenge');
include($_PHPLIB['libdir'] . 'crloginform.ihtml');
}
public function auth_validatelogin()
{
global $username, $password, $challenge, $response, $timestamp;
if ($password == '') {
return false;
}
if (isset($username)) {
// This provides access for 'loginform.ihtml'
$this->auth['uname'] = $username;
}
// Sanity check: If the user presses 'reload', don't allow a login with the data
// again. Instead, prompt again.
if ($timestamp < (time() - 60 * 15)) {
return false;
}
$this->db->query(
sprintf("SELECT user_id, perms, password FROM %s WHERE username = '%s'",
$this->database_table, addslashes($username))
);
while ($this->db->next_record()) {
$uid = $this->db->f('user_id');
$perm = $this->db->f('perms');
$pass = $this->db->f('password');
}
$exspected_response = md5("$username:$pass:$challenge");
// True when JS is disabled
if ($response == '') {
if ($password != $pass) {
return false;
} else {
$this->auth['perm'] = $perm;
return $uid;
}
}
// Response is set, JS is enabled
if ($exspected_response != $response) {
return false;
} else {
$this->auth['perm'] = $perm;
return $uid;
}
}
}
##
## Contenido_Challenge_Crypt_Auth: Keep passwords in md5 hashes rather
## than cleartext in database
## Author: Jim Zajkowski <jim@jimz.com>
class Contenido_Challenge_Crypt_Auth extends Auth
{
public $classname = 'Contenido_Challenge_Crypt_Auth';
public $lifetime = 15;
public $magic = 'Frrobo123xxica'; ## Challenge seed
public $database_class = 'DB_Contenido';
public $database_table = '';
public $group_table = '';
public $member_table = '';
public function __construct()
{
global $cfg;
$this->database_table = $cfg['tab']['phplib_auth_user_md5'];
$this->group_table = $cfg['tab']['groups'];
$this->member_table = $cfg['tab']['groupmembers'];
$this->lifetime = $cfg['backend']['timeout'];
if ($this->lifetime == 0) {
$this->lifetime = 15;
}
}
public function auth_loginform()
{
global $sess, $challenge, $_PHPLIB, $cfg;
$challenge = md5(uniqid($this->magic));
$sess->register('challenge');
include($cfg['path']['contenido'] . 'main.loginform.php');
}
public function auth_loglogin($uid)
{
global $cfg, $client, $lang, $auth, $sess, $saveLoginTime;
$perm = new Contenido_Perm();
$timestamp = date('Y-m-d H:i:s');
$idcatart = '0';
/* Find the first accessible client and language for the user */
// All the needed information should be available in clients_lang - but the previous code was designed with a
// reference to the clients table. Maybe fail-safe technology, who knows...
$sql = 'SELECT tblClientsLang.idclient, tblClientsLang.idlang FROM ' .
$cfg['tab']['clients'] . ' AS tblClients, ' . $cfg['tab']['clients_lang'] . ' AS tblClientsLang ' .
'WHERE tblClients.idclient = tblClientsLang.idclient ORDER BY idclient ASC, idlang ASC';
$this->db->query($sql);
$bFound = false;
while ($this->db->next_record() && !$bFound) {
$iTmpClient = $this->db->f('idclient');
$iTmpLang = $this->db->f('idlang');
if ($perm->have_perm_client_lang($iTmpClient, $iTmpLang)) {
$client = $iTmpClient;
$lang = $iTmpLang;
$bFound = true;
}
}
if (isset($idcat) && isset($idart)) {
// SECURITY FIX
$sql = "SELECT idcatart
FROM
". $cfg['tab']['cat_art'] ."
WHERE
idcat = '".Contenido_Security::toInteger($idcat)."' AND
idart = '".Contenido_Security::toInteger($idart)."'";
$this->db->query($sql);
$this->db->next_record();
$idcatart = $this->db->f('idcatart');
}
if (!is_numeric($client) || !is_numeric($lang)) {
return;
}
$idaction = $perm->getIDForAction('login');
$lastentry = $this->db->nextid($cfg['tab']['actionlog']);
$sql = "INSERT INTO
". $cfg['tab']['actionlog']."
SET
idlog = $lastentry,
user_id = '" . $uid . "',
idclient = '".Contenido_Security::toInteger($client)."',
idlang = '".Contenido_Security::toInteger($lang)."',
idaction = $idaction,
idcatart = $idcatart,
logtimestamp = '$timestamp'";
$this->db->query($sql);
$sess->register('saveLoginTime');
$saveLoginTime = true;
}
public function auth_validatelogin()
{
global $username, $password, $challenge, $response, $formtimestamp, $auth_handlers;
$gperm = array();
if ($password == '') {
return false;
}
if (($formtimestamp + (60*15)) < time()) {
return false;
}
if (isset($username)) {
$this->auth['uname'] = $username; ## This provides access for 'loginform.ihtml'
} elseif ($this->nobody) { ## provides for 'default login cancel'
$uid = $this->auth['uname'] = $this->auth['uid'] = 'nobody';
return $uid;
}
$uid = false;
$perm = false;
$pass = false;
$sDate = date('Y-m-d');
$this->db->query(sprintf("SELECT user_id, perms, password FROM %s WHERE username = '%s' AND
(valid_from <= '".$sDate."' OR valid_from = '0000-00-00' OR valid_from is NULL) AND
(valid_to >= '".$sDate."' OR valid_to = '0000-00-00' OR valid_to is NULL)",
$this->database_table,
Contenido_Security::escapeDB($username, $this->db)
));
$sMaintenanceMode = getSystemProperty('maintenance', 'mode');
while($this->db->next_record()) {
$uid = $this->db->f('user_id');
$perm = $this->db->f('perms');
$pass = $this->db->f('password'); ## Password is stored as a md5 hash
$bInMaintenance = false;
if ($sMaintenanceMode == 'enabled') {
#sysadmins are allowed to login every time
if (!preg_match('/sysadmin/', $perm)) {
$bInMaintenance = true;
}
}
if ($bInMaintenance) {
unset($uid);
unset($perm);
unset($pass);
}
if (is_array($auth_handlers) && !$bInMaintenance) {
if (array_key_exists($pass, $auth_handlers)) {
$success = call_user_func($auth_handlers[$pass], $username, $password);
if ($success) {
$uid = md5($username);
$pass = md5($password);
}
}
}
}
if ($uid == false) {
## No user found, sleep and exit
sleep(5);
return false;
} else {
$this->db->query(sprintf("SELECT a.group_id AS group_id, a.perms AS perms ".
"FROM %s AS a, %s AS b WHERE a.group_id = b.group_id AND b.user_id = '%s'",
$this->group_table,
$this->member_table,
$uid
));
if ($perm != '') {
$gperm[] = $perm;
}
while ($this->db->next_record()) {
$gperm[] = $this->db->f('perms');
}
if (is_array($gperm)) {
$perm = implode(',',$gperm);
}
if ($response == '') { ## True when JS is disabled
if (md5($password) != $pass) { ## md5 hash for non-JavaScript browsers
sleep(5);
return false;
} else {
$this->auth['perm'] = $perm;
$this->auth_loglogin($uid);
return $uid;
}
}
$expected_response = md5("$username:$pass:$challenge");
if ($expected_response != $response) { ## Response is set, JS is enabled
sleep(5);
return false;
} else {
$this->auth['perm'] = $perm;
$this->auth_loglogin($uid);
return $uid;
}
}
}
}
class Contenido_Frontend_Challenge_Crypt_Auth extends Auth
{
public $classname = 'Contenido_Frontend_Challenge_Crypt_Auth';
public $lifetime = 15;
public $magic = 'Frrobo123xxica'; ## Challenge seed
public $database_class = 'DB_Contenido';
public $database_table = '';
public $fe_database_table = '';
public $group_table = '';
public $member_table = '';
public $nobody = true;
public function __construct()
{
global $cfg;
$this->database_table = $cfg['tab']['phplib_auth_user_md5'];
$this->fe_database_table = $cfg['tab']['frontendusers'];
$this->group_table = $cfg['tab']['groups'];
$this->member_table = $cfg['tab']['groupmembers'];
}
public function auth_preauth()
{
global $password;
if ($password == '') {
/* Stay as nobody when an empty password is passed */
$uid = $this->auth['uname'] = $this->auth['uid'] = 'nobody';
return false;
}
return $this->auth_validatelogin();
}
public function auth_loginform()
{
global $sess, $challenge, $_PHPLIB, $client, $cfgClient;
$challenge = md5(uniqid($this->magic));
$sess->register('challenge');
include($cfgClient[$client]['path']['frontend'].'front_crcloginform.inc.php');
}
public function auth_validatelogin()
{
global $username, $password, $challenge, $response, $auth_handlers, $client;
$client = (int)$client;
if(isset($username)) {
$this->auth['uname'] = $username; ## This provides access for 'loginform.ihtml'
} else if ($this->nobody) { ## provides for 'default login cancel'
$uid = $this->auth['uname'] = $this->auth['uid'] = 'nobody';
return $uid;
}
$uid = false;
/* Authentification via frontend users */
$this->db->query(sprintf("SELECT idfrontenduser, password FROM %s WHERE username = '%s' AND idclient='$client' AND active='1'",
$this->fe_database_table,
Contenido_Security::escapeDB(urlencode($username), $this->db)
));
if ($this->db->next_record()) {
$uid = $this->db->f('idfrontenduser');
$perm = 'frontend';
$pass = $this->db->f('password');
}
if ($uid == false) {
/* Authentification via backend users */
$this->db->query(sprintf("SELECT user_id, perms, password FROM %s WHERE username = '%s'",
$this->database_table,
Contenido_Security::escapeDB($username, $this->db) ));
while($this->db->next_record()) {
$uid = $this->db->f('user_id');
$perm = $this->db->f('perms');
$pass = $this->db->f('password'); ## Password is stored as a md5 hash
if (is_array($auth_handlers)) {
if (array_key_exists($pass, $auth_handlers)) {
$success = call_user_func($auth_handlers[$pass], $username, $password);
if ($success) {
$uid = md5($username);
$pass = md5($password);
}
}
}
}
if ($uid !== false) {
$this->db->query(sprintf("SELECT a.group_id AS group_id, a.perms AS perms ".
"FROM %s AS a, %s AS b WHERE a.group_id = b.group_id AND ".
"b.user_id = '%s'",
$this->group_table,
$this->member_table,
$uid
));
/* Deactivated: Backend user would be sysadmin when logged on as frontend user
* (and perms would be checked), see http://www.contenido.org/forum/viewtopic.php?p=85666#85666
$perm = 'sysadmin'; */
if ($perm != '') {
$gperm[] = $perm;
}
while ($this->db->next_record()) {
$gperm[] = $this->db->f('perms');
}
if (is_array($gperm)) {
$perm = implode(',',$gperm);
}
}
}
if ($uid == false) {
## User not found, sleep and exit
sleep(5);
return false;
} else {
if ($response == '') { ## True when JS is disabled
if (md5($password) != $pass) { ## md5 hash for non-JavaScript browsers
sleep(5);
return false;
} else {
$this->auth['perm'] = $perm;
return $uid;
}
}
$expected_response = md5("$username:$pass:$challenge");
if ($expected_response != $response) { ## Response is set, JS is enabled
sleep(5);
return false;
} else {
$this->auth['perm'] = $perm;
return $uid;
}
}
}
}
/**
* Registers an external auth handler
*/
function register_auth_handler($aHandlers)
{
global $auth_handlers;
if (!is_array($auth_handlers)) {
$auth_handlers = array();
}
if (!is_array($aHandlers)) {
$aHandlers = Array($aHandlers);
}
foreach ($aHandlers as $sHandler) {
if (!in_array($sHandler, $auth_handlers)) {
$auth_handlers[md5($sHandler)] = $sHandler;
}
}
}
?>

110
branches/php7/conlib/page.inc Normale Datei
Datei anzeigen

@ -0,0 +1,110 @@
<?php
/**
* Project:
* Contenido Content Management System
*
* Description:
* Session Management for PHP3
*
* Requirements:
* @con_php_req 5
*
* @package ContenidoBackendArea
* @version 1.1.1.1
* @author Boris Erdmann, Kristian Koehntopp
* @copyright four for business AG <www.4fb.de>
* @license http://www.contenido.org/license/LIZENZ.txt
* @link http://www.4fb.de
* @link http://www.contenido.org
* @since file available since contenido release <Contenido Version>
* @deprecated file deprecated in contenido release <Contenido Version>
*
* {@internal
* created 2002-07-21
* modified 2008-07-04, bilal arslan, added security fix
*
* $Id: page.inc 1315 2011-03-03 00:02:52Z xmurrix $:
* }}
*
*/
if(!defined('CON_FRAMEWORK')) {
die('Illegal call');
}
function page_open($feature) {
global $_PHPLIB;
# enable sess and all dependent features.
if (isset($feature["sess"])) {
global $sess;
$sess = new $feature["sess"];
$sess->start();
# the auth feature depends on sess
if (isset($feature["auth"])) {
global $auth;
if (!isset($auth)) {
$auth = new $feature["auth"];
}
$auth->start();
# the perm feature depends on auth and sess
if (isset($feature["perm"])) {
global $perm;
if (!isset($perm)) {
$perm = new $feature["perm"];
}
}
# the user feature depends on auth and sess
if (isset($feature["user"])) {
global $user;
if (!isset($user)) {
$user = new $feature["user"];
}
$user->start($auth->auth["uid"]);
}
}
## Load the auto_init-File, if one is specified.
if (($sess->auto_init != "") && !$sess->in) {
$sess->in = 1;
include($_PHPLIB["libdir"] . $sess->auto_init);
if ($sess->secure_auto_init != "") {
$sess->freeze();
}
}
}
}
function page_close() {
global $sess, $user;
if (isset($sess)) {
$sess->freeze();
if (isset($user) && method_exists($user, "freeze")) {
$user->freeze();
}
}
}
function sess_load($session) {
reset($session);
while (list($k,$v) = each($session)) {
$GLOBALS[$k] = new $v;
$GLOBALS[$k]->start();
}
}
function sess_save($session) {
reset($session);
while (list(,$v) = each($session)) {
$GLOBALS[$v]->freeze();
}
}
?>

678
branches/php7/conlib/perm.inc Normale Datei
Datei anzeigen

@ -0,0 +1,678 @@
<?php
/**
* Project:
* Contenido Content Management System
*
* Description:
* Session Management for PHP3
*
* Requirements:
* @con_php_req 5
*
* @package ContenidoBackendArea
* @version 0.1
* @author Boris Erdmann, Kristian Koehntopp
* @copyright four for business AG <www.4fb.de>
* @license http://www.contenido.org/license/LIZENZ.txt
* @link http://www.4fb.de
* @link http://www.contenido.org
* @since file available since contenido release <Contenido Version>
* @deprecated file deprecated in contenido release <Contenido Version>
*
* {@internal
* created 2002-08-16
* modified 2008-07-04, bilal arslan, added security fix
* modified 2009-10-29, Murat Purc, replaced deprecated functions (PHP 5.3 ready) and some formatting
*
* $Id: perm.inc 1315 2011-03-03 00:02:52Z xmurrix $:
* }}
*
*/
if (!defined('CON_FRAMEWORK')) {
die('Illegal call');
}
class Contenido_Perm {
var $classname = "Contenido_Perm";
var $areacache = array();
var $actioncache = array();
var $db;
var $db_perm;
function getGroupsForUser($user) {
global $cfg;
if (!is_object($this->db)) {
$this->db = new DB_Contenido;
}
$sql = "SELECT group_id FROM
" . $cfg["tab"]["groupmembers"] . "
WHERE user_id = '" . Contenido_Security::escapeDB($user, $this->db) . "'";
$this->db->query($sql);
$groups = array();
while ($this->db->next_record()) {
$groups[] = $this->db->f("group_id");
}
return $groups;
}
function getIDForArea($area) {
global $cfg;
if (!is_object($this->db_perm)) {
$this->db_perm = new DB_Contenido;
}
if (!is_numeric($area)) {
if (!@ array_key_exists($area, $this->areacache)) {
$sql = "SELECT idarea
FROM
" . $cfg["tab"]["area"] . "
WHERE
name = \"" . Contenido_Security::escapeDB($area, $this->db_perm) . "\"";
$this->db_perm->query($sql);
$this->db_perm->next_record();
$this->areacache[$area] = $this->db_perm->f("idarea");
$area = $this->db_perm->f(0);
} else {
$area = $this->areacache[$area];
}
return ($area);
}
return $area;
}
function getIDForAction($action) {
global $cfg;
if (!is_object($this->db_perm)) {
$this->db_perm = new DB_Contenido;
}
if (!is_numeric($action)) {
if (!@ array_key_exists($action, $this->actioncache)) {
$sql = "SELECT idaction
FROM
" . $cfg["tab"]["actions"] . "
WHERE
name = \"" . Contenido_Security::escapeDB($action, $this->db_perm) . "\"";
$this->db_perm->query($sql);
$this->db_perm->next_record();
$this->actioncache[$action] = $this->db_perm->f("idaction");
$action = $this->db_perm->f(0);
} else {
$action = $this->actioncache[$action];
}
return ($action);
}
return $action;
}
function load_permissions($force = false) {
global $sess, $area_rights, $item_rights, $db, $client, $lang, $auth, $cfg, $changelang, $changeclient;
$return = "1";
//if not admin or sysadmin
if (!$this->have_perm()) {
$return = isset($area_rights);
if (!isset($area_rights) || !isset($item_rights) || isset($changeclient) || isset($changelang) || $force) {
$return = "3";
//register variables
$sess->register("area_rights");
$sess->register("item_rights");
$item_rights = array();
$groups = $this->getGroupsForUser($auth->auth["uid"]);
if (is_array($groups)) {
foreach ($groups as $group) {
$this->load_permissions_for_user($group);
}
}
$this->load_permissions_for_user($auth->auth["uid"]);
}
}
return $return;
}
function load_permissions_for_user($user) {
global $db, $client, $lang, $cfg;
global $area_rights, $item_rights;
$sql = "SELECT *
FROM " . $cfg["tab"]["rights"] . "
WHERE user_id='" . Contenido_Security::escapeDB($user, $db) . "' AND idcat='0' AND idclient='" . Contenido_Security::toInteger($client) . "' AND idlang='" . Contenido_Security::toInteger($lang) . "'";
$db->query($sql);
if (!is_array($area_rights)) {
$area_rights = array();
}
while ($db->next_record()) {
$area_rights[$db->f("idarea")][$db->f("idaction")] = true;
}
// Select Rights for Article and Sructure Atention Hard code Areas
$sql = "SELECT
idarea
FROM
" . $cfg["tab"]["area"];
$db->query($sql);
$tmp_area = array();
while ($db->next_record()) {
array_push($tmp_area, $db->f("idarea"));
}
$tmp_area_string = implode("','", array_keys($tmp_area));
$sql = "SELECT
idarea, idaction, idcat
FROM " . $cfg["tab"]["rights"] . "
WHERE user_id='" . Contenido_Security::escapeDB($user, $db) . "' AND idclient='" . Contenido_Security::toInteger($client) . "' AND idlang='" . Contenido_Security::toInteger($lang) . "' AND idarea IN ('$tmp_area_string') AND idcat != '0'";
$db->query($sql);
while ($db->next_record()) {
$item_rights[$db->f(0)][$db->f(1)][$db->f(2)] = $db->f(2);
}
}
function have_perm_area_action_anyitem($area, $action = 0) {
if ($this->have_perm_area_action($area, $action)) {
return true;
}
$area = $this->getIDForArea($area);
$action = $this->getIDForAction($action);
global $item_rights;
if (isset($item_rights[$area][$action])) {
return true;
} else {
return false;
}
}
function have_perm_area_action_item($area, $action, $itemid) {
global $item_rights, $auth, $client, $lang, $cfg;
if (!is_object($this->db)) {
$this->db = new DB_Contenido;
}
$area = $this->getIDForArea($area);
$action = $this->getIDForAction($action);
if ($this->have_perm()) {
return true;
} else {
//if the user has a right on this action in this area check for the items
if ($this->have_perm_area_action($area, $action)) {
return true;
}
//check rights for the action in this area at this item
if (isset($item_rights[$area][$action][$itemid])) {
//if have action for area + action +item check right for client and lang
return true;
} elseif ($item_rights[$area] != "noright") {
$groupsForUser = $this->getGroupsForUser($auth->auth[uid]);
$groupsForUser[] = $auth->auth[uid];
$tmp_userstring = implode("','", $groupsForUser);
$sql = "SELECT *
FROM " . $cfg["tab"]["rights"] . "
WHERE user_id IN ('" . $tmp_userstring . "') AND idclient = '" . Contenido_Security::toInteger($client) . "' AND idlang = '" . Contenido_Security::toInteger($lang) . "' AND idarea = '$area' AND idcat != '0'";
$this->db->query($sql);
//if there are no rights for this area set the flag norights
if ($this->db->nf() == 0) {
$item_rights[$area] = "noright";
return false;
}
while ($this->db->next_record()) {
$item_rights[$this->db->f("idarea")][$this->db->f("idaction")][$this->db->f("idcat")] = $this->db->f("idcat");
}
//check
if (isset($item_rights[$area][$action][$itemid])) {
//if have action for area + action +item check right for client and lang
return true;
}
}
return false;
}
}
function getParentAreaId($area) {
global $client, $lang, $cfg, $sess;
if (!is_object($this->db)) {
$this->db = new DB_Contenido;
}
if (is_numeric($area)) {
$sql = "SELECT
b.name
FROM
" . $cfg["tab"]["area"] . " AS a,
" . $cfg["tab"]["area"] . " AS b
WHERE
a.idarea = '" . Contenido_Security::toInteger($area) . "' AND
b.name = a.parent_id";
} else {
$sql = "SELECT
b.name
FROM
" . $cfg["tab"]["area"] . " AS a,
" . $cfg["tab"]["area"] . " AS b
WHERE
a.name = '" . Contenido_Security::escapeDB($area, $this->db) . "' AND
b.name = a.parent_id";
}
$this->db->query($sql);
if ($this->db->next_record()) {
return $this->db->f(0);
} else {
return $area;
}
}
function have_perm_area_action($area, $action = 0) {
global $area_rights, $client, $lang, $cfg;
//if not admin or sysadmin
if (!is_object($this->db_perm)) {
$this->db_perm = new DB_Contenido;
}
$area = $this->getIDForArea($area);
$action = $this->getIDForAction($action);
if ($action == 0) {
$area = $this->getParentAreaId($area);
}
$area = $this->getIDForArea($area);
if (!$this->have_perm()) {
if ($action == 0 && $area_rights[$area]) {
//if have action for area + action check right for client and lang
return ($this->have_perm_client_lang($client, $lang));
}
//check rights for the action in this area
if ($area_rights[$area][$action]) {
//if have action for area + action check right for client and lang
return $this->have_perm_client_lang($client, $lang);
}
return false;
}
return true;
}
function have_perm_client_lang($client, $lang) {
// Changed back to a full featured function, as have_perm
// needs $client as global variable - not provided by this
// function
//return ($this->have_perm("client[$client],lang[$lang]"));
global $auth;
if (!isset($auth->auth['perm'])) {
$auth->auth['perm'] = '';
}
// Split the permissions of the user
$userperm = explode(',', $auth->auth['perm']);
if (in_array('sysadmin', $userperm)) {
return true; // User is sysadmin
} elseif (in_array("admin[$client]", $userperm)) {
return true; // User is admin
} else {
// Check rights for the client and the language
$pageperm = explode(',', "client[$client],lang[$lang]");
foreach ($pageperm as $value) {
if (!in_array($value, $userperm)) {
return false;
}
}
}
return true;
}
/**
* hasClientPermission
* Checks if a user has access rights for a specific client.
*
* @param integer $iClient idclient to check, or false for the current client
* @param object $oUser User object to check against, or false for the current user
*/
function hasClientPermission($iClient = false, $oUser = false) {
global $auth;
if ($iClient === false) {
global $client;
$iClient = $client;
}
$oUser = $this->_checkUserObject($oUser);
if ($this->isSysadmin($oUser) || $this->isClientAdmin($iClient, $oUser) || $this->isClientUser($iClient, $oUser)) {
return true;
} else {
return false;
}
/* Commented out Timo Trautmann, because here only client access is checked, possibility for admin or sysadmin access was ignored
functions isSysadmin isClientAdmin isClientUser also handles permission for groups
#Check clients' rights of users' group(s)
$aGroups = $this->getGroupsForUser($auth->auth["uid"]);
if (is_array($aGroups))
{
foreach ($aGroups as $group)
{
$oGroup = new Group;
$oGroup->loadGroupByGroupID ($group);
if ($this->isClientGroup($iClient, $oGroup))
{
return true;
}
}
}
return false;
} */
}
/**
* isClientUser
* Checks if the given user has access permission for a client
*
* @param integer $iClient idclient to check
* @param object $oUser User object to check against
*/
function isClientUser($iClient, $oUser) {
$oUser = $this->_checkUserObject($oUser);
$aPermissions = explode(",", $oUser->getEffectiveUserPerms());
if (in_array("client[$iClient]", $aPermissions)) {
return true;
}
return false;
}
/**
* isClientGroup
* Checks if the given group has access permission for a client
*
* @param integer $iClient idclient to check
* @param object $oGroup Group object to check against
*/
function isClientGroup($iClient, $oGroup) {
$aPermissions = explode(",", $oGroup->getField("perms"));
if (in_array("client[$iClient]", $aPermissions)) {
return true;
}
return false;
}
/**
* isClientAdmin
* Checks if the given user has an admin permission
*
* @param integer $iClient idclient to check
* @param object $oUser User object to check against
*/
function isClientAdmin($iClient, $oUser) {
$oUser = $this->_checkUserObject($oUser);
$aPermissions = explode(",", $oUser->getEffectiveUserPerms());
if (in_array("admin[$iClient]", $aPermissions)) {
return true;
}
return false;
}
/**
* Checks if the given user has sysadmin permission
*
* @param User $oUser userobject or false (default)
* @return boolean true if user is sysadmin
*/
public function isSysadmin($oUser = FALSE) {
$oUser2Check = $this->_checkUserObject($oUser);
if(!is_object($oUser2Check)) {
return false;
}
$aPermissions = explode(",", $oUser2Check->getEffectiveUserPerms());
if (in_array("sysadmin", $aPermissions)) {
return true;
}
return false;
}
/**
* _checkUserObject
*
* Checks if the given object is a user object.
*
* If oUser is false, initialize the object from the currently logged in user. If oUser is not
* a object of the class User, issue a warning.
*
* @parameter object oUser User object
* @access private
*/
private function _checkUserObject($oUser) {
if ($oUser === false) {
global $currentuser;
$oUser = $currentuser;
}
if (!is_object($oUser)) {
global $auth;
$oUser = new User;
$oUser->loadUserByUserID($auth->auth["uid"]);
}
if (strtolower(get_class($oUser)) != "user") {
cWarning(__FILE__, __LINE__, "oUser parameter is not of type User");
}
return $oUser;
}
/**
* @deprecated
*/
function have_perm_client($p = 'x') {
global $auth, $client;
if (!isset($auth->auth['perm'])) {
$auth->auth['perm'] = '';
}
//split the permissions of the user
$userperm = explode(',', $auth->auth['perm']);
//if User is sysadmin or admin at this client return true
if (in_array('sysadmin', $userperm)) {
return true;
}
//if there are more permissions to ask split them
$pageperm = explode(',', $p);
foreach ($pageperm as $value) {
if (!in_array($value, $userperm)) {
return false;
}
}
return true;
}
function have_perm($p = 'x') {
global $auth, $client;
if (!isset($auth->auth['perm'])) {
$auth->auth['perm'] = '';
}
//split the permissions of the user
$userperm = explode(',', $auth->auth['perm']);
//if User is sysadmin or admin at this client return true
if (in_array('sysadmin', $userperm)) {
return true;
} elseif (in_array("admin[$client]", $userperm)) {
return true;
//else check rights for the client and the language
} else {
//if there are more permissions to ask split them
$pageperm = explode(',', $p);
foreach ($pageperm as $value) {
if (!in_array($value, $userperm)) {
return false;
}
}
}
return true;
}
//checks if an item have any perms
function have_perm_item($mainarea, $itemid) {
global $cfg, $item_rights, $cfg, $client, $lang, $auth, $area_tree, $sess;
$mainarea = $this->getIDForArea($mainarea);
//if is not admin or sysadmin
if (!$this->have_perm()) {
if (!is_object($this->db)) {
$this->db = new DB_Contenido;
}
$this->showareas($mainarea);
$flg = false;
//check if there are any rights for this areas
foreach ($area_tree[$mainarea] as $value) {
// if the flag noright is set there are no rights in this area
if ($item_rights[$value] == "noright") {
continue;
} elseif (is_array($item_rights[$value])) {
//if there are any rights
foreach ($item_rights[$value] as $value2) {
if (in_array($itemid, $value2)) {
return true;
}
}
} elseif ($item_rights[$value] != "noright") {
$groupsForUser = $this->getGroupsForUser($auth->auth[uid]);
$groupsForUser[] = $auth->auth[uid];
//else search for rights for this user in this area
$sql = "SELECT
*
FROM
" . $cfg["tab"]["rights"] . "
WHERE
user_id IN ('" . implode("','", $groupsForUser) . "') AND
idclient = '" . Contenido_Security::toInteger($client) . "' AND
idlang = '" . Contenido_Security::toInteger($lang) . "' AND
idarea = '$value' AND
idcat != '0'";
$this->db->query($sql);
//if there are no rights for this area set the flag norights
if ($this->db->affected_rows() == 0) {
$item_rights[$value] = "noright";
}
//set the rights
while ($this->db->next_record()) {
if ($this->db->f("idcat") == $itemid) {
$flg = true;
}
$item_rights[$this->db->f("idarea")][$this->db->f("idaction")][$this->db->f("idcat")] = $this->db->f("idcat");
}
} //end if
} //end for
return $flg;
} //end if
return true;
}
function showareas($mainarea) {
global $area_tree, $sess, $perm, $cfg;
if (!is_object($this->db)) {
$this->db = new DB_Contenido;
}
$mainarea = $this->getIDForArea($mainarea);
//if $area_tree for this area is not register
if (!isset($area_tree[$mainarea])) {
$sess->register("area_tree");
// parent_id uses the name not the idarea
$sql = "SELECT
name
FROM
" . $cfg["tab"]["area"] . "
WHERE
idarea='$mainarea'";
$this->db->query($sql);
$this->db->next_record();
$name = $this->db->f("name");
//check which subareas are there and write them in the array
$sql = "SELECT
idarea
FROM
" . $cfg["tab"]["area"] . "
WHERE
parent_id='$name' OR
idarea='$mainarea'";
$this->db->query($sql);
$area_tree[$mainarea] = array();
while ($this->db->next_record()) {
$area_tree[$mainarea][] = $this->db->f("idarea");
}
}
return $mainarea;
}
}

Datei anzeigen

@ -0,0 +1,69 @@
<?php
/**
* Project:
* Contenido Content Management System
*
* Description:
* Session Management for PHP3
*
* Requirements:
* @con_php_req 5
*
* @package ContenidoBackendArea
* @version 1.4
* @author Boris Erdmann, Kristian Koehntopp
* @copyright four for business AG <www.4fb.de>
* @license http://www.contenido.org/license/LIZENZ.txt
* @link http://www.4fb.de
* @link http://www.contenido.org
*
*
*
* {@internal
* created 2000-01-01
* modified 2008-07-04, bilal arslan, added security fix
* modified 2009-10-29, Murat Purc, automatic loading of configured database driver
* modified 2011-03-21, Murat Purc, inclusion of ct_session.inc
*
* $Id: prepend.php 67 2012-05-09 13:28:03Z oldperl $:
* }}
*
*/
if (!defined('CON_FRAMEWORK')) {
die('Illegal call');
}
$_PHPLIB = array();
$_PHPLIB['libdir'] = str_replace ('\\', '/', dirname(__FILE__) . '/');
global $cfg;
require($_PHPLIB['libdir'] . 'db_sql_abstract.inc');
// include/require database driver
$dbDriverFileName = 'db_' . $cfg['database_extension'] . '.inc';
if (is_file($_PHPLIB['libdir'] . $dbDriverFileName)) {
require_once($_PHPLIB['libdir'] . $dbDriverFileName);
} else {
die('Invalid database extension: ' . $cfg['database_extension']);
}
unset($dbDriverFileName);
require_once($_PHPLIB['libdir'] . 'ct_sql.inc'); // Data storage container: database
require_once($_PHPLIB['libdir'] . 'ct_file.inc'); // Data storage container: file
require_once($_PHPLIB['libdir'] . 'ct_shm.inc'); // Data storage container: memory
require_once($_PHPLIB['libdir'] . 'ct_session.inc');// Data storage container: memory
require_once($_PHPLIB['libdir'] . 'ct_null.inc'); // Data storage container: null -
// no session container - Contenido does not work
require_once($_PHPLIB['libdir'] . 'session.inc'); // Required for everything below.
require_once($_PHPLIB['libdir'] . 'auth.inc'); // Disable this, if you are not using authentication.
require_once($_PHPLIB['libdir'] . 'perm.inc'); // Disable this, if you are not using permission checks.
// Additional require statements go before this line
require_once($_PHPLIB['libdir'] . 'local.php'); // Required, contains your local configuration.
require_once($_PHPLIB['libdir'] . 'page.inc'); // Required, contains the page management functions.

Datei anzeigen

@ -0,0 +1,536 @@
<?php
/**
* ConLite Session Management
*
* @package Core
* @subpackage cSystemClasses
* @version $Rev:$
* @author Ortwin Pinke <conlite@ortwinpinke.de>
* @copyright (c) 2014, ConLite Team <www.conlite.org>
* @link http://conlite.org ConLite Portal
*
* $Id:$
*/
/**
* @package ContenidoBackendArea
* @version 1.1.1.2
* @author Boris Erdmann, Kristian Koehntopp
* @copyright four for business AG <www.4fb.de>
* @license http://www.contenido.org/license/LIZENZ.txt
* @link http://www.4fb.de
* @link http://www.contenido.org
*/
if(!defined('CON_FRAMEWORK')) {die('Illegal call');}
/**
* old session class, now only extends new cSession
*
* @deprecated since version 2.0
*/
class Session extends cSession {
}
class cSession {
var $classname = "Session"; ## Needed for object serialization.
## Define the parameters of your session by either overwriting
## these values or by subclassing session (recommended).
var $magic = ""; ## Some string you should change.
var $mode = "cookie"; ## We propagate session IDs with cookies
var $fallback_mode; ## If this doesn't work, fall back...
var $lifetime = 0; ## 0 = do session cookies, else minutes
var $cookie_domain = ""; ## If set, the domain for which the
## session cookie is set.
var $gc_time = 1440; ## Purge all session data older than 1440 minutes.
var $gc_probability = 5; ## Garbage collect probability in percent
var $auto_init = ""; ## Name of the autoinit-File, if any.
var $secure_auto_init = 1; ## Set to 0 only, if all pages call
## page_close() guaranteed.
var $allowcache = "no"; ## "passive", "no", "private" or "public"
var $allowcache_expire = 1440; ## If you allowcache, data expires in this
## many minutes.
var $that_class = ""; ## Name of data storage container
##
## End of parameters.
##
var $name; ## Session name
var $id; ## Unique Session ID
var $that;
var $pt = array(); ## This Array contains the registered things
var $in = 0; ## Marker: Did we already include the autoinit file?
var $expires; ## Expire date
var $_expires;
## register($things):
##
## call this function to register the things that should become persistent
function register($things) {
$things = explode(",", $things);
reset($things);
while (list(, $thing) = each($things)) {
$thing = trim($thing);
if ($thing) {
$this->pt[$thing] = true;
}
}
}
function setExpires($time) {
$this->_expires = $time;
}
function is_registered($name) {
if (isset($this->pt[$name]) && $this->pt[$name] == true)
return true;
return false;
}
function unregister($things) {
$things = explode(",", $things);
reset($things);
while (list(, $thing) = each($things)) {
$thing = trim($thing);
if ($thing) {
unset($this->pt[$thing]);
}
}
}
## get_id():
##
## Propagate the session id according to mode and lifetime.
## Will create a new id if necessary. To take over abandoned sessions,
## one may provide the new session id as a parameter (not recommended).
function get_id($id = "") {
global $_COOKIE, $_GET, $_POST, $QUERY_STRING;
$newid = true;
$this->name = $this->cookiename == "" ? $this->classname : $this->cookiename;
if ("" == $id) {
$newid = false;
switch ($this->mode) {
case "get":
$id = isset($_GET[$this->name]) ?
$_GET[$this->name] :
( isset($_POST[$this->name]) ?
$_POST[$this->name] :
"");
break;
case "cookie":
$id = isset($_COOKIE[$this->name]) ?
$_COOKIE[$this->name] : "";
break;
default:
die("This has not been coded yet.");
break;
}
}
if ("" == $id) {
$newid = true;
$id = $this->that->ac_newid(md5(uniqid($this->magic)), $this->name);
}
switch ($this->mode) {
case "cookie":
if ($newid && ( 0 == $this->lifetime )) {
SetCookie($this->name, $id, 0, "/", $this->cookie_domain);
}
if (0 < $this->lifetime) {
SetCookie($this->name, $id, time() + $this->lifetime * 60, "/", $this->cookie_domain);
}
// Remove session ID info from QUERY String - it is in cookie
if (isset($QUERY_STRING) && ("" != $QUERY_STRING)) {
$QUERY_STRING = preg_replace(
"/(^|&)" . quotemeta(urlencode($this->name)) . "=" . $id . "(&|$)/", "\\1", $QUERY_STRING);
}
break;
case "get":
if (isset($QUERY_STRING) && ("" != $QUERY_STRING)) {
$QUERY_STRING = preg_replace(
"/(^|&)" . quotemeta(urlencode($this->name)) . "=" . $id . "(&|$)/", "\\1", $QUERY_STRING);
}
break;
default:
;
break;
}
$this->id = $id;
}
## put_id():
##
## Stop using the current session id (unset cookie, ...) and
## abandon a session.
function put_id() {
global $_COOKIE;
switch ($this->mode) {
case "cookie":
$this->name = $this->cookiename == "" ? $this->classname : $this->cookiename;
SetCookie($this->name, "", 0, "/", $this->cookie_domain);
$_COOKIE[$this->name] = "";
break;
default:
// do nothing. We don't need to die for modes other than cookie here.
break;
}
}
## delete():
##
## Delete the current session record and put the session id.
function delete() {
$this->that->ac_delete($this->id, $this->name);
$this->put_id();
}
## url($url):
##
## Helper function: returns $url concatenated with the current
## session $id.
function url($url) {
// Remove existing session info from url
$url = preg_replace(
"/([&?])" . quotemeta(urlencode($this->name)) . "=" . $this->id . "(&|$)/", "\\1", $url);
// Remove trailing ?/& if needed
$url = preg_replace("/[&?]+$/", "", $url);
switch ($this->mode) {
case "get":
$url .= ( strpos($url, "?") != false ? "&" : "?" ) .
urlencode($this->name) . "=" . $this->id;
break;
default:
;
break;
}
// Encode naughty characters in the URL
$url = str_replace(array("<", ">", " ", "\"", "'"), array("%3C", "%3E", "+", "%22", "%27"), $url);
return $url;
}
function purl($url) {
print $this->url($url);
}
/**
*
* @param array $aParam
* @return string
*/
function self_url($aParam = array()) {
$sURI = $_SERVER["PHP_SELF"];
parse_str($_SERVER["QUERY_STRING"], $aQuery);
$aQuery = array_merge($aQuery, $aParam);
$sQuery = http_build_query($aQuery,'','&');
return $this->url($_SERVER["PHP_SELF"] . "?" . $sQuery);
}
function pself_url() {
print $this->self_url();
}
function hidden_session($mode = 0) {
if ($mode) {
return sprintf("<input type=\"hidden\" name=\"%s\" value=\"%s\">\n", $this->name, $this->id);
} else {
printf("<input type=\"hidden\" name=\"%s\" value=\"%s\">\n", $this->name, $this->id);
}
}
function add_query($qarray) {
global $PHP_SELF;
global $QUERY_STRING;
if ((isset($QUERY_STRING) && ("" != $QUERY_STRING)) || ($this->mode == "get")) {
$sep_char = "&";
} else {
$sep_char = "?";
}
$qstring = "";
while (list($k, $v) = each($qarray)) {
$qstring .= $sep_char . urlencode($k) . "=" . urlencode($v);
$sep_char = "&";
}
return $qstring;
}
function padd_query($qarray) {
print $this->add_query($qarray);
}
## serialize($var,&$str):
##
## appends a serialized representation of $$var
## at the end of $str.
##
## To be able to serialize an object, the object must implement
## a variable $classname (containing the name of the class as string)
## and a variable $persistent_slots (containing the names of the slots
## to be saved as an array of strings).
function serialize($var, &$str) {
static $t, $l, $k;
## Determine the type of $$var
eval("\$t = gettype(\$$var);");
switch ($t) {
case "array":
## $$var is an array. Enumerate the elements and serialize them.
eval("reset(\$$var); \$l = gettype(list(\$k)=each(\$$var));");
$str .= "\$$var = array(); ";
while ("array" == $l) {
## Structural recursion
$this->serialize($var . "['" . preg_replace("/([\\'])/", "\\\\1", $k) . "']", $str);
eval("\$l = gettype(list(\$k)=each(\$$var));");
}
break;
case "object":
## $$var is an object. Enumerate the slots and serialize them.
eval("\$k = \$${var}->classname; \$l = reset(\$${var}->persistent_slots);");
$str.="\$$var = new $k; ";
while ($l) {
## Structural recursion.
$this->serialize($var . "->" . $l, $str);
eval("\$l = next(\$${var}->persistent_slots);");
}
break;
default:
## $$var is an atom. Extract it to $l, then generate code.
eval("\$l = \$$var;");
$str.="\$$var = '" . preg_replace("/([\\'])/", "\\\\1", $l) . "'; ";
break;
}
}
function get_lock() {
$this->that->ac_get_lock();
}
function release_lock() {
$this->that->ac_release_lock();
}
## freeze():
##
## freezes all registered things ( scalar variables, arrays, objects ) into
## a database table
function freeze() {
$str = "";
//print "DBG: <pre>"; var_dump($this->pt); print "</pre>\n";
$this->serialize("this->in", $str);
$this->serialize("this->pt", $str);
reset($this->pt);
while (list($thing) = each($this->pt)) {
$thing = trim($thing);
if ($thing && isset($GLOBALS[$thing])) {
$this->serialize("GLOBALS['" . $thing . "']", $str);
}
}
//return;
$r = $this->that->ac_store($this->id, $this->name, $str);
$this->release_lock();
if (!$r)
$this->that->ac_halt("Session: freeze() failed.");
}
## thaw:
##
## Reload frozen variables from the database and microwave them.
function thaw() {
$this->get_lock();
$vals = $this->that->ac_get_value($this->id, $this->name);
eval(sprintf(";%s", $vals));
}
##
## Variable precedence functions
##
function reimport_get_vars() {
$this->reimport_any_vars("_GET");
}
function reimport_post_vars() {
$this->reimport_any_vars("_POST");
}
function reimport_cookie_vars() {
$this->reimport_any_vars("HTTP_COOKIE_VARS");
}
function reimport_any_vars($arrayname) {
global $$arrayname;
if (!is_array($$arrayname))
return;
reset($$arrayname);
while (list($key, $val) = each($$arrayname)) {
$GLOBALS[$key] = $val;
}
}
##
## All this is support infrastructure for the start() method
##
function set_container() {
$name = $this->that_class;
$this->that = new $name;
$this->that->ac_start();
}
function set_tokenname() {
$this->name = $this->cookiename == "" ? $this->classname : $this->cookiename;
}
function release_token($sid = "") {
global $_COOKIE, $_POST, $_GET,
$HTTP_HOST, $HTTPS;
if (isset($this->fallback_mode) && ("get" == $this->fallback_mode) && ("cookie" == $this->mode) && (!isset($_COOKIE[$this->name]))) {
// Looks like no cookie here - check GET/POST params
if (isset($_GET[$this->name]) || isset($_POST[$this->name])) {
// Session info passed via GET/POST - go to fallback_mode
$this->mode = $this->fallback_mode;
} else {
// It seems to be the first load of this page -
// no cookie and no GET/POST params
// Generate session ID and setup cookie.
$this->get_id($sid);
// Next line is to generate correct self_url() later
$this->mode = $this->fallback_mode;
if (isset($HTTPS) && $HTTPS == 'on') {
## You will need to fix suexec as well, if you
## use Apache and CGI PHP
$PROTOCOL = 'https';
} else {
$PROTOCOL = 'http';
}
header("Status: 302 Moved Temporarily");
header("Location: " . $PROTOCOL . "://" . $HTTP_HOST . $this->self_url());
exit;
}
}
}
function put_headers() {
# Allowing a limited amount of caching, as suggested by
# Padraic Renaghan on phplib@lists.netuse.de.
#
# Note that in HTTP/1.1 the Cache-Control headers override the Expires
# headers and HTTP/1.0 ignores headers it does not recognize (e.g,
# Cache-Control). Mulitple Cache-Control directives are split into
# mulitple headers to better support MSIE 4.x.
#
# Added pre- and post-check for MSIE 5.x as suggested by R.C.Winters,
# see http://msdn.microsoft.com/workshop/author/perf/perftips.asp#Use%20Cache-Control%20Extensions
# for details
switch ($this->allowcache) {
case "passive":
$mod_gmt = gmdate("D, d M Y H:i:s", getlastmod()) . " GMT";
header("Last-Modified: " . $mod_gmt);
# possibly ie5 needs the pre-check line. This needs testing.
header("Cache-Control: post-check=0, pre-check=0");
break;
case "public":
$exp_gmt = gmdate("D, d M Y H:i:s", time() + $this->allowcache_expire * 60) . " GMT";
$mod_gmt = gmdate("D, d M Y H:i:s", getlastmod()) . " GMT";
header("Expires: " . $exp_gmt);
header("Last-Modified: " . $mod_gmt);
header("Cache-Control: public");
header("Cache-Control: max-age=" . $this->allowcache_expire * 60);
break;
case "private":
$mod_gmt = gmdate("D, d M Y H:i:s", getlastmod()) . " GMT";
header("Expires: Mon, 26 Jul 1997 05:00:00 GMT");
header("Last-Modified: " . $mod_gmt);
header("Cache-Control: private");
header("Cache-Control: max-age=" . $this->allowcache_expire * 60);
header("Cache-Control: pre-check=" . $this->allowcache_expire * 60);
break;
default:
$rand = md5(mt_rand());
$mod_gmt = gmdate("D, d M Y H:i:s", time() - 3600) . " GMT";
if ($this->_expires > 0) {
header("Expires: " . gmdate("D, d M Y H:i:s", $this->_expires) . " GMT");
} else {
header("Expires: Mon, 26 Jul 1997 05:00:00 GMT");
}
header("Last-Modified: " . gmdate("D, d M Y H:i:s") . " GMT");
header("Cache-Control:no-store, no-cache, must-revalidate");
header("Cache-Control: post-check=0, pre-check=0", false);
header("Cache-control: private, no-cache");
header("Pragma: no-cache");
header("ETag: $rand");
break;
}
}
##
## Garbage collection
##
## Destroy all session data older than this
##
function gc() {
srand(time());
if ((rand() % 100) < $this->gc_probability) {
$this->that->ac_gc($this->gc_time, $this->name);
}
}
##
## Initialization
##
function start($sid = "") {
$this->set_container();
$this->set_tokenname();
$this->put_headers();
$this->release_token($sid);
$this->get_id($sid);
$this->thaw();
$this->gc();
$this->setExpires(0);
}
}