init php7 branch after svn-crash
Dieser Commit ist enthalten in:
Ursprung
c78fbec2fa
Commit
ba252159d2
|
@ -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() { ; }
|
||||||
|
}
|
||||||
|
?>
|
|
@ -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 '';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
?>
|
|
@ -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();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
?>
|
|
@ -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 "";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
?>
|
|
@ -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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
?>
|
|
@ -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]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
?>
|
|
@ -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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
?>
|
|
@ -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();
|
||||||
|
}
|
||||||
|
}
|
|
@ -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();
|
||||||
|
}
|
||||||
|
}
|
|
@ -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 '';
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -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();
|
||||||
|
}
|
|
@ -0,0 +1,4 @@
|
||||||
|
<?php
|
||||||
|
header("Location:/index.php");
|
||||||
|
exit;
|
||||||
|
?>
|
|
@ -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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
?>
|
|
@ -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();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
?>
|
|
@ -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;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -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.
|
|
@ -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);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
Laden…
In neuem Issue referenzieren