Namespace changes initial setup
* move all the libs into the correct folders * libs folder is now called lib * Smarty update to 3.1.30 * main config update with / is now set via core variable (dynamic)
This commit is contained in:
979
www/lib/CoreLibs/ACL/Login.inc
Normal file
979
www/lib/CoreLibs/ACL/Login.inc
Normal file
@@ -0,0 +1,979 @@
|
||||
<?
|
||||
/*********************************************************************
|
||||
* AUTHOR: Clemens "Gullevek" Schwaighofer (www.gullevek.org)
|
||||
* CREATED: 2000/06/01
|
||||
* VERSION: 4.0.0
|
||||
* RELEASED LICENSE: GNU GPL 3
|
||||
* SHORT DESCRIPTON:
|
||||
* ~ 2003/03/03: change the whole include file into one class
|
||||
* advantages are a) can include before actuall call, can control it
|
||||
* easer (login db, etc), etc etc etc
|
||||
*
|
||||
* a login lib that should stand out of all others
|
||||
* will be a class one day
|
||||
*
|
||||
* descrption of session_vars
|
||||
* DEBUG_ALL - set to one, prints out error_msg var at end of php execution
|
||||
* DB_DEBUG - prints out database debugs (query, etc)
|
||||
* GROUP_LEVEL - the level he can access (numeric)
|
||||
* USER_NAME - login name from user
|
||||
* LANG - lang to show edit interface (not yet used)
|
||||
* DEFAULT_CHARSET - in connection with LANG (not yet used)
|
||||
* PAGES - array of hashes
|
||||
* edit_page_id - ID from the edit_pages table
|
||||
* filename - name of the file
|
||||
* page_name - name in menu
|
||||
* menu - appears in menu
|
||||
* popup - is a popup
|
||||
* popup_x - if popup -> width
|
||||
* popup_y - if popup -> height
|
||||
* online - page is online (user can access)
|
||||
* query_string - string to paste for popup (will change)
|
||||
*
|
||||
* HISTORY:
|
||||
* 2010/12/21 (cs) merge back password change interface
|
||||
* 2010/12/17 (cs) change that password can be blowfish encrypted, auto detects if other encryption is used (md5, std des) and tries to use them
|
||||
* 2007/05/29 (cs) BUG with assign query and visible sub arrays to pages
|
||||
* 2005/09/21 (cs) if error -> unset the session vars
|
||||
* 2005/07/04 (cs) add a function to write into the edit log file
|
||||
* 2005/07/01 (cs) start adepting login class to new edit interface layout
|
||||
* 2005/03/31 (cs) fixed the class call with all debug vars
|
||||
* 2004/11/17 (cs) unused var cleanup
|
||||
* 2004/11/16 (cs) rewrite login so it uses a template and not just plain html. prepare it, so it will be able to use external stuff later (some interface has to be designed for that
|
||||
* 2004/11/16 (cs) removed the mobile html part from login * 2004/09/30 (cs) layout fix
|
||||
* 2003-11-11: if user has debug 1 unset memlimit, because there can be serious problems with the query logging
|
||||
* 2003-06-12: added flag to PAGES array
|
||||
* changed the get vars from GLOBALS to _POST
|
||||
* changed the session registration. no more GLOBAL vars are registered
|
||||
* only _SESSION["..."]
|
||||
* 2003-06-09: added mobile phone login possibility
|
||||
* 2003-03-04: droped ADMIN and added GROUP_LEVEL
|
||||
* 2003-03-03: started to change the include file function collection
|
||||
* to become a class
|
||||
* 2003-02-28: various advances and changes, but far from perfect
|
||||
* decided to change it into a class for easier handling
|
||||
* add also possibility to change what will stored in the
|
||||
* login session ?
|
||||
* 2000-06-01: created basic idea and functions
|
||||
*********************************************************************/
|
||||
|
||||
// try to include file from LIBS path, or from normal path
|
||||
_spl_autoload('Class.DB.IO.inc');
|
||||
|
||||
class login extends db_io
|
||||
{
|
||||
private $euid; // the user id var
|
||||
private $permission_okay = 0; // is set to one if login okay, or EUID is set and user is okay to access this page
|
||||
public $login; // pressed login
|
||||
private $username; // login name
|
||||
private $password; // login password
|
||||
private $logout; // logout button
|
||||
private $login_error; // login error code, can be matched to the array login_error_msg, which holds the string
|
||||
private $password_change = false; // if this is set to true, the user can change passwords
|
||||
private $pw_change_deny_users = array (); // array of users for which the password change is forbidden
|
||||
|
||||
// all possible login error conditions
|
||||
private $login_error_msg = array ();
|
||||
// this is an array holding all strings & templates passed from the outside (translation)
|
||||
private $login_template = array ('strings' => array (), 'password_change' => '', 'template' => '');
|
||||
|
||||
// acl vars
|
||||
public $acl = array ();
|
||||
public $default_acl_list = array ();
|
||||
|
||||
// METHOD: login
|
||||
// PARAMS: db_config -> array for logging in to DB where edit_users tables are
|
||||
// db_debug -> sets debug output for db_io (can be overruled with DB_DEBUG)
|
||||
// RETURN: none
|
||||
// DESC : cunstroctuor, does ALL, opens db, works through connection checks, closes itself
|
||||
public function __construct($db_config, $lang = 'en_utf8', $debug = 0, $db_debug = 0, $echo = 1, $print = 0)
|
||||
{
|
||||
// log login data for this class only
|
||||
$this->log_per_class = 1;
|
||||
|
||||
// create db connection and init base class
|
||||
parent::__construct($db_config, $debug, $db_debug, $echo, $print);
|
||||
|
||||
// no session could be found at all
|
||||
if (!session_id()) {
|
||||
echo "<b>Session not started!</b><br>Use 'session_start();'.<br>For less problems with other session, you can set a session name with 'session_name(\"name\");'.<br>";
|
||||
exit;
|
||||
}
|
||||
|
||||
// get the language sub class & init it
|
||||
_spl_autoload('Class.l10n.inc');
|
||||
$this->l = new l10n($lang);
|
||||
|
||||
// if we have a search path we need to set it, to use the correct DB to login
|
||||
// check what schema to use. if there is a login schema use this, else check if there is a schema set in the config, or fall back to DB_SCHEMA if this exists, if this also does not exists use public schema
|
||||
$SCHEMA = defined('LOGIN_DB_SCHEMA') ? LOGIN_DB_SCHEMA : ($db_config['db_schema'] ? $db_config['db_schema'] : (defined('DB_SCHEMA') ? DB_SCHEMA : 'public'));
|
||||
$this->db_exec("SET search_path TO ".$SCHEMA);
|
||||
$this->euid = array_key_exists('EUID', $_SESSION) ? $_SESSION['EUID'] : 0; // if there is none, there is none, saves me POST/GET check
|
||||
// get login vars, are so, can't be changed
|
||||
// prepare
|
||||
if (!isset($_POST['login_login'])) {
|
||||
$_POST['login_login'] = '';
|
||||
}
|
||||
if (!isset($_POST['login_username'])) {
|
||||
$_POST['login_username'] = '';
|
||||
}
|
||||
if (!isset($_POST['login_password'])) {
|
||||
$_POST['login_password'] = '';
|
||||
}
|
||||
if (!isset($_POST['login_logout'])) {
|
||||
$_POST['login_logout'] = '';
|
||||
}
|
||||
if (!isset($_POST['change_password'])) {
|
||||
$_POST['change_password'] = '';
|
||||
}
|
||||
if (!isset($_POST['pw_username'])) {
|
||||
$_POST['pw_username'] = '';
|
||||
}
|
||||
if (!isset($_POST['pw_old_password'])) {
|
||||
$_POST['pw_old_password'] = '';
|
||||
}
|
||||
if (!isset($_POST['pw_new_password'])) {
|
||||
$_POST['pw_new_password'] = '';
|
||||
}
|
||||
if (!isset($_POST['pw_new_password_confirm'])) {
|
||||
$_POST['pw_new_password_confirm'] = '';
|
||||
}
|
||||
// pass on vars to Object vars
|
||||
$this->login = $_POST["login_login"];
|
||||
$this->username = $_POST["login_username"];
|
||||
$this->password = $_POST["login_password"];
|
||||
$this->logout = $_POST["login_logout"];
|
||||
// password change vars
|
||||
$this->change_password = $_POST["change_password"];
|
||||
$this->pw_username = $_POST['pw_username'];
|
||||
$this->pw_old_password = $_POST['pw_old_password'];
|
||||
$this->pw_new_password = $_POST['pw_new_password'];
|
||||
$this->pw_new_password_confirm = $_POST['pw_new_password_confirm'];
|
||||
// logout target (from config)
|
||||
$this->logout_target = LOGOUT_TARGET;
|
||||
// disallow user list for password change
|
||||
$this->pw_change_deny_users = array ('admin');
|
||||
// set flag if password change is okay
|
||||
if (defined('PASSWORD_CHANGE')) {
|
||||
$this->password_change = PASSWORD_CHANGE;
|
||||
}
|
||||
// max login counts before error reporting
|
||||
$this->max_login_error_count = 10;
|
||||
// users that never get locked, even if they are set strict
|
||||
$this->lock_deny_users = array ('admin');
|
||||
|
||||
// internal
|
||||
$this->class_info["login"] = array(
|
||||
"class_name" => "Login",
|
||||
"class_version" => "4.0.0",
|
||||
"class_created" => "2000-06-01",
|
||||
"class_author" => "cs/gullevek/at"
|
||||
);
|
||||
|
||||
// init default ACL list array
|
||||
$_SESSION['DEFAULT_ACL_LIST'] = array ();
|
||||
// read the current edit_access_right list into an array
|
||||
$q = "SELECT level, type, name FROM edit_access_right WHERE level >= 0 ORDER BY level";
|
||||
while ($res = $this->db_return($q)) {
|
||||
// level to description format (numeric)
|
||||
$this->default_acl_list[$res['level']] = array (
|
||||
'type' => $res['type'],
|
||||
'name' => $res['name']
|
||||
);
|
||||
}
|
||||
// write that into the session
|
||||
$_SESSION['DEFAULT_ACL_LIST'] = $this->default_acl_list;
|
||||
|
||||
// if username & password & !$euid start login
|
||||
$this->login_login_user();
|
||||
// checks if $euid given check if user is okay for that side
|
||||
$this->login_check_permissions();
|
||||
// logsout user
|
||||
$this->login_logout_user();
|
||||
// if the password change flag is okay, run the password change method
|
||||
if ($this->password_change) {
|
||||
$this->login_password_change();
|
||||
}
|
||||
// if !$euid || permission not okay, print login screan
|
||||
echo $this->login_print_login();
|
||||
// closing all connections, depending on error status, exit
|
||||
if (!$this->login_close_class()) {
|
||||
// do not go anywhere, quit processing here
|
||||
// do something with possible debug data?
|
||||
if (TARGET == 'live' || TARGET == 'remote') {
|
||||
// login
|
||||
$this->debug_output_all = DEBUG ? 1 : 0;
|
||||
$this->echo_output_all = 0;
|
||||
$this->print_output_all = DEBUG ? 1 : 0;
|
||||
}
|
||||
$status_msg = $this->print_error_msg();
|
||||
if ($this->echo_output_all) {
|
||||
echo $status_msg;
|
||||
}
|
||||
exit;
|
||||
}
|
||||
// set acls for this user/group and this page
|
||||
$this->login_set_acl();
|
||||
}
|
||||
|
||||
// METHOD: _login
|
||||
// PARAMS: none
|
||||
// RETURN: none
|
||||
// DESC : deconstructory, called with the last function to close DB connection
|
||||
public function __destruct()
|
||||
{
|
||||
parent::__destruct();
|
||||
}
|
||||
|
||||
// METHOD: login_login_user
|
||||
// PARAMS: none
|
||||
// RETURN: none
|
||||
// DESC : if user pressed login button this script is called, but only if there is no preview euid set
|
||||
private function login_login_user()
|
||||
{
|
||||
// have to get the global stuff here for setting it later
|
||||
if (!$this->euid && $this->login) {
|
||||
if (!($this->password && $this->username)) {
|
||||
$this->login_error = 102;
|
||||
} else {
|
||||
// we have to get the themes in here too
|
||||
$q = "SELECT eu.edit_user_id, username, password, eu.edit_group_id, eg.name AS edit_group_name, admin, eu.login_error_count, eu.login_error_date_last, eu.login_error_date_first, eu.strict, eu.locked, ";
|
||||
$q .= "debug, db_debug, ";
|
||||
$q .= "eareu.level AS user_level, eareu.type AS user_type, ";
|
||||
$q .= "eareg.level AS group_level, eareg.type AS group_type, ";
|
||||
$q .= "eu.enabled, el.short_name AS lang_short, el.iso_name AS lang_iso, first.header_color AS first_header_color, second.header_color AS second_header_color, second.template ";
|
||||
$q .= "FROM edit_user eu ";
|
||||
$q .= "LEFT JOIN edit_scheme second ON (second.edit_scheme_id = eu.edit_scheme_id AND second.enabled = 1), ";
|
||||
$q .= "edit_language el, edit_group eg, ";
|
||||
$q .= "edit_access_right eareu, ";
|
||||
$q .= "edit_access_right eareg, ";
|
||||
$q .= "edit_scheme first ";
|
||||
$q .= "WHERE first.edit_scheme_id = eg.edit_scheme_id AND eu.edit_group_id = eg.edit_group_id AND eu.edit_language_id = el.edit_language_id AND ";
|
||||
$q .= "eu.edit_access_right_id = eareu.edit_access_right_id AND ";
|
||||
$q .= "eg.edit_access_right_id = eareg.edit_access_right_id AND ";
|
||||
// password match is done in script, against old plain or new blowfish encypted
|
||||
$q .= "(LOWER(username) = '".strtolower($this->username)."') ";
|
||||
$res = $this->db_return($q);
|
||||
// username is wrong, but we throw for wrong username and wrong password the same error
|
||||
if (!$this->cursor_ext[md5($q)]["num_rows"]) {
|
||||
$this->login_error = 1010;
|
||||
} else {
|
||||
// if login errors is half of max errors and the last login error was less than 10s ago, forbid any new login try
|
||||
|
||||
// check with what kind of prefix the password begins:
|
||||
// $2a$ or $2y$: BLOWFISCH
|
||||
// $1$: MD5
|
||||
// $ and one alphanumeric letter, 13 chars long, but nor $ at the end: STD_DESC
|
||||
// if no $ => normal password
|
||||
// NOW, if we have a password encoded, but not the correct encoder available, throw special error
|
||||
|
||||
// check flow
|
||||
// - user is enabled
|
||||
// - user is not locked
|
||||
// - password is readable
|
||||
// - encrypted password matches
|
||||
// - plain password matches
|
||||
|
||||
if (!$res["enabled"]) {
|
||||
// user is enabled
|
||||
$this->login_error = 104;
|
||||
} elseif ($res['locked']) {
|
||||
// user is locked, either set or auto set
|
||||
$this->login_error = 105;
|
||||
} elseif ((preg_match("/^\\$2(a|y)\\$/", $res['password']) && CRYPT_BLOWFISH != 1) || (preg_match("/^\\$1\\$/", $res['password']) && CRYPT_MD5 != 1) || (preg_match("/^\\$[0-9A-Za-z.]{12}$/", $res['password']) && CRYPT_STD_DES != 1)) {
|
||||
// this means password cannot be decrypted because of missing crypt methods
|
||||
$this->login_error = 9999;
|
||||
} elseif ((preg_match("/^\\$2(a|y)\\$/", $res['password']) || preg_match("/^\\$1\\$/", $res['password']) || preg_match("/^\\$[0-9A-Za-z.]{12}$/", $res['password'])) && !$this->verifyCryptString($this->password, $res['password'])) {
|
||||
// check passwword as crypted, $2a$ or $2y$ is blowfish start, $1$ is MD5 start, $\w{12} is standard DES
|
||||
$this->login_error = 1011;
|
||||
} elseif (!preg_match("/^\\$2(a|y)\\$/", $res['password']) && !preg_match("/^\\$1\\$/", $res['password']) && !preg_match("/^\\$[0-9A-Za-z.]{12}$/", $res['password']) && $res['password'] != $this->password) {
|
||||
// check old plain password, non case sensitive
|
||||
$this->login_error = 1012;
|
||||
} else {
|
||||
// normal user processing
|
||||
// set class var and session var
|
||||
$_SESSION["EUID"] = $this->euid = $res["edit_user_id"];
|
||||
// check if user is okay
|
||||
$this->login_check_permissions();
|
||||
if (!$this->login_error) {
|
||||
// now set all session vars and read page permissions
|
||||
$GLOBALS["DEBUG_ALL"] = $_SESSION["DEBUG_ALL"] = $res["debug"];
|
||||
$GLOBALS["DB_DEBUG"] = $_SESSION["DB_DEBUG"] = $res["db_debug"];
|
||||
$_SESSION["USER_NAME"] = $res["username"];
|
||||
$_SESSION["ADMIN"] = $res["admin"];
|
||||
$_SESSION["GROUP_NAME"] = $res["edit_group_name"];
|
||||
$_SESSION["USER_ACL_LEVEL"] = $res["user_level"];
|
||||
$_SESSION["USER_ACL_TYPE"] = $res["user_type"];
|
||||
$_SESSION["GROUP_ACL_LEVEL"] = $res["group_level"];
|
||||
$_SESSION["GROUP_ACL_TYPE"] = $res["group_type"];
|
||||
$_SESSION["TEMPLATE"] = ($res["template"]) ? $res["template"] : DEFAULT_TEMPLATE;
|
||||
$_SESSION["HEADER_COLOR"] = ($res["second_header_color"]) ? $res["second_header_color"] : $res["first_header_color"];
|
||||
$_SESSION["LANG"] = $res["lang_short"];
|
||||
$_SESSION["DEFAULT_CHARSET"] = $res["lang_iso"];
|
||||
$_SESSION["DEFAULT_LANG"] = $res["lang_short"].'_'.strtolower(str_replace('-', '', $res["lang_iso"]));
|
||||
// reset any login error count for this user
|
||||
if ($res['login_error_count'] > 0) {
|
||||
$q = "UPDATE edit_user SET login_error_count = 0, login_error_date_last = NULL, login_error_date_first = NULL WHERE edit_user_id = ".$res['edit_user_id'];
|
||||
$this->db_exec($q);
|
||||
}
|
||||
$pages = array();
|
||||
$edit_page_ids = array();
|
||||
// set pages access
|
||||
$q = "SELECT ep.edit_page_id, filename, ep.name AS edit_page_name, ep.order_number AS edit_page_order, menu, popup, popup_x, popup_y, online, ear.level, ear.type ";
|
||||
$q .= "FROM edit_page ep, edit_page_access epa, edit_access_right ear ";
|
||||
$q .= "WHERE ep.edit_page_id = epa.edit_page_id AND ear.edit_access_right_id = epa.edit_access_right_id ";
|
||||
$q .= "AND epa.enabled = 1 AND epa.edit_group_id = ".$res["edit_group_id"]." ";
|
||||
$q .= "ORDER BY ep.order_number";
|
||||
while ($res = $this->db_return($q)) {
|
||||
// page id array for sub data readout
|
||||
$edit_page_ids[] = $res['edit_page_id'];
|
||||
// create the array for pages
|
||||
array_push($pages, array (
|
||||
"edit_page_id" => $res["edit_page_id"],
|
||||
"filename" => $res["filename"],
|
||||
"page_name" => $res["edit_page_name"],
|
||||
"order" => $res['edit_page_order'],
|
||||
"menu" => $res["menu"],
|
||||
"popup" => $res["popup"],
|
||||
"popup_x" => $res["popup_x"],
|
||||
"popup_y" => $res["popup_y"],
|
||||
"online" => $res["online"],
|
||||
"acl_level" => $res["level"],
|
||||
"acl_type" => $res["type"],
|
||||
"query" => array (),
|
||||
"visible" => array ()
|
||||
));
|
||||
// make reference filename -> level
|
||||
$pages_acl[$res["filename"]] = $res["level"];
|
||||
} // for each page
|
||||
// get the visible groups for all pages and write them to the pages
|
||||
$_edit_page_id = 0;
|
||||
$q = "SELECT epvg.edit_page_id, name, flag FROM edit_visible_group evp, edit_page_visible_group epvg WHERE evp.edit_visible_group_id = epvg.edit_visible_group_id AND epvg.edit_page_id IN (".join(', ', $edit_page_ids).") ORDER BY epvg.edit_page_id";
|
||||
while ($res = $this->db_return($q)) {
|
||||
if ($res['edit_page_id'] != $_edit_page_id) {
|
||||
// search the pos in the array push
|
||||
$pos = $this->array_search_recursive($res['edit_page_id'], $pages, 'edit_page_id');
|
||||
$_edit_page_id = $res['edit_page_id'];
|
||||
}
|
||||
$pages[$pos[0]]['visible'][$res['name']] = $res['flag'];
|
||||
}
|
||||
// get the same for the query strings
|
||||
$_edit_page_id = 0;
|
||||
$q = "SELECT eqs.edit_page_id, name, value, dynamic FROM edit_query_string eqs WHERE enabled = 1 AND edit_page_id IN (".join(', ', $edit_page_ids).") ORDER BY eqs.edit_page_id";
|
||||
while ($res = $this->db_return($q)) {
|
||||
if ($res['edit_page_id'] != $_edit_page_id) {
|
||||
// search the pos in the array push
|
||||
$pos = $this->array_search_recursive($res['edit_page_id'], $pages, 'edit_page_id');
|
||||
$_edit_page_id = $res['edit_page_id'];
|
||||
}
|
||||
$pages[$pos[0]]['query'][] = array (
|
||||
"name" => $res['name'],
|
||||
"value" => $res['value'],
|
||||
"dynamic" => $res['dynamic']
|
||||
);
|
||||
}
|
||||
|
||||
$_SESSION["PAGES"] = $pages;
|
||||
$_SESSION["PAGES_ACL_LEVEL"] = $pages_acl;
|
||||
// load the edit_access user rights
|
||||
$q = "SELECT ea.edit_access_id, level, type, ea.name, ea.color, ea.uid, edit_default ";
|
||||
$q .= "FROM edit_access_user eau, edit_access_right ear, edit_access ea ";
|
||||
$q .= "WHERE eau.edit_access_id = ea.edit_access_id AND eau.edit_access_right_id = ear.edit_access_right_id AND eau.enabled = 1 AND edit_user_id = ".$this->euid." ";
|
||||
$q .= "ORDER BY ea.name";
|
||||
$unit_access = array();
|
||||
$eauid = array();
|
||||
$unit_acl = array();
|
||||
while ($res = $this->db_return($q)) {
|
||||
// read edit access data fields and drop them into the unit access array
|
||||
$q_sub ="SELECT name, value FROM edit_access_data WHERE enabled = 1 AND edit_access_id = ".$res['edit_access_id'];
|
||||
$ea_data = array ();
|
||||
while ($res_sub = $this->db_return($q_sub)) {
|
||||
$ea_data[$res_sub['name']] = $res_sub['value'];
|
||||
}
|
||||
// build master unit array
|
||||
$unit_access[$res['edit_access_id']] = array (
|
||||
"id" => $res['edit_access_id'],
|
||||
"acl_level" => $res["level"],
|
||||
"acl_type" => $res["type"],
|
||||
"name" => $res["name"],
|
||||
"uid" => $res['uid'],
|
||||
"color" => $res["color"],
|
||||
"default" => $res["edit_default"],
|
||||
'data' => $ea_data
|
||||
);
|
||||
// set the default unit
|
||||
if ($res['edit_default']) {
|
||||
$_SESSION["UNIT_DEFAULT"] = $res['edit_access_id'];
|
||||
}
|
||||
// sub arrays for simple access
|
||||
array_push($eauid, $res['edit_access_id']);
|
||||
$unit_acl[$res['edit_access_id']] = $res['level'];
|
||||
}
|
||||
$_SESSION["UNIT"] = $unit_access;
|
||||
$_SESSION["UNIT_ACL_LEVEL"] = $unit_acl;
|
||||
$_SESSION['EAID'] = $eauid;
|
||||
} // user has permission to THIS page
|
||||
} // user was not enabled or other login error
|
||||
if ($this->login_error) {
|
||||
if ($res['login_error_count'] == 0) {
|
||||
$login_error_date_first = ', login_error_date_first = NOW()';
|
||||
}
|
||||
// update login error count for this user
|
||||
$q = "UPDATE edit_user SET login_error_count = login_error_count + 1, login_error_date_last = NOW() $login_error_date_first WHERE edit_user_id = ".$res['edit_user_id'];
|
||||
$this->db_exec($q);
|
||||
// totally lock the user if error max is reached
|
||||
if ($res['login_error_count'] + 1 > $this->max_login_error_count) {
|
||||
// do some alert reporting in case this error is too big
|
||||
// if strict is set, lock this user
|
||||
// this needs manual unlocking by an admin user
|
||||
if ($res['strict'] && !in_array($this->username, $this->lock_deny_users)) {
|
||||
$q = "UPDATE edit_user SET locked = 1 WHERE edit_user_id = ".$res['edit_user_id'];
|
||||
}
|
||||
}
|
||||
}
|
||||
} // user was not found
|
||||
} // if not username AND password where given
|
||||
// if there was an login error, show login screen
|
||||
if ($this->login_error) {
|
||||
// reset the perm var, to confirm logout
|
||||
$this->permission_okay = 0;
|
||||
}
|
||||
} // if he pressed login at least and is not yet loggined in
|
||||
}
|
||||
|
||||
// METHOD: login_check_permission
|
||||
// PARAMS: none
|
||||
// RETUNR none
|
||||
// DESC : for every page the user access this script checks if he is allowed to do so
|
||||
public function login_check_permissions()
|
||||
{
|
||||
if ($this->euid && $this->login_error != 103) {
|
||||
$q = "SELECT filename ";
|
||||
$q .= "FROM edit_page ep, edit_page_access epa, edit_group eg, edit_user eu ";
|
||||
$q .= "WHERE ep.edit_page_id = epa.edit_page_id AND eg.edit_group_id = epa.edit_group_id AND eg.edit_group_id = eu.edit_group_id ";
|
||||
$q .= "AND eu.edit_user_id = ".$this->euid." AND filename = '".$this->page_name."' AND eg.enabled = 1 AND epa.enabled = 1";
|
||||
$res = $this->db_return_row($q);
|
||||
// unset mem limit if debug is set to 1
|
||||
// if (($GLOBALS["DEBUG_ALL"] || $GLOBALS["DB_DEBUG"] || $_SESSION["DEBUG_ALL"] || $_SESSION["DB_DEBUG"]) && ini_get('memory_limit') != -1)
|
||||
// ini_set('memory_limit', -1);
|
||||
if ($res["filename"] == $this->page_name) {
|
||||
$this->permission_okay = 1;
|
||||
} else {
|
||||
$this->login_error = 103;
|
||||
$this->permission_okay = 0;
|
||||
}
|
||||
}
|
||||
// if called from public, so we can check if the permissions are ok
|
||||
return $this->permission_okay;
|
||||
}
|
||||
|
||||
// METHOD: login_logout_user
|
||||
// PARAMS: none
|
||||
// RETURN: none
|
||||
// DESC : if a user pressed on logout, destroyes session and unsets all global vars
|
||||
public function login_logout_user()
|
||||
{
|
||||
if ($this->logout || $this->login_error) {
|
||||
// unregister and destroy session vars
|
||||
unset($_SESSION["EUID"]);
|
||||
unset($_SESSION["GROUP_LEVEL"]);
|
||||
unset($_SESSION["PAGES"]);
|
||||
unset($_SESSION["USER_NAME"]);
|
||||
unset($_SESSION["UNIT"]);
|
||||
unset($_SESSION["DEBUG_ALL"]);
|
||||
unset($_SESSION["DB_DEBUG"]);
|
||||
unset($GLOBALS["DEBUG_ALL"]);
|
||||
unset($GLOBALS["DB_DEBUG"]);
|
||||
unset($_SESSION["LANG"]);
|
||||
unset($_SESSION["DEFAULT_CHARSET"]);
|
||||
unset($_SESSION["DEFAULT_LANG"]);
|
||||
unset($_SESSION["GROUP_NAME"]);
|
||||
unset($_SESSION["HEADER_COLOR"]);
|
||||
session_destroy();
|
||||
// he prints the login screen again
|
||||
$this->permission_okay = 0;
|
||||
}
|
||||
}
|
||||
|
||||
// METHOD: login_set_acl
|
||||
// PARAMS: none
|
||||
// RETURN: none
|
||||
// DESC : sets all the basic ACLs
|
||||
// init set the basic acl the user has, based on the following rules
|
||||
// * init set from config DEFAULT ACL
|
||||
// * if page ACL is set, it overrides the default ACL
|
||||
// * if group ACL is set, it overrides the page ACL
|
||||
// * if user ACL is set, it overrides the group ACL
|
||||
// set the page ACL
|
||||
// * default ACL set
|
||||
// * set group ACL if not default overrides default ACL
|
||||
// * set page ACL if not default overrides group ACL
|
||||
// set edit access ACL and set default edit access group
|
||||
// * if an account ACL is set, set this parallel, account ACL overrides user ACL if it applies
|
||||
// * if edit access ACL level is set, use this, else use page
|
||||
// set all base ACL levels as a list keyword -> ACL number
|
||||
public function login_set_acl()
|
||||
{
|
||||
// we start with the default acl
|
||||
$this->acl['base'] = DEFAULT_ACL_LEVEL;
|
||||
|
||||
// set admin flag and base to 100
|
||||
if ($_SESSION['ADMIN']) {
|
||||
$this->acl['admin'] = 1;
|
||||
$this->acl['base'] = 100;
|
||||
} else {
|
||||
// now go throw the flow and set the correct ACL
|
||||
// user > page > group
|
||||
// group ACL 0
|
||||
if ($_SESSION['GROUP_ACL_LEVEL'] != -1) {
|
||||
$this->acl['base'] = $_SESSION['GROUP_ACL_LEVEL'];
|
||||
}
|
||||
// page ACL 1
|
||||
if ($_SESSION['PAGES_ACL_LEVEL'][$this->page_name] != -1) {
|
||||
$this->acl['base'] = $_SESSION['PAGES_ACL_LEVEL'][$this->page_name];
|
||||
}
|
||||
// user ACL 2
|
||||
if ($_SESSION['USER_ACL_LEVEL'] != -1) {
|
||||
$this->acl['base'] = $_SESSION['USER_ACL_LEVEL'];
|
||||
}
|
||||
}
|
||||
|
||||
// set the current page acl
|
||||
// start with default acl
|
||||
// set group if not -1, overrides default
|
||||
// set page if not -1, overrides group set
|
||||
$this->acl['page'] = DEFAULT_ACL_LEVEL;
|
||||
if ($_SESSION['GROUP_ACL_LEVEL'] != -1) {
|
||||
$this->acl['page'] = $_SESSION['GROUP_ACL_LEVEL'];
|
||||
}
|
||||
if (isset($_SESSION['PAGES_ACL_LEVEL'][$this->page_name]) && $_SESSION['PAGES_ACL_LEVEL'][$this->page_name] != -1) {
|
||||
$this->acl['page'] = $_SESSION['PAGES_ACL_LEVEL'][$this->page_name];
|
||||
}
|
||||
|
||||
// PER ACCOUNT (UNIT/edit access)->
|
||||
foreach ($_SESSION['UNIT'] as $ea_id => $unit) {
|
||||
// if admin flag is set, all units are set to 100
|
||||
if ($this->acl['admin']) {
|
||||
$this->acl['unit'][$ea_id] = $this->acl['base'];
|
||||
} else {
|
||||
if ($unit['acl_level'] != -1) {
|
||||
$this->acl['unit'][$ea_id] = $unit['acl_level'];
|
||||
} else {
|
||||
$this->acl['unit'][$ea_id] = $this->acl['base'];
|
||||
}
|
||||
}
|
||||
// detail name/level set
|
||||
$this->acl['unit_detail'][$ea_id] = array (
|
||||
'name' => $unit['name'],
|
||||
'uid' => $unit['uid'],
|
||||
'level' => $this->default_acl_list[$this->acl['unit'][$ea_id]]['name'],
|
||||
'default' => $unit['default'],
|
||||
'data' => $unit['data']
|
||||
);
|
||||
// set default
|
||||
if ($unit['default']) {
|
||||
$this->acl['unit_id'] = $unit['id'];
|
||||
$this->acl['unit_name'] = $unit['name'];
|
||||
$this->acl['unit_uid'] = $unit['uid'];
|
||||
}
|
||||
}
|
||||
// flag if to show extra edit access drop downs (because user has multiple groups assigned)
|
||||
if (count($_SESSION['UNIT']) > 1) {
|
||||
$this->acl['show_ea_extra'] = 1;
|
||||
} else {
|
||||
$this->acl['show_ea_extra'] = 0;
|
||||
}
|
||||
// set the default edit access
|
||||
$this->acl['default_edit_access'] = $_SESSION['UNIT_DEFAULT'];
|
||||
// integrate the type acl list, but only for the keyword -> level
|
||||
foreach ($this->default_acl_list as $level => $data) {
|
||||
$this->acl['min'][$data['type']] = $level;
|
||||
}
|
||||
// set the full acl list too
|
||||
$this->acl['acl_list'] = $_SESSION['DEFAULT_ACL_LIST'];
|
||||
// debug
|
||||
// $this->debug('ACL', $this->print_ar($this->acl));
|
||||
}
|
||||
|
||||
// METHOD: login_check_edit_access
|
||||
// PARAMS: edit_access_id to check
|
||||
// RETURN: true/false: if the edit access is not in the valid list: false
|
||||
// DESC : checks if this edit access id is valid
|
||||
public function login_check_edit_access($edit_access_id)
|
||||
{
|
||||
if (array_key_exists($edit_access_id, $this->acl['unit'])) {
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// METHOD: login_password_change
|
||||
// PARAMS: none
|
||||
// RETURN: none
|
||||
// DESC : changes a user password
|
||||
private function login_password_change()
|
||||
{
|
||||
if ($this->change_password) {
|
||||
$event = 'Password Change';
|
||||
// check that given username is NOT in the deny list, else silent skip (with error log)
|
||||
if (!in_array($this->pw_username, $this->pw_change_deny_users)) {
|
||||
if (!$this->pw_username || !$this->pw_password) {
|
||||
$this->login_error = 200;
|
||||
$data = 'Missing username or old password.';
|
||||
}
|
||||
// check user exist, if not -> error
|
||||
if (!$this->login_error) {
|
||||
$q = "SELECT edit_user_id FROM edit_user WHERE enabled = 1 AND username = '".$this->db_escape_string($this->pw_username)."'";
|
||||
list ($edit_user_id) = $this->db_return_row($q);
|
||||
if (!$edit_user_id) {
|
||||
// username wrong
|
||||
$this->login_error = 201;
|
||||
$data = 'User could not be found';
|
||||
}
|
||||
}
|
||||
// check old passwords match -> error
|
||||
if (!$this->login_error) {
|
||||
$q = "SELECT edit_user_id FROM edit_user WHERE enabled = 1 AND username = '".$this->db_escape_string($this->pw_username)."' AND password = '".$this->db_escape_string($this->pw_old_password)."'";
|
||||
list ($edit_user_id) = $this->db_return_row($q);
|
||||
if (!$edit_user_id) {
|
||||
// old password wrong
|
||||
$this->login_error = 202;
|
||||
$data = 'The old password does not match';
|
||||
}
|
||||
}
|
||||
// check if new passwords were filled out -> error
|
||||
if (!$this->login_error) {
|
||||
if (!$this->pw_new_password || !$this->pw_new_password_confirm) {
|
||||
$this->login_error = 203;
|
||||
$data = 'Missing new password or new password confirm.';
|
||||
}
|
||||
}
|
||||
// check new passwords both match -> error
|
||||
if (!$this->login_error) {
|
||||
if ($this->pw_new_password != $this->pw_new_password_confirm) {
|
||||
$this->login_error = 204;
|
||||
$data = 'The new passwords do not match: '.$this->pw_new_password.' == '.$this->pw_new_password_confirm;
|
||||
}
|
||||
}
|
||||
// no error change this users password
|
||||
if (!$this->login_error) {
|
||||
// update the user (edit_user_id) with the new password
|
||||
$q = "UPDATE edit_user SET password = '".$this->db_escape_string($this->cryptString($this->pw_new_password))."' WHERE edit_user_id = ".$edit_user_id;
|
||||
$this->db_exec($q);
|
||||
$data = 'Password change for user "'.$this->pw_username.'" from "'.$this->pw_old_password.'" to "'.$this->pw_new_password.'"';
|
||||
}
|
||||
} else {
|
||||
// illegal user error
|
||||
$this->login_error = '220';
|
||||
$data = 'Illegal user for password change: '.$this->pw_username;
|
||||
}
|
||||
// log this password change attempt
|
||||
$this->write_log($event, $data, $this->login_error, $pw_username, $pw_old_password);
|
||||
} // button pressed
|
||||
}
|
||||
|
||||
// METHOD: login_print_login
|
||||
// PARAMS: none
|
||||
// RETURN: none
|
||||
// DESC : prints out login html part if no permission (error) is set
|
||||
private function login_print_login()
|
||||
{
|
||||
if (!$this->permission_okay) {
|
||||
// set the templates now
|
||||
$this->login_set_templates();
|
||||
// if there is a global logout target ...
|
||||
if (file_exists($this->logout_target) && $this->logout_target) {
|
||||
$LOGOUT_TARGET = $this->logout_target;
|
||||
} else {
|
||||
$LOGOUT_TARGET = "";
|
||||
}
|
||||
|
||||
$html_string = $this->login_template['template'];
|
||||
|
||||
// if password change is okay
|
||||
if ($this->password_change) {
|
||||
$html_string_password_change = $this->login_template['password_change'];
|
||||
|
||||
// pre change the data in the PASSWORD_CHANGE_DIV first
|
||||
foreach ($this->login_template['strings'] as $string => $data) {
|
||||
if ($data) {
|
||||
$html_string_password_change = str_replace("{".$string."}", $data, $html_string_password_change);
|
||||
}
|
||||
}
|
||||
$this->login_template['strings']['PASSWORD_CHANGE_DIV'] = $html_string_password_change;
|
||||
}
|
||||
|
||||
// put in the logout redirect string
|
||||
if ($this->logout && $LOGOUT_TARGET) {
|
||||
$html_string = str_replace("{LOGOUT_TARGET}", '<meta http-equiv="refresh" content="0; URL='.$LOGOUT_TARGET.'">', $html_string);
|
||||
} else {
|
||||
$html_string = str_replace("{LOGOUT_TARGET}", '', $html_string);
|
||||
}
|
||||
|
||||
// print error messagae
|
||||
if ($this->login_error) {
|
||||
$html_string = str_replace("{ERROR_MSG}", $this->login_error_msg[$this->login_error]."<br>", $html_string);
|
||||
} else {
|
||||
$html_string = str_replace("{ERROR_MSG}", "<br>", $html_string);
|
||||
}
|
||||
|
||||
// create the replace array context
|
||||
foreach ($this->login_template['strings'] as $string => $data) {
|
||||
$html_string = str_replace("{".$string."}", $data, $html_string);
|
||||
}
|
||||
|
||||
// return the created HTML here
|
||||
return $html_string;
|
||||
} // if permission is 0 then print out login
|
||||
}
|
||||
|
||||
// METHOD: login_close_class
|
||||
// PARAMS: none
|
||||
// RETURN: none
|
||||
// DESC : last function called, writes log and prints out error msg and exists script if permission 0
|
||||
private function login_close_class()
|
||||
{
|
||||
// write to LOG table ...
|
||||
if ($this->login_error || $this->login || $this->logout) {
|
||||
$username = '';
|
||||
$password = '';
|
||||
// set event
|
||||
if ($this->login) {
|
||||
$event = "Login";
|
||||
} elseif ($this->logout) {
|
||||
$event = "Logout";
|
||||
} else {
|
||||
$event = "No Permission";
|
||||
}
|
||||
// prepare for log
|
||||
if ($this->euid) {
|
||||
// get user from user table
|
||||
$q = "SELECT username, password FROM edit_user WHERE edit_user_id = ".$this->euid;
|
||||
list($username, $password) = $this->db_return_row($q);
|
||||
} // if euid is set, get username (or try)
|
||||
$this->write_log($event, '', $this->login_error, $username, $password);
|
||||
} // write log under certain settings
|
||||
// now close DB connection
|
||||
// $this->error_msg = $this->_login();
|
||||
if (!$this->permission_okay) {
|
||||
return false;
|
||||
} else {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
// METHOD: login_set_templates
|
||||
// PARAMS:
|
||||
// RETURN: none
|
||||
// DESC : checks if there are external templates, if not uses internal fallback ones
|
||||
private function login_set_templates()
|
||||
{
|
||||
$strings = array (
|
||||
'HTML_TITLE' => $this->l->__("LOGIN"),
|
||||
'TITLE' => $this->l->__("LOGIN"),
|
||||
'USERNAME' => $this->l->__("Username"),
|
||||
'PASSWORD' => $this->l->__("Password"),
|
||||
'LOGIN' => $this->l->__("Login"),
|
||||
'ERROR_MSG' => '',
|
||||
'LOGOUT_TARGET' => '',
|
||||
'PASSWORD_CHANGE_BUTTON_VALUE' => $this->l->__('Change Password')
|
||||
);
|
||||
|
||||
$error_msgs = array (
|
||||
"100" => $this->l->__("Fatal Error: <b>[EUID] came in as GET/POST!</b>"), // actually obsolete
|
||||
"1010" => $this->l->__("Fatal Error: <b>Login Failed - Wrong Username or Password</b>"), // user not found
|
||||
"1011" => $this->l->__("Fatal Error: <b>Login Failed - Wrong Username or Password</b>"), // blowfish password wrong
|
||||
"1012" => $this->l->__("Fatal Error: <b>Login Failed - Wrong Username or Password</b>"), // fallback md5 password wrong
|
||||
"102" => $this->l->__("Fatal Error: <b>Login Failed - Please enter username and password</b>"),
|
||||
"103" => $this->l->__("Fatal Error: <b>You do not have the rights to access this Page</b>"),
|
||||
"104" => $this->l->__("Fatal Error: <b>Login Failed - User not enabled</b>"),
|
||||
"105" => $this->l->__("Fatal Error: <b>Login Failed - User is locked</b>"),
|
||||
"220" => $this->l->__("Fatal Error: <b>Password change - The user could not be found</b>"), // actually this is an illegal user, but I mask it
|
||||
'200' => $this->l->__("Fatal Error: <b>Password change - Please enter username and old password</b>"),
|
||||
"201" => $this->l->__("Fatal Error: <b>Password change - The user could not be found</b>"),
|
||||
"202" => $this->l->__("Fatal Error: <b>Password change - The old password is not correct</b>"),
|
||||
"203" => $this->l->__("Fatal Error: <b>Password change - Please fill out both new password fields</b>"),
|
||||
"204" => $this->l->__("Fatal Error: <b>Password change - The new passwords do not match</b>"),
|
||||
"9999" => $this->l->__("Fatal Error: <b>necessary crypt engine could not be found</b>. Login is impossible") // this is bad bad error
|
||||
);
|
||||
|
||||
// if password change is okay
|
||||
if ($this->password_change) {
|
||||
$strings = array_merge($strings, array (
|
||||
'TITLE_PASSWORD_CHANGE' => 'Change Password for User',
|
||||
'OLD_PASSWORD' => $this->l->__("Old Password"),
|
||||
'NEW_PASSWORD' => $this->l->__("New Password"),
|
||||
'NEW_PASSWORD_CONFIRM' => $this->l->__("New Password confirm"),
|
||||
'CLOSE' => $this->l->__('Close'),
|
||||
'JS_SHOW_HIDE' => "function ShowHideDiv(id) { element = document.getElementById(id); if (element.className == 'visible' || !element.className) element.className = 'hidden'; else element.className = 'visible'; }",
|
||||
'PASSWORD_CHANGE_BUTTON' => '<input type="button" name="pw_change" value="'.$strings['PASSWORD_CHANGE_BUTTON_VALUE'].'" OnClick="ShowHideDiv(\'pw_change_div\');">'
|
||||
));
|
||||
$this->login_template['password_change'] = <<<EOM
|
||||
<div id="pw_change_div" class="hidden" style="position: absolute; top: 30px; left: 50px; width: 400px; height: 220px; background-color: white; border: 1px solid black; padding: 25px;">
|
||||
<table>
|
||||
<tr><td class="norm" align="center" colspan="2"><h3>{TITLE_PASSWORD_CHANGE}</h3></td></tr>
|
||||
<tr><td class="norm" colspan="2">{ERROR_MSG}</td></tr>
|
||||
<tr><td class="norm" align="right">{USERNAME}</td><td><input type="text" name="pw_username" value=""></td></tr>
|
||||
<tr><td class="norm" align="right">{OLD_PASSWORD}</td><td><input type="password" name="pw_old_password" value=""></td></tr>
|
||||
<tr><td class="norm" align="right">{NEW_PASSWORD}</td><td><input type="password" name="pw_new_password" value=""></td></tr>
|
||||
<tr><td class="norm" align="right">{NEW_PASSWORD_CONFIRM}</td><td><input type="password" name="pw_new_password_confirm" value=""></td></tr>
|
||||
<tr><td></td><td><input type="submit" name="change_password" value="{PASSWORD_CHANGE_BUTTON_VALUE}"><input type="button" name="pw_change" value="{CLOSE}" OnClick="ShowHideDiv('pw_change_div');"></td></tr>
|
||||
</table>
|
||||
</div>
|
||||
EOM;
|
||||
} else {
|
||||
$strings = array_merge($strings, array (
|
||||
'JS_SHOW_HIDE' => '',
|
||||
'PASSWORD_CHANGE_BUTTON' => '',
|
||||
'PASSWORD_CHANGE_DIV' => ''
|
||||
));
|
||||
}
|
||||
|
||||
// first check if all strings are set from outside, if not, set with default ones
|
||||
while (list($string, $data) = each($strings)) {
|
||||
if (!array_key_exists($string, $this->login_template['strings'])) {
|
||||
$this->login_template['strings'][$string] = $data;
|
||||
}
|
||||
}
|
||||
|
||||
// error msgs the same
|
||||
while (list($code, $data) = each($error_msgs)) {
|
||||
if (!array_key_exists($code, $this->login_error_msg)) {
|
||||
$this->login_error_msg[$code] = $data;
|
||||
}
|
||||
}
|
||||
|
||||
// now check templates
|
||||
if (!$this->login_template['template']) {
|
||||
$this->login_template['template'] = <<<EOM
|
||||
<html>
|
||||
<head>
|
||||
<title>{HTML_TITLE}</title>
|
||||
<style type="text/css">
|
||||
.norm { font-family: Verdana, Arial, Helvetica, sans-serif; font-size: 10px; line-height: 15px; color: #000000}
|
||||
h3 { font-size: 18px; }
|
||||
.visible { visibility: visible; }
|
||||
.hidden { visibility: hidden; display: none; }
|
||||
</style>
|
||||
<script language="JavaScript">
|
||||
<!--
|
||||
{JS_SHOW_HIDE}
|
||||
//-->
|
||||
</script>
|
||||
{LOGOUT_TARGET}
|
||||
</head>
|
||||
|
||||
<body bgcolor="#FFFFFF">
|
||||
<br>
|
||||
<br>
|
||||
<br>
|
||||
<form method="post">
|
||||
<table width="500" border="0" cellpadding="2" cellspacing="1">
|
||||
<tr>
|
||||
<td class="norm" align="right">
|
||||
<h3>{TITLE}</h3>
|
||||
</td>
|
||||
<td> </td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="norm" colspan="2" align="center">
|
||||
{ERROR_MSG}
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td align="right" class="norm">{USERNAME}</td>
|
||||
<td><input type="text" name="login_username"></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td align="right" class="norm">{PASSWORD}</td>
|
||||
<td><input type="password" name="login_password"></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td align="right"></td>
|
||||
<td>
|
||||
<input type="submit" name="login_login" value="{LOGIN}">
|
||||
{PASSWORD_CHANGE_BUTTON}
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td align="right">
|
||||
<br><br>
|
||||
</td>
|
||||
<td> </td>
|
||||
</tr>
|
||||
</table>
|
||||
{PASSWORD_CHANGE_DIV}
|
||||
</form>
|
||||
</body>
|
||||
</html>
|
||||
EOM;
|
||||
}
|
||||
}
|
||||
|
||||
// METHOD: write_log
|
||||
// PARAMS: event -> string of what has been done
|
||||
// data -> data information (id, etc)
|
||||
// error -> if error, write error string (not enougth data, etc)
|
||||
// RETURN: none
|
||||
// DESC : writes detailed data into the edit user log table (keep log what user does)
|
||||
private function write_log($event, $data, $error = "", $username = "", $password = "")
|
||||
{
|
||||
if ($this->login) {
|
||||
$this->action = 'Login';
|
||||
} elseif ($this->logout) {
|
||||
$this->action = 'Logout';
|
||||
}
|
||||
$_data_binary = array (
|
||||
'_SESSION' => $_SESSION,
|
||||
'_GET' => $_GET,
|
||||
'_POST' => $_POST,
|
||||
'_FILES' => $_FILES,
|
||||
'error' => $this->login_error
|
||||
);
|
||||
$data_binary = $this->db_escape_bytea(bzcompress(serialize($_data_binary)));
|
||||
// SQL querie for log entry
|
||||
$q = "INSERT INTO edit_log ";
|
||||
$q .= "(username, password, euid, event_date, event, error, data, data_binary, page, ";
|
||||
$q .= "ip, user_agent, referer, script_name, query_string, server_name, http_host, http_accept, http_accept_charset, http_accept_encoding, session_id, ";
|
||||
$q .= "action, action_id, action_yes, action_flag, action_menu, action_loaded, action_value, action_error) ";
|
||||
$q .= "VALUES ('".$this->db_escape_string($username)."', '".$this->db_escape_string($password)."', ".(($this->euid) ? $this->euid : 'NULL').", ";
|
||||
$q .= "NOW(), '".$this->db_escape_string($event)."', '".$this->db_escape_string($error)."', '".$this->db_escape_string($data)."', '".$data_binary."', '".$this->page_name."', ";
|
||||
foreach (array('REMOTE_ADDR', 'HTTP_USER_AGENT', 'HTTP_REFERER', 'SCRIPT_FILENAME', 'QUERY_STRING', 'SERVER_NAME', 'HTTP_HOST', 'HTTP_ACCEPT', 'HTTP_ACCEPT_CHARSET', 'HTTP_ACCEPT_ENCODING') as $server_code) {
|
||||
if (array_key_exists($server_code, $_SERVER)) {
|
||||
$q .= "'".$this->db_escape_string($_SERVER[$server_code])."', ";
|
||||
} else {
|
||||
$q .= "NULL, ";
|
||||
}
|
||||
}
|
||||
$q .= "'".session_id()."', ";
|
||||
$q .= "'".$this->db_escape_string($this->action)."', '".$this->db_escape_string($this->username)."', NULL, '".$this->db_escape_string($this->login_error)."', NULL, NULL, '".$this->db_escape_string($this->permission_okay)."', NULL)";
|
||||
$this->db_exec($q, 'NULL');
|
||||
}
|
||||
|
||||
// METHOD: login_check_edit_access_id
|
||||
// PARAMS: edit access id to check
|
||||
// RETURN: same edit access id if ok, or the default edit access id if given one is not valud
|
||||
// DESC : checks that the given edit access id is valid for this user
|
||||
public function login_check_edit_access_id($edit_access_id)
|
||||
{
|
||||
if (!array_key_exists($edit_access_id, $_SESSION["UNIT"])) {
|
||||
return $_SESSION["UNIT_DEFAULT"];
|
||||
} else {
|
||||
return $edit_access_id;
|
||||
}
|
||||
}
|
||||
|
||||
// METHOD: login_set_edit_access_data
|
||||
// PARAMS: edit access id, key value to search for
|
||||
// RETURN: false for not found or string for found data
|
||||
// DESC : searchs in the data set for the unit for the data key and returns the value asociated with it
|
||||
public function login_set_edit_access_data($edit_access_id, $data_key)
|
||||
{
|
||||
if (!$_SESSION['UNIT'][$edit_access_id]['data'][$data_key]) {
|
||||
return false;
|
||||
} else {
|
||||
return $_SESSION['UNIT'][$edit_access_id]['data'][$data_key];
|
||||
}
|
||||
}
|
||||
} // close class
|
||||
410
www/lib/CoreLibs/Admin/Backend.inc
Normal file
410
www/lib/CoreLibs/Admin/Backend.inc
Normal file
@@ -0,0 +1,410 @@
|
||||
<?
|
||||
/*********************************************************************
|
||||
* AUTHOR: Clemens "Gullevek" Schwaighofer (www.gullevek.org)
|
||||
* CREATED: 2006/08/15
|
||||
* VERSION: 0.1.0
|
||||
* RELEASED LICENSE: GNU GPL 3
|
||||
* DESCRIPTION
|
||||
* Basic Admin interface backend
|
||||
* - sets action flags
|
||||
* - menu creation
|
||||
* - array vars for smarty
|
||||
*
|
||||
* PUBLIC VARIABLES
|
||||
*
|
||||
* PRIVATE VARIABLES
|
||||
*
|
||||
* PUBLIC METHODS
|
||||
*
|
||||
* PRIVATE METHODS
|
||||
*
|
||||
* HISTORY:
|
||||
*
|
||||
*********************************************************************/
|
||||
|
||||
// try to include file from LIBS path, or from normal path
|
||||
_spl_autoload('Class.DB.IO.inc');
|
||||
|
||||
class AdminBackend extends db_io
|
||||
{
|
||||
// page name
|
||||
public $page_name; // the name of the current page
|
||||
public $menu = array();
|
||||
public $menu_show_flag = 0; // top menu flag (mostly string)
|
||||
// action ids
|
||||
public $action_list = array ('action', 'action_id', 'action_sub_id', 'action_yes', 'action_flag', 'action_menu', 'action_value', 'action_error', 'action_loaded');
|
||||
public $action;
|
||||
public $action_id;
|
||||
public $action_sub_id;
|
||||
public $action_yes;
|
||||
public $action_flag;
|
||||
public $action_menu;
|
||||
public $action_loaded;
|
||||
public $action_value;
|
||||
public $action_error;
|
||||
// ACL array variable if we want to set acl data from outisde
|
||||
public $acl = array ();
|
||||
// the current active edit access id
|
||||
public $edit_access_id;
|
||||
// error/warning/info messages
|
||||
public $messages = array ();
|
||||
public $error = 0;
|
||||
public $warning = 0;
|
||||
public $info = 0;
|
||||
// smarty publics
|
||||
public $DATA;
|
||||
public $HEADER;
|
||||
public $DEBUG_DATA;
|
||||
public $CONTENT_DATA;
|
||||
|
||||
// CONSTRUCTOR / DECONSTRUCTOR |====================================>
|
||||
public function __construct($db_config, $lang, $debug = 0, $db_debug = 0, $echo = 1, $print = 0)
|
||||
{
|
||||
// get the language sub class & init it
|
||||
_spl_autoload('Class.l10n.inc');
|
||||
|
||||
$this->l = new l10n($lang);
|
||||
|
||||
// init the database class
|
||||
// $this->db_io($db_config, $debug, $db_debug, $echo, $print);
|
||||
parent::__construct($db_config, $debug, $db_debug, $echo, $print);
|
||||
|
||||
// internal
|
||||
$this->class_info["adbBackend"] = array(
|
||||
"class_name" => "Admin Interface Backend",
|
||||
"class_version" => "0.1.0",
|
||||
"class_created" => "2006/08/15",
|
||||
"class_author" => "cs/gullevek/jp"
|
||||
);
|
||||
|
||||
// set page name
|
||||
$this->page_name = $this->get_page_name();
|
||||
|
||||
// set the action ids
|
||||
foreach ($this->action_list as $_action) {
|
||||
$this->$_action = (isset($_POST[$_action])) ? $_POST[$_action] : '';
|
||||
}
|
||||
|
||||
$this->default_acl = DEFAULT_ACL_LEVEL;
|
||||
|
||||
// random key generation
|
||||
$this->key_range = array_merge(range('A', 'Z'), range('a', 'z'), range('0', '9'));
|
||||
$GLOBALS["_KEY_RANGE"] = $this->key_range;
|
||||
$this->one_key_length = count($this->key_range);
|
||||
$this->key_length = 4; // pow($this->one_key_length, 4); // hardcoded, should be more than enought (62*62*62*62)
|
||||
|
||||
// queue key
|
||||
if (preg_match("/^(add|save|delete|remove|move|up|down|push_live)$/", $this->action)) {
|
||||
$this->queue_key = join(
|
||||
'',
|
||||
array_map(
|
||||
function () {
|
||||
$range = $GLOBALS['_KEY_RANGE'];
|
||||
return $range[rand(0, (count($range) - 1))];
|
||||
},
|
||||
range(1, 3)
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
// deconstructor
|
||||
public function __destruct()
|
||||
{
|
||||
parent::__destruct();
|
||||
}
|
||||
|
||||
// INTERNAL METHODS |===============================================>
|
||||
|
||||
|
||||
// PUBLIC METHODS |=================================================>
|
||||
|
||||
// METHOD: adbEditLog()
|
||||
// PARAMS: event -> any kind of event description, data -> any kind of data related to that event
|
||||
// RETURN: none
|
||||
// DESC: writes all action vars plus other info into edit_log table
|
||||
public function adbEditLog($event = '', $data = '', $write_type = 'STRING')
|
||||
{
|
||||
if ($write_type == 'BINARY') {
|
||||
$data_binary = $this->db_escape_bytea(bzcompress(serialize($data)));
|
||||
$data = 'see bzip compressed data_binary field';
|
||||
}
|
||||
if ($write_type == 'STRING') {
|
||||
$data = $this->db_escape_string(serialize($data));
|
||||
}
|
||||
|
||||
$q = "INSERT INTO ".LOGIN_DB_SCHEMA.".edit_log ";
|
||||
$q .= "(euid, event_date, event, data, data_binary, page, ";
|
||||
$q .= "ip, user_agent, referer, script_name, query_string, server_name, http_host, http_accept, http_accept_charset, http_accept_encoding, session_id, ";
|
||||
$q .= "action, action_id, action_yes, action_flag, action_menu, action_loaded, action_value, action_error) ";
|
||||
$q .= "VALUES ";
|
||||
$q .= "(".@$_SESSION['EUID'].", NOW(), '".$this->db_escape_string($event)."', '".$data."', '".$data_binary."', '".$this->page_name."', ";
|
||||
$q .= "'".@$_SERVER["REMOTE_ADDR"]."', '".$this->db_escape_string(@$_SERVER['HTTP_USER_AGENT'])."', ";
|
||||
$q .= "'".$this->db_escape_string(@$_SERVER['HTTP_REFERER'])."', '".$this->db_escape_string(@$_SERVER['SCRIPT_FILENAME'])."', ";
|
||||
$q .= "'".$this->db_escape_string(@$_SERVER['QUERY_STRING'])."', '".$this->db_escape_string(@$_SERVER['SERVER_NAME'])."', ";
|
||||
$q .= "'".$this->db_escape_string(@$_SERVER['HTTP_HOST'])."', '".$this->db_escape_string(@$_SERVER['HTTP_ACCEPT'])."', ";
|
||||
$q .= "'".$this->db_escape_string(@$_SERVER['HTTP_ACCEPT_CHARSET'])."', '".$this->db_escape_string(@$_SERVER['HTTP_ACCEPT_ENCODING'])."', ";
|
||||
$q .= "'".session_id()."', ";
|
||||
$q .= "'".$this->db_escape_string($this->action)."', '".$this->db_escape_string($this->action_id)."', ";
|
||||
$q .= "'".$this->db_escape_string($this->action_yes)."', '".$this->db_escape_string($this->action_flag)."', ";
|
||||
$q .= "'".$this->db_escape_string($this->action_menu)."', '".$this->db_escape_string($this->action_loaded)."', ";
|
||||
$q .= "'".$this->db_escape_string($this->action_value)."', '".$this->db_escape_string($this->action_error)."')";
|
||||
$this->db_exec($q, 'NULL');
|
||||
}
|
||||
|
||||
|
||||
// ==================================
|
||||
// ALL THE PAGE RIGHTS/USER RIGHTS/ETC need to fixed and put into one
|
||||
// proper settings have to be done with the defined top down rights flow
|
||||
// ==================================
|
||||
// all ACLs are set in the login class
|
||||
|
||||
// METHOD: adbTopMenu
|
||||
// PARAMS: level
|
||||
// RETURN: returns an array for the top menu with all correct settings
|
||||
// DESC: menu creater
|
||||
public function adbTopMenu($flag = 0)
|
||||
{
|
||||
if ($this->menu_show_flag) {
|
||||
$flag = $this->menu_show_flag;
|
||||
}
|
||||
|
||||
// get the session pages array
|
||||
$pages = $_SESSION["PAGES"];
|
||||
if (!is_array($pages)) {
|
||||
$pages = array ();
|
||||
}
|
||||
|
||||
//$this->debug('pages', $this->print_ar($pages));
|
||||
|
||||
// if flag is 0, then we show all, else, we show only the matching flagges array points
|
||||
// array is already sorted after correct order
|
||||
reset($pages);
|
||||
for ($i = 0; $i < count($pages); $i ++) {
|
||||
$show = 0;
|
||||
// is it visible in the menu & is it online
|
||||
if ($pages[$i]["menu"] && $pages[$i]["online"]) {
|
||||
// check if it falls into our flag if we have a flag
|
||||
if ($flag) {
|
||||
foreach ($pages[$i]["visible"] as $name => $key) {
|
||||
if ($key == $flag) {
|
||||
$show = 1;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// if no flag given, show all menu points
|
||||
$show = 1;
|
||||
}
|
||||
|
||||
if ($show) {
|
||||
// if it is popup, write popup arrayound
|
||||
if ($pages[$i]["popup"]) {
|
||||
$type = "popup";
|
||||
} else {
|
||||
$type = "normal";
|
||||
}
|
||||
$query_string = '';
|
||||
if (count($pages[$i]["query"])) {
|
||||
for ($j = 0; $j < count($pages[$i]["query"]); $j ++) {
|
||||
if (strlen($query_string)) {
|
||||
$query_string .= "&";
|
||||
}
|
||||
$query_string .= $pages[$i]["query"][$j]["name"]."=";
|
||||
if (!$pages[$i]["query"][$j]["dynamic"]) {
|
||||
$query_string .= urlencode($pages[$i]["query"][$j]["value"]);
|
||||
} else {
|
||||
$query_string .= $_GET[$pages[$i]["query"][$j]["value"]] ? urlencode($_GET[$pages[$i]["query"][$j]["value"]]) : urlencode($_POST[$pages[$i]["query"][$j]["value"]]);
|
||||
}
|
||||
}
|
||||
}
|
||||
$url = $pages[$i]["filename"];
|
||||
if (strlen($query_string)) {
|
||||
$url .= "?".$query_string;
|
||||
}
|
||||
$name = $pages[$i]["page_name"];
|
||||
// if page name matchs -> set selected flag
|
||||
$selected = 0;
|
||||
if ($this->get_page_name() == $pages[$i]["filename"]) {
|
||||
$selected = 1;
|
||||
$this->page_name = $name;
|
||||
}
|
||||
// last check, is this menu point okay to show
|
||||
$enabled = 0;
|
||||
if ($this->adbShowMenuPoint($pages[$i]["filename"])) {
|
||||
$enabled = 1;
|
||||
}
|
||||
// write in to view menu array
|
||||
array_push($this->menu, array("name" => $this->l->__($name), "url" => $url, "selected" => $selected, "enabled" => $enabled, "type" => $type));
|
||||
} // show page
|
||||
} // online and in menu
|
||||
} // for each page
|
||||
return $this->menu;
|
||||
}
|
||||
|
||||
// METHOD: adbShowMenuPoint
|
||||
// PARAMS: filename
|
||||
// RETURN: returns boolean true/false
|
||||
// DESC: checks if this filename is in the current situation (user id, etc) available
|
||||
public function adbShowMenuPoint($filename)
|
||||
{
|
||||
$enabled = 0;
|
||||
switch ($filename) {
|
||||
default:
|
||||
$enabled = 1;
|
||||
break;
|
||||
};
|
||||
return $enabled;
|
||||
}
|
||||
|
||||
// REMARK: below function has moved to "Class.Basic"
|
||||
// METHOD: adbAssocArray
|
||||
// PARAMS: db array, key, value part
|
||||
// RETURN: returns and associative array
|
||||
// DESC: creates out of a normal db_return array an assoc array
|
||||
public function adbAssocArray($db_array, $key, $value)
|
||||
{
|
||||
return $this->GenAssocArray($db_array, $key, $value);
|
||||
}
|
||||
|
||||
// REMARK: below function has moved to "Class.Basic"
|
||||
// METHOD: adbByteStringFormat
|
||||
// PARAMS: int
|
||||
// RETURN: string
|
||||
// DESC: converts bytes into formated string with KB, MB, etc
|
||||
public function adbByteStringFormat($number)
|
||||
{
|
||||
return $this->ByteStringFormat($number);
|
||||
}
|
||||
|
||||
// REMARK: below function has moved to "Class.Basic"
|
||||
// METHOD: adbCreateThumbnail
|
||||
// PARAMS: id from picture where from we create a thumbnail
|
||||
// x -> max x size of thumbnail
|
||||
// y -> max y size of thumbnail
|
||||
// dummy -> if set to true, then if no images was found we show a dummy image
|
||||
// path -> if source start is not ROOT path, if empty ROOT is choosen
|
||||
// cache -> cache path, if not given TMP is used
|
||||
// RETURN: thumbnail name
|
||||
// DESC: converts picture to a thumbnail with max x and max y size
|
||||
public function adbCreateThumbnail($pic, $size_x, $size_y, $dummy = false, $path = "", $cache = "")
|
||||
{
|
||||
return $this->CreateThumbnail($pic, $size_x, $size_y, $dummy, $path, $cache);
|
||||
}
|
||||
|
||||
// METHOD: adbMsg
|
||||
// PARAMS: level -> info/warning/error
|
||||
// msg -> string, can be printf formated
|
||||
// var array -> optional data for a possible printf formated msg
|
||||
// RETURN: none
|
||||
// DESC: wrapper function to fill up the mssages array
|
||||
public function adbMsg($level, $msg, $vars = array ())
|
||||
{
|
||||
if (!preg_match("/^info|warning|error$/", $level)) {
|
||||
$level = "info";
|
||||
}
|
||||
$this->messages[] = array (
|
||||
'msg' => sprintf($this->l->__($msg), $vars),
|
||||
'class' => $level
|
||||
);
|
||||
switch ($level) {
|
||||
case 'info':
|
||||
$this->info = 1;
|
||||
break;
|
||||
case 'warning':
|
||||
$this->warning = 1;
|
||||
break;
|
||||
case 'error':
|
||||
$this->error = 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// METHOD: adbLiveQueue
|
||||
// PARAMS: queue_key -> string to identfy the queue
|
||||
// type -> INSERT/UPDATE/DELETE
|
||||
// target -> target table to write to
|
||||
// data -> SQL part to write, this can include #KEY_VALUE#, #KEY_NAME# for delete sub queries
|
||||
// key_name -> key name, mostly used for update search
|
||||
// key_value -> data for the key
|
||||
// associate -> NULL for free, LOCK for first insert, group key for reference to first entry
|
||||
// file -> string for special file copy actions; mostyle "test#live;..."
|
||||
// RETURN: none
|
||||
// DESC: writes live queue
|
||||
public function adbLiveQueue($queue_key, $type, $target, $data, $key_name, $key_value, $associate = null, $file = null)
|
||||
{
|
||||
$q = "INSERT INTO ".GLOBAL_DB_SCHEMA.".live_queue (";
|
||||
$q .= "queue_key, key_value, key_name, type, target, data, group_key, action, associate, file";
|
||||
$q .= ") VALUES (";
|
||||
$q .= "'".$this->db_escape_string($queue_key)."', '".$this->db_escape_string($key_value)."', ";
|
||||
$q .= "'".$this->db_escape_string($key_name)."', '".$this->db_escape_string($type)."', ";
|
||||
$q .= "'".$this->db_escape_string($target)."', '".$this->db_escape_string($data)."', ";
|
||||
$q .= "'".$this->queue_key."', '".$this->action."', '".$this->db_escape_string($associate)."', ";
|
||||
$q .= "'".$this->db_escape_string($file)."')";
|
||||
$this->db_exec($q);
|
||||
}
|
||||
|
||||
// METHOD: adbPrintDateTime
|
||||
// PARAMS: year, month, day, hour, min: the date and time values
|
||||
// suffix: additional info printed after the date time variable in the drop down, also used for ID in the on change JS call
|
||||
// minute steps, can be 1 (default), 5, 10, etc, if invalid (outside 1h range, it falls back to 1min)
|
||||
// RETURN: HTML formated strings for drop down lists of date and time
|
||||
// DESC: print the date/time drop downs, used in any queue/send/insert at date/time place
|
||||
public function adbPrintDateTime($year, $month, $day, $hour, $min, $suffix = '', $min_steps = 1)
|
||||
{
|
||||
// if suffix given, add _ before
|
||||
if ($suffix) {
|
||||
$suffix = '_'.$suffix;
|
||||
}
|
||||
if ($min_steps < 1 || $min_steps > 59) {
|
||||
$min_steps = 1;
|
||||
}
|
||||
|
||||
$on_change_call = 'dt_list(\''.$suffix.'\');';
|
||||
|
||||
// always be 1h ahead (for safety)
|
||||
$timestamp = time() + 3600; // in seconds
|
||||
|
||||
// the max year is this year + 1;
|
||||
$max_year = date("Y", $timestamp) + 1;
|
||||
|
||||
// preset year, month, ...
|
||||
$year = (!$year) ? date("Y", $timestamp) : $year;
|
||||
$month = (!$month) ? date("m", $timestamp) : $month;
|
||||
$day = (!$day) ? date("d", $timestamp) : $day;
|
||||
$hour = (!$hour) ? date("H", $timestamp) : $hour;
|
||||
$min = (!$min) ? date("i", $timestamp) : $min; // add to five min?
|
||||
// max days in selected month
|
||||
$days_in_month = date("t", strtotime($year."-".$month."-".$day." ".$hour.":".$min.":0"));
|
||||
|
||||
// from now to ?
|
||||
$string = $this->l->__('Year').' ';
|
||||
$string .= '<select id="year'.$suffix.'" name="year'.$suffix.'" onChange="'.$on_change_call.'">';
|
||||
for ($i = date("Y"); $i <= $max_year; $i ++) {
|
||||
$string .= '<option value="'.$i.'" '.(($year == $i) ? 'selected' : '').'>'.$i.'</option>';
|
||||
}
|
||||
$string .= '</select> '.$this->l->__('Month').' ';
|
||||
$string .= '<select id="month'.$suffix.'" name="month'.$suffix.'" onChange="'.$on_change_call.'">';
|
||||
for ($i = 1; $i <= 12; $i ++) {
|
||||
$string .= '<option value="'.(($i < 10) ? '0'.$i : $i).'" '.(($month == $i) ? 'selected' : '').'>'.$i.'</option>';
|
||||
}
|
||||
$string .= '</select> '.$this->l->__('Day').' ';
|
||||
$string .= '<select id="day'.$suffix.'" name="day'.$suffix.'" onChange="'.$on_change_call.'">';
|
||||
for ($i = 1; $i <= $days_in_month; $i ++) {
|
||||
// set weekday text based on current month ($month) and year ($year)
|
||||
$string .= '<option value="'.(($i < 10) ? '0'.$i : $i).'" '.(($day == $i) ? 'selected' : '').'>'.$i.' ('.$this->l->__(date('D', mktime(0, 0, 0, $month, $i, $year))).')</option>';
|
||||
}
|
||||
$string .= '</select> '.$this->l->__('Hour').' ';
|
||||
$string .= '<select id="hour'.$suffix.'" name="hour'.$suffix.'" onChange="'.$on_change_call.'">';
|
||||
for ($i = 0; $i <= 23; $i ++) {
|
||||
$string .= '<option value="'.(($i < 10) ? '0'.$i : $i).'" '.(($hour == $i) ? 'selected' : '').'>'.$i.'</option>';
|
||||
}
|
||||
$string .= '</select> '.$this->l->__('Minute').' ';
|
||||
$string .= '<select id="min'.$suffix.'" name="min'.$suffix.'" onChange="'.$on_change_call.'">';
|
||||
for ($i = 0; $i <= 59; $i += $min_steps) {
|
||||
$string .= '<option value="'.(( $i < 10) ? '0'.$i : $i).'" '.(($min == $i) ? 'selected' : '').'>'.$i.'</option>';
|
||||
}
|
||||
$string .= '</select>';
|
||||
// return the datetime select string
|
||||
return $string;
|
||||
}
|
||||
}
|
||||
2266
www/lib/CoreLibs/Basic.inc
Normal file
2266
www/lib/CoreLibs/Basic.inc
Normal file
File diff suppressed because it is too large
Load Diff
497
www/lib/CoreLibs/DB/Extended/ArrayIO.inc
Normal file
497
www/lib/CoreLibs/DB/Extended/ArrayIO.inc
Normal file
@@ -0,0 +1,497 @@
|
||||
<?
|
||||
/*********************************************************************
|
||||
* AUTHOR: Clemens "Gullevek" Schwaighofer (www.gullevek.org)
|
||||
* CREATED: 2002/12/17
|
||||
* VERSION: 0.4.0
|
||||
* RELEASED LICENSE: GNU GPL 3
|
||||
* SHORT DESCRIPTION:
|
||||
* DB Array IO Class:
|
||||
* writes, reads or deletes a complete array (one data set) in/out a
|
||||
* table from the connected DB.
|
||||
* you don't have to write any SQL queries, worry over update/insert
|
||||
*
|
||||
* PUBLIC VARIABLES
|
||||
*
|
||||
* PRIVATE VARIABLES
|
||||
*
|
||||
* PUBLIC METHODS
|
||||
*
|
||||
* PRIVATE METHODS
|
||||
*
|
||||
* HISTORY:
|
||||
* 2005/07/07 (cs) updated array class for postgres: set 0 & NULL if int field given, insert uses () values () syntax
|
||||
* 2005/03/31 (cs) fixed the class call with all debug vars
|
||||
* 2003-03-10: error_ids where still wrong chagned 11->21 and 12->22
|
||||
* 2003-02-26: db_array_io is no longer single class but extens db_io,
|
||||
* as it needs it anyway
|
||||
* moved the class info vars into class_info array into
|
||||
* the constructor, removed info function
|
||||
* 2003-02-24: in db_delete moved query build to top, or pk_name/value
|
||||
* will be reset before delete is done
|
||||
* 2002-12-20: just added info() method
|
||||
* 2002-12-17: splitted the class from other file (with main db wrapper)
|
||||
*********************************************************************/
|
||||
|
||||
// picture upload should be taken out from here and out in media_class
|
||||
// as it actually has nothing to do with this one here ? (or at least
|
||||
// put into separete function in this class)
|
||||
|
||||
// try to include file from LIBS path, or from normal path
|
||||
_spl_autoload('Class.DB.IO.inc');
|
||||
|
||||
// subclass for one array handling
|
||||
class db_array_io extends db_io
|
||||
{
|
||||
// main calss variables
|
||||
public $table_array; // the array from the table to work on
|
||||
public $table_name; // the table_name
|
||||
public $pk_name; // the primary key from this table
|
||||
public $pk_id; // the PK id
|
||||
|
||||
// METHOD db_array_io
|
||||
// PARAMS db_config -> db_io class init vars
|
||||
// table_array -> the array from the table
|
||||
// table_name -> name of the table (for the array)
|
||||
// db_debug -> turn on db_io debug output (DB_DEBUG as global var does the same)
|
||||
// RETURN none
|
||||
// DESC constructor for the array io class, set the
|
||||
// primary key name automatically (from array)
|
||||
public function __construct($db_config, $table_array, $table_name, $debug = 0, $db_debug = 0, $echo = 1, $print = 0)
|
||||
{
|
||||
// instance db_io class
|
||||
parent::__construct($db_config, $debug, $db_debug, $echo, $print);
|
||||
// more error vars for this class
|
||||
$this->error_string["21"] = "No Primary Key given";
|
||||
$this->error_string["22"] = "Could not run Array Query";
|
||||
|
||||
$this->table_array = $table_array;
|
||||
$this->table_name = $table_name;
|
||||
|
||||
// set primary key for given table_array
|
||||
if ($this->table_array) {
|
||||
while (list($key, $value) = each($table_array)) {
|
||||
if ($value["pk"]) {
|
||||
$this->pk_name = $key;
|
||||
}
|
||||
}
|
||||
} // set pk_name IF table_array was given
|
||||
// internal
|
||||
$this->class_info["db_array_io"] = array(
|
||||
"class_name" => "DB Array IO",
|
||||
"class_version" => "0.4.0",
|
||||
"class_created" => "2002/12/17",
|
||||
"class_author" => "cs/gullevek/at"
|
||||
);
|
||||
}
|
||||
|
||||
// deconstruktor
|
||||
public function __destruct()
|
||||
{
|
||||
parent::__destruct();
|
||||
}
|
||||
|
||||
// METHOD convert_data
|
||||
// PARAMS string -> the string that should be changed
|
||||
// RETURN string -> the altered string
|
||||
// DESC changes all previously alterd HTML code into visible one,
|
||||
// works for <b>,<i>, and <a> (thought <a> can be / or should
|
||||
// be handled with the magic links functions
|
||||
// used with the read function
|
||||
public function convert_data($text)
|
||||
{
|
||||
$text = str_replace('<b>', '<b>', $text);
|
||||
$text = str_replace('</b>', '</b>', $text);
|
||||
$text = str_replace('<i>', '<i>', $text);
|
||||
$text = str_replace('</i>', '</i>', $text);
|
||||
// my need a change
|
||||
$text = str_replace('<a href="', '<a target="_blank" href="', $text);
|
||||
$text = str_replace('">', '">', $text);
|
||||
$text = str_replace('</a>', '</a>', $text);
|
||||
return $text;
|
||||
}
|
||||
|
||||
// METHOD convert_entities
|
||||
// PARAMS string -> string to be changed
|
||||
// RETURN string -> altered string
|
||||
// DESC changeds all HTML entities into non HTML ones
|
||||
public function convert_entities($text)
|
||||
{
|
||||
$text = str_replace('<', '<', $text);
|
||||
$text = str_replace('>', '>', $text);
|
||||
$text = str_replace('&', '&', $text);
|
||||
$text = str_replace('"', '"', $text);
|
||||
$text = str_replace(''', "'", $text);
|
||||
return $text;
|
||||
}
|
||||
|
||||
// METHOD db_dump_array
|
||||
// PARAMS none
|
||||
// RETURN returns the current array
|
||||
// DESC dumps the current data
|
||||
public function db_dump_array($write = 0)
|
||||
{
|
||||
reset($this->table_array);
|
||||
while (list($column, $data_array) = each($this->table_array)) {
|
||||
$string .= "<b>".$column."</b> -> ".$data_array["value"]."<br>";
|
||||
}
|
||||
// add output to internal error_msg
|
||||
if ($write) {
|
||||
$this->error_msg['db'] .= $string;
|
||||
}
|
||||
return $string;
|
||||
}
|
||||
|
||||
// METHOD _db_error
|
||||
// PARAMS none
|
||||
// RETURN none
|
||||
// DESC writes errors to internal error string
|
||||
/* function _db_error()
|
||||
{
|
||||
// if error occured
|
||||
if ($this->error_id)
|
||||
{
|
||||
$this->error_msg['db'] .= "<b>-DB_ARRAY-error-></b> ".$this->error_id.": ".$this->error_string[$this->error_id]." <br>";
|
||||
}
|
||||
} */
|
||||
|
||||
// METHOD db_check_pk_set
|
||||
// PARAMS none
|
||||
// RETURN none
|
||||
// DESC checks if pk is set and if not, set from pk_id and if this also not set return 0
|
||||
public function db_check_pk_set()
|
||||
{
|
||||
// if pk_id is set, overrule ...
|
||||
if ($this->pk_id) {
|
||||
$this->table_array[$this->pk_name]["value"] = $this->pk_id;
|
||||
}
|
||||
// if not set ... produce error
|
||||
if (!$this->table_array[$this->pk_name]["value"]) {
|
||||
// if no PK found, error ...
|
||||
$this->error_id = 21;
|
||||
$this->_db_error();
|
||||
return 0;
|
||||
} else {
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
// METHOD db_reset_array
|
||||
// PARAMS reset_pk -> if set reset the pk too
|
||||
// RETURN none
|
||||
// DESC resets the whole array
|
||||
public function db_reset_array($reset_pk = 0)
|
||||
{
|
||||
reset($this->table_array);
|
||||
while (list($column, $data_array) = each($this->table_array)) {
|
||||
if (!$this->table_array[$column]["pk"]) {
|
||||
unset($this->table_array[$column]["value"]);
|
||||
} elseif ($reset_pk) {
|
||||
unset($this->table_array[$column]["value"]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// METHOD db_delete
|
||||
// PARAMS optional the table_array, if not given uses class var
|
||||
// RETURN 1 for successfull delete or 0 for error
|
||||
// DESC deletes one dataset
|
||||
public function db_delete($table_array = 0)
|
||||
{
|
||||
if (is_array($table_array)) {
|
||||
$this->table_array = $table_array;
|
||||
}
|
||||
if (!$this->db_check_pk_set()) {
|
||||
return $this->table_array;
|
||||
}
|
||||
// delete query
|
||||
$q = "DELETE FROM ".$this->table_name." WHERE ";
|
||||
$q .= $this->pk_name." = ".$this->table_array[$this->pk_name]["value"]." ";
|
||||
// delete files and build FK query
|
||||
reset($this->table_array);
|
||||
while (list($column, $data_array) = each($this->table_array)) {
|
||||
// suchen nach bildern und löschen ...
|
||||
if ($this->table_array[$column]["file"] && file_exists($this->table_array[$column]["url"].$this->table_array[$column]["value"])) {
|
||||
if (file_exists($this->table_array[$column]["path"].$this->table_array[$column]["value"])) {
|
||||
unlink($this->table_array[$column]["path"].$this->table_array[$column]["value"]);
|
||||
}
|
||||
$dateiname = str_replace("_tn", "", $this->table_array[$column]["value"]);
|
||||
if (file_exists($this->table_array[$column]["path"].$dateiname)) {
|
||||
unlink($this->table_array[$column]["path"].$dateiname);
|
||||
}
|
||||
}
|
||||
|
||||
if ($this->table_array[$column]["fk"]) {
|
||||
// zusammenstellen der FKs
|
||||
if ($q_where) {
|
||||
$q_where .= " AND ";
|
||||
}
|
||||
$q_where .= $column." = ".$this->table_array[$column]["value"];
|
||||
}
|
||||
// allgemeines zurücksetzen des arrays
|
||||
unset($this->table_array[$column]["value"]);
|
||||
}
|
||||
|
||||
// attach fk row if there ...
|
||||
if ($q_where) {
|
||||
$q .= " AND ".$q_where;
|
||||
}
|
||||
// if 0, error
|
||||
unset($this->pk_id);
|
||||
if (!$this->db_exec($q)) {
|
||||
$this->error_id=22;
|
||||
$this->_db_error();
|
||||
}
|
||||
return $this->table_array;
|
||||
}
|
||||
|
||||
// METHOD db_read
|
||||
// PARAMS edit -> if 1 data will not be altered for output, optional the table_array, if not given uses class var
|
||||
// RETURN true or false for reading
|
||||
// DESC reads one row into the array
|
||||
public function db_read($edit = 0, $table_array = 0)
|
||||
{
|
||||
// if array give, overrules internal array
|
||||
if (is_array($table_array)) {
|
||||
$this->table_array = $table_array;
|
||||
}
|
||||
if (!$this->db_check_pk_set()) {
|
||||
return $this->table_array;
|
||||
}
|
||||
reset($this->table_array);
|
||||
// create select part & addition FK part
|
||||
while (list($column, $data_array)=each($this->table_array)) {
|
||||
if ($q_select) {
|
||||
$q_select .= ", ";
|
||||
}
|
||||
$q_select .= $column;
|
||||
|
||||
// check FK ...
|
||||
if ($this->table_array[$column]["fk"] && $this->table_array[$column]["value"]) {
|
||||
if ($q_where) {
|
||||
$q_where .= " AND ";
|
||||
}
|
||||
$q_where .= $column .= " = ".$this->table_array[$column]["value"];
|
||||
}
|
||||
}
|
||||
|
||||
$q = "SELECT ";
|
||||
$q .= $q_select;
|
||||
$q .= " FROM ".$this->table_name." WHERE ";
|
||||
$q .= $this->pk_name." = ".$this->table_array[$this->pk_name]["value"]." ";
|
||||
if ($q_where) {
|
||||
$q .= " AND ".$q_where;
|
||||
}
|
||||
|
||||
// if query was executed okay, else set error
|
||||
if ($this->db_exec($q)) {
|
||||
if ($res = $this->db_fetch_array()) {
|
||||
reset($this->table_array);
|
||||
while (list($column, $data_array) = each($this->table_array)) {
|
||||
// wenn "edit" dann gib daten wie in DB zurück, ansonten aufbereiten für ausgabe
|
||||
// ?? sollte das nicht draußen ??? man weis ja net was da drin steht --> is noch zu überlegen
|
||||
// echo "EDIT: $edit | Spalte: $column | type: ".$this->table_array[$column]["type"]." | Res: ".$res[$column]."<br>";
|
||||
if ($edit) {
|
||||
$this->table_array[$column]["value"] = $res[$column];
|
||||
// if password, also write to hidden
|
||||
if ($this->table_array[$column]["type"] == "password") {
|
||||
$this->table_array[$column]["HIDDEN_value"] = $res[$column];
|
||||
}
|
||||
} else {
|
||||
$this->table_array[$column]["value"] = $this->convert_data(nl2br($res[$column]));
|
||||
// had to put out the htmlentities from the line above as it breaks japanese characters
|
||||
}
|
||||
}
|
||||
}
|
||||
// possible db_fetch_array errors ...
|
||||
$this->pk_id = $this->table_array[$this->pk_name]["value"];
|
||||
} else {
|
||||
$this->error_id = 22;
|
||||
$this->_db_error();
|
||||
}
|
||||
return $this->table_array;
|
||||
}
|
||||
|
||||
// METHOD db_write
|
||||
// PARAMS addslashes -> if 1 will make an addslashes for each array field, optional the table_array, if not given uses class var
|
||||
// RETURN true or false on write
|
||||
// DESC writes on set into DB or updates one set (if PK exists)
|
||||
public function db_write($addslashes = 0, $table_array = 0)
|
||||
{
|
||||
if (is_array($table_array)) {
|
||||
$this->table_array = $table_array;
|
||||
}
|
||||
// PK ID check
|
||||
// if ($this->pk_id && !$this->table_array[$this->pk_name]["value"]) {
|
||||
// $this->table_array[$this->pk_name]["value"]=$this->pk_id;
|
||||
// }
|
||||
// checken ob PKs gesetzt, wenn alle -> update, wenn keiner -> insert, wenn ein paar -> ERROR!
|
||||
if (!$this->table_array[$this->pk_name]["value"]) {
|
||||
$insert = 1;
|
||||
} else {
|
||||
$insert = 0;
|
||||
}
|
||||
|
||||
reset($this->table_array);
|
||||
while (list($column, $data_array) = each($this->table_array)) {
|
||||
|
||||
/********************************* START FILE *************************************/
|
||||
// file upload
|
||||
if ($this->table_array[$column]["file"]) {
|
||||
// falls was im tmp drinnen, sprich ein upload, datei kopieren, Dateinamen in db schreiben
|
||||
// falls datei schon am server (physischer pfad), dann einfach url in db schreiben (update)
|
||||
// falls in "delete" "ja" dann loeschen (und gibts eh nur beim update)
|
||||
if ($this->table_array[$column]["delete"]) {
|
||||
unset($this->table_array[$column]["delete"]);
|
||||
if (file_exists($this->table_array[$column]["path"].$this->table_array[$column]["value"])) {
|
||||
unlink($this->table_array[$column]["path"].$this->table_array[$column]["value"]);
|
||||
}
|
||||
$dateiname = str_replace("_tn", "", $this->table_array[$column]["value"]);
|
||||
if (file_exists($this->table_array[$column]["path"].$dateiname)) {
|
||||
unlink($this->table_array[$column]["path"].$dateiname);
|
||||
}
|
||||
$this->table_array[$column]["value"] = "";
|
||||
} else {
|
||||
if ($this->table_array[$column]["tmp"] != "none" && $this->table_array[$column]["tmp"]) {
|
||||
// Dateiname zusammenbasteln: org-name + _pkid liste + .ext
|
||||
list($name, $ext) = explode(".", $this->table_array[$column]["dn"]);
|
||||
|
||||
// mozilla, patch
|
||||
$fn_name = explode("/", $this->table_array[$column]["dn"]);
|
||||
$this->table_array[$column]["dn"] = $fn_name[count($fn_name)-1];
|
||||
$filename_parts = explode(".", $this->table_array[$column]["dn"]);
|
||||
$ext = end($filename_parts);
|
||||
array_splice($filename_parts, -1, 1);
|
||||
$name = str_replace(" ", "_", implode(".", $filename_parts));
|
||||
//echo "PK: $pk_ids_file<br>";
|
||||
$dateiname = $name.$pk_ids_file.".".$ext;
|
||||
//echo "Dn: $dateiname";
|
||||
copy($this->table_array[$column]["tmp"], $this->table_array[$column]["path"].$dateiname);
|
||||
// automatisch thumbnail generieren, geht nur mit convert (ImageMagic!!!), aber nur bei bild ..
|
||||
if (strtolower($ext) == "jpeg" || strtolower($ext) == "jpg" || strtolower($ext) == "gif" || strtolower($ext) == "png") {
|
||||
$dateiname_tn = $name.$pk_ids_file."_tn.".$ext;
|
||||
$eingang = $this->table_array[$column]["path"].$dateiname;
|
||||
$ausgang = $this->table_array[$column]["path"].$dateiname_tn;
|
||||
$com = "convert -geometry 115 $eingang $ausgang";
|
||||
exec($com);
|
||||
$this->table_array[$column]["value"] = $dateiname_tn;
|
||||
} else {
|
||||
$this->table_array[$column]["value"] = $dateiname;
|
||||
}
|
||||
} elseif (file_exists($this->table_array[$column]["path"].$this->table_array[$column]["value"])) {
|
||||
// mach gar nix, wenn bild schon da ???
|
||||
}
|
||||
} // delete or upload
|
||||
} // file IF
|
||||
/********************************* END FILE **************************************/
|
||||
|
||||
// do not write 'pk' (primary key) or 'view' values
|
||||
if (!$this->table_array[$column]["pk"] && $this->table_array[$column]['type'] != 'view' && strlen($column) > 0) {
|
||||
// for password use hidden value if main is not set
|
||||
if ($this->table_array[$column]["type"] == "password" && !$this->table_array[$column]["value"]) {
|
||||
$this->table_array[$column]["value"] = $this->table_array[$column]["HIDDEN_value"];
|
||||
}
|
||||
if (!$insert) {
|
||||
if (strlen($q_data)) {
|
||||
$q_data .= ", ";
|
||||
}
|
||||
$q_data .= $column." = ";
|
||||
} else {
|
||||
// this is insert
|
||||
if (strlen($q_data)) {
|
||||
$q_data .= ", ";
|
||||
}
|
||||
if ($q_vars) {
|
||||
$q_vars .= ", ";
|
||||
}
|
||||
$q_vars .= $column;
|
||||
}
|
||||
// integer is different
|
||||
if ($this->table_array[$column]["int"] || $this->table_array[$column]["int_null"]) {
|
||||
$this->debug('write_check', "[$column][".$this->table_array[$column]["value"]."] Foo: ".isset($this->table_array[$column]["value"])." | ".$this->table_array[$column]["int_null"]);
|
||||
if (!$this->table_array[$column]["value"] && $this->table_array[$column]["int_null"]) {
|
||||
$_value = 'NULL';
|
||||
} elseif (!isset($this->table_array[$column]["value"])) {
|
||||
$_value = 0;
|
||||
} else {
|
||||
$_value = $this->table_array[$column]["value"];
|
||||
}
|
||||
$q_data .= $_value;
|
||||
} elseif ($this->table_array[$column]["interval"]) {
|
||||
// for interval we check if no value, then we set null
|
||||
if (!$this->table_array[$column]["value"]) {
|
||||
$_value = 'NULL';
|
||||
}
|
||||
$q_data .= $_value;
|
||||
} else {
|
||||
// normal string
|
||||
$q_data .= "'";
|
||||
// if add slashes do convert & add slashes else write AS is
|
||||
if ($addslashes) {
|
||||
$q_data .= $this->db_escape_string($this->convert_entities($this->table_array[$column]["value"]));
|
||||
} else {
|
||||
$q_data .= $this->db_escape_string($this->table_array[$column]["value"]);
|
||||
}
|
||||
$q_data .= "'";
|
||||
}
|
||||
}
|
||||
} // while ...
|
||||
|
||||
// NOW get PK, and FK settings (FK only for update query)
|
||||
// get it at the end, cause now we can be more sure of no double IDs, etc
|
||||
reset($this->table_array);
|
||||
// create select part & addition FK part
|
||||
while (list($column, $data_array) = each($this->table_array)) {
|
||||
// check FK ...
|
||||
if ($this->table_array[$column]["fk"] && $this->table_array[$column]["value"]) {
|
||||
if ($q_where) {
|
||||
$q_where .= " AND ";
|
||||
}
|
||||
$q_where .= $column .= " = ".$this->table_array[$column]["value"];
|
||||
}
|
||||
}
|
||||
|
||||
// if no PK set, then get max ID from DB
|
||||
if (!$this->table_array[$this->pk_name]["value"]) {
|
||||
// max id, falls INSERT
|
||||
$q = "SELECT MAX(".$this->pk_name.") + 1 AS pk_id FROM ".$this->table_name;
|
||||
$res = $this->db_return_row($q);
|
||||
if (!$res["pk_id"]) {
|
||||
$res["pk_id"] = 1;
|
||||
}
|
||||
$this->table_array[$this->pk_name]["value"] = $res["pk_id"];
|
||||
}
|
||||
|
||||
if (!$insert) {
|
||||
$q = "UPDATE ".$this->table_name." SET ";
|
||||
$q .= $q_data;
|
||||
$q .= " WHERE ";
|
||||
$q .= $this->pk_name." = ".$this->table_array[$this->pk_name]["value"]." ";
|
||||
if ($q_where) {
|
||||
$q .= " AND ".$q_where;
|
||||
}
|
||||
// set pk_id ... if it has changed or so
|
||||
$this->pk_id = $this->table_array[$this->pk_name]["value"];
|
||||
} else {
|
||||
$q = "INSERT INTO ".$this->table_name." ";
|
||||
$q .= "(".$q_vars.") ";
|
||||
$q .= "VALUES (".$q_data.")";
|
||||
// write primary key too
|
||||
// if ($q_data)
|
||||
// $q .= ", ";
|
||||
// $q .= $this->pk_name." = ".$this->table_array[$this->pk_name]["value"]." ";
|
||||
// $this->pk_id = $this->table_array[$this->pk_name]["value"];
|
||||
}
|
||||
// return success or not
|
||||
if (!$this->db_exec($q)) {
|
||||
$this->error_id = 22;
|
||||
$this->_db_error();
|
||||
}
|
||||
// set primary key
|
||||
if ($insert) {
|
||||
$this->table_array[$this->pk_name]["value"] = $this->insert_id;
|
||||
$this->ok = $this->insert_id;
|
||||
}
|
||||
// return the table if needed
|
||||
return $this->table_array;
|
||||
}
|
||||
} // end of class
|
||||
1746
www/lib/CoreLibs/DB/IO.inc
Normal file
1746
www/lib/CoreLibs/DB/IO.inc
Normal file
File diff suppressed because it is too large
Load Diff
397
www/lib/CoreLibs/DB/SQL/PgSQL.inc
Normal file
397
www/lib/CoreLibs/DB/SQL/PgSQL.inc
Normal file
@@ -0,0 +1,397 @@
|
||||
<?
|
||||
/*********************************************************************
|
||||
* AUTHOR: Clemens "Gullevek" Schwaighofer (www.gullevek.org)
|
||||
* CREATED: 2003/04/09
|
||||
* SHORT DESCRIPTION:
|
||||
* pgsql wrapper calls
|
||||
* HISTORY:
|
||||
* 2008/04/16 (cs) wrapper for pg escape string
|
||||
* 2007/01/11 (cs) add prepare/execute for postgres
|
||||
* 2006/09/12 (cs) in case db_query retuns false, save the query and run the query through the send/get procedure to get correct error data from the db
|
||||
* 2006/06/26 (cs) added port for db connection
|
||||
* 2006/04/03 (cs) added meta data for table
|
||||
* 2005/07/25 (cs) removed the plural s remove, not needed and not 100% working
|
||||
* 2005/07/07 (cs) the default it is table_name _ id
|
||||
* 2005/01/19 (cs) changed the pgsql connect, so it dies if it can't connect to the DB
|
||||
* 2004/09/30 (cs) layout cleanup
|
||||
* /
|
||||
|
||||
* collection of PostgreSQL wrappers
|
||||
* REQUIRES 5.x PHP!!!
|
||||
*
|
||||
* pg_prepare
|
||||
* pg_execute
|
||||
* pg_num_rows
|
||||
* pg_num_fields
|
||||
* pg_field_name
|
||||
* pg_affected_rows (*)
|
||||
* pg_fetch_array
|
||||
* pg_query
|
||||
* pg_send_query
|
||||
* pg_get_result
|
||||
* pg_connection_busy
|
||||
* pg_close
|
||||
* pg_connect (*)
|
||||
* pg_meta_data
|
||||
* pg_escape_string
|
||||
*
|
||||
*/
|
||||
|
||||
class db_pgsql
|
||||
{
|
||||
private $last_error_query;
|
||||
private $dbh;
|
||||
// public $currval_query;
|
||||
|
||||
// METHOD: __construct
|
||||
// PARAMS: none
|
||||
// RETURN: none
|
||||
// DESC : class constructor
|
||||
public function __construct()
|
||||
{
|
||||
}
|
||||
|
||||
public function _db_last_error_query()
|
||||
{
|
||||
if ($this->last_error_query) {
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// METHOD: _db_query
|
||||
// PARAMS: query
|
||||
// RETURN: query result
|
||||
// DESC : wrapper for gp_query, catches error and stores it in class var
|
||||
public function _db_query($query)
|
||||
{
|
||||
$this->last_error_query = '';
|
||||
// read out the query status and save the query if needed
|
||||
$result = pg_query($this->dbh, $query);
|
||||
if (!$result) {
|
||||
$this->last_error_query = $query;
|
||||
}
|
||||
return $result;
|
||||
}
|
||||
|
||||
// METHOD: _db_send_query
|
||||
// PARAMS: query
|
||||
// RETURN: true/false if query was sent successful
|
||||
// DESC : sends an async query to the server
|
||||
public function _db_send_query($query)
|
||||
{
|
||||
return pg_send_query($this->dbh, $query);
|
||||
}
|
||||
|
||||
// METHOD: _db_get_result
|
||||
// PARAMS: none
|
||||
// RETURN: resource handler
|
||||
// DESC : wrapper for pg_get_result
|
||||
public function _db_get_result()
|
||||
{
|
||||
$this->last_error_query = '';
|
||||
$result = pg_get_result($this->dbh);
|
||||
if ($error = pg_result_error($result)) {
|
||||
$this->last_error_query = $error;
|
||||
}
|
||||
return $result;
|
||||
}
|
||||
|
||||
// METHOD: _db_close
|
||||
// PARAMS: none
|
||||
// RETURN: none
|
||||
// DESC : wrapper for pg_close
|
||||
public function _db_close()
|
||||
{
|
||||
if (is_resource($this->dbh)) {
|
||||
if (pg_connection_status($this->dbh) === PGSQL_CONNECTION_OK) {
|
||||
pg_close($this->dbh);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// METHOD: _db_prepare
|
||||
// PARAMS: prepare name, query
|
||||
// RETURN: prepared statement handler
|
||||
// DESC : wrapper for pg_prepare
|
||||
public function _db_prepare($name, $query)
|
||||
{
|
||||
$result = pg_prepare($this->dbh, $name, $query);
|
||||
if (!$result) {
|
||||
$this->last_error_query = $query;
|
||||
}
|
||||
return $result;
|
||||
}
|
||||
|
||||
// METHOD: _db_execute
|
||||
// PARAMS: prepare name, data for query
|
||||
// RETURN: returns status
|
||||
// DESC : wrapper for pg_execute for running a prepared statement
|
||||
public function _db_execute($name, $data)
|
||||
{
|
||||
$result = pg_execute($this->dbh, $name, $data);
|
||||
if (!$result) {
|
||||
$this->last_error_query = $query;
|
||||
}
|
||||
return $result;
|
||||
}
|
||||
|
||||
// METHOD: _db_num_rows
|
||||
// PARAMS: cursor
|
||||
// RETURN: rows
|
||||
// DESC : wrapper for pg_num_rows
|
||||
public function _db_num_rows($cursor)
|
||||
{
|
||||
return pg_num_rows($cursor);
|
||||
}
|
||||
|
||||
// METHOD: _db_num_fields
|
||||
// PARAMS: cursor
|
||||
// RETURN: number for fields in query
|
||||
// DESC : wrapper for pg_num_fields
|
||||
public function _db_num_fields($cursor)
|
||||
{
|
||||
return pg_num_fields($cursor);
|
||||
}
|
||||
|
||||
// METHOD: _db_field_name
|
||||
// PARAMS: cursor, field position
|
||||
// RETURN: name of field
|
||||
// DESC : wrapper for pg_field_name
|
||||
public function _db_field_name($cursor, $i)
|
||||
{
|
||||
return pg_field_name($cursor, $i);
|
||||
}
|
||||
|
||||
// METHOD: _db_fetch_array
|
||||
// PARAMS: cursor, opt result type
|
||||
// RETURN: row
|
||||
// DESC : wrapper for pg_fetch_array
|
||||
public function _db_fetch_array($cursor, $result_type = '')
|
||||
{
|
||||
// result type is passed on as is [should be checked]
|
||||
if ($result_type) {
|
||||
return pg_fetch_array($cursor, NULL, $result_type);
|
||||
} else {
|
||||
return pg_fetch_array($cursor);
|
||||
}
|
||||
}
|
||||
|
||||
// METHOD: _db_fetch_all
|
||||
// PARAMS: cursor
|
||||
// RETURN: all rows as array
|
||||
// DESC : wrapper for pg_fetch_array
|
||||
public function _db_fetch_all($cursor)
|
||||
{
|
||||
return pg_fetch_all($cursor);
|
||||
}
|
||||
|
||||
// METHOD: _db_affected_ros
|
||||
// PARAMS: cursor
|
||||
// RETURN: number for rows
|
||||
// DESC : wrapper for pg_affected_rows
|
||||
public function _db_affected_rows($cursor)
|
||||
{
|
||||
return pg_affected_rows($cursor);
|
||||
}
|
||||
|
||||
// METHOD: _db_insert_id
|
||||
// PARAMS: query, primary key name
|
||||
// RETURN: last insert primary key
|
||||
// DESC : reads the last inserted primary key for the query
|
||||
// if ther is no pk_name tries to auto built it from the table name
|
||||
// this only works if db schema is after "no plural names. and pk name is table name + _id
|
||||
// detects schema prefix in table name
|
||||
public function _db_insert_id($query, $pk_name)
|
||||
{
|
||||
// only if an insert has been done
|
||||
if (preg_match("/^insert /i", $query)) {
|
||||
$schema = '';
|
||||
// get table name from insert
|
||||
$array = explode(' ', $query);
|
||||
$_table = $array[2];
|
||||
// if there is a dot inside, we need to split
|
||||
if (strstr($_table, '.')) {
|
||||
list($schema, $table) = explode('.', $_table);
|
||||
} else {
|
||||
$table = $_table;
|
||||
}
|
||||
// no PK name given at all
|
||||
if (!$pk_name) {
|
||||
// if name is plurar, make it singular
|
||||
// if (preg_match("/.*s$/i", $table))
|
||||
// $table = substr($table, 0, -1);
|
||||
// set pk_name to "id"
|
||||
$pk_name = $table."_id";
|
||||
}
|
||||
$seq = (($schema) ? $schema.'.' : '').$table."_".$pk_name."_seq";
|
||||
$q = "SELECT CURRVAL('$seq') AS insert_id";
|
||||
// $this->currval_query = $q;
|
||||
// I have to do manually or I overwrite the original insert internal vars ...
|
||||
if ($q = $this->_db_query($q)) {
|
||||
list($id) = $this->_db_fetch_array($q);
|
||||
} else {
|
||||
$id = array(-1, $q);
|
||||
}
|
||||
return $id;
|
||||
}
|
||||
}
|
||||
|
||||
// METHOD: _db_primary_key
|
||||
// PARAMS: table and optional schema
|
||||
// RETURN: primary key name OR false if not possible
|
||||
// DESC : queries database for the primary key name to this table in the selected schema
|
||||
public function _db_primary_key($table, $schema = '')
|
||||
{
|
||||
if ($table) {
|
||||
// check if schema set is different from schema given, only needed if schema is not empty
|
||||
$table_prefix = '';
|
||||
if ($schema) {
|
||||
$q = "SHOW search_path";
|
||||
$cursor = $this->_db_query($q);
|
||||
$search_path = $this->_db_fetch_array($cursor)['search_path'];
|
||||
if ($search_path != $schema) {
|
||||
$table_prefix = $schema.'.';
|
||||
}
|
||||
}
|
||||
// read from table the PK name
|
||||
// faster primary key get
|
||||
$q = "SELECT pg_attribute.attname AS column_name, format_type(pg_attribute.atttypid, pg_attribute.atttypmod) AS type ";
|
||||
$q .= "FROM pg_index, pg_class, pg_attribute ";
|
||||
if ($schema) {
|
||||
$q .= ", pg_namespace ";
|
||||
}
|
||||
$q .= "WHERE ";
|
||||
// regclass translates the OID to the name
|
||||
$q .= "pg_class.oid = '".$table_prefix.$table."'::regclass AND ";
|
||||
$q .= "indrelid = pg_class.oid AND ";
|
||||
if ($schema) {
|
||||
$q .= "nspname = '".$schema."' AND ";
|
||||
$q .= "pg_class.relnamespace = pg_namespace.oid AND ";
|
||||
}
|
||||
$q .= "pg_attribute.attrelid = pg_class.oid AND ";
|
||||
$q .= "pg_attribute.attnum = any(pg_index.indkey) ";
|
||||
$q .= "AND indisprimary";
|
||||
$cursor = $this->_db_query($q);
|
||||
if ($cursor) {
|
||||
return $this->_db_fetch_array($cursor)['column_name'];
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// METHOD: _db_connect
|
||||
// PARAMS: host name, user name, password, database name, optional port (defaults to default postgres port), optional ssl (default allow)
|
||||
// RETURN: database handler
|
||||
// DESC : wrapper for pg_connect, writes out failure to screen if error occurs (hidden var)
|
||||
public function _db_connect($db_host, $db_user, $db_pass, $db_name, $db_port = 5432, $db_ssl = 'allow')
|
||||
{
|
||||
// to avoid empty db_port
|
||||
if (!$db_port) {
|
||||
$db_port = 5432;
|
||||
}
|
||||
$this->dbh = pg_connect("host=".$db_host." port=".$db_port." user=".$db_user." password=".$db_pass." dbname=".$db_name." sslmode=".$db_ssl);
|
||||
if (!$this->dbh) {
|
||||
die("<!-- Can't connect [host=".$db_host." port=".$db_port." user=".$db_user." password=XXXX dbname=".$db_name." sslmode=".$db_ssl."] //-->");
|
||||
}
|
||||
return $this->dbh;
|
||||
}
|
||||
|
||||
// METHOD: _db_print_error
|
||||
// PARAMS: database handler, cursor
|
||||
// RETURN: error string (HTML)
|
||||
// DESC : reads the last error for this cursor
|
||||
public function _db_print_error($cursor = '')
|
||||
{
|
||||
// run the query again for the error result here
|
||||
if (!$cursor && $this->last_error_query) {
|
||||
pg_send_query($this->dbh, $this->last_error_query);
|
||||
$this->last_error_query = '';
|
||||
$cursor = pg_get_result($this->dbh);
|
||||
}
|
||||
if (pg_result_error($cursor)) {
|
||||
return "<span style=\"color: red;\"><b>-PostgreSQL-Error-></b> ".pg_result_error($cursor)."</span><br>";
|
||||
}
|
||||
}
|
||||
|
||||
// METHOD: _db_meta_data
|
||||
// PARAMS: table name
|
||||
// RETURN: array with table data
|
||||
// DESC : wrapper for pg_emta_data
|
||||
public function _db_meta_data($table)
|
||||
{
|
||||
return pg_meta_data($this->dbh, $table);
|
||||
}
|
||||
|
||||
// METHOD: _db_escape_string
|
||||
// PARAMS: string
|
||||
// RETURN: escaped string for postgres
|
||||
// DESC : wrapper for pg_escape_string
|
||||
public function _db_escape_string($string)
|
||||
{
|
||||
return pg_escape_string($this->dbh, $string);
|
||||
}
|
||||
|
||||
// METHOD: _db_escape_bytea
|
||||
// PARAMS: string
|
||||
// RETURN: escape bytes for postgres
|
||||
// DESC : wrapper for pg_escape_bytea
|
||||
public function _db_escape_bytea($bytea)
|
||||
{
|
||||
return pg_escape_bytea($this->dbh, $bytea);
|
||||
}
|
||||
|
||||
// METHOD: _db_connection_busy
|
||||
// PARAMS: none
|
||||
// RETURN: true/false for busy connection
|
||||
// DESC : wrapper for pg_connection_busy
|
||||
public function _db_connection_busy()
|
||||
{
|
||||
return pg_connection_busy($this->dbh);
|
||||
}
|
||||
|
||||
// METHOD: _db_version
|
||||
// PARAMS: none
|
||||
// RETURN: databse version
|
||||
// DESC : wrapper for pg_version
|
||||
public function _db_version()
|
||||
{
|
||||
// array has client, protocol, server
|
||||
// we just need the server
|
||||
$v = pg_version($this->dbh);
|
||||
return $v['server'];
|
||||
}
|
||||
|
||||
// METHOD: _db_array_parse
|
||||
// PARAMS: input text, output array [needed]
|
||||
// [internal] limit: are we at the end of the parse
|
||||
// [internal] offset: shift for {}
|
||||
// RETURN: array with the elements
|
||||
// DESC : postgresql array to php array
|
||||
public function _db_array_parse($text, &$output, $limit = false, $offset = 1)
|
||||
{
|
||||
if (false === $limit) {
|
||||
$limit = strlen($text) - 1;
|
||||
$output = array();
|
||||
}
|
||||
if ('{}' != $text) {
|
||||
do {
|
||||
if ('{' != $text{$offset}) {
|
||||
preg_match("/(\\{?\"([^\"\\\\]|\\\\.)*\"|[^,{}]+)+([,}]+)/", $text, $match, 0, $offset);
|
||||
$offset += strlen($match[0]);
|
||||
$output[] = ('"' != $match[1]{0} ? $match[1] : stripcslashes(substr($match[1], 1, -1)));
|
||||
if ('},' == $match[3]) {
|
||||
return $offset;
|
||||
}
|
||||
} else {
|
||||
$offset = pg_array_parse($text, $output[], $limit, $offset + 1);
|
||||
}
|
||||
} while ($limit > $offset);
|
||||
}
|
||||
return $output;
|
||||
}
|
||||
}
|
||||
259
www/lib/CoreLibs/DB/SQL/TRAIT_db_pgsql.inc
Normal file
259
www/lib/CoreLibs/DB/SQL/TRAIT_db_pgsql.inc
Normal file
@@ -0,0 +1,259 @@
|
||||
<?
|
||||
/*********************************************************************
|
||||
* AUTHOR: Clemens "Gullevek" Schwaighofer (www.gullevek.org)
|
||||
* CREATED: 2003/04/09
|
||||
* SHORT DESCRIPTION:
|
||||
* pgsq; wrapper calls
|
||||
* HISTORY:
|
||||
* 2008/04/16 (cs) wrapper for pg escape string
|
||||
* 2007/01/11 (cs) add prepare/execute for postgres
|
||||
* 2006/09/12 (cs) in case db_query retuns false, save the query and run the query through the send/get procedure to get correct error data from the db
|
||||
* 2006/06/26 (cs) added port for db connection
|
||||
* 2006/04/03 (cs) added meta data for table
|
||||
* 2005/07/25 (cs) removed the plural s remove, not needed and not 100% working
|
||||
* 2005/07/07 (cs) the default it is table_name _ id
|
||||
* 2005/01/19 (cs) changed the pgsql connect, so it dies if it can't connect to the DB
|
||||
* 2004/09/30 (cs) layout cleanup
|
||||
* /
|
||||
|
||||
/* collection of PostgreSQL wrappers
|
||||
* REQUIRES 5.4 PHP!!! (should do check for this)
|
||||
*
|
||||
* pg_prepare
|
||||
* pg_execute
|
||||
* pg_num_rows
|
||||
* pg_num_fields
|
||||
* pg_field_name
|
||||
* pg_affected_rows (*)
|
||||
* pg_fetch_array
|
||||
* pg_query
|
||||
* pg_close
|
||||
* pg_connect (*)
|
||||
* pg_meta_data
|
||||
* pg_escape_string
|
||||
*
|
||||
*/
|
||||
|
||||
trait db_pgsql
|
||||
{
|
||||
private $last_error_query;
|
||||
private $currval_query;
|
||||
|
||||
// METHOD: _db_query
|
||||
// PARAMS: query, database handler
|
||||
// RETURN: query result
|
||||
// DESC : wrapper for gp_query, catches error and stores it in class var
|
||||
private function _db_query($query, $dbh)
|
||||
{
|
||||
// read out the query status and save the query if needed
|
||||
$result = @pg_query($dbh, $query);
|
||||
if (!$result) {
|
||||
$this->last_error_query = $query;
|
||||
}
|
||||
return $result;
|
||||
}
|
||||
|
||||
// METHOD: _db_close
|
||||
// PARAMS: database handler
|
||||
// RETURN: none
|
||||
// DESC : wrapper for pg_close
|
||||
private function _db_close($dbh)
|
||||
{
|
||||
pg_close($dbh);
|
||||
}
|
||||
|
||||
// METHOD: _db_prepare
|
||||
// PARAMS: database handler, prepare name, query
|
||||
// RETURN: prepared statement handler
|
||||
// DESC : wrapper for pg_prepare
|
||||
private function _db_prepare($dbh, $name, $query)
|
||||
{
|
||||
return @pg_prepare($dbh, $name, $query);
|
||||
}
|
||||
|
||||
// METHOD: _db_execute
|
||||
// PARAMS: database handler, prepare name, data for query
|
||||
// RETURN: returns status
|
||||
// DESC : wrapper for pg_execute for running a prepared statement
|
||||
private function _db_execute($dbh, $name, $data)
|
||||
{
|
||||
return @pg_execute($dbh, $name, $data);
|
||||
}
|
||||
|
||||
// METHOD: _db_num_rows
|
||||
// PARAMS: cursor
|
||||
// RETURN: rows
|
||||
// DESC : wrapper for pg_num_rows
|
||||
private function _db_num_rows($cursor)
|
||||
{
|
||||
return pg_num_rows($cursor);
|
||||
}
|
||||
|
||||
// METHOD: _db_num_fields
|
||||
// PARAMS: cursor
|
||||
// RETURN: number for fields in query
|
||||
// DESC : wrapper for pg_num_fields
|
||||
private function _db_num_fields($cursor)
|
||||
{
|
||||
return pg_num_fields($cursor);
|
||||
}
|
||||
|
||||
// METHOD: _db_field_name
|
||||
// PARAMS: cursor, field position
|
||||
// RETURN: name of field
|
||||
// DESC : wrapper for pg_field_name
|
||||
private function _db_field_name($cursor, $i)
|
||||
{
|
||||
return pg_field_name($cursor, $i);
|
||||
}
|
||||
|
||||
// METHOD: _db_fetch_array
|
||||
// PARAMS: cursor
|
||||
// RETURN: row
|
||||
// DESC : wrapper for pg_fetch_array
|
||||
private function _db_fetch_array($cursor)
|
||||
{
|
||||
return pg_fetch_array($cursor);
|
||||
}
|
||||
|
||||
// METHOD: _db_affected_ros
|
||||
// PARAMS: database handler, cursor
|
||||
// RETURN: number for rows
|
||||
// DESC : wrapper for pg_affected_rows
|
||||
private function _db_affected_rows($dbh, $cursor)
|
||||
{
|
||||
return pg_affected_rows($cursor);
|
||||
}
|
||||
|
||||
// METHOD: _db_insert_id
|
||||
// PARAMS: database handler, query, primary key name
|
||||
// RETURN: last insert primary key
|
||||
// DESC : reads the last inserted primary key for the query
|
||||
// if ther is no pk_name tries to auto built it from the table name
|
||||
// this only works if db schema is after "no plural names. and pk name is table name + _id
|
||||
// detects schema prefix in table name
|
||||
private function _db_insert_id($dbh, $query, $pk_name)
|
||||
{
|
||||
// only if an insert has been done
|
||||
if (preg_match("/^insert /i", $query)) {
|
||||
// get table name from insert
|
||||
$array = explode(' ', $query);
|
||||
$_table = $array[2];
|
||||
// if there is a dot inside, we need to split
|
||||
if (strstr($_table, '.')) {
|
||||
list ($schema, $table) = explode('.', $_table);
|
||||
} else {
|
||||
$table = $_table;
|
||||
}
|
||||
// no PK name given at all
|
||||
if (!$pk_name) {
|
||||
// if name is plurar, make it singular
|
||||
// if (preg_match("/.*s$/i", $table))
|
||||
// $table = substr($table, 0, -1);
|
||||
// set pk_name to "id"
|
||||
$pk_name = $table."_id";
|
||||
}
|
||||
$seq = (($schema) ? $schema.'.' : '').$table."_".$pk_name."_seq";
|
||||
$q = "SELECT CURRVAL('$seq') AS insert_id";
|
||||
$this->currval_query = $q;
|
||||
//echo "Q: $q<Br>";
|
||||
// I have to do manually or I overwrite the original insert internal vars ...
|
||||
if ($q = @pg_query($dbh, $q)) {
|
||||
list($id) = pg_fetch_array($q);
|
||||
} else {
|
||||
$id = array(-1, $q);
|
||||
}
|
||||
return $id;
|
||||
}
|
||||
}
|
||||
|
||||
// METHOD: _db_connect
|
||||
// PARAMS: host name, user name, password, database name, optional port (defaults to default postgres port), optional ssl (default allow)
|
||||
// RETURN: database handler
|
||||
// DESC : wrapper for pg_connect, writes out failure to screen if error occurs (hidden var)
|
||||
private function _db_connect($db_host, $db_user, $db_pass, $db_name, $db_port = 5432, $db_ssl = 'allow')
|
||||
{
|
||||
// to avoid empty db_port
|
||||
if (!$db_port) {
|
||||
$db_port = 5432;
|
||||
}
|
||||
$this->dbh = @pg_connect("host=".$db_host." port=".$db_port." user=".$db_user." password=".$db_pass." dbname=".$db_name." sslmode=".$db_ssl);
|
||||
if (!$this->dbh) {
|
||||
die("<!-- Can't connect [host=".$db_host." port=".$db_port." user=".$db_user." password=XXXX dbname=".$db_name." sslmode=".$db_ssl."] //-->");
|
||||
}
|
||||
return $this->dbh;
|
||||
}
|
||||
|
||||
// METHOD: _db_print_error
|
||||
// PARAMS: database handler, cursor
|
||||
// RETURN: error string (HTML)
|
||||
// DESC : reads the last error for this cursor
|
||||
private function _db_print_error($dbh, $cursor = '')
|
||||
{
|
||||
// run the query again for the error result here
|
||||
if (!$cursor && $this->last_error_query) {
|
||||
pg_send_query($dbh, $this->last_error_query);
|
||||
$this->last_error_query = "";
|
||||
$cursor = pg_get_result($dbh);
|
||||
}
|
||||
if (pg_result_error($cursor)) {
|
||||
return "<span style=\"color: red;\"><b>-PostgreSQL-Error-></b> ".pg_result_error($cursor)."</span><br>";
|
||||
}
|
||||
}
|
||||
|
||||
// METHOD: _db_meta_data
|
||||
// PARAMS: database handler, table name
|
||||
// RETURN: array with table data
|
||||
// DESC : wrapper for pg_emta_data
|
||||
private function _db_meta_data($dbh, $table)
|
||||
{
|
||||
return @pg_meta_data($dbh, $table);
|
||||
}
|
||||
|
||||
// METHOD: _db_escape_string
|
||||
// PARAMS: string
|
||||
// RETURN: escaped string for postgres
|
||||
// DESC : wrapper for pg_escape_string
|
||||
private function _db_escape_string($string)
|
||||
{
|
||||
return pg_escape_string($this->dbh, $string);
|
||||
}
|
||||
|
||||
// METHOD: _db_escape_bytea
|
||||
// PARAMS: string
|
||||
// RETURN: escape bytes for postgres
|
||||
// DESC : wrapper for pg_escape_bytea
|
||||
private function _db_escape_bytea($bytea)
|
||||
{
|
||||
return pg_escape_bytea($this->dbh, $bytea);
|
||||
}
|
||||
|
||||
// METHOD: _db_array_parse
|
||||
// PARAMS: input text, output array [needed]
|
||||
// [internal] limit: are we at the end of the parse
|
||||
// [internal] offset: shift for {}
|
||||
// RETURN: array with the elements
|
||||
// DESC : postgresql array to php array
|
||||
private function _db_array_parse($text, &$output, $limit = false, $offset = 1)
|
||||
{
|
||||
if (false === $limit) {
|
||||
$limit = strlen($text) - 1;
|
||||
$output = array();
|
||||
}
|
||||
if ('{}' != $text) {
|
||||
do {
|
||||
if ('{' != $text{$offset}) {
|
||||
preg_match("/(\\{?\"([^\"\\\\]|\\\\.)*\"|[^,{}]+)+([,}]+)/", $text, $match, 0, $offset);
|
||||
$offset += strlen($match[0]);
|
||||
$output[] = ('"' != $match[1]{0} ? $match[1] : stripcslashes(substr($match[1], 1, -1)));
|
||||
if ('},' == $match[3]) {
|
||||
return $offset;
|
||||
}
|
||||
} else {
|
||||
$offset = pg_array_parse($text, $output[], $limit, $offset + 1);
|
||||
}
|
||||
} while ($limit > $offset);
|
||||
}
|
||||
return $output;
|
||||
}
|
||||
}
|
||||
375
www/lib/CoreLibs/DB/SQL/db_pgsql_pdo.inc
Normal file
375
www/lib/CoreLibs/DB/SQL/db_pgsql_pdo.inc
Normal file
@@ -0,0 +1,375 @@
|
||||
<?
|
||||
/*********************************************************************
|
||||
* AUTHOR: Clemens "Gullevek" Schwaighofer (www.gullevek.org)
|
||||
* CREATED: 2014/12/3
|
||||
* SHORT DESCRIPTION:
|
||||
* pgsql pdo wrapper calls
|
||||
* HISTORY:
|
||||
* /
|
||||
|
||||
/* collection of PostgreSQL wrappers
|
||||
* REQUIRES 5.x PHP with compiled pdo pgsql (--with-pdo-pgsql)
|
||||
*
|
||||
*/
|
||||
|
||||
class db_pgsql
|
||||
{
|
||||
private $last_error_query;
|
||||
private $dbh;
|
||||
private $cursor = array();
|
||||
|
||||
// METHOD: __construct
|
||||
// PARAMS: none
|
||||
// RETURN: none
|
||||
// DESC : class constructor
|
||||
public function __construct()
|
||||
{
|
||||
}
|
||||
|
||||
public function _db_last_error_query()
|
||||
{
|
||||
if ($this->last_error_query) {
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// METHOD: _db_query
|
||||
// PARAMS: query
|
||||
// RETURN: cursor
|
||||
// DESC : was wrapper for pg_query, now it runs pepare and execute in one set. uses the query md5 as the cursor name
|
||||
public function _db_query($query)
|
||||
{
|
||||
$this->last_error_query = '';
|
||||
/* // read out the query status and save the query if needed
|
||||
$result = @pg_query($this->dbh, $query);
|
||||
if (!$result)
|
||||
$this->last_error_query = $query; */
|
||||
$cursor = $this->_db_prepare(md5($query), $query);
|
||||
$result = $this->_db_execute(md5($query), array ());
|
||||
if (!$result) {
|
||||
$this->last_error_query = $query;
|
||||
}
|
||||
return $cursor;
|
||||
}
|
||||
|
||||
// METHOD: _db_query_result
|
||||
// PARAMS: query
|
||||
// RETURN: result from query
|
||||
// DESC : only valid for the pdo version here. use with care
|
||||
public function _db_query_result($query)
|
||||
{
|
||||
return $this->dbh->query($query);
|
||||
}
|
||||
|
||||
// METHOD: _db_send_query
|
||||
// PARAMS: query
|
||||
// RETURN: true/false if query was sent successful
|
||||
// DESC : sends an async query to the server
|
||||
public function _db_send_query($query)
|
||||
{
|
||||
// return @pg_send_query($this->dbh, $query);
|
||||
}
|
||||
|
||||
// METHOD: _db_get_result
|
||||
// PARAMS: none
|
||||
// RETURN: resource handler
|
||||
// DESC : wrapper for pg_get_result
|
||||
public function _db_get_result()
|
||||
{
|
||||
$this->last_error_query = '';
|
||||
/* $result = pg_get_result($this->dbh);
|
||||
if ($error = pg_result_error($result)) {
|
||||
$this->last_error_query = $error;
|
||||
}*/
|
||||
return $result;
|
||||
}
|
||||
|
||||
// METHOD: _db_close
|
||||
// PARAMS: none
|
||||
// RETURN: none
|
||||
// DESC : wrapper for pg_close
|
||||
public function _db_close()
|
||||
{
|
||||
if (is_array($this->cursor)) {
|
||||
foreach ($this->cursor as $key => $data) {
|
||||
$this->cursor[$key]->closeCursor;
|
||||
$this->cursor[$key] = null;
|
||||
}
|
||||
}
|
||||
$this->dbh = null;
|
||||
}
|
||||
|
||||
// METHOD: _db_prepare
|
||||
// PARAMS: prepare name, query
|
||||
// RETURN: prepared statement handler
|
||||
// DESC : wrapper for pg_prepare
|
||||
public function _db_prepare($name, $query)
|
||||
{
|
||||
// return @pg_prepare($this->dbh, $name, $query);
|
||||
$this->cursor[$name] = $this->dbh->prepare($query);
|
||||
return $this->cursor[$name];
|
||||
}
|
||||
|
||||
// METHOD: _db_execute
|
||||
// PARAMS: prepare name, data for query
|
||||
// RETURN: returns status
|
||||
// DESC : wrapper for pg_execute for running a prepared statement
|
||||
public function _db_execute($name, $data)
|
||||
{
|
||||
// return @pg_execute($this->dbh, $name, $data);
|
||||
return $this->cursor[$name]->execute($data);
|
||||
}
|
||||
|
||||
// METHOD: _db_num_rows
|
||||
// PARAMS: cursor
|
||||
// RETURN: rows
|
||||
// DESC : wrapper for pg_num_rows
|
||||
public function _db_num_rows($cursor)
|
||||
{
|
||||
// return pg_num_rows($cursor);
|
||||
return $cusor->rowCount();
|
||||
}
|
||||
|
||||
// METHOD: _db_num_fields
|
||||
// PARAMS: cursor
|
||||
// RETURN: number for fields in query
|
||||
// DESC : wrapper for pg_num_fields
|
||||
public function _db_num_fields($cursor)
|
||||
{
|
||||
// return pg_num_fields($cursor);
|
||||
return $cursor->columnCount();
|
||||
}
|
||||
|
||||
// METHOD: _db_field_name
|
||||
// PARAMS: cursor, field position
|
||||
// RETURN: name of field
|
||||
// DESC : wrapper for pg_field_name
|
||||
public function _db_field_name($cursor, $i)
|
||||
{
|
||||
// return pg_field_name($cursor, $i);
|
||||
}
|
||||
|
||||
// METHOD: _db_fetch_array
|
||||
// PARAMS: cursor
|
||||
// RETURN: row
|
||||
// DESC : wrapper for pg_fetch_array
|
||||
public function _db_fetch_array($cursor)
|
||||
{
|
||||
// return pg_fetch_array($cursor);
|
||||
return $cursor->fetch();
|
||||
}
|
||||
|
||||
// METHOD: _db_affected_ros
|
||||
// PARAMS: cursor
|
||||
// RETURN: number for rows
|
||||
// DESC : wrapper for pg_affected_rows
|
||||
public function _db_affected_rows($cursor)
|
||||
{
|
||||
// return pg_affected_rows($cursor);
|
||||
return $cusor->rowCount();
|
||||
}
|
||||
|
||||
// METHOD: _db_insert_id
|
||||
// PARAMS: query, primary key name
|
||||
// RETURN: last insert primary key
|
||||
// DESC : reads the last inserted primary key for the query
|
||||
// if ther is no pk_name tries to auto built it from the table name
|
||||
// this only works if db schema is after "no plural names. and pk name is table name + _id
|
||||
// detects schema prefix in table name
|
||||
public function _db_insert_id($query, $pk_name)
|
||||
{
|
||||
// only if an insert has been done
|
||||
if (preg_match("/^insert /i", $query)) {
|
||||
$schema = '';
|
||||
// get table name from insert
|
||||
$array = explode(' ', $query);
|
||||
$_table = $array[2];
|
||||
// if there is a dot inside, we need to split
|
||||
if (strstr($_table, '.')) {
|
||||
list($schema, $table) = explode('.', $_table);
|
||||
} else {
|
||||
$table = $_table;
|
||||
}
|
||||
// no PK name given at all
|
||||
if (!$pk_name) {
|
||||
// if name is plural, make it singular
|
||||
// if (preg_match("/.*s$/i", $table))
|
||||
// $table = substr($table, 0, -1);
|
||||
// set pk_name to "id"
|
||||
$pk_name = $table."_id";
|
||||
}
|
||||
$seq = (($schema) ? $schema.'.' : '').$table."_".$pk_name."_seq";
|
||||
$q = "SELECT CURRVAL('$seq') AS insert_id";
|
||||
// I have to do manually or I overwrite the original insert internal vars ...
|
||||
$row = $this->_db_query_result($q);
|
||||
if ($row['insert_id']) {
|
||||
$id = $row['insert_id'];
|
||||
} else {
|
||||
$id = array(-1, $q);
|
||||
}
|
||||
return $id;
|
||||
}
|
||||
}
|
||||
|
||||
// METHOD: _db_primary_key
|
||||
// PARAMS: table and optional schema
|
||||
// RETURN: primary key name OR false if not possible
|
||||
// DESC : queries database for the primary key name to this table in the selected schema
|
||||
public function _db_primary_key($table, $schema = '')
|
||||
{
|
||||
if ($table) {
|
||||
// check if schema set is different from schema given, only needed if schema is not empty
|
||||
$table_prefix = '';
|
||||
if ($schema) {
|
||||
$q = "SHOW search_path";
|
||||
// $cursor = $this->_db_query($q);
|
||||
// $search_path = $this->_db_fetch_array($cursor)['search_path'];
|
||||
$search_path = $this->_db_query_result($q)['search_path'];
|
||||
if ($search_path != $schema) {
|
||||
$table_prefix = $schema.'.';
|
||||
}
|
||||
}
|
||||
// read from table the PK name
|
||||
// faster primary key get
|
||||
$q = "SELECT pg_attribute.attname AS column_name, format_type(pg_attribute.atttypid, pg_attribute.atttypmod) AS type ";
|
||||
$q .= "FROM pg_index, pg_class, pg_attribute ";
|
||||
if ($schema) {
|
||||
$q .= ", pg_namespace ";
|
||||
}
|
||||
$q .= "WHERE ";
|
||||
// regclass translates the OID to the name
|
||||
$q .= "pg_class.oid = '".$table_prefix.$table."'::regclass AND ";
|
||||
$q .= "indrelid = pg_class.oid AND ";
|
||||
if ($schema) {
|
||||
$q .= "nspname = '".$schema."' AND ";
|
||||
$q .= "pg_class.relnamespace = pg_namespace.oid AND ";
|
||||
}
|
||||
$q .= "pg_attribute.attrelid = pg_class.oid AND ";
|
||||
$q .= "pg_attribute.attnum = any(pg_index.indkey) ";
|
||||
$q .= "AND indisprimary";
|
||||
$row = $this->_db_query_result($q);
|
||||
if ($row === false) {
|
||||
return false;
|
||||
} else {
|
||||
return $row['column_name'];
|
||||
}
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// METHOD: _db_connect
|
||||
// PARAMS: host name, user name, password, database name, optional port (defaults to default postgres port), optional ssl (default allow)
|
||||
// RETURN: database handler
|
||||
// DESC : wrapper for pg_connect, writes out failure to screen if error occurs (hidden var)
|
||||
public function _db_connect($db_host, $db_user, $db_pass, $db_name, $db_port = 5432, $db_ssl = 'allow')
|
||||
{
|
||||
// to avoid empty db_port
|
||||
if (!$db_port) {
|
||||
$db_port = 5432;
|
||||
}
|
||||
try {
|
||||
$this->dbh = new PDO('pgsql:host='.$db_host.';dbname='.$db_name.';port='.$db_port.';sslmode='.$db_ssl, $db_user, $db_pass);
|
||||
} catch (PDOException $e) {
|
||||
print "Error!: ".$e->getMessage()."\n";
|
||||
die("<!-- Can't connect [host=".$db_host." port=".$db_port." user=".$db_user." password=XXXX dbname=".$db_name." sslmode=".$db_ssl."]: ".$e->getMEssage()."//-->");
|
||||
}
|
||||
return $this->dbh;
|
||||
}
|
||||
|
||||
// METHOD: _db_print_error
|
||||
// PARAMS: database handler, cursor
|
||||
// RETURN: error string (HTML)
|
||||
// DESC : reads the last error for this cursor
|
||||
public function _db_print_error($cursor = '')
|
||||
{
|
||||
/* // run the query again for the error result here
|
||||
if (!$cursor && $this->last_error_query)
|
||||
{
|
||||
pg_send_query($this->dbh, $this->last_error_query);
|
||||
$this->last_error_query = '';
|
||||
$cursor = pg_get_result($this->dbh);
|
||||
}
|
||||
if (pg_result_error($cursor))
|
||||
return "<span style=\"color: red;\"><b>-PostgreSQL-Error-></b> ".pg_result_error($cursor)."</span><br>"; */
|
||||
}
|
||||
|
||||
// METHOD: _db_meta_data
|
||||
// PARAMS: table name
|
||||
// RETURN: array with table data
|
||||
// DESC : wrapper for pg_emta_data
|
||||
public function _db_meta_data($table)
|
||||
{
|
||||
// return @pg_meta_data($this->dbh, $table);
|
||||
}
|
||||
|
||||
// METHOD: _db_escape_string
|
||||
// PARAMS: string
|
||||
// RETURN: escaped string for postgres
|
||||
// DESC : wrapper for pg_escape_string
|
||||
public function _db_escape_string($string)
|
||||
{
|
||||
// return pg_escape_string($this->dbh, $string);
|
||||
}
|
||||
|
||||
// METHOD: _db_escape_bytea
|
||||
// PARAMS: string
|
||||
// RETURN: escape bytes for postgres
|
||||
// DESC : wrapper for pg_escape_bytea
|
||||
public function _db_escape_bytea($bytea)
|
||||
{
|
||||
// return pg_escape_bytea($this->dbh, $bytea);
|
||||
}
|
||||
|
||||
// METHOD: _db_connection_busy
|
||||
// PARAMS: none
|
||||
// RETURN: true/false for busy connection
|
||||
// DESC : wrapper for pg_connection_busy
|
||||
public function _db_connection_busy()
|
||||
{
|
||||
// return pg_connection_busy($this->dbh);
|
||||
}
|
||||
|
||||
// METHOD: _db_version
|
||||
// PARAMS: none
|
||||
// RETURN: databse version
|
||||
// DESC : wrapper for pg_version
|
||||
public function _db_version()
|
||||
{
|
||||
// array has client, protocol, server
|
||||
// we just need the server
|
||||
$v = pg_version($this->dbh);
|
||||
return $v['server'];
|
||||
}
|
||||
|
||||
// METHOD: _db_array_parse
|
||||
// PARAMS: input text, output array [needed]
|
||||
// [internal] limit: are we at the end of the parse
|
||||
// [internal] offset: shift for {}
|
||||
// RETURN: array with the elements
|
||||
// DESC : postgresql array to php array
|
||||
public function _db_array_parse($text, &$output, $limit = false, $offset = 1)
|
||||
{
|
||||
if (false === $limit) {
|
||||
$limit = strlen($text) - 1;
|
||||
$output = array();
|
||||
}
|
||||
if ('{}' != $text) {
|
||||
do {
|
||||
if ('{' != $text{$offset}) {
|
||||
preg_match("/(\\{?\"([^\"\\\\]|\\\\.)*\"|[^,{}]+)+([,}]+)/", $text, $match, 0, $offset);
|
||||
$offset += strlen($match[0]);
|
||||
$output[] = ('"' != $match[1]{0} ? $match[1] : stripcslashes(substr($match[1], 1, -1)));
|
||||
if ('},' == $match[3]) {
|
||||
return $offset;
|
||||
}
|
||||
} else {
|
||||
$offset = pg_array_parse($text, $output[], $limit, $offset + 1);
|
||||
}
|
||||
} while ($limit > $offset);
|
||||
}
|
||||
return $output;
|
||||
}
|
||||
}
|
||||
71
www/lib/CoreLibs/Language/Core/FileReader.inc
Executable file
71
www/lib/CoreLibs/Language/Core/FileReader.inc
Executable file
@@ -0,0 +1,71 @@
|
||||
<?php
|
||||
|
||||
namespace CoreLibs\Language\Core;
|
||||
|
||||
class FileReader
|
||||
{
|
||||
public $fr_pos;
|
||||
public $fr_fd;
|
||||
public $fr_length;
|
||||
|
||||
public function __construct($filename)
|
||||
{
|
||||
if (file_exists($filename)) {
|
||||
$this->fr_length = filesize($filename);
|
||||
$this->fr_pos = 0;
|
||||
$this->fr_fd = fopen($filename, 'rb');
|
||||
if (!$this->fr_fd) {
|
||||
$this->error = 3; // Cannot read file, probably permissions
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
$this->error = 2; // File doesn't exist
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public function read($bytes)
|
||||
{
|
||||
if ($bytes) {
|
||||
fseek($this->fr_fd, $this->fr_pos);
|
||||
|
||||
// PHP 5.1.1 does not read more than 8192 bytes in one fread()
|
||||
// the discussions at PHP Bugs suggest it's the intended behaviour
|
||||
$data = '';
|
||||
while ($bytes > 0) {
|
||||
$chunk = fread($this->fr_fd, $bytes);
|
||||
$data .= $chunk;
|
||||
$bytes -= strlen($chunk);
|
||||
}
|
||||
$this->fr_pos = ftell($this->fr_fd);
|
||||
|
||||
return $data;
|
||||
} else {
|
||||
return '';
|
||||
}
|
||||
}
|
||||
|
||||
public function seekto($pos)
|
||||
{
|
||||
fseek($this->fr_fd, $pos);
|
||||
$this->fr_pos = ftell($this->fr_fd);
|
||||
return $this->fr_pos;
|
||||
}
|
||||
|
||||
public function currentpos()
|
||||
{
|
||||
return $this->fr_pos;
|
||||
}
|
||||
|
||||
public function length()
|
||||
{
|
||||
return $this->fr_length;
|
||||
}
|
||||
|
||||
public function close()
|
||||
{
|
||||
fclose($this->fr_fd);
|
||||
}
|
||||
}
|
||||
|
||||
# __END__
|
||||
460
www/lib/CoreLibs/Language/Core/GetTextReader.inc
Executable file
460
www/lib/CoreLibs/Language/Core/GetTextReader.inc
Executable file
@@ -0,0 +1,460 @@
|
||||
<?php
|
||||
/*
|
||||
Copyright (c) 2003, 2009 Danilo Segan <danilo@kvota.net>.
|
||||
Copyright (c) 2005 Nico Kaiser <nico@siriux.net>
|
||||
|
||||
This file is part of PHP-gettext.
|
||||
|
||||
PHP-gettext is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
PHP-gettext is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with PHP-gettext; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
namespace CoreLibs\Language\Core;
|
||||
|
||||
/**
|
||||
* Provides a simple gettext replacement that works independently from
|
||||
* the system's gettext abilities.
|
||||
* It can read MO files and use them for translating strings.
|
||||
* The files are passed to gettext_reader as a Stream (see streams.php)
|
||||
*
|
||||
* This version has the ability to cache all strings and translations to
|
||||
* speed up the string lookup.
|
||||
* While the cache is enabled by default, it can be switched off with the
|
||||
* second parameter in the constructor (e.g. whenusing very large MO files
|
||||
* that you don't want to keep in memory)
|
||||
*/
|
||||
class GetTextReader
|
||||
{
|
||||
// public:
|
||||
public $error = 0; // public variable that holds error code (0 if no error)
|
||||
|
||||
//private:
|
||||
private $BYTEORDER = 0; // 0: low endian, 1: big endian
|
||||
private $STREAM = null;
|
||||
private $short_circuit = false;
|
||||
private $enable_cache = false;
|
||||
private $originals = null; // offset of original table
|
||||
private $translations = null; // offset of translation table
|
||||
private $pluralheader = null; // cache header field for plural forms
|
||||
private $total = 0; // total string count
|
||||
private $table_originals = null; // table for original strings (offsets)
|
||||
private $table_translations = null; // table for translated strings (offsets)
|
||||
private $cache_translations = null; // original -> translation mapping
|
||||
|
||||
|
||||
/* Methods */
|
||||
|
||||
|
||||
/**
|
||||
* Reads a 32bit Integer from the Stream
|
||||
*
|
||||
* @access private
|
||||
* @return Integer from the Stream
|
||||
*/
|
||||
private function readint()
|
||||
{
|
||||
if ($this->BYTEORDER == 0) {
|
||||
// low endian
|
||||
$input = unpack('V', $this->STREAM->read(4));
|
||||
return array_shift($input);
|
||||
} else {
|
||||
// big endian
|
||||
$input = unpack('N', $this->STREAM->read(4));
|
||||
return array_shift($input);
|
||||
}
|
||||
}
|
||||
|
||||
public function read($bytes)
|
||||
{
|
||||
return $this->STREAM->read($bytes);
|
||||
}
|
||||
|
||||
/**
|
||||
* Reads an array of Integers from the Stream
|
||||
*
|
||||
* @param int count How many elements should be read
|
||||
* @return Array of Integers
|
||||
*/
|
||||
public function readintarray($count)
|
||||
{
|
||||
if ($this->BYTEORDER == 0) {
|
||||
// low endian
|
||||
return unpack('V'.$count, $this->STREAM->read(4 * $count));
|
||||
} else {
|
||||
// big endian
|
||||
return unpack('N'.$count, $this->STREAM->read(4 * $count));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* @param object Reader the StreamReader object
|
||||
* @param boolean enable_cache Enable or disable caching of strings (default on)
|
||||
*/
|
||||
public function __construct($Reader, $enable_cache = true)
|
||||
{
|
||||
// If there isn't a StreamReader, turn on short circuit mode.
|
||||
if (!$Reader || isset($Reader->error)) {
|
||||
$this->short_circuit = true;
|
||||
return;
|
||||
}
|
||||
|
||||
// Caching can be turned off
|
||||
$this->enable_cache = $enable_cache;
|
||||
|
||||
$MAGIC1 = "\x95\x04\x12\xde";
|
||||
$MAGIC2 = "\xde\x12\x04\x95";
|
||||
|
||||
$this->STREAM = $Reader;
|
||||
$magic = $this->read(4);
|
||||
if ($magic == $MAGIC1) {
|
||||
$this->BYTEORDER = 1;
|
||||
} elseif ($magic == $MAGIC2) {
|
||||
$this->BYTEORDER = 0;
|
||||
} else {
|
||||
$this->error = 1; // not MO file
|
||||
return false;
|
||||
}
|
||||
|
||||
// FIXME: Do we care about revision? We should.
|
||||
$revision = $this->readint();
|
||||
|
||||
$this->total = $this->readint();
|
||||
$this->originals = $this->readint();
|
||||
$this->translations = $this->readint();
|
||||
}
|
||||
|
||||
/**
|
||||
* Loads the translation tables from the MO file into the cache
|
||||
* If caching is enabled, also loads all strings into a cache
|
||||
* to speed up translation lookups
|
||||
*
|
||||
* @access private
|
||||
*/
|
||||
private function load_tables()
|
||||
{
|
||||
if (is_array($this->cache_translations) &&
|
||||
is_array($this->table_originals) &&
|
||||
is_array($this->table_translations)) {
|
||||
return;
|
||||
}
|
||||
|
||||
/* get original and translations tables */
|
||||
if (!is_array($this->table_originals)) {
|
||||
$this->STREAM->seekto($this->originals);
|
||||
$this->table_originals = $this->readintarray($this->total * 2);
|
||||
}
|
||||
if (!is_array($this->table_translations)) {
|
||||
$this->STREAM->seekto($this->translations);
|
||||
$this->table_translations = $this->readintarray($this->total * 2);
|
||||
}
|
||||
|
||||
if ($this->enable_cache) {
|
||||
$this->cache_translations = array ();
|
||||
/* read all strings in the cache */
|
||||
for ($i = 0; $i < $this->total; $i++) {
|
||||
$this->STREAM->seekto($this->table_originals[$i * 2 + 2]);
|
||||
$original = $this->STREAM->read($this->table_originals[$i * 2 + 1]);
|
||||
$this->STREAM->seekto($this->table_translations[$i * 2 + 2]);
|
||||
$translation = $this->STREAM->read($this->table_translations[$i * 2 + 1]);
|
||||
$this->cache_translations[$original] = $translation;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a string from the "originals" table
|
||||
*
|
||||
* @access private
|
||||
* @param int num Offset number of original string
|
||||
* @return string Requested string if found, otherwise ''
|
||||
*/
|
||||
private function get_original_string($num)
|
||||
{
|
||||
$length = $this->table_originals[$num * 2 + 1];
|
||||
$offset = $this->table_originals[$num * 2 + 2];
|
||||
if (!$length) {
|
||||
return '';
|
||||
}
|
||||
$this->STREAM->seekto($offset);
|
||||
$data = $this->STREAM->read($length);
|
||||
return (string)$data;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a string from the "translations" table
|
||||
*
|
||||
* @access private
|
||||
* @param int num Offset number of original string
|
||||
* @return string Requested string if found, otherwise ''
|
||||
*/
|
||||
private function get_translation_string($num)
|
||||
{
|
||||
$length = $this->table_translations[$num * 2 + 1];
|
||||
$offset = $this->table_translations[$num * 2 + 2];
|
||||
if (!$length) {
|
||||
return '';
|
||||
}
|
||||
$this->STREAM->seekto($offset);
|
||||
$data = $this->STREAM->read($length);
|
||||
return (string)$data;
|
||||
}
|
||||
|
||||
/**
|
||||
* Binary search for string
|
||||
*
|
||||
* @access private
|
||||
* @param string string
|
||||
* @param int start (internally used in recursive function)
|
||||
* @param int end (internally used in recursive function)
|
||||
* @return int string number (offset in originals table)
|
||||
*/
|
||||
private function find_string($string, $start = -1, $end = -1)
|
||||
{
|
||||
if (($start == -1) or ($end == -1)) {
|
||||
// find_string is called with only one parameter, set start end end
|
||||
$start = 0;
|
||||
$end = $this->total;
|
||||
}
|
||||
if (abs($start - $end) <= 1) {
|
||||
// We're done, now we either found the string, or it doesn't exist
|
||||
$txt = $this->get_original_string($start);
|
||||
if ($string == $txt) {
|
||||
return $start;
|
||||
} else {
|
||||
return -1;
|
||||
}
|
||||
} elseif ($start > $end) {
|
||||
// start > end -> turn around and start over
|
||||
return $this->find_string($string, $end, $start);
|
||||
} else {
|
||||
// Divide table in two parts
|
||||
$half = (int)(($start + $end) / 2);
|
||||
$cmp = strcmp($string, $this->get_original_string($half));
|
||||
if ($cmp == 0) {
|
||||
// string is exactly in the middle => return it
|
||||
return $half;
|
||||
} elseif ($cmp < 0) {
|
||||
// The string is in the upper half
|
||||
return $this->find_string($string, $start, $half);
|
||||
} else {
|
||||
// Translateshe string is in the lower half
|
||||
return $this->find_string($string, $half, $end);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Translates a string
|
||||
*
|
||||
* @access public
|
||||
* @param string string to be translated
|
||||
* @return string translated string (or original, if not found)
|
||||
*/
|
||||
public function translate($string)
|
||||
{
|
||||
if ($this->short_circuit) {
|
||||
return $string;
|
||||
}
|
||||
$this->load_tables();
|
||||
|
||||
if ($this->enable_cache) {
|
||||
// Caching enabled, get translated string from cache
|
||||
if (array_key_exists($string, $this->cache_translations)) {
|
||||
return $this->cache_translations[$string];
|
||||
} else {
|
||||
return $string;
|
||||
}
|
||||
} else {
|
||||
// Caching not enabled, try to find string
|
||||
$num = $this->find_string($string);
|
||||
if ($num == -1) {
|
||||
return $string;
|
||||
} else {
|
||||
return $this->get_translation_string($num);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Sanitize plural form expression for use in PHP eval call.
|
||||
*
|
||||
* @access private
|
||||
* @return string sanitized plural form expression
|
||||
*/
|
||||
private function sanitize_plural_expression($expr)
|
||||
{
|
||||
// Get rid of disallowed characters.
|
||||
$expr = preg_replace('@[^a-zA-Z0-9_:;\(\)\?\|\&=!<>+*/\%-]@', '', $expr);
|
||||
|
||||
// Add parenthesis for tertiary '?' operator.
|
||||
$expr .= ';';
|
||||
$res = '';
|
||||
$p = 0;
|
||||
for ($i = 0; $i < strlen($expr); $i++) {
|
||||
$ch = $expr[$i];
|
||||
switch ($ch) {
|
||||
case '?':
|
||||
$res .= ' ? (';
|
||||
$p++;
|
||||
break;
|
||||
case ':':
|
||||
$res .= ') : (';
|
||||
break;
|
||||
case ';':
|
||||
$res .= str_repeat(')', $p).';';
|
||||
$p = 0;
|
||||
break;
|
||||
default:
|
||||
$res .= $ch;
|
||||
}
|
||||
}
|
||||
return $res;
|
||||
}
|
||||
|
||||
/**
|
||||
* Parse full PO header and extract only plural forms line.
|
||||
*
|
||||
* @access private
|
||||
* @return string verbatim plural form header field
|
||||
*/
|
||||
private function extract_plural_forms_header_from_po_header($header)
|
||||
{
|
||||
if (preg_match("/(^|\n)plural-forms: ([^\n]*)\n/i", $header, $regs)) {
|
||||
$expr = $regs[2];
|
||||
} else {
|
||||
$expr = "nplurals=2; plural=n == 1 ? 0 : 1;";
|
||||
}
|
||||
return $expr;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get possible plural forms from MO header
|
||||
*
|
||||
* @access private
|
||||
* @return string plural form header
|
||||
*/
|
||||
private function get_plural_forms()
|
||||
{
|
||||
// lets assume message number 0 is header
|
||||
// this is true, right?
|
||||
$this->load_tables();
|
||||
|
||||
// cache header field for plural forms
|
||||
if (! is_string($this->pluralheader)) {
|
||||
if ($this->enable_cache) {
|
||||
$header = $this->cache_translations[""];
|
||||
} else {
|
||||
$header = $this->get_translation_string(0);
|
||||
}
|
||||
$expr = $this->extract_plural_forms_header_from_po_header($header);
|
||||
$this->pluralheader = $this->sanitize_plural_expression($expr);
|
||||
}
|
||||
return $this->pluralheader;
|
||||
}
|
||||
|
||||
/**
|
||||
* Detects which plural form to take
|
||||
*
|
||||
* @access private
|
||||
* @param n count
|
||||
* @return int array index of the right plural form
|
||||
*/
|
||||
private function select_string($n)
|
||||
{
|
||||
$string = $this->get_plural_forms();
|
||||
$string = str_replace('nplurals', "\$total", $string);
|
||||
$string = str_replace("n", $n, $string);
|
||||
$string = str_replace('plural', "\$plural", $string);
|
||||
|
||||
$total = 0;
|
||||
$plural = 0;
|
||||
|
||||
eval("$string");
|
||||
if ($plural >= $total) {
|
||||
$plural = $total - 1;
|
||||
}
|
||||
return $plural;
|
||||
}
|
||||
|
||||
/**
|
||||
* Plural version of gettext
|
||||
*
|
||||
* @access public
|
||||
* @param string single
|
||||
* @param string plural
|
||||
* @param string number
|
||||
* @return translated plural form
|
||||
*/
|
||||
public function ngettext($single, $plural, $number)
|
||||
{
|
||||
if ($this->short_circuit) {
|
||||
if ($number != 1) {
|
||||
return $plural;
|
||||
} else {
|
||||
return $single;
|
||||
}
|
||||
}
|
||||
|
||||
// find out the appropriate form
|
||||
$select = $this->select_string($number);
|
||||
|
||||
// this should contains all strings separated by NULLs
|
||||
$key = $single . chr(0) . $plural;
|
||||
|
||||
if ($this->enable_cache) {
|
||||
if (! array_key_exists($key, $this->cache_translations)) {
|
||||
return ($number != 1) ? $plural : $single;
|
||||
} else {
|
||||
$result = $this->cache_translations[$key];
|
||||
$list = explode(chr(0), $result);
|
||||
return $list[$select];
|
||||
}
|
||||
} else {
|
||||
$num = $this->find_string($key);
|
||||
if ($num == -1) {
|
||||
return ($number != 1) ? $plural : $single;
|
||||
} else {
|
||||
$result = $this->get_translation_string($num);
|
||||
$list = explode(chr(0), $result);
|
||||
return $list[$select];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public function pgettext($context, $msgid)
|
||||
{
|
||||
$key = $context.chr(4).$msgid;
|
||||
$ret = $this->translate($key);
|
||||
if (strpos($ret, "\004") !== false) {
|
||||
return $msgid;
|
||||
} else {
|
||||
return $ret;
|
||||
}
|
||||
}
|
||||
|
||||
public function npgettext($context, $singular, $plural, $number)
|
||||
{
|
||||
$key = $context.chr(4).$singular;
|
||||
$ret = $this->ngettext($key, $plural, $number);
|
||||
if (strpos($ret, "\004") !== false) {
|
||||
return $singular;
|
||||
} else {
|
||||
return $ret;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
# __END__
|
||||
182
www/lib/CoreLibs/Language/Core/streams.php
Normal file
182
www/lib/CoreLibs/Language/Core/streams.php
Normal file
@@ -0,0 +1,182 @@
|
||||
<?php
|
||||
/*
|
||||
Copyright (c) 2003, 2005, 2006, 2009 Danilo Segan <danilo@kvota.net>.
|
||||
|
||||
This file is part of PHP-gettext.
|
||||
|
||||
PHP-gettext is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
PHP-gettext is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with PHP-gettext; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
|
||||
// Simple class to wrap file streams, string streams, etc.
|
||||
// seek is essential, and it should be byte stream
|
||||
class StreamReader
|
||||
{
|
||||
// should return a string [FIXME: perhaps return array of bytes?]
|
||||
public function read($bytes)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
// should return new position
|
||||
public function seekto($position)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
// returns current position
|
||||
public function currentpos()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
// returns length of entire stream (limit for seekto()s)
|
||||
public function length()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
class StringReader
|
||||
{
|
||||
public $_pos;
|
||||
public $_str;
|
||||
|
||||
public function __construct($str = '')
|
||||
{
|
||||
$this->_str = $str;
|
||||
$this->_pos = 0;
|
||||
}
|
||||
|
||||
public function read($bytes)
|
||||
{
|
||||
$data = substr($this->_str, $this->_pos, $bytes);
|
||||
$this->_pos += $bytes;
|
||||
if (strlen($this->_str)<$this->_pos) {
|
||||
$this->_pos = strlen($this->_str);
|
||||
}
|
||||
|
||||
return $data;
|
||||
}
|
||||
|
||||
public function seekto($pos)
|
||||
{
|
||||
$this->_pos = $pos;
|
||||
if (strlen($this->_str)<$this->_pos) {
|
||||
$this->_pos = strlen($this->_str);
|
||||
}
|
||||
return $this->_pos;
|
||||
}
|
||||
|
||||
public function currentpos()
|
||||
{
|
||||
return $this->_pos;
|
||||
}
|
||||
|
||||
public function length()
|
||||
{
|
||||
return strlen($this->_str);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
class FileReader
|
||||
{
|
||||
public $_pos;
|
||||
public $_fd;
|
||||
public $_length;
|
||||
|
||||
public function __construct($filename)
|
||||
{
|
||||
if (file_exists($filename)) {
|
||||
$this->_length=filesize($filename);
|
||||
$this->_pos = 0;
|
||||
$this->_fd = fopen($filename, 'rb');
|
||||
if (!$this->_fd) {
|
||||
$this->error = 3; // Cannot read file, probably permissions
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
$this->error = 2; // File doesn't exist
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public function read($bytes)
|
||||
{
|
||||
if ($bytes) {
|
||||
fseek($this->_fd, $this->_pos);
|
||||
|
||||
// PHP 5.1.1 does not read more than 8192 bytes in one fread()
|
||||
// the discussions at PHP Bugs suggest it's the intended behaviour
|
||||
$data = '';
|
||||
while ($bytes > 0) {
|
||||
$chunk = fread($this->_fd, $bytes);
|
||||
$data .= $chunk;
|
||||
$bytes -= strlen($chunk);
|
||||
}
|
||||
$this->_pos = ftell($this->_fd);
|
||||
|
||||
return $data;
|
||||
} else {
|
||||
return '';
|
||||
}
|
||||
}
|
||||
|
||||
public function seekto($pos)
|
||||
{
|
||||
fseek($this->_fd, $pos);
|
||||
$this->_pos = ftell($this->_fd);
|
||||
return $this->_pos;
|
||||
}
|
||||
|
||||
public function currentpos()
|
||||
{
|
||||
return $this->_pos;
|
||||
}
|
||||
|
||||
public function length()
|
||||
{
|
||||
return $this->_length;
|
||||
}
|
||||
|
||||
public function close()
|
||||
{
|
||||
fclose($this->_fd);
|
||||
}
|
||||
}
|
||||
|
||||
// Preloads entire file in memory first, then creates a StringReader
|
||||
// over it (it assumes knowledge of StringReader internals)
|
||||
class CachedFileReader extends StringReader
|
||||
{
|
||||
public function __construct($filename)
|
||||
{
|
||||
if (file_exists($filename)) {
|
||||
$length=filesize($filename);
|
||||
$fd = fopen($filename, 'rb');
|
||||
|
||||
if (!$fd) {
|
||||
$this->error = 3; // Cannot read file, probably permissions
|
||||
return false;
|
||||
}
|
||||
$this->_str = fread($fd, $length);
|
||||
fclose($fd);
|
||||
} else {
|
||||
$this->error = 2; // File doesn't exist
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
118
www/lib/CoreLibs/Language/l10.inc
Normal file
118
www/lib/CoreLibs/Language/l10.inc
Normal file
@@ -0,0 +1,118 @@
|
||||
<?
|
||||
/*********************************************************************
|
||||
* AUTHOR: Clemens "Gullevek" Schwaighofer (www.gullevek.org)
|
||||
* CREATED: 2004/11/18
|
||||
* VERSION: 0.1.1
|
||||
* RELEASED LICENSE: GNU GPL 3
|
||||
* SHORT DESCRIPTION:
|
||||
* init class for gettext. Original was just a function & var setting include for wordpress.
|
||||
* I changed that to a class to be more portable with my style of coding
|
||||
*
|
||||
* PUBLIC VARIABLES
|
||||
*
|
||||
* PRIVATE VARIABLES
|
||||
*
|
||||
* PUBLIC METHODS
|
||||
* __: returns string (translated or original if not found)
|
||||
* _e: echos out string (translated or original if not found)
|
||||
* __ngettext: should return plural. never tested this.
|
||||
*
|
||||
* PRIVATE METHODS
|
||||
*
|
||||
* HISTORY:
|
||||
* 2005/10/17 (cs) made an on the fly switch method (reload of lang)
|
||||
*********************************************************************/
|
||||
|
||||
// try to include file from LIBS path, or from normal path
|
||||
_spl_autoload('Class.Basic.inc');
|
||||
|
||||
class l10n extends basic
|
||||
{
|
||||
private $lang = '';
|
||||
private $mofile = '';
|
||||
private $input;
|
||||
private $l10n;
|
||||
|
||||
public function __construct($lang = '', $path = DEFAULT_TEMPLATE)
|
||||
{
|
||||
foreach (array('streams.php', 'gettext.php') as $include_file) {
|
||||
_spl_autoload($include_file);
|
||||
}
|
||||
|
||||
if (!$lang) {
|
||||
$this->lang = 'en';
|
||||
} else {
|
||||
$this->lang = $lang;
|
||||
}
|
||||
|
||||
if (is_dir(LAYOUT.$path.LANG)) {
|
||||
$path = LAYOUT.$path.LANG;
|
||||
} elseif (!is_dir($path)) {
|
||||
$path = '';
|
||||
}
|
||||
|
||||
$this->mofile = $path.$this->lang.".mo";
|
||||
|
||||
// check if get a readable mofile
|
||||
if (is_readable($this->mofile)) {
|
||||
$this->input = new FileReader($this->mofile);
|
||||
} else {
|
||||
$this->input = false;
|
||||
}
|
||||
|
||||
$this->l10n = new gettext_reader($this->input);
|
||||
}
|
||||
|
||||
// reloads the mofile, if the location of the lang file changes
|
||||
public function l10nReloadMOfile($lang, $path = DEFAULT_TEMPLATE)
|
||||
{
|
||||
$old_mofile = $this->mofile;
|
||||
$old_lang = $this->lang;
|
||||
|
||||
$this->lang = $lang;
|
||||
|
||||
if (is_dir(LAYOUT.$path.LANG)) {
|
||||
$path = LAYOUT.$path.LANG;
|
||||
} elseif (!is_dir($path)) {
|
||||
$path = '';
|
||||
}
|
||||
|
||||
$this->mofile = $path.$this->lang.".mo";
|
||||
|
||||
// check if get a readable mofile
|
||||
if (is_readable($this->mofile)) {
|
||||
$this->input = new FileReader($this->mofile);
|
||||
$this->l10n = new gettext_reader($this->input);
|
||||
} else {
|
||||
// else fall back to the old ones
|
||||
$this->mofile = $old_mofile;
|
||||
$this->lang = $old_lang;
|
||||
}
|
||||
}
|
||||
|
||||
public function __($text)
|
||||
{
|
||||
return $this->l10n->translate($text);
|
||||
}
|
||||
|
||||
public function _e($text)
|
||||
{
|
||||
echo $this->l10n->translate($text);
|
||||
}
|
||||
|
||||
// Return the plural form.
|
||||
public function __ngettext($single, $plural, $number)
|
||||
{
|
||||
return $this->l10n->ngettext($single, $plural, $number);
|
||||
}
|
||||
|
||||
public function __get_lang()
|
||||
{
|
||||
return $this->lang;
|
||||
}
|
||||
|
||||
public function __get_mofile()
|
||||
{
|
||||
return $this->mofile;
|
||||
}
|
||||
}
|
||||
1707
www/lib/CoreLibs/Output/Form/Generate.inc
Normal file
1707
www/lib/CoreLibs/Output/Form/Generate.inc
Normal file
File diff suppressed because it is too large
Load Diff
666
www/lib/CoreLibs/Output/Progressbar.inc
Normal file
666
www/lib/CoreLibs/Output/Progressbar.inc
Normal file
@@ -0,0 +1,666 @@
|
||||
<?php
|
||||
/*
|
||||
* Class ProgressBar
|
||||
*
|
||||
* Author: Gerd Weitenberg (hahnebuechen@web.de)
|
||||
* Date: 2005.03.09
|
||||
*
|
||||
* Update: Clemens Schwaighofer
|
||||
* Date: 2012.9.5 [stacked output]
|
||||
* Date: 2013.2.21 [proper class formatting]
|
||||
*
|
||||
*/
|
||||
|
||||
class ProgressBar
|
||||
{
|
||||
// private vars
|
||||
|
||||
public $code; // unique code
|
||||
public $status = 'new'; // current status (new,show,hide)
|
||||
public $step = 0; // current step
|
||||
public $position = array(); // current bar position
|
||||
|
||||
public $clear_buffer_size = 1; // we need to send this before the lfush to get browser output
|
||||
public $clear_buffer_size_init = 1024*1024; // if I don't send that junk, it won't send anything
|
||||
|
||||
// public vars
|
||||
|
||||
public $min = 0; // minimal steps
|
||||
public $max = 100; // maximal steps
|
||||
|
||||
public $left = 5; // bar position from left
|
||||
public $top = 5; // bar position from top
|
||||
public $width = 300; // bar width
|
||||
public $height = 25; // bar height
|
||||
public $pedding = 0; // bar pedding
|
||||
public $color = '#0033ff'; // bar color
|
||||
public $bgr_color = '#c0c0c0'; // bar background color
|
||||
public $bgr_color_master = '#ffffff'; // master div background color
|
||||
public $border = 1; // bar border width
|
||||
public $brd_color = '#000000'; // bar border color
|
||||
|
||||
public $direction = 'right'; // direction of motion (right,left,up,down)
|
||||
|
||||
public $frame = array('show' => false); // ProgressBar Frame
|
||||
/* 'show' => false, # frame show (true/false)
|
||||
'left' => 200, # frame position from left
|
||||
'top' => 100, # frame position from top
|
||||
'width' => 300, # frame width
|
||||
'height' => 75, # frame height
|
||||
'color' => '#c0c0c0', # frame color
|
||||
'border' => 2, # frame border
|
||||
'brd_color' => '#dfdfdf #404040 #404040 #dfdfdf' # frame border color
|
||||
*/
|
||||
|
||||
public $label = array(); // ProgressBar Labels
|
||||
/* 'name' => array( # label name
|
||||
'type' => 'text', # label type (text,button,step,percent,crossbar)
|
||||
'value' => 'Please wait ...', # label value
|
||||
'left' => 10, # label position from left
|
||||
'top' => 20, # label position from top
|
||||
'width' => 0, # label width
|
||||
'height' => 0, # label height
|
||||
'align' => 'left', # label align
|
||||
'font-size' => 11, # label font size
|
||||
'font-family' => 'Verdana, Tahoma, Arial', # label font family
|
||||
'font-weight' => '', # label font weight
|
||||
'color' => '#000000', # label font color
|
||||
'bgr_color' => '' # label background color
|
||||
)
|
||||
*/
|
||||
|
||||
// constructor
|
||||
public function __construct($width = 0, $height = 0)
|
||||
{
|
||||
$this->code = substr(md5(microtime()), 0, 6);
|
||||
if ($width > 0) {
|
||||
$this->width = $width;
|
||||
}
|
||||
if ($height > 0) {
|
||||
$this->height = $height;
|
||||
}
|
||||
// needs to be called twice or I do not get any output
|
||||
$this->_flushCache($this->clear_buffer_size_init);
|
||||
$this->_flushCache($this->clear_buffer_size_init);
|
||||
}
|
||||
|
||||
// private functions
|
||||
|
||||
private function _flushCache($clear_buffer_size = 0)
|
||||
{
|
||||
if (!$clear_buffer_size) {
|
||||
$clear_buffer_size = $this->clear_buffer_size;
|
||||
}
|
||||
echo str_repeat(' ', $clear_buffer_size);
|
||||
ob_flush();
|
||||
flush();
|
||||
}
|
||||
|
||||
private function _calculatePercent($step)
|
||||
{
|
||||
// avoid divison through 0
|
||||
if ($this->max - $this->min == 0) {
|
||||
$this->max ++;
|
||||
}
|
||||
$percent = round(($step - $this->min) / ($this->max - $this->min) * 100);
|
||||
if ($percent > 100) {
|
||||
$percent = 100;
|
||||
}
|
||||
return $percent;
|
||||
}
|
||||
|
||||
private function _calculatePosition($step)
|
||||
{
|
||||
switch ($this->direction) {
|
||||
case 'right':
|
||||
case 'left':
|
||||
$bar = $this->width;
|
||||
break;
|
||||
case 'down':
|
||||
case 'up':
|
||||
$bar = $this->height;
|
||||
break;
|
||||
}
|
||||
// avoid divison through 0
|
||||
if ($this->max - $this->min == 0) {
|
||||
$this->max ++;
|
||||
}
|
||||
$pixel = round(($step - $this->min) * ($bar - ($this->pedding * 2)) / ($this->max - $this->min));
|
||||
if ($step <= $this->min) {
|
||||
$pixel = 0;
|
||||
}
|
||||
if ($step >= $this->max) {
|
||||
$pixel = $bar - ($this->pedding * 2);
|
||||
}
|
||||
|
||||
switch ($this->direction) {
|
||||
case 'right':
|
||||
$position['left'] = $this->pedding;
|
||||
$position['top'] = $this->pedding;
|
||||
$position['width'] = $pixel;
|
||||
$position['height'] = $this->height - ($this->pedding * 2);
|
||||
break;
|
||||
case 'left':
|
||||
$position['left'] = $this->width - $this->pedding - $pixel;
|
||||
$position['top'] = $this->pedding;
|
||||
$position['width'] = $pixel;
|
||||
$position['height'] = $this->height - ($this->pedding * 2);
|
||||
break;
|
||||
case 'down':
|
||||
$position['left'] = $this->pedding;
|
||||
$position['top'] = $this->pedding;
|
||||
$position['width'] = $this->width - ($this->pedding * 2);
|
||||
$position['height'] = $pixel;
|
||||
break;
|
||||
case 'up':
|
||||
$position['left'] = $this->pedding;
|
||||
$position['top'] = $this->height - $this->pedding - $pixel;
|
||||
$position['width'] = $this->width - ($this->pedding * 2);
|
||||
$position['height'] = $pixel;
|
||||
break;
|
||||
}
|
||||
return $position;
|
||||
}
|
||||
|
||||
private function _setStep($step)
|
||||
{
|
||||
if ($step > $this->max) {
|
||||
$step = $this->max;
|
||||
}
|
||||
if ($step < $this->min) {
|
||||
$step = $this->min;
|
||||
}
|
||||
$this->step = $step;
|
||||
}
|
||||
|
||||
// public functions
|
||||
public function setFrame($width = 0, $height = 0)
|
||||
{
|
||||
$this->frame = array (
|
||||
'show' => true,
|
||||
'left' => 20,
|
||||
'top' => 35,
|
||||
'width' => $this->width + 6,
|
||||
'height' => 'auto',
|
||||
'color' => '#c0c0c0',
|
||||
'border' => 2,
|
||||
'brd_color' => '#dfdfdf #404040 #404040 #dfdfdf'
|
||||
);
|
||||
|
||||
if ($width > 0) {
|
||||
$this->frame['width'] = $width;
|
||||
}
|
||||
if ($height > 0) {
|
||||
$this->frame['height'] = $height;
|
||||
}
|
||||
}
|
||||
|
||||
public function addLabel($type, $name, $value = ' ')
|
||||
{
|
||||
switch ($type) {
|
||||
case 'text':
|
||||
$this->label[$name] = array(
|
||||
'type' => 'text',
|
||||
'value' => $value,
|
||||
'left' => 0, // keep all to the left in box
|
||||
'top' => 2, // default top is 2px
|
||||
'width' => $this->width,
|
||||
'height' => 0,
|
||||
'align' => 'left',
|
||||
'font-size' => 11,
|
||||
'font-family' => 'Verdana, Tahoma, Arial',
|
||||
'font-weight' => 'normal',
|
||||
'color' => '#000000',
|
||||
'bgr_color' => ''
|
||||
);
|
||||
break;
|
||||
case 'button':
|
||||
$this->label[$name] = array(
|
||||
'type' => 'button',
|
||||
'value' => $value,
|
||||
'action' => '',
|
||||
'target' => 'self',
|
||||
'left' => 5,
|
||||
'top' => 5,
|
||||
'width' => 0,
|
||||
'height' => 0,
|
||||
'align' => 'center',
|
||||
'font-size' => 11,
|
||||
'font-family' => 'Verdana, Tahoma, Arial',
|
||||
'font-weight' => 'normal',
|
||||
'color' => '#000000',
|
||||
'bgr_color' => ''
|
||||
);
|
||||
break;
|
||||
case 'step':
|
||||
$this->label[$name] = array(
|
||||
'type' => 'step',
|
||||
'value' => $value,
|
||||
'left' => $this->left + 5,
|
||||
'top' => $this->top + 5,
|
||||
'width' => 10,
|
||||
'height' => 0,
|
||||
'align' => 'right',
|
||||
'font-size' => 11,
|
||||
'font-family' => 'Verdana, Tahoma, Arial',
|
||||
'font-weight' => 'normal',
|
||||
'color' => '#000000',
|
||||
'bgr_color' => ''
|
||||
);
|
||||
break;
|
||||
case 'percentlbl':
|
||||
case 'percent':
|
||||
// check font size
|
||||
if ($this->height <= 11) {
|
||||
$font_size = $this->height - 1;
|
||||
} else {
|
||||
$font_size = 11;
|
||||
}
|
||||
$this->label[$name] = array(
|
||||
'type' => $type, // either percent or percentlbl
|
||||
'value' => $value,
|
||||
'left' => false,
|
||||
'top' => round(($this->height - $font_size) / log($this->height - $font_size, 7), 0) - $this->pedding,
|
||||
'width' => $this->width,
|
||||
'height' => 0,
|
||||
'align' => 'center',
|
||||
'font-size' => $font_size,
|
||||
'font-family' => 'sans-serif',
|
||||
'font-weight' => 'normal',
|
||||
'color' => '#000000',
|
||||
'bgr_color' => ''
|
||||
);
|
||||
// print "THIS[$name]: ".$this->label[$name]['left']." | ".$this->label[$name]['width']."<br>";
|
||||
break;
|
||||
case 'crossbar':
|
||||
$this->label[$name] = array(
|
||||
'type' => 'crossbar',
|
||||
'value' => $value,
|
||||
'left' => $this->left + ($this->width / 2),
|
||||
'top' => $this->top - 16,
|
||||
'width' => 10,
|
||||
'height' => 0,
|
||||
'align' => 'center',
|
||||
'font-size' => 11,
|
||||
'font-family' => 'Verdana, Tahoma, Arial',
|
||||
'font-weight' => 'normal',
|
||||
'color' => '#000000',
|
||||
'bgr_color' => ''
|
||||
);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
public function addButton($name, $value, $action, $target = 'self')
|
||||
{
|
||||
$this->addLabel('button', $name, $value);
|
||||
$this->label[$name]['action'] = $action;
|
||||
$this->label[$name]['target'] = $target;
|
||||
}
|
||||
|
||||
public function setLabelPosition($name, $left, $top, $width, $height, $align = '')
|
||||
{
|
||||
// print "SET POSITION[$name]: $left<br>";
|
||||
// if this is percent, we ignore anything, it is auto positioned
|
||||
if ($this->label[$name]['type'] != 'percent') {
|
||||
foreach (array('top', 'left', 'width', 'height') as $pos_name) {
|
||||
if ($$pos_name !== false) {
|
||||
$this->label[$name][$pos_name] = intval($$pos_name);
|
||||
}
|
||||
}
|
||||
|
||||
if ($align != '') {
|
||||
$this->label[$name]['align'] = $align;
|
||||
}
|
||||
}
|
||||
// init
|
||||
if ($this->status != 'new') {
|
||||
$output = '<script type="text/JavaScript">';
|
||||
$output .= 'document.getElementById("plbl'.$name.$this->code.'").style.top="'.$this->label[$name]['top'].'px";';
|
||||
$output .= 'document.getElementById("plbl'.$name.$this->code.'").style.left="'.$this->label[$name]['left'].'px";';
|
||||
$output .= 'document.getElementById("plbl'.$name.$this->code.'").style.width="'.$this->label[$name]['width'].'px";';
|
||||
$output .= 'document.getElementById("plbl'.$name.$this->code.'").style.height="'.$this->label[$name]['height'].'px";';
|
||||
$output .= 'document.getElementById("plbl'.$name.$this->code.'").style.align="'.$this->label[$name]['align'].'";';
|
||||
$output .= '</script>'."\n";
|
||||
echo $output;
|
||||
$this->_flushCache();
|
||||
}
|
||||
}
|
||||
|
||||
public function setLabelColor($name, $color)
|
||||
{
|
||||
$this->label[$name]['color'] = $color;
|
||||
if ($this->status != 'new') {
|
||||
echo '<script type="text/JavaScript">document.getElementById("plbl'.$name.$this->code.'").style.color="'.$color.'";</script>'."\n";
|
||||
$this->_flushCache();
|
||||
}
|
||||
}
|
||||
|
||||
public function setLabelBackground($name, $color)
|
||||
{
|
||||
$this->label[$name]['bgr_color'] = $color;
|
||||
if ($this->status != 'new') {
|
||||
echo '<script type="text/JavaScript">document.getElementById("plbl'.$name.$this->code.'").style.background="'.$color.'";</script>'."\n";
|
||||
$this->_flushCache();
|
||||
}
|
||||
}
|
||||
|
||||
public function setLabelFont($name, $size, $family = '', $weight = '')
|
||||
{
|
||||
// just in case if it is too small
|
||||
if (intval($size) < 0) {
|
||||
$size = 11;
|
||||
}
|
||||
// if this is percent, the size is not allowed to be bigger than the bar size - 5px
|
||||
if ($this->label[$name]['type'] == 'percent' && intval($size) >= $this->height) {
|
||||
$size = $this->height - 1;
|
||||
}
|
||||
// position the label new if this is percent
|
||||
if ($this->label[$name]['type'] == 'percent') {
|
||||
$this->label[$name]['top'] = round(($this->height - intval($size)) / log($this->height - intval($size), 7), 0) - $this->pedding;
|
||||
}
|
||||
// print "HEIGHT: ".$this->height.", Size: ".intval($size).", Pedding: ".$this->pedding.", Calc: ".round($this->height - intval($size)).", Log: ".log($this->height - intval($size), 7)."<br>";
|
||||
// then set like usual
|
||||
$this->label[$name]['font-size'] = intval($size);
|
||||
if ($family != '') {
|
||||
$this->label[$name]['font-family'] = $family;
|
||||
}
|
||||
if ($weight != '') {
|
||||
$this->label[$name]['font-weight'] = $weight;
|
||||
}
|
||||
|
||||
if ($this->status != 'new') {
|
||||
$output = '<script type="text/JavaScript">';
|
||||
$output .= 'document.getElementById("plbl'.$name.$this->code.'").style.font-size="'.$this->label[$name]['font-size'].'px";';
|
||||
$output .= 'document.getElementById("plbl'.$name.$this->code.'").style.font-family="'.$this->label[$name]['font-family'].'";';
|
||||
$output .= 'document.getElementById("plbl'.$name.$this->code.'").style.font-weight="'.$this->label[$name]['font-weight'].'";';
|
||||
$output .= '</script>'."\n";
|
||||
echo $output;
|
||||
$this->_flushCache();
|
||||
}
|
||||
}
|
||||
|
||||
public function setLabelValue($name, $value)
|
||||
{
|
||||
$this->label[$name]['value'] = $value;
|
||||
// print "NAME[$name], Status: ".$this->status.": ".$value."<Br>";
|
||||
if ($this->status != 'new') {
|
||||
echo '<script type="text/JavaScript">PBlabelText'.$this->code.'("'.$name.'","'.$this->label[$name]['value'].'");</script>'."\n";
|
||||
$this->_flushCache();
|
||||
}
|
||||
}
|
||||
|
||||
public function setBarColor($color)
|
||||
{
|
||||
$this->color = $color;
|
||||
if ($this->status != 'new') {
|
||||
echo '<script type="text/JavaScript">document.getElementById("pbar'.$this->code.'").style.background="'.$color.'";</script>'."\n";
|
||||
$this->_flushCache();
|
||||
}
|
||||
}
|
||||
|
||||
public function setBarBackground($color)
|
||||
{
|
||||
$this->bgr_color = $color;
|
||||
if ($this->status != 'new') {
|
||||
echo '<script type="text/JavaScript">document.getElementById("pbrd'.$this->code.'").style.background="'.$color.'";</script>'."\n";
|
||||
$this->_flushCache();
|
||||
}
|
||||
}
|
||||
|
||||
public function setBarDirection($direction)
|
||||
{
|
||||
$this->direction = $direction;
|
||||
|
||||
if ($this->status != 'new') {
|
||||
$this->position = $this->_calculatePosition($this->step);
|
||||
|
||||
echo '<script type="text/JavaScript">';
|
||||
echo 'PBposition'.$this->code.'("left",'.$this->position['left'].');';
|
||||
echo 'PBposition'.$this->code.'("top",'.$this->position['top'].');';
|
||||
echo 'PBposition'.$this->code.'("width",'.$this->position['width'].');';
|
||||
echo 'PBposition'.$this->code.'("height",'.$this->position['height'].');';
|
||||
echo '</script>'."\n";
|
||||
$this->_flushCache();
|
||||
}
|
||||
}
|
||||
|
||||
public function getHtml()
|
||||
{
|
||||
$html = '';
|
||||
$js = '';
|
||||
$html_button = '';
|
||||
|
||||
$this->_setStep($this->step);
|
||||
$this->position = $this->_calculatePosition($this->step);
|
||||
|
||||
if ($this->top || $this->left) {
|
||||
$style_master = 'position:relative;top:'.$this->top.'px;left:'.$this->left.'px;width:'.($this->width + 10).'px;';
|
||||
}
|
||||
$html = '<div id="pbm'.$this->code.'" style="'.$style_master.'background:'.$this->bgr_color_master.';">';
|
||||
$style_brd = 'width:'.$this->width.'px;height:'.$this->height.'px;background:'.$this->bgr_color.';';
|
||||
if ($this->border > 0) {
|
||||
$style_brd .= 'border:'.$this->border.'px solid; border-color:'.$this->brd_color.'; -webkit-border-radius: 5px 5px 5px 5px; border-radius: 5px 5px 5px 5px; -webkit-shadow: 2px 2px 10px rgba(0, 0, 0, 0.25) inset; box-shadow: 2px 2px 10px rgba(0, 0, 0, 0.25) inset;';
|
||||
}
|
||||
|
||||
$style_bar = 'position:relative;width:'.$this->position['width'].'px;height:'.$this->position['height'].'px;background:'.$this->color.';';
|
||||
if ($this->position['top'] !== false) {
|
||||
$style_bar .= 'top:'.$this->position['top'].'px;';
|
||||
}
|
||||
if ($this->position['left'] !== false) {
|
||||
$style_bar .= 'left:'.$this->position['left'].'px;';
|
||||
}
|
||||
if ($this->border > 0) {
|
||||
$style_bar .= '-webkit-border-radius: 5px 5px 5px 5px; border-radius: 5px 5px 5px 5px; -webkit-shadow: 2px 2px 10px rgba(0, 0, 0, 0.25) inset; box-shadow: 2px 2px 10px rgba(0, 0, 0, 0.25) inset;';
|
||||
}
|
||||
|
||||
if ($this->frame['show'] == true) {
|
||||
if ($this->frame['border'] > 0) {
|
||||
$border = 'border:'.$this->frame['border'].'px solid;border-color:'.$this->frame['brd_color'].';margin-top:2px;-webkit-border-radius: 5px 5px 5px 5px; border-radius: 5px 5px 5px 5px;';
|
||||
}
|
||||
$html .= '<div id="pfrm'.$this->code.'" style="width:'.$this->frame['width'].'px;height:'.$this->frame['height'].'px;'.$border.'background:'.$this->frame['color'].';">'."\n";
|
||||
}
|
||||
|
||||
// temp write the bar here, we add that later, below all the html + progress %
|
||||
$html_bar_top = '<div id="pbrd'.$this->code.'" style="'.$style_brd.($this->frame['show'] == true ? 'margin-left: 2px;margin-bottom:2px;' : '').'">'."\n";
|
||||
$html_bar_top .= '<div id="pbar'.$this->code.'" style="'.$style_bar.'">';
|
||||
// insert single percent there
|
||||
$html_bar_bottom = '</div></div>'."\n";
|
||||
|
||||
$js .= 'function PBposition'.$this->code.'(item,pixel) {'."\n";
|
||||
$js .= ' pixel = parseInt(pixel);'."\n";
|
||||
$js .= ' switch(item) {'."\n";
|
||||
$js .= ' case "left": document.getElementById("pbar'.$this->code.'").style.left=(pixel) + \'px\'; break;'."\n";
|
||||
$js .= ' case "top": document.getElementById("pbar'.$this->code.'").style.top=(pixel) + \'px\'; break;'."\n";
|
||||
$js .= ' case "width": document.getElementById("pbar'.$this->code.'").style.width=(pixel) + \'px\'; break;'."\n";
|
||||
$js .= ' case "height": document.getElementById("pbar'.$this->code.'").style.height=(pixel) + \'px\'; break;'."\n";
|
||||
$js .= ' }'."\n";
|
||||
$js .= '}'."\n";
|
||||
|
||||
//print "DUMP LABEL: <br><pre>".print_r($this->label, 1)."</pre><br>";
|
||||
foreach ($this->label as $name => $data) {
|
||||
// set what type of move we do
|
||||
$move_prefix = $data['type'] == 'button' ? 'margin' : 'padding';
|
||||
$style_lbl = 'position:relative;';
|
||||
if ($data['top'] !== false) {
|
||||
$style_lbl .= $move_prefix.'-top:'.$data['top'].'px;';
|
||||
}
|
||||
if ($data['left'] !== false) {
|
||||
$style_lbl .= $move_prefix.'-left:'.$data['left'].'px;';
|
||||
}
|
||||
$style_lbl .= 'text-align:'.$data['align'].';';
|
||||
if ($data['width'] > 0) {
|
||||
$style_lbl .= 'width:'.$data['width'].'px;';
|
||||
}
|
||||
if ($data['height'] > 0) {
|
||||
$style_lbl .= 'height:'.$data['height'].'px;';
|
||||
}
|
||||
|
||||
if (array_key_exists('font-size', $data)) {
|
||||
$style_lbl .= 'font-size:'.$data['font-size'].'px;';
|
||||
}
|
||||
if (array_key_exists('font-family', $data)) {
|
||||
$style_lbl .= 'font-family:'.$data['font-family'].';';
|
||||
}
|
||||
if (array_key_exists('font-weight', $data)) {
|
||||
$style_lbl .= 'font-weight:'.$data['font-weight'].';';
|
||||
}
|
||||
if (array_key_exists('bgr_color', $data) && ($data['bgr_color'] != '')) {
|
||||
$style_lbl .= 'background:'.$data['bgr_color'].';';
|
||||
}
|
||||
|
||||
if (array_key_exists('type', $data)) {
|
||||
switch ($data['type']) {
|
||||
case 'text':
|
||||
$html .= '<div id="plbl'.$name.$this->code.'" style="'.$style_lbl.'margin-bottom:2px;">'.$data['value'].'</div>'."\n";
|
||||
break;
|
||||
case 'button':
|
||||
$html_button .= '<div><input id="plbl'.$name.$this->code.'" type="button" value="'.$data['value'].'" style="'.$style_lbl.'margin-bottom:5px;" onclick="'.$data['target'].'.location.href=\''.$data['action'].'\'" /></div>'."\n";
|
||||
break;
|
||||
case 'step':
|
||||
$html .= '<div id="plbl'.$name.$this->code.'" style="'.$style_lbl.'">'.$this->step.'</div>'."\n";
|
||||
break;
|
||||
case 'percent':
|
||||
// only one inner percent
|
||||
// print "STYLE[$name]: ".$style_lbl."<br>";
|
||||
if (!$html_percent) {
|
||||
$html_percent = '<div id="plbl'.$name.$this->code.'" style="'.$style_lbl.'width:'.$data['width'].'px;line-height:1;text-shadow: 0 0 .2em white, 0 0 .5em white;">'.$this->_calculatePercent($this->step).'%</div>'."\n";
|
||||
}
|
||||
break;
|
||||
case 'percentlbl':
|
||||
$html .= '<div id="plbl'.$name.$this->code.'" style="'.$style_lbl.'width:'.$data['width'].'px;">'.$this->_calculatePercent($this->step).'%</div>'."\n";
|
||||
break;
|
||||
case 'crossbar':
|
||||
$html .= '<div id="plbl'.$name.$this->code.'" style="'.$style_lbl.'">'.$data['value'].'</div>'."\n";
|
||||
|
||||
$js .= 'function PBrotaryCross'.$name.$this->code.'() {'."\n";
|
||||
$js .= ' cross = document.getElementById("plbl'.$name.$this->code.'").firstChild.nodeValue;'."\n";
|
||||
$js .= ' switch(cross) {'."\n";
|
||||
$js .= ' case "--": cross = "\\\\"; break;'."\n";
|
||||
$js .= ' case "\\\\": cross = "|"; break;'."\n";
|
||||
$js .= ' case "|": cross = "/"; break;'."\n";
|
||||
$js .= ' default: cross = "--"; break;'."\n";
|
||||
$js .= ' }'."\n";
|
||||
$js .= ' document.getElementById("plbl'.$name.$this->code.'").firstChild.nodeValue = cross;'."\n";
|
||||
$js .= '}'."\n";
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// write the progress bar + inner percent inside
|
||||
$html .= $html_bar_top;
|
||||
$html .= $html_percent;
|
||||
$html .= $html_bar_bottom;
|
||||
$html .= $html_button; // any buttons on bottom
|
||||
|
||||
if (count($this->label) > 0) {
|
||||
$js .= 'function PBlabelText'.$this->code.'(name,text) {'."\n";
|
||||
$js .= ' name = "plbl" + name + "'.$this->code.'";'."\n";
|
||||
$js .= ' document.getElementById(name).innerHTML=text;'."\n";
|
||||
$js .= '}'."\n";
|
||||
}
|
||||
|
||||
if ($this->frame['show'] == true) {
|
||||
$html .= '</div>'."\n";
|
||||
}
|
||||
|
||||
$html .= '<script type="text/JavaScript">'."\n";
|
||||
$html .= $js;
|
||||
$html .= '</script>'."\n";
|
||||
|
||||
$html .= '</div>';
|
||||
|
||||
return $html;
|
||||
}
|
||||
|
||||
public function show()
|
||||
{
|
||||
$this->status = 'show';
|
||||
echo $this->getHtml();
|
||||
$this->_flushCache();
|
||||
}
|
||||
|
||||
public function moveStep($step)
|
||||
{
|
||||
$last_step = $this->step;
|
||||
$this->_setStep($step);
|
||||
|
||||
$js = '';
|
||||
$new_position = $this->_calculatePosition($this->step);
|
||||
if ($new_position['width'] != $this->position['width'] && ($this->direction == 'right' || $this->direction == 'left')) {
|
||||
if ($this->direction=='left') {
|
||||
$js .= 'PBposition'.$this->code.'("left",'.$new_position['left'].');';
|
||||
}
|
||||
$js .= 'PBposition'.$this->code.'("width",'.$new_position['width'].');';
|
||||
}
|
||||
if ($new_position['height'] != $this->position['height'] && ($this->direction == 'up' || $this->direction == 'down')) {
|
||||
if ($this->direction=='up') {
|
||||
$js .= 'PBposition'.$this->code.'("top",'.$new_position['top'].');';
|
||||
}
|
||||
$js .= 'PBposition'.$this->code.'("height",'.$new_position['height'].');';
|
||||
}
|
||||
$this->position = $new_position;
|
||||
foreach ($this->label as $name => $data) {
|
||||
if (array_key_exists('type', $data)) {
|
||||
switch($data['type']) {
|
||||
case 'step':
|
||||
if ($this->step != $last_step) {
|
||||
$js .= 'PBlabelText'.$this->code.'("'.$name.'","'.$this->step.'/'.$this->max.'");';
|
||||
}
|
||||
break;
|
||||
case 'percentlbl':
|
||||
case 'percent':
|
||||
$percent = $this->_calculatePercent($this->step);
|
||||
if ($percent != $this->_calculatePercent($last_step)) {
|
||||
$js .= 'PBlabelText'.$this->code.'("'.$name.'","'.$percent.'%");';
|
||||
}
|
||||
break;
|
||||
case 'crossbar':
|
||||
$js .= 'PBrotaryCross'.$name.$this->code.'();';
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if ($js != '') {
|
||||
echo '<script type="text/JavaScript">'.$js.'</script>'."\n";
|
||||
$this->_flushCache();
|
||||
}
|
||||
}
|
||||
|
||||
public function moveNext()
|
||||
{
|
||||
$this->moveStep($this->step + 1);
|
||||
}
|
||||
|
||||
public function moveMin()
|
||||
{
|
||||
$this->moveStep($this->min);
|
||||
}
|
||||
|
||||
public function hide()
|
||||
{
|
||||
if ($this->status == 'show') {
|
||||
$this->status = 'hide';
|
||||
|
||||
$output = '<script type="text/JavaScript">';
|
||||
$output .= 'document.getElementById("pbm'.$this->code.'").style.visibility="hidden";document.getElementById("pbm'.$this->code.'").style.display="none";';
|
||||
$output .= '</script>'."\n";
|
||||
echo $output;
|
||||
$this->_flushCache();
|
||||
}
|
||||
}
|
||||
|
||||
public function unhide()
|
||||
{
|
||||
if ($this->status == 'hide') {
|
||||
$this->status = 'show';
|
||||
|
||||
$output = '<script type="text/JavaScript">';
|
||||
$output .= 'document.getElementById("pbm'.$this->code.'").style.visibility="visible";document.getElementById("pbm'.$this->code.'").style.visibility="block";';
|
||||
$output .= '</script>'."\n";
|
||||
echo $output;
|
||||
$this->_flushCache();
|
||||
}
|
||||
}
|
||||
}
|
||||
29
www/lib/CoreLibs/Template/SmartyExtend.Inc
Normal file
29
www/lib/CoreLibs/Template/SmartyExtend.Inc
Normal file
@@ -0,0 +1,29 @@
|
||||
<?
|
||||
/********************************************************************
|
||||
* AUTHOR: Clemens "Gullevek" Schwaighofer (www.gullevek.org)
|
||||
* CREATED: 2004/12/21
|
||||
* SHORT DESCRIPTION:
|
||||
* extends smarty with the l10n class so I can use __(, etc calls
|
||||
* HISTORY:
|
||||
* 2005/06/22 (cs) include smarty class here, so there is no need to include it in the main file
|
||||
*********************************************************************/
|
||||
|
||||
// read in the Smarty class for definition
|
||||
// use smarty BC for backwards compability
|
||||
// try to include file from LIBS path, or from normal path
|
||||
_spl_autoload('SmartyBC.class.php');
|
||||
|
||||
class SmartyML extends SmartyBC
|
||||
{
|
||||
public $l10n;
|
||||
|
||||
// constructor class, just sets the language stuff
|
||||
public function __construct($lang)
|
||||
{
|
||||
SmartyBC::__construct();
|
||||
_spl_autoload('Class.l10n.inc');
|
||||
$this->l10n = new l10n($lang);
|
||||
// variable variable register
|
||||
$this->register_modifier('getvar', array(&$this, 'get_template_vars'));
|
||||
}
|
||||
}
|
||||
31
www/lib/CoreLibs/Upload/Core/qqUploadedFileForm.inc
Executable file
31
www/lib/CoreLibs/Upload/Core/qqUploadedFileForm.inc
Executable file
@@ -0,0 +1,31 @@
|
||||
<?php
|
||||
|
||||
namespace CoreLibs\Upload\Core;
|
||||
|
||||
/**
|
||||
* Handle file uploads via regular form post (uses the $_FILES array)
|
||||
*/
|
||||
class qqUploadedFileForm
|
||||
{
|
||||
/**
|
||||
* Save the file to the specified path
|
||||
* @return boolean TRUE on success
|
||||
*/
|
||||
public function save($path)
|
||||
{
|
||||
if (!move_uploaded_file($_FILES['qqfile']['tmp_name'], $path)) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
public function getName()
|
||||
{
|
||||
return $_FILES['qqfile']['name'];
|
||||
}
|
||||
public function getSize()
|
||||
{
|
||||
return $_FILES['qqfile']['size'];
|
||||
}
|
||||
}
|
||||
|
||||
# __END__
|
||||
46
www/lib/CoreLibs/Upload/Core/qqUploadedFileXhr.inc
Executable file
46
www/lib/CoreLibs/Upload/Core/qqUploadedFileXhr.inc
Executable file
@@ -0,0 +1,46 @@
|
||||
<?php
|
||||
|
||||
namespace CoreLibs\Upload\Core;
|
||||
|
||||
/**
|
||||
* Handle file uploads via XMLHttpRequest
|
||||
*/
|
||||
class qqUploadedFileXhr
|
||||
{
|
||||
/**
|
||||
* Save the file to the specified path
|
||||
* @return boolean TRUE on success
|
||||
*/
|
||||
public function save($path)
|
||||
{
|
||||
$input = fopen("php://input", "r");
|
||||
$temp = tmpfile();
|
||||
$realSize = stream_copy_to_stream($input, $temp);
|
||||
fclose($input);
|
||||
|
||||
if ($realSize != $this->getSize()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$target = fopen($path, "w");
|
||||
fseek($temp, 0, SEEK_SET);
|
||||
stream_copy_to_stream($temp, $target);
|
||||
fclose($target);
|
||||
|
||||
return true;
|
||||
}
|
||||
public function getName()
|
||||
{
|
||||
return $_GET['qqfile'];
|
||||
}
|
||||
public function getSize()
|
||||
{
|
||||
if (isset($_SERVER["CONTENT_LENGTH"])) {
|
||||
return (int)$_SERVER["CONTENT_LENGTH"];
|
||||
} else {
|
||||
throw new Exception('Getting content length is not supported.');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
# __END__
|
||||
112
www/lib/CoreLibs/Upload/qqFileUploader.inc
Executable file
112
www/lib/CoreLibs/Upload/qqFileUploader.inc
Executable file
@@ -0,0 +1,112 @@
|
||||
<?php
|
||||
|
||||
namespace CoreLibs\Upload;
|
||||
|
||||
use \CoreLibs\Upload\Core\qqUploadedFileForm;
|
||||
use \CoreLibs\Upload\Core\qqUploadedFileXhr;
|
||||
|
||||
class qqFileUploader
|
||||
{
|
||||
private $allowedExtensions = array();
|
||||
private $sizeLimit = 10485760;
|
||||
private $file;
|
||||
|
||||
public function __construct(array $allowedExtensions = array(), $sizeLimit = 10485760)
|
||||
{
|
||||
$allowedExtensions = array_map("strtolower", $allowedExtensions);
|
||||
|
||||
$this->allowedExtensions = $allowedExtensions;
|
||||
$this->sizeLimit = $sizeLimit;
|
||||
|
||||
$this->checkServerSettings();
|
||||
|
||||
if (isset($_GET['qqfile'])) {
|
||||
$this->file = new qqUploadedFileXhr();
|
||||
} elseif (isset($_FILES['qqfile'])) {
|
||||
$this->file = new qqUploadedFileForm();
|
||||
} else {
|
||||
$this->file = false;
|
||||
}
|
||||
}
|
||||
|
||||
private function checkServerSettings()
|
||||
{
|
||||
$postSize = $this->toBytes(ini_get('post_max_size'));
|
||||
$uploadSize = $this->toBytes(ini_get('upload_max_filesize'));
|
||||
|
||||
if ($postSize < $this->sizeLimit || $uploadSize < $this->sizeLimit) {
|
||||
$size = max(1, $this->sizeLimit / 1024 / 1024) . 'M';
|
||||
die("{'error':'increase post_max_size and upload_max_filesize to $size'}");
|
||||
}
|
||||
}
|
||||
|
||||
private function toBytes($str)
|
||||
{
|
||||
$val = trim($str);
|
||||
$last = strtolower($str[strlen($str)-1]);
|
||||
switch ($last) {
|
||||
case 'g':
|
||||
$val *= 1024;
|
||||
// no break
|
||||
case 'm':
|
||||
$val *= 1024;
|
||||
// no break
|
||||
case 'k':
|
||||
$val *= 1024;
|
||||
}
|
||||
return $val;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns array('success'=>true) or array('error'=>'error message')
|
||||
*/
|
||||
public function handleUpload($uploadDirectory, $replaceOldFile = false)
|
||||
{
|
||||
if (!is_writable($uploadDirectory)) {
|
||||
return array('error' => "Server error. Upload directory isn't writable.");
|
||||
}
|
||||
|
||||
if (!$this->file) {
|
||||
return array('error' => 'No files were uploaded.');
|
||||
}
|
||||
|
||||
$size = $this->file->getSize();
|
||||
|
||||
if ($size == 0) {
|
||||
return array('error' => 'File is empty');
|
||||
}
|
||||
|
||||
if ($size > $this->sizeLimit) {
|
||||
return array('error' => 'File is too large');
|
||||
}
|
||||
|
||||
$pathinfo = pathinfo($this->file->getName());
|
||||
$filename = $pathinfo['filename'];
|
||||
//$filename = md5(uniqid());
|
||||
$ext = $pathinfo['extension'];
|
||||
|
||||
if ($this->allowedExtensions && !in_array(strtolower($ext), $this->allowedExtensions)) {
|
||||
$these = implode(', ', $this->allowedExtensions);
|
||||
return array('error' => 'File has an invalid extension, it should be one of '. $these . '.');
|
||||
}
|
||||
|
||||
if (!$replaceOldFile) {
|
||||
/// don't overwrite previous files that were uploaded
|
||||
while (file_exists($uploadDirectory . $filename . '.' . $ext)) {
|
||||
$filename .= rand(10, 99);
|
||||
}
|
||||
}
|
||||
|
||||
$this->uploadFileName = $uploadDirectory . $filename . '.' . $ext;
|
||||
$this->uploadFileExt = $ext;
|
||||
|
||||
if ($this->file->save($uploadDirectory . $filename . '.' . $ext)) {
|
||||
return array('success'=>true);
|
||||
} else {
|
||||
return array('error'=> 'Could not save uploaded file.' .
|
||||
'The upload was cancelled, or server error encountered');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
# __END__
|
||||
Reference in New Issue
Block a user