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:
Clemens Schwaighofer
2018-03-23 13:43:22 +09:00
parent 7d42256a30
commit 5474ae2dda
313 changed files with 19000 additions and 14776 deletions

View 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>&nbsp;</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>&nbsp;</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

View 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

File diff suppressed because it is too large Load Diff

View 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('&lt;b&gt;', '<b>', $text);
$text = str_replace('&lt;/b&gt;', '</b>', $text);
$text = str_replace('&lt;i&gt;', '<i>', $text);
$text = str_replace('&lt;/i&gt;', '</i>', $text);
// my need a change
$text = str_replace('&lt;a href=&quot;', '<a target="_blank" href="', $text);
$text = str_replace('&quot;&gt;', '">', $text);
$text = str_replace('&lt;/a&gt;', '</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('&lt;', '<', $text);
$text = str_replace('&gt;', '>', $text);
$text = str_replace('&amp;', '&', $text);
$text = str_replace('&quot;', '"', $text);
$text = str_replace('&#039;', "'", $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

File diff suppressed because it is too large Load Diff

View 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;
}
}

View 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;
}
}

View 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;
}
}

View 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__

View 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__

View 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;
}
}
}

View 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;
}
}

File diff suppressed because it is too large Load Diff

View 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 = '&nbsp;')
{
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();
}
}
}

View 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'));
}
}

View 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__

View 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__

View 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__

104
www/lib/Error.Handling.inc Normal file
View File

@@ -0,0 +1,104 @@
<?
/*********************************************************************
* AUTHOR: Clemens Schwaighofer
* CREATED: 2011/2/8
* DESCRIPTION: pre function to collect all non critical errors into a log file if possible
* include this file at the very beginning of the script to get the notices, strict, etc messages.
* error etc will still be written to the log/display
*********************************************************************/
// define the base working directory outside because in the function it might return undefined
DEFINE('CURRENT_WORKING_DIR', getcwd().'/');
// METHOD: MyErrorHandler
// PARAMS: $type: the error code from PHP
// $message: the error message from php
// $file: in which file the error happend. this is the source file (eg include)
// $line: in which line the error happened
// $context: array with all the variable
// RETURN: true, so cought errors do not get processed by the PHP error engine
// DESC: will catch any error except E_ERROR and try to write them to the log file in log/php_error-<DAY>.llog
// if this fails, it will print the data to the window via echo
function MyErrorHandler($type, $message, $file, $line, $context)
{
if (!(error_reporting() & $type) && !SHOW_ALL_ERRORS) {
// This error code is not included in error_reporting
return;
}
// ERROR LEVEL
$error_level = array (
1 => 'E_ERROR',
2 => 'E_WARNING',
4 => 'E_PARSE',
8 => 'E_NOTICE',
16 => 'E_CORE_ERROR',
32 => 'E_CORE_WARNING',
64 => 'E_COMPILE_ERROR',
128 => 'E_COMPILE_WARNING',
256 => 'E_USER_ERROR',
512 => 'E_USER_WARNING',
1024 => 'E_USER_NOTICE',
2048 => 'E_STRICT',
4096 => 'E_RECOVERABLE_ERROR',
8192 => 'E_DEPRICATED',
16384 => 'E_USER_DEPRICATED',
30719 => 'E_ALL'
);
// get the current page name (strip path)
$page_temp = explode("/", $_SERVER["PHP_SELF"]);
// the output string:
// [] current timestamp
// {} the current page name in which the error occured (running script)
// [] the file where the error actually happened
// <> the line number in this file
// [|] error name and error number
// : the php error message
$output = '['.date("Y-m-d H:i:s").'] {'.array_pop($page_temp).'} ['.$file.'] <'.$line.'> ['.$error_level[$type].'|'.$type.']: '.$message;
# try to open file
$ROOT = CURRENT_WORKING_DIR;
$LOG = 'log/';
// if the log folder is not found, try to create it
if (!is_dir($ROOT.$LOG) && !is_file($ROOT.LOG)) {
$ok = mkdir($ROOT.$LOG);
}
$error = 0;
// again, if the folder now exists, else set error flag
if (is_dir($ROOT.$LOG)) {
$fn = $ROOT.$LOG.'php_errors-'.date('Y-m-d').'.log';
// when opening, surpress the warning so we can catch the no file pointer below without throwing a warning for this
$fp = @fopen($fn, 'a');
// write if we have a file pointer, else set error flag
if ($fp) {
fwrite($fp, $output."\n");
fclose($fp);
} else {
$error = 1;
}
} else {
$error = 1;
}
// if the above writing failed
if ($error) {
// if the display errors is on
// pretty print output for HTML
if (ini_get("display_errors")) {
echo "<div style='border: 1px dotted red; background-color: #ffffe5; color: #000000; padding: 5px; margin-bottom: 2px;'>";
echo "<div style='color: orange; font-weight: bold;'>".$error_level[$type].":</div>";
echo "<b>$message</b> on line <b>$line</b> in <b>$file</b>";
echo "</div>";
}
// if write to log is on
// simplified, remove datetime for log file
if (ini_get('log_errors')) {
error_log('{'.$page_temp.'} ['.$file.'] <'.$line.'> ['.$error_level[$type].'|'.$type.']: '.$message);
}
}
// return true, to avoid that php calls its own error stuff
// if E_ERROR, the php one gets called anyway
return true;
}
// init the error handler
set_error_handler("MyErrorHandler");

Binary file not shown.

BIN
www/lib/Fonts/MankSans.ttf Normal file

Binary file not shown.

Binary file not shown.

Binary file not shown.

BIN
www/lib/Fonts/tahoma.ttf Normal file

Binary file not shown.

1
www/lib/Smarty Symbolic link
View File

@@ -0,0 +1 @@
smarty-3.1.30/

1
www/lib/pChart Symbolic link
View File

@@ -0,0 +1 @@
pChart2.1.4/

View File

@@ -0,0 +1,184 @@
<?php
/*
pBarcode128 - class to create barcodes (128B)
Version : 2.1.4
Made by : Jean-Damien POGOLOTTI
Last Update : 19/01/2014
This file can be distributed under the license you can find at :
http://www.pchart.net/license
You can find the whole class documentation on the pChart web site.
*/
/* pData class definition */
class pBarcode128
{
var $Codes;
var $Reverse;
var $Result;
var $pChartObject;
var $CRC;
/* Class creator */
function pBarcode128($BasePath="")
{
$this->Codes = "";
$this->Reverse = "";
$FileHandle = @fopen($BasePath."data/128B.db", "r");
if (!$FileHandle) { die("Cannot find barcode database (".$BasePath."128B.db)."); }
while (!feof($FileHandle))
{
$Buffer = fgets($FileHandle,4096);
$Buffer = str_replace(chr(10),"",$Buffer);
$Buffer = str_replace(chr(13),"",$Buffer);
$Values = preg_split("/;/",$Buffer);
$this->Codes[$Values[1]]["ID"] = $Values[0];
$this->Codes[$Values[1]]["Code"] = $Values[2];
$this->Reverse[$Values[0]]["Code"] = $Values[2];
$this->Reverse[$Values[0]]["Asc"] = $Values[1];
}
fclose($FileHandle);
}
/* Return the projected size of a barcode */
function getSize($TextString,$Format="")
{
$Angle = isset($Format["Angle"]) ? $Format["Angle"] : 0;
$ShowLegend = isset($Format["ShowLegend"]) ? $Format["ShowLegend"] : FALSE;
$LegendOffset = isset($Format["LegendOffset"]) ? $Format["LegendOffset"] : 5;
$DrawArea = isset($Format["DrawArea"]) ? $Format["DrawArea"] : FALSE;
$FontSize = isset($Format["FontSize"]) ? $Format["FontSize"] : 12;
$Height = isset($Format["Height"]) ? $Format["Height"] : 30;
$TextString = $this->encode128($TextString);
$BarcodeLength = strlen($this->Result);
if ( $DrawArea ) { $WOffset = 20; } else { $WOffset = 0; }
if ( $ShowLegend ) { $HOffset = $FontSize+$LegendOffset+$WOffset; } else { $HOffset = 0; }
$X1 = cos($Angle * PI / 180) * ($WOffset+$BarcodeLength);
$Y1 = sin($Angle * PI / 180) * ($WOffset+$BarcodeLength);
$X2 = $X1 + cos(($Angle+90) * PI / 180) * ($HOffset+$Height);
$Y2 = $Y1 + sin(($Angle+90) * PI / 180) * ($HOffset+$Height);
$AreaWidth = max(abs($X1),abs($X2));
$AreaHeight = max(abs($Y1),abs($Y2));
return(array("Width"=>$AreaWidth,"Height"=>$AreaHeight));
}
function encode128($Value,$Format="")
{
$this->Result = "11010010000";
$this->CRC = 104;
$TextString = "";
for($i=1;$i<=strlen($Value);$i++)
{
$CharCode = ord($this->mid($Value,$i,1));
if ( isset($this->Codes[$CharCode]) )
{
$this->Result = $this->Result.$this->Codes[$CharCode]["Code"];
$this->CRC = $this->CRC + $i*$this->Codes[$CharCode]["ID"];
$TextString = $TextString.chr($CharCode);
}
}
$this->CRC = $this->CRC - floor($this->CRC/103)*103;
$this->Result = $this->Result.$this->Reverse[$this->CRC]["Code"];
$this->Result = $this->Result."1100011101011";
return($TextString);
}
/* Create the encoded string */
function draw($Object,$Value,$X,$Y,$Format="")
{
$this->pChartObject = $Object;
$R = isset($Format["R"]) ? $Format["R"] : 0;
$G = isset($Format["G"]) ? $Format["G"] : 0;
$B = isset($Format["B"]) ? $Format["B"] : 0;
$Alpha = isset($Format["Alpha"]) ? $Format["Alpha"] : 100;
$Height = isset($Format["Height"]) ? $Format["Height"] : 30;
$Angle = isset($Format["Angle"]) ? $Format["Angle"] : 0;
$ShowLegend = isset($Format["ShowLegend"]) ? $Format["ShowLegend"] : FALSE;
$LegendOffset = isset($Format["LegendOffset"]) ? $Format["LegendOffset"] : 5;
$DrawArea = isset($Format["DrawArea"]) ? $Format["DrawArea"] : FALSE;
$AreaR = isset($Format["AreaR"]) ? $Format["AreaR"] : 255;
$AreaG = isset($Format["AreaG"]) ? $Format["AreaG"] : 255;
$AreaB = isset($Format["AreaB"]) ? $Format["AreaB"] : 255;
$AreaBorderR = isset($Format["AreaBorderR"]) ? $Format["AreaBorderR"] : $AreaR;
$AreaBorderG = isset($Format["AreaBorderG"]) ? $Format["AreaBorderG"] : $AreaG;
$AreaBorderB = isset($Format["AreaBorderB"]) ? $Format["AreaBorderB"] : $AreaB;
$TextString = $this->encode128($Value);
if ( $DrawArea )
{
$X1 = $X + cos(($Angle-135) * PI / 180) * 10;
$Y1 = $Y + sin(($Angle-135) * PI / 180) * 10;
$X2 = $X1 + cos($Angle * PI / 180) * (strlen($this->Result)+20);
$Y2 = $Y1 + sin($Angle * PI / 180) * (strlen($this->Result)+20);
if ( $ShowLegend )
{
$X3 = $X2 + cos(($Angle+90) * PI / 180) * ($Height+$LegendOffset+$this->pChartObject->FontSize+10);
$Y3 = $Y2 + sin(($Angle+90) * PI / 180) * ($Height+$LegendOffset+$this->pChartObject->FontSize+10);
}
else
{
$X3 = $X2 + cos(($Angle+90) * PI / 180) * ($Height+20);
$Y3 = $Y2 + sin(($Angle+90) * PI / 180) * ($Height+20);
}
$X4 = $X3 + cos(($Angle+180) * PI / 180) * (strlen($this->Result)+20);
$Y4 = $Y3 + sin(($Angle+180) * PI / 180) * (strlen($this->Result)+20);
$Polygon = array($X1,$Y1,$X2,$Y2,$X3,$Y3,$X4,$Y4);
$Settings = array("R"=>$AreaR,"G"=>$AreaG,"B"=>$AreaB,"BorderR"=>$AreaBorderR,"BorderG"=>$AreaBorderG,"BorderB"=>$AreaBorderB);
$this->pChartObject->drawPolygon($Polygon,$Settings);
}
for($i=1;$i<=strlen($this->Result);$i++)
{
if ( $this->mid($this->Result,$i,1) == 1 )
{
$X1 = $X + cos($Angle * PI / 180) * $i;
$Y1 = $Y + sin($Angle * PI / 180) * $i;
$X2 = $X1 + cos(($Angle+90) * PI / 180) * $Height;
$Y2 = $Y1 + sin(($Angle+90) * PI / 180) * $Height;
$Settings = array("R"=>$R,"G"=>$G,"B"=>$B,"Alpha"=>$Alpha);
$this->pChartObject->drawLine($X1,$Y1,$X2,$Y2,$Settings);
}
}
if ( $ShowLegend )
{
$X1 = $X + cos($Angle * PI / 180) * (strlen($this->Result)/2);
$Y1 = $Y + sin($Angle * PI / 180) * (strlen($this->Result)/2);
$LegendX = $X1 + cos(($Angle+90) * PI / 180) * ($Height+$LegendOffset);
$LegendY = $Y1 + sin(($Angle+90) * PI / 180) * ($Height+$LegendOffset);
$Settings = array("R"=>$R,"G"=>$G,"B"=>$B,"Alpha"=>$Alpha,"Angle"=>-$Angle,"Align"=>TEXT_ALIGN_TOPMIDDLE);
$this->pChartObject->drawText($LegendX,$LegendY,$TextString,$Settings);
}
}
function left($value,$NbChar) { return substr($value,0,$NbChar); }
function right($value,$NbChar) { return substr($value,strlen($value)-$NbChar,$NbChar); }
function mid($value,$Depart,$NbChar) { return substr($value,$Depart-1,$NbChar); }
}
?>

View File

@@ -0,0 +1,200 @@
<?php
/*
pBarcode39 - class to create barcodes (39B)
Version : 2.1.4
Made by : Jean-Damien POGOLOTTI
Last Update : 19/01/2014
This file can be distributed under the license you can find at :
http://www.pchart.net/license
You can find the whole class documentation on the pChart web site.
*/
/* pData class definition */
class pBarcode39
{
var $Codes;
var $Reverse;
var $Result;
var $pChartObject;
var $CRC;
var $MOD43;
/* Class creator */
function pBarcode39($BasePath="",$EnableMOD43=FALSE)
{
$this->MOD43 = $EnableMOD43;
$this->Codes = "";
$this->Reverse = "";
$FileHandle = @fopen($BasePath."data/39.db", "r");
if (!$FileHandle) { die("Cannot find barcode database (".$BasePath."data/39.db)."); }
while (!feof($FileHandle))
{
$Buffer = fgets($FileHandle,4096);
$Buffer = str_replace(chr(10),"",$Buffer);
$Buffer = str_replace(chr(13),"",$Buffer);
$Values = preg_split("/;/",$Buffer);
$this->Codes[$Values[0]] = $Values[1];
}
fclose($FileHandle);
}
/* Return the projected size of a barcode */
function getSize($TextString,$Format="")
{
$Angle = isset($Format["Angle"]) ? $Format["Angle"] : 0;
$ShowLegend = isset($Format["ShowLegend"]) ? $Format["ShowLegend"] : FALSE;
$LegendOffset = isset($Format["LegendOffset"]) ? $Format["LegendOffset"] : 5;
$DrawArea = isset($Format["DrawArea"]) ? $Format["DrawArea"] : FALSE;
$FontSize = isset($Format["FontSize"]) ? $Format["FontSize"] : 12;
$Height = isset($Format["Height"]) ? $Format["Height"] : 30;
$TextString = $this->encode39($TextString);
$BarcodeLength = strlen($this->Result);
if ( $DrawArea ) { $WOffset = 20; } else { $WOffset = 0; }
if ( $ShowLegend ) { $HOffset = $FontSize+$LegendOffset+$WOffset; } else { $HOffset = 0; }
$X1 = cos($Angle * PI / 180) * ($WOffset+$BarcodeLength);
$Y1 = sin($Angle * PI / 180) * ($WOffset+$BarcodeLength);
$X2 = $X1 + cos(($Angle+90) * PI / 180) * ($HOffset+$Height);
$Y2 = $Y1 + sin(($Angle+90) * PI / 180) * ($HOffset+$Height);
$AreaWidth = max(abs($X1),abs($X2));
$AreaHeight = max(abs($Y1),abs($Y2));
return(array("Width"=>$AreaWidth,"Height"=>$AreaHeight));
}
/* Create the encoded string */
function encode39($Value)
{
$this->Result = "100101101101"."0";
$TextString = "";
for($i=1;$i<=strlen($Value);$i++)
{
$CharCode = ord($this->mid($Value,$i,1));
if ( $CharCode >= 97 && $CharCode <= 122 ) { $CharCode = $CharCode - 32; }
if ( isset($this->Codes[chr($CharCode)]) )
{
$this->Result = $this->Result.$this->Codes[chr($CharCode)]."0";
$TextString = $TextString.chr($CharCode);
}
}
if ( $this->MOD43 )
{
$Checksum = $this->checksum($TextString);
$this->Result = $this->Result.$this->Codes[$Checksum]."0";
}
$this->Result = $this->Result."100101101101";
$TextString = "*".$TextString."*";
return($TextString);
}
/* Create the encoded string */
function draw($Object,$Value,$X,$Y,$Format="")
{
$this->pChartObject = $Object;
$R = isset($Format["R"]) ? $Format["R"] : 0;
$G = isset($Format["G"]) ? $Format["G"] : 0;
$B = isset($Format["B"]) ? $Format["B"] : 0;
$Alpha = isset($Format["Alpha"]) ? $Format["Alpha"] : 100;
$Height = isset($Format["Height"]) ? $Format["Height"] : 30;
$Angle = isset($Format["Angle"]) ? $Format["Angle"] : 0;
$ShowLegend = isset($Format["ShowLegend"]) ? $Format["ShowLegend"] : FALSE;
$LegendOffset = isset($Format["LegendOffset"]) ? $Format["LegendOffset"] : 5;
$DrawArea = isset($Format["DrawArea"]) ? $Format["DrawArea"] : FALSE;
$AreaR = isset($Format["AreaR"]) ? $Format["AreaR"] : 255;
$AreaG = isset($Format["AreaG"]) ? $Format["AreaG"] : 255;
$AreaB = isset($Format["AreaB"]) ? $Format["AreaB"] : 255;
$AreaBorderR = isset($Format["AreaBorderR"]) ? $Format["AreaBorderR"] : $AreaR;
$AreaBorderG = isset($Format["AreaBorderG"]) ? $Format["AreaBorderG"] : $AreaG;
$AreaBorderB = isset($Format["AreaBorderB"]) ? $Format["AreaBorderB"] : $AreaB;
$TextString = $this->encode39($Value);
if ( $DrawArea )
{
$X1 = $X + cos(($Angle-135) * PI / 180) * 10;
$Y1 = $Y + sin(($Angle-135) * PI / 180) * 10;
$X2 = $X1 + cos($Angle * PI / 180) * (strlen($this->Result)+20);
$Y2 = $Y1 + sin($Angle * PI / 180) * (strlen($this->Result)+20);
if ( $ShowLegend )
{
$X3 = $X2 + cos(($Angle+90) * PI / 180) * ($Height+$LegendOffset+$this->pChartObject->FontSize+10);
$Y3 = $Y2 + sin(($Angle+90) * PI / 180) * ($Height+$LegendOffset+$this->pChartObject->FontSize+10);
}
else
{
$X3 = $X2 + cos(($Angle+90) * PI / 180) * ($Height+20);
$Y3 = $Y2 + sin(($Angle+90) * PI / 180) * ($Height+20);
}
$X4 = $X3 + cos(($Angle+180) * PI / 180) * (strlen($this->Result)+20);
$Y4 = $Y3 + sin(($Angle+180) * PI / 180) * (strlen($this->Result)+20);
$Polygon = array($X1,$Y1,$X2,$Y2,$X3,$Y3,$X4,$Y4);
$Settings = array("R"=>$AreaR,"G"=>$AreaG,"B"=>$AreaB,"BorderR"=>$AreaBorderR,"BorderG"=>$AreaBorderG,"BorderB"=>$AreaBorderB);
$this->pChartObject->drawPolygon($Polygon,$Settings);
}
for($i=1;$i<=strlen($this->Result);$i++)
{
if ( $this->mid($this->Result,$i,1) == 1 )
{
$X1 = $X + cos($Angle * PI / 180) * $i;
$Y1 = $Y + sin($Angle * PI / 180) * $i;
$X2 = $X1 + cos(($Angle+90) * PI / 180) * $Height;
$Y2 = $Y1 + sin(($Angle+90) * PI / 180) * $Height;
$Settings = array("R"=>$R,"G"=>$G,"B"=>$B,"Alpha"=>$Alpha);
$this->pChartObject->drawLine($X1,$Y1,$X2,$Y2,$Settings);
}
}
if ( $ShowLegend )
{
$X1 = $X + cos($Angle * PI / 180) * (strlen($this->Result)/2);
$Y1 = $Y + sin($Angle * PI / 180) * (strlen($this->Result)/2);
$LegendX = $X1 + cos(($Angle+90) * PI / 180) * ($Height+$LegendOffset);
$LegendY = $Y1 + sin(($Angle+90) * PI / 180) * ($Height+$LegendOffset);
$Settings = array("R"=>$R,"G"=>$G,"B"=>$B,"Alpha"=>$Alpha,"Angle"=>-$Angle,"Align"=>TEXT_ALIGN_TOPMIDDLE);
$this->pChartObject->drawText($LegendX,$LegendY,$TextString,$Settings);
}
}
function checksum( $string )
{
$checksum = 0;
$length = strlen( $string );
$charset = '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ-. $/+%';
for( $i=0; $i < $length; ++$i )
$checksum += strpos( $charset, $string[$i] );
return substr( $charset, ($checksum % 43), 1 );
}
function left($value,$NbChar) { return substr($value,0,$NbChar); }
function right($value,$NbChar) { return substr($value,strlen($value)-$NbChar,$NbChar); }
function mid($value,$Depart,$NbChar) { return substr($value,$Depart-1,$NbChar); }
}
?>

View File

@@ -0,0 +1,326 @@
<?php
/*
pBubble - class to draw bubble charts
Version : 2.1.4
Made by : Jean-Damien POGOLOTTI
Last Update : 19/01/2014
This file can be distributed under the license you can find at :
http://www.pchart.net/license
You can find the whole class documentation on the pChart web site.
*/
define("BUBBLE_SHAPE_ROUND" , 700001);
define("BUBBLE_SHAPE_SQUARE" , 700002);
/* pBubble class definition */
class pBubble
{
var $pChartObject;
var $pDataObject;
/* Class creator */
function pBubble($pChartObject,$pDataObject)
{
$this->pChartObject = $pChartObject;
$this->pDataObject = $pDataObject;
}
/* Prepare the scale */
function bubbleScale($DataSeries,$WeightSeries)
{
if ( !is_array($DataSeries) ) { $DataSeries = array($DataSeries); }
if ( !is_array($WeightSeries) ) { $WeightSeries = array($WeightSeries); }
/* Parse each data series to find the new min & max boundaries to scale */
$NewPositiveSerie = ""; $NewNegativeSerie = ""; $MaxValues = 0; $LastPositive = 0; $LastNegative = 0;
foreach($DataSeries as $Key => $SerieName)
{
$SerieWeightName = $WeightSeries[$Key];
$this->pDataObject->setSerieDrawable($SerieWeightName,FALSE);
if ( count($this->pDataObject->Data["Series"][$SerieName]["Data"]) > $MaxValues ) { $MaxValues = count($this->pDataObject->Data["Series"][$SerieName]["Data"]); }
foreach($this->pDataObject->Data["Series"][$SerieName]["Data"] as $Key => $Value)
{
if ( $Value >= 0 )
{
$BubbleBounds = $Value + $this->pDataObject->Data["Series"][$SerieWeightName]["Data"][$Key];
if ( !isset($NewPositiveSerie[$Key]) )
{ $NewPositiveSerie[$Key] = $BubbleBounds; }
elseif ( $NewPositiveSerie[$Key] < $BubbleBounds )
{ $NewPositiveSerie[$Key] = $BubbleBounds; }
$LastPositive = $BubbleBounds;
}
else
{
$BubbleBounds = $Value - $this->pDataObject->Data["Series"][$SerieWeightName]["Data"][$Key];
if ( !isset($NewNegativeSerie[$Key]) )
{ $NewNegativeSerie[$Key] = $BubbleBounds; }
elseif ( $NewNegativeSerie[$Key] > $BubbleBounds )
{ $NewNegativeSerie[$Key] = $BubbleBounds; }
$LastNegative = $BubbleBounds;
}
}
}
/* Check for missing values and all the fake positive serie */
if ( $NewPositiveSerie != "" )
{
for ($i=0; $i<$MaxValues; $i++) { if (!isset($NewPositiveSerie[$i])) { $NewPositiveSerie[$i] = $LastPositive; } }
$this->pDataObject->addPoints($NewPositiveSerie,"BubbleFakePositiveSerie");
}
/* Check for missing values and all the fake negative serie */
if ( $NewNegativeSerie != "" )
{
for ($i=0; $i<$MaxValues; $i++) { if (!isset($NewNegativeSerie[$i])) { $NewNegativeSerie[$i] = $LastNegative; } }
$this->pDataObject->addPoints($NewNegativeSerie,"BubbleFakeNegativeSerie");
}
}
function resetSeriesColors()
{
$Data = $this->pDataObject->getData();
$Palette = $this->pDataObject->getPalette();
$ID = 0;
foreach($Data["Series"] as $SerieName => $SeriesParameters)
{
if ( $SeriesParameters["isDrawable"] )
{
$this->pDataObject->Data["Series"][$SerieName]["Color"]["R"] = $Palette[$ID]["R"];
$this->pDataObject->Data["Series"][$SerieName]["Color"]["G"] = $Palette[$ID]["G"];
$this->pDataObject->Data["Series"][$SerieName]["Color"]["B"] = $Palette[$ID]["B"];
$this->pDataObject->Data["Series"][$SerieName]["Color"]["Alpha"] = $Palette[$ID]["Alpha"];
$ID++;
}
}
}
/* Prepare the scale */
function drawBubbleChart($DataSeries,$WeightSeries,$Format="")
{
$ForceAlpha = isset($Format["ForceAlpha"]) ? $Format["ForceAlpha"] : VOID;
$DrawBorder = isset($Format["DrawBorder"]) ? $Format["DrawBorder"] : TRUE;
$BorderWidth = isset($Format["BorderWidth"]) ? $Format["BorderWidth"] : 1;
$Shape = isset($Format["Shape"]) ? $Format["Shape"] : BUBBLE_SHAPE_ROUND;
$Surrounding = isset($Format["Surrounding"]) ? $Format["Surrounding"] : NULL;
$BorderR = isset($Format["BorderR"]) ? $Format["BorderR"] : 0;
$BorderG = isset($Format["BorderG"]) ? $Format["BorderG"] : 0;
$BorderB = isset($Format["BorderB"]) ? $Format["BorderB"] : 0;
$BorderAlpha = isset($Format["BorderAlpha"]) ? $Format["BorderAlpha"] : 30;
$RecordImageMap = isset($Format["RecordImageMap"]) ? $Format["RecordImageMap"] : FALSE;
if ( !is_array($DataSeries) ) { $DataSeries = array($DataSeries); }
if ( !is_array($WeightSeries) ) { $WeightSeries = array($WeightSeries); }
$Data = $this->pDataObject->getData();
$Palette = $this->pDataObject->getPalette();
if ( isset($Data["Series"]["BubbleFakePositiveSerie"] ) ) { $this->pDataObject->setSerieDrawable("BubbleFakePositiveSerie",FALSE); }
if ( isset($Data["Series"]["BubbleFakeNegativeSerie"] ) ) { $this->pDataObject->setSerieDrawable("BubbleFakeNegativeSerie",FALSE); }
$this->resetSeriesColors();
list($XMargin,$XDivs) = $this->pChartObject->scaleGetXSettings();
foreach($DataSeries as $Key => $SerieName)
{
$AxisID = $Data["Series"][$SerieName]["Axis"];
$Mode = $Data["Axis"][$AxisID]["Display"];
$Format = $Data["Axis"][$AxisID]["Format"];
$Unit = $Data["Axis"][$AxisID]["Unit"];
if (isset($Data["Series"][$SerieName]["Description"])) { $SerieDescription = $Data["Series"][$SerieName]["Description"]; } else { $SerieDescription = $SerieName; }
$XStep = ($this->pChartObject->GraphAreaX2-$this->pChartObject->GraphAreaX1-$XMargin*2)/$XDivs;
$X = $this->pChartObject->GraphAreaX1 + $XMargin;
$Y = $this->pChartObject->GraphAreaY1 + $XMargin;
$Color = array("R"=>$Palette[$Key]["R"],"G"=>$Palette[$Key]["G"],"B"=>$Palette[$Key]["B"],"Alpha"=>$Palette[$Key]["Alpha"]);
if ( $ForceAlpha != VOID ) { $Color["Alpha"]=$ForceAlpha; }
if ( $DrawBorder )
{
if ( $BorderWidth != 1 )
{
if ( $Surrounding != NULL )
{ $BorderR = $Palette[$Key]["R"]+$Surrounding; $BorderG = $Palette[$Key]["G"]+$Surrounding; $BorderB = $Palette[$Key]["B"]+$Surrounding; }
else
{ $BorderR = $BorderR; $BorderG = $BorderG; $BorderB = $BorderB; }
if ( $ForceAlpha != VOID ) { $BorderAlpha = $ForceAlpha/2; }
$BorderColor = array("R"=>$BorderR,"G"=>$BorderG,"B"=>$BorderB,"Alpha"=>$BorderAlpha);
}
else
{
$Color["BorderAlpha"] = $BorderAlpha;
if ( $Surrounding != NULL )
{ $Color["BorderR"] = $Palette[$Key]["R"]+$Surrounding; $Color["BorderG"] = $Palette[$Key]["G"]+$Surrounding; $Color["BorderB"] = $Palette[$Key]["B"]+$Surrounding; }
else
{ $Color["BorderR"] = $BorderR; $Color["BorderG"] = $BorderG; $Color["BorderB"] = $BorderB; }
if ( $ForceAlpha != VOID ) { $Color["BorderAlpha"] = $ForceAlpha/2; }
}
}
foreach($Data["Series"][$SerieName]["Data"] as $iKey => $Point)
{
$Weight = $Point + $Data["Series"][$WeightSeries[$Key]]["Data"][$iKey];
$PosArray = $this->pChartObject->scaleComputeY($Point,array("AxisID"=>$AxisID));
$WeightArray = $this->pChartObject->scaleComputeY($Weight,array("AxisID"=>$AxisID));
if ( $Data["Orientation"] == SCALE_POS_LEFTRIGHT )
{
if ( $XDivs == 0 ) { $XStep = 0; } else { $XStep = ($this->pChartObject->GraphAreaX2-$this->pChartObject->GraphAreaX1-$XMargin*2)/$XDivs; }
$Y = floor($PosArray); $CircleRadius = floor(abs($PosArray - $WeightArray)/2);
if ( $Shape == BUBBLE_SHAPE_SQUARE )
{
if ( $RecordImageMap ) { $this->pChartObject->addToImageMap("RECT",floor($X-$CircleRadius).",".floor($Y-$CircleRadius).",".floor($X+$CircleRadius).",".floor($Y+$CircleRadius),$this->pChartObject->toHTMLColor($Palette[$Key]["R"],$Palette[$Key]["G"],$Palette[$Key]["B"]),$SerieDescription,$Data["Series"][$WeightSeries[$Key]]["Data"][$iKey]); }
if ( $BorderWidth != 1 )
{
$this->pChartObject->drawFilledRectangle($X-$CircleRadius-$BorderWidth,$Y-$CircleRadius-$BorderWidth,$X+$CircleRadius+$BorderWidth,$Y+$CircleRadius+$BorderWidth,$BorderColor);
$this->pChartObject->drawFilledRectangle($X-$CircleRadius,$Y-$CircleRadius,$X+$CircleRadius,$Y+$CircleRadius,$Color);
}
else
$this->pChartObject->drawFilledRectangle($X-$CircleRadius,$Y-$CircleRadius,$X+$CircleRadius,$Y+$CircleRadius,$Color);
}
elseif ( $Shape == BUBBLE_SHAPE_ROUND )
{
if ( $RecordImageMap ) { $this->pChartObject->addToImageMap("CIRCLE",floor($X).",".floor($Y).",".floor($CircleRadius),$this->pChartObject->toHTMLColor($Palette[$Key]["R"],$Palette[$Key]["G"],$Palette[$Key]["B"]),$SerieDescription,$Data["Series"][$WeightSeries[$Key]]["Data"][$iKey]); }
if ( $BorderWidth != 1 )
{
$this->pChartObject->drawFilledCircle($X,$Y,$CircleRadius+$BorderWidth,$BorderColor);
$this->pChartObject->drawFilledCircle($X,$Y,$CircleRadius,$Color);
}
else
$this->pChartObject->drawFilledCircle($X,$Y,$CircleRadius,$Color);
}
$X = $X + $XStep;
}
elseif ( $Data["Orientation"] == SCALE_POS_TOPBOTTOM )
{
if ( $XDivs == 0 ) { $XStep = 0; } else { $XStep = ($this->pChartObject->GraphAreaY2-$this->pChartObject->GraphAreaY1-$XMargin*2)/$XDivs; }
$X = floor($PosArray); $CircleRadius = floor(abs($PosArray - $WeightArray)/2);
if ( $Shape == BUBBLE_SHAPE_SQUARE )
{
if ( $RecordImageMap ) { $this->pChartObject->addToImageMap("RECT",floor($X-$CircleRadius).",".floor($Y-$CircleRadius).",".floor($X+$CircleRadius).",".floor($Y+$CircleRadius),$this->pChartObject->toHTMLColor($Palette[$Key]["R"],$Palette[$Key]["G"],$Palette[$Key]["B"]),$SerieDescription,$Data["Series"][$WeightSeries[$Key]]["Data"][$iKey]); }
if ( $BorderWidth != 1 )
{
$this->pChartObject->drawFilledRectangle($X-$CircleRadius-$BorderWidth,$Y-$CircleRadius-$BorderWidth,$X+$CircleRadius+$BorderWidth,$Y+$CircleRadius+$BorderWidth,$BorderColor);
$this->pChartObject->drawFilledRectangle($X-$CircleRadius,$Y-$CircleRadius,$X+$CircleRadius,$Y+$CircleRadius,$Color);
}
else
$this->pChartObject->drawFilledRectangle($X-$CircleRadius,$Y-$CircleRadius,$X+$CircleRadius,$Y+$CircleRadius,$Color);
}
elseif ( $Shape == BUBBLE_SHAPE_ROUND )
{
if ( $RecordImageMap ) { $this->pChartObject->addToImageMap("CIRCLE",floor($X).",".floor($Y).",".floor($CircleRadius),$this->pChartObject->toHTMLColor($Palette[$Key]["R"],$Palette[$Key]["G"],$Palette[$Key]["B"]),$SerieDescription,$Data["Series"][$WeightSeries[$Key]]["Data"][$iKey]); }
if ( $BorderWidth != 1 )
{
$this->pChartObject->drawFilledCircle($X,$Y,$CircleRadius+$BorderWidth,$BorderColor);
$this->pChartObject->drawFilledCircle($X,$Y,$CircleRadius,$Color);
}
else
$this->pChartObject->drawFilledCircle($X,$Y,$CircleRadius,$Color);
}
$Y = $Y + $XStep;
}
}
}
}
function writeBubbleLabel($SerieName,$SerieWeightName,$Points,$Format="")
{
$OverrideTitle = isset($Format["OverrideTitle"]) ? $Format["OverrideTitle"] : NULL;
$DrawPoint = isset($Format["DrawPoint"]) ? $Format["DrawPoint"] : LABEL_POINT_BOX;
if ( !is_array($Points) ) { $Point = $Points; $Points = ""; $Points[] = $Point; }
$Data = $this->pDataObject->getData();
$Palette = $this->pDataObject->getPalette();
if ( !isset($Data["Series"][$SerieName]) || !isset($Data["Series"][$SerieWeightName]) )
return(0);
list($XMargin,$XDivs) = $this->pChartObject->scaleGetXSettings();
$AxisID = $Data["Series"][$SerieName]["Axis"];
$AxisMode = $Data["Axis"][$AxisID]["Display"];
$AxisFormat = $Data["Axis"][$AxisID]["Format"];
$AxisUnit = $Data["Axis"][$AxisID]["Unit"];
$XStep = ($this->pChartObject->GraphAreaX2-$this->pChartObject->GraphAreaX1-$XMargin*2)/$XDivs;
$X = $this->pChartObject->GraphAreaX1 + $XMargin;
$Y = $this->pChartObject->GraphAreaY1 + $XMargin;
$Color = array("R"=>$Data["Series"][$SerieName]["Color"]["R"],"G"=>$Data["Series"][$SerieName]["Color"]["G"],"B"=>$Data["Series"][$SerieName]["Color"]["B"],"Alpha"=>$Data["Series"][$SerieName]["Color"]["Alpha"]);
foreach($Points as $Key => $Point)
{
$Value = $Data["Series"][$SerieName]["Data"][$Point];
$PosArray = $this->pChartObject->scaleComputeY($Value,array("AxisID"=>$AxisID));
if ( isset($Data["Abscissa"]) && isset($Data["Series"][$Data["Abscissa"]]["Data"][$Point]) )
$Abscissa = $Data["Series"][$Data["Abscissa"]]["Data"][$Point]." : ";
else
$Abscissa = "";
$Value = $this->pChartObject->scaleFormat($Value,$AxisMode,$AxisFormat,$AxisUnit);
$Weight = $Data["Series"][$SerieWeightName]["Data"][$Point];
$Caption = $Abscissa.$Value." / ".$Weight;
if ( isset($Data["Series"][$SerieName]["Description"]) )
$Description = $Data["Series"][$SerieName]["Description"];
else
$Description = "No description";
$Series = "";
$Series[] = array("Format"=>$Color,"Caption"=>$Caption);
if ( $Data["Orientation"] == SCALE_POS_LEFTRIGHT )
{
if ( $XDivs == 0 ) { $XStep = 0; } else { $XStep = ($this->pChartObject->GraphAreaX2-$this->pChartObject->GraphAreaX1-$XMargin*2)/$XDivs; }
$X = floor($X + $Point * $XStep);
$Y = floor($PosArray);
}
else
{
if ( $XDivs == 0 ) { $YStep = 0; } else { $YStep = ($this->pChartObject->GraphAreaY2-$this->pChartObject->GraphAreaY1-$XMargin*2)/$XDivs; }
$X = floor($PosArray);
$Y = floor($Y + $Point * $YStep);
}
if ( $DrawPoint == LABEL_POINT_CIRCLE )
$this->pChartObject->drawFilledCircle($X,$Y,3,array("R"=>255,"G"=>255,"B"=>255,"BorderR"=>0,"BorderG"=>0,"BorderB"=>0));
elseif ( $DrawPoint == LABEL_POINT_BOX )
$this->pChartObject->drawFilledRectangle($X-2,$Y-2,$X+2,$Y+2,array("R"=>255,"G"=>255,"B"=>255,"BorderR"=>0,"BorderG"=>0,"BorderB"=>0));
$this->pChartObject->drawLabelBox($X,$Y-3,$Description,$Series,$Format);
}
}
}
?>

View File

@@ -0,0 +1,280 @@
<?php
/*
pCache - speed up the rendering by caching up the pictures
Version : 2.1.4
Made by : Jean-Damien POGOLOTTI
Last Update : 19/01/2014
This file can be distributed under the license you can find at :
http://www.pchart.net/license
You can find the whole class documentation on the pChart web site.
*/
/* pData class definition */
class pCache
{
var $CacheFolder;
var $CacheIndex;
var $CacheDB;
/* Class creator */
function pCache($Settings="")
{
$CacheFolder = isset($Settings["CacheFolder"]) ? $Settings["CacheFolder"] : "cache";
$CacheIndex = isset($Settings["CacheIndex"]) ? $Settings["CacheIndex"] : "index.db";
$CacheDB = isset($Settings["CacheDB"]) ? $Settings["CacheDB"] : "cache.db";
$this->CacheFolder = $CacheFolder;
$this->CacheIndex = $CacheIndex;
$this->CacheDB = $CacheDB;
if (!file_exists($this->CacheFolder."/".$this->CacheIndex)) { touch($this->CacheFolder."/".$this->CacheIndex); }
if (!file_exists($this->CacheFolder."/".$this->CacheDB)) { touch($this->CacheFolder."/".$this->CacheDB); }
}
/* Flush the cache contents */
function flush()
{
if (file_exists($this->CacheFolder."/".$this->CacheIndex)) { unlink($this->CacheFolder."/".$this->CacheIndex); touch($this->CacheFolder."/".$this->CacheIndex); }
if (file_exists($this->CacheFolder."/".$this->CacheDB)) { unlink($this->CacheFolder."/".$this->CacheDB); touch($this->CacheFolder."/".$this->CacheDB); }
}
/* Return the MD5 of the data array to clearly identify the chart */
function getHash($Data,$Marker="")
{ return(md5($Marker.serialize($Data->Data))); }
/* Write the generated picture to the cache */
function writeToCache($ID,$pChartObject)
{
/* Compute the paths */
$TemporaryFile = $this->CacheFolder."/tmp_".rand(0,1000).".png";
$Database = $this->CacheFolder."/".$this->CacheDB;
$Index = $this->CacheFolder."/".$this->CacheIndex;
/* Flush the picture to a temporary file */
imagepng($pChartObject->Picture ,$TemporaryFile);
/* Retrieve the files size */
$PictureSize = filesize($TemporaryFile);
$DBSize = filesize($Database);
/* Save the index */
$Handle = fopen($Index,"a");
fwrite($Handle, $ID.",".$DBSize.",".$PictureSize.",".time().",0 \r\n");
fclose($Handle);
/* Get the picture raw contents */
$Handle = fopen($TemporaryFile,"r");
$Raw = fread($Handle,$PictureSize);
fclose($Handle);
/* Save the picture in the solid database file */
$Handle = fopen($Database,"a");
fwrite($Handle, $Raw);
fclose($Handle);
/* Remove temporary file */
unlink($TemporaryFile);
}
/* Remove object older than the specified TS */
function removeOlderThan($Expiry)
{ $this->dbRemoval(array("Expiry"=>$Expiry)); }
/* Remove an object from the cache */
function remove($ID)
{ $this->dbRemoval(array("Name"=>$ID)); }
/* Remove with specified criterias */
function dbRemoval($Settings)
{
$ID = isset($Settings["Name"]) ? $Settings["Name"] : NULL;
$Expiry = isset($Settings["Expiry"]) ? $Settings["Expiry"] : -(24*60*60);
$TS = time()-$Expiry;
/* Compute the paths */
$Database = $this->CacheFolder."/".$this->CacheDB;
$Index = $this->CacheFolder."/".$this->CacheIndex;
$DatabaseTemp = $this->CacheFolder."/".$this->CacheDB.".tmp";
$IndexTemp = $this->CacheFolder."/".$this->CacheIndex.".tmp";
/* Single file removal */
if ( $ID != NULL )
{
/* Retrieve object informations */
$Object = $this->isInCache($ID,TRUE);
/* If it's not in the cache DB, go away */
if ( !$Object ) { return(0); }
}
/* Create the temporary files */
if (!file_exists($DatabaseTemp)) { touch($DatabaseTemp); }
if (!file_exists($IndexTemp)) { touch($IndexTemp); }
/* Open the file handles */
$IndexHandle = @fopen($Index, "r");
$IndexTempHandle = @fopen($IndexTemp, "w");
$DBHandle = @fopen($Database, "r");
$DBTempHandle = @fopen($DatabaseTemp, "w");
/* Remove the selected ID from the database */
while (!feof($IndexHandle))
{
$Entry = fgets($IndexHandle, 4096);
$Entry = str_replace("\r","",$Entry);
$Entry = str_replace("\n","",$Entry);
$Settings = preg_split("/,/",$Entry);
if ( $Entry != "" )
{
$PicID = $Settings[0];
$DBPos = $Settings[1];
$PicSize = $Settings[2];
$GeneratedTS = $Settings[3];
$Hits = $Settings[4];
if ( $Settings[0] != $ID && $GeneratedTS > $TS)
{
$CurrentPos = ftell($DBTempHandle);
fwrite($IndexTempHandle, $PicID.",".$CurrentPos.",".$PicSize.",".$GeneratedTS.",".$Hits."\r\n");
fseek($DBHandle,$DBPos);
$Picture = fread($DBHandle,$PicSize);
fwrite($DBTempHandle,$Picture);
}
}
}
/* Close the handles */
fclose($IndexHandle);
fclose($IndexTempHandle);
fclose($DBHandle);
fclose($DBTempHandle);
/* Remove the prod files */
unlink($Database);
unlink($Index);
/* Swap the temp & prod DB */
rename($DatabaseTemp,$Database);
rename($IndexTemp,$Index);
}
function isInCache($ID,$Verbose=FALSE,$UpdateHitsCount=FALSE)
{
/* Compute the paths */
$Index = $this->CacheFolder."/".$this->CacheIndex;
/* Search the picture in the index file */
$Handle = @fopen($Index, "r");
while (!feof($Handle))
{
$IndexPos = ftell($Handle);
$Entry = fgets($Handle, 4096);
if ( $Entry != "" )
{
$Settings = preg_split("/,/",$Entry);
$PicID = $Settings[0];
if ( $PicID == $ID )
{
fclose($Handle);
$DBPos = $Settings[1];
$PicSize = $Settings[2];
$GeneratedTS = $Settings[3];
$Hits = intval($Settings[4]);
if ( $UpdateHitsCount )
{
$Hits++;
if ( strlen($Hits) < 7 ) { $Hits = $Hits.str_repeat(" ",7-strlen($Hits)); }
$Handle = @fopen($Index, "r+");
fseek($Handle,$IndexPos);
fwrite($Handle, $PicID.",".$DBPos.",".$PicSize.",".$GeneratedTS.",".$Hits."\r\n");
fclose($Handle);
}
if ($Verbose)
{ return(array("DBPos"=>$DBPos,"PicSize"=>$PicSize,"GeneratedTS"=>$GeneratedTS,"Hits"=>$Hits)); }
else
{ return(TRUE); }
}
}
}
fclose($Handle);
/* Picture isn't in the cache */
return(FALSE);
}
/* Automatic output method based on the calling interface */
function autoOutput($ID,$Destination="output.png")
{
if (php_sapi_name() == "cli")
$this->saveFromCache($ID,$Destination);
else
$this->strokeFromCache($ID);
}
function strokeFromCache($ID)
{
/* Get the raw picture from the cache */
$Picture = $this->getFromCache($ID);
/* Do we have a hit? */
if ( $Picture == NULL ) { return(FALSE); }
header('Content-type: image/png');
echo $Picture;
return(TRUE);
}
function saveFromCache($ID,$Destination)
{
/* Get the raw picture from the cache */
$Picture = $this->getFromCache($ID);
/* Do we have a hit? */
if ( $Picture == NULL ) { return(FALSE); }
/* Flush the picture to a file */
$Handle = fopen($Destination,"w");
fwrite($Handle,$Picture);
fclose($Handle);
/* All went fine */
return(TRUE);
}
function getFromCache($ID)
{
/* Compute the path */
$Database = $this->CacheFolder."/".$this->CacheDB;
/* Lookup for the picture in the cache */
$CacheInfo = $this->isInCache($ID,TRUE,TRUE);
/* Not in the cache */
if (!$CacheInfo) { return(NULL); }
/* Get the database extended information */
$DBPos = $CacheInfo["DBPos"];
$PicSize = $CacheInfo["PicSize"];
/* Extract the picture from the solid cache file */
$Handle = @fopen($Database, "r");
fseek($Handle,$DBPos);
$Picture = fread($Handle,$PicSize);
fclose($Handle);
/* Return back the raw picture data */
return($Picture);
}
}
?>

View File

@@ -0,0 +1,788 @@
<?php
/*
pDraw - class to manipulate data arrays
Version : 2.1.4
Made by : Jean-Damien POGOLOTTI
Last Update : 19/01/2014
This file can be distributed under the license you can find at :
http://www.pchart.net/license
You can find the whole class documentation on the pChart web site.
*/
/* Axis configuration */
define("AXIS_FORMAT_DEFAULT" , 680001);
define("AXIS_FORMAT_TIME" , 680002);
define("AXIS_FORMAT_DATE" , 680003);
define("AXIS_FORMAT_METRIC" , 680004);
define("AXIS_FORMAT_CURRENCY" , 680005);
define("AXIS_FORMAT_TRAFFIC" , 680006);
define("AXIS_FORMAT_CUSTOM" , 680007);
/* Axis position */
define("AXIS_POSITION_LEFT" , 681001);
define("AXIS_POSITION_RIGHT" , 681002);
define("AXIS_POSITION_TOP" , 681001);
define("AXIS_POSITION_BOTTOM" , 681002);
/* Families of data points */
define("SERIE_SHAPE_FILLEDCIRCLE" , 681011);
define("SERIE_SHAPE_FILLEDTRIANGLE" , 681012);
define("SERIE_SHAPE_FILLEDSQUARE" , 681013);
define("SERIE_SHAPE_FILLEDDIAMOND" , 681017);
define("SERIE_SHAPE_CIRCLE" , 681014);
define("SERIE_SHAPE_TRIANGLE" , 681015);
define("SERIE_SHAPE_SQUARE" , 681016);
define("SERIE_SHAPE_DIAMOND" , 681018);
/* Axis position */
define("AXIS_X" , 682001);
define("AXIS_Y" , 682002);
/* Define value limits */
define("ABSOLUTE_MIN" , -10000000000000);
define("ABSOLUTE_MAX" , 10000000000000);
/* Replacement to the PHP NULL keyword */
define("VOID" , 0.123456789);
/* Euro symbol for GD fonts */
define("EURO_SYMBOL" , utf8_encode("&#8364;"));
/* pData class definition */
class pData
{
var $Data;
var $Palette = array("0"=>array("R"=>188,"G"=>224,"B"=>46,"Alpha"=>100),
"1"=>array("R"=>224,"G"=>100,"B"=>46,"Alpha"=>100),
"2"=>array("R"=>224,"G"=>214,"B"=>46,"Alpha"=>100),
"3"=>array("R"=>46,"G"=>151,"B"=>224,"Alpha"=>100),
"4"=>array("R"=>176,"G"=>46,"B"=>224,"Alpha"=>100),
"5"=>array("R"=>224,"G"=>46,"B"=>117,"Alpha"=>100),
"6"=>array("R"=>92,"G"=>224,"B"=>46,"Alpha"=>100),
"7"=>array("R"=>224,"G"=>176,"B"=>46,"Alpha"=>100));
/* Class creator */
function pData()
{
$this->Data = "";
$this->Data["XAxisDisplay"] = AXIS_FORMAT_DEFAULT;
$this->Data["XAxisFormat"] = NULL;
$this->Data["XAxisName"] = NULL;
$this->Data["XAxisUnit"] = NULL;
$this->Data["Abscissa"] = NULL;
$this->Data["AbsicssaPosition"] = AXIS_POSITION_BOTTOM;
$this->Data["Axis"][0]["Display"] = AXIS_FORMAT_DEFAULT;
$this->Data["Axis"][0]["Position"] = AXIS_POSITION_LEFT;
$this->Data["Axis"][0]["Identity"] = AXIS_Y;
}
/* Add a single point or an array to the given serie */
function addPoints($Values,$SerieName="Serie1")
{
if (!isset($this->Data["Series"][$SerieName]))
$this->initialise($SerieName);
if ( is_array($Values) )
{
foreach($Values as $Key => $Value)
{ $this->Data["Series"][$SerieName]["Data"][] = $Value; }
}
else
$this->Data["Series"][$SerieName]["Data"][] = $Values;
if ( $Values != VOID )
{
$StrippedData = $this->stripVOID($this->Data["Series"][$SerieName]["Data"]);
if ( empty($StrippedData) ) { $this->Data["Series"][$SerieName]["Max"] = 0; $this->Data["Series"][$SerieName]["Min"] =0; return(0); }
$this->Data["Series"][$SerieName]["Max"] = max($StrippedData);
$this->Data["Series"][$SerieName]["Min"] = min($StrippedData);
}
}
/* Strip VOID values */
function stripVOID($Values)
{ if (!is_array($Values)) { return(array()); } $Result = array(); foreach($Values as $Key => $Value) { if ( $Value != VOID ) { $Result[] = $Value; } } return($Result); }
/* Return the number of values contained in a given serie */
function getSerieCount($Serie)
{ if (isset($this->Data["Series"][$Serie]["Data"])) { return(sizeof($this->Data["Series"][$Serie]["Data"])); } else { return(0); } }
/* Remove a serie from the pData object */
function removeSerie($Series)
{
if ( !is_array($Series) ) { $Series = $this->convertToArray($Series); }
foreach($Series as $Key => $Serie) { if (isset($this->Data["Series"][$Serie])) { unset($this->Data["Series"][$Serie]); } }
}
/* Return a value from given serie & index */
function getValueAt($Serie,$Index=0)
{ if (isset($this->Data["Series"][$Serie]["Data"][$Index])) { return($this->Data["Series"][$Serie]["Data"][$Index]); } else { return(NULL); } }
/* Return the values array */
function getValues($Serie)
{ if (isset($this->Data["Series"][$Serie]["Data"])) { return($this->Data["Series"][$Serie]["Data"]); } else { return(NULL); } }
/* Reverse the values in the given serie */
function reverseSerie($Series)
{
if ( !is_array($Series) ) { $Series = $this->convertToArray($Series); }
foreach($Series as $Key => $Serie) { if (isset($this->Data["Series"][$Serie]["Data"])) { $this->Data["Series"][$Serie]["Data"] = array_reverse($this->Data["Series"][$Serie]["Data"]); } }
}
/* Return the sum of the serie values */
function getSum($Serie)
{ if (isset($this->Data["Series"][$Serie])) { return(array_sum($this->Data["Series"][$Serie]["Data"])); } else { return(NULL); } }
/* Return the max value of a given serie */
function getMax($Serie)
{ if (isset($this->Data["Series"][$Serie]["Max"])) { return($this->Data["Series"][$Serie]["Max"]); } else { return(NULL); } }
/* Return the min value of a given serie */
function getMin($Serie)
{ if (isset($this->Data["Series"][$Serie]["Min"])) { return($this->Data["Series"][$Serie]["Min"]); } else { return(NULL); } }
/* Set the description of a given serie */
function setSerieShape($Series,$Shape=SERIE_SHAPE_FILLEDCIRCLE)
{
if ( !is_array($Series) ) { $Series = $this->convertToArray($Series); }
foreach($Series as $Key => $Serie) { if (isset($this->Data["Series"][$Serie]) ) { $this->Data["Series"][$Serie]["Shape"] = $Shape; } }
}
/* Set the description of a given serie */
function setSerieDescription($Series,$Description="My serie")
{
if ( !is_array($Series) ) { $Series = $this->convertToArray($Series); }
foreach($Series as $Key => $Serie) { if (isset($this->Data["Series"][$Serie]) ) { $this->Data["Series"][$Serie]["Description"] = $Description; } }
}
/* Set a serie as "drawable" while calling a rendering function */
function setSerieDrawable($Series,$Drawable=TRUE)
{
if ( !is_array($Series) ) { $Series = $this->convertToArray($Series); }
foreach($Series as $Key => $Serie) { if (isset($this->Data["Series"][$Serie]) ) { $this->Data["Series"][$Serie]["isDrawable"] = $Drawable; } }
}
/* Set the icon associated to a given serie */
function setSeriePicture($Series,$Picture=NULL)
{
if ( !is_array($Series) ) { $Series = $this->convertToArray($Series); }
foreach($Series as $Key => $Serie) { if (isset($this->Data["Series"][$Serie]) ) { $this->Data["Series"][$Serie]["Picture"] = $Picture; } }
}
/* Set the name of the X Axis */
function setXAxisName($Name)
{ $this->Data["XAxisName"] = $Name; }
/* Set the display mode of the X Axis */
function setXAxisDisplay($Mode,$Format=NULL)
{ $this->Data["XAxisDisplay"] = $Mode; $this->Data["XAxisFormat"] = $Format; }
/* Set the unit that will be displayed on the X axis */
function setXAxisUnit($Unit)
{ $this->Data["XAxisUnit"] = $Unit; }
/* Set the serie that will be used as abscissa */
function setAbscissa($Serie)
{ if (isset($this->Data["Series"][$Serie])) { $this->Data["Abscissa"] = $Serie; } }
function setAbsicssaPosition($Position = AXIS_POSITION_BOTTOM)
{ $this->Data["AbsicssaPosition"] = $Position; }
/* Set the name of the abscissa axis */
function setAbscissaName($Name)
{ $this->Data["AbscissaName"] = $Name; }
/* Create a scatter group specifyin X and Y data series */
function setScatterSerie($SerieX,$SerieY,$ID=0)
{ if (isset($this->Data["Series"][$SerieX]) && isset($this->Data["Series"][$SerieY]) ) { $this->initScatterSerie($ID); $this->Data["ScatterSeries"][$ID]["X"] = $SerieX; $this->Data["ScatterSeries"][$ID]["Y"] = $SerieY; } }
/* Set the shape of a given sctatter serie */
function setScatterSerieShape($ID,$Shape=SERIE_SHAPE_FILLEDCIRCLE)
{ if (isset($this->Data["ScatterSeries"][$ID]) ) { $this->Data["ScatterSeries"][$ID]["Shape"] = $Shape; } }
/* Set the description of a given scatter serie */
function setScatterSerieDescription($ID,$Description="My serie")
{ if (isset($this->Data["ScatterSeries"][$ID]) ) { $this->Data["ScatterSeries"][$ID]["Description"] = $Description; } }
/* Set the icon associated to a given scatter serie */
function setScatterSeriePicture($ID,$Picture=NULL)
{ if (isset($this->Data["ScatterSeries"][$ID]) ) { $this->Data["ScatterSeries"][$ID]["Picture"] = $Picture; } }
/* Set a scatter serie as "drawable" while calling a rendering function */
function setScatterSerieDrawable($ID ,$Drawable=TRUE)
{ if (isset($this->Data["ScatterSeries"][$ID]) ) { $this->Data["ScatterSeries"][$ID]["isDrawable"] = $Drawable; } }
/* Define if a scatter serie should be draw with ticks */
function setScatterSerieTicks($ID,$Width=0)
{ if ( isset($this->Data["ScatterSeries"][$ID]) ) { $this->Data["ScatterSeries"][$ID]["Ticks"] = $Width; } }
/* Define if a scatter serie should be draw with a special weight */
function setScatterSerieWeight($ID,$Weight=0)
{ if ( isset($this->Data["ScatterSeries"][$ID]) ) { $this->Data["ScatterSeries"][$ID]["Weight"] = $Weight; } }
/* Associate a color to a scatter serie */
function setScatterSerieColor($ID,$Format)
{
$R = isset($Format["R"]) ? $Format["R"] : 0;
$G = isset($Format["G"]) ? $Format["G"] : 0;
$B = isset($Format["B"]) ? $Format["B"] : 0;
$Alpha = isset($Format["Alpha"]) ? $Format["Alpha"] : 100;
if ( isset($this->Data["ScatterSeries"][$ID]) )
{
$this->Data["ScatterSeries"][$ID]["Color"]["R"] = $R;
$this->Data["ScatterSeries"][$ID]["Color"]["G"] = $G;
$this->Data["ScatterSeries"][$ID]["Color"]["B"] = $B;
$this->Data["ScatterSeries"][$ID]["Color"]["Alpha"] = $Alpha;
}
}
/* Compute the series limits for an individual and global point of view */
function limits()
{
$GlobalMin = ABSOLUTE_MAX;
$GlobalMax = ABSOLUTE_MIN;
foreach($this->Data["Series"] as $Key => $Value)
{
if ( $this->Data["Abscissa"] != $Key && $this->Data["Series"][$Key]["isDrawable"] == TRUE)
{
if ( $GlobalMin > $this->Data["Series"][$Key]["Min"] ) { $GlobalMin = $this->Data["Series"][$Key]["Min"]; }
if ( $GlobalMax < $this->Data["Series"][$Key]["Max"] ) { $GlobalMax = $this->Data["Series"][$Key]["Max"]; }
}
}
$this->Data["Min"] = $GlobalMin;
$this->Data["Max"] = $GlobalMax;
return(array($GlobalMin,$GlobalMax));
}
/* Mark all series as drawable */
function drawAll()
{ foreach($this->Data["Series"] as $Key => $Value) { if ( $this->Data["Abscissa"] != $Key ) { $this->Data["Series"][$Key]["isDrawable"]=TRUE; } } }
/* Return the average value of the given serie */
function getSerieAverage($Serie)
{
if ( isset($this->Data["Series"][$Serie]) )
{
$SerieData = $this->stripVOID($this->Data["Series"][$Serie]["Data"]);
return(array_sum($SerieData)/sizeof($SerieData));
}
else
return(NULL);
}
/* Return the geometric mean of the given serie */
function getGeometricMean($Serie)
{
if ( isset($this->Data["Series"][$Serie]) )
{
$SerieData = $this->stripVOID($this->Data["Series"][$Serie]["Data"]);
$Seriesum = 1; foreach($SerieData as $Key => $Value) { $Seriesum = $Seriesum * $Value; }
return(pow($Seriesum,1/sizeof($SerieData)));
}
else
return(NULL);
}
/* Return the harmonic mean of the given serie */
function getHarmonicMean($Serie)
{
if ( isset($this->Data["Series"][$Serie]) )
{
$SerieData = $this->stripVOID($this->Data["Series"][$Serie]["Data"]);
$Seriesum = 0; foreach($SerieData as $Key => $Value) { $Seriesum = $Seriesum + 1/$Value; }
return(sizeof($SerieData)/$Seriesum);
}
else
return(NULL);
}
/* Return the standard deviation of the given serie */
function getStandardDeviation($Serie)
{
if ( isset($this->Data["Series"][$Serie]) )
{
$Average = $this->getSerieAverage($Serie);
$SerieData = $this->stripVOID($this->Data["Series"][$Serie]["Data"]);
$DeviationSum = 0;
foreach($SerieData as $Key => $Value)
$DeviationSum = $DeviationSum + ($Value-$Average)*($Value-$Average);
$Deviation = sqrt($DeviationSum/count($SerieData));
return($Deviation);
}
else
return(NULL);
}
/* Return the Coefficient of variation of the given serie */
function getCoefficientOfVariation($Serie)
{
if ( isset($this->Data["Series"][$Serie]) )
{
$Average = $this->getSerieAverage($Serie);
$StandardDeviation = $this->getStandardDeviation($Serie);
if ( $StandardDeviation != 0 )
return($StandardDeviation/$Average);
else
return(NULL);
}
else
return(NULL);
}
/* Return the median value of the given serie */
function getSerieMedian($Serie)
{
if ( isset($this->Data["Series"][$Serie]) )
{
$SerieData = $this->stripVOID($this->Data["Series"][$Serie]["Data"]);
sort($SerieData);
$SerieCenter = floor(sizeof($SerieData)/2);
if ( isset($SerieData[$SerieCenter]) )
return($SerieData[$SerieCenter]);
else
return(NULL);
}
else
return(NULL);
}
/* Return the x th percentil of the given serie */
function getSeriePercentile($Serie="Serie1",$Percentil=95)
{
if (!isset($this->Data["Series"][$Serie]["Data"])) { return(NULL); }
$Values = count($this->Data["Series"][$Serie]["Data"])-1;
if ( $Values < 0 ) { $Values = 0; }
$PercentilID = floor(($Values/100)*$Percentil+.5);
$SortedValues = $this->Data["Series"][$Serie]["Data"];
sort($SortedValues);
if ( is_numeric($SortedValues[$PercentilID]) )
return($SortedValues[$PercentilID]);
else
return(NULL);
}
/* Add random values to a given serie */
function addRandomValues($SerieName="Serie1",$Options="")
{
$Values = isset($Options["Values"]) ? $Options["Values"] : 20;
$Min = isset($Options["Min"]) ? $Options["Min"] : 0;
$Max = isset($Options["Max"]) ? $Options["Max"] : 100;
$withFloat = isset($Options["withFloat"]) ? $Options["withFloat"] : FALSE;
for ($i=0;$i<=$Values;$i++)
{
if ( $withFloat ) { $Value = rand($Min*100,$Max*100)/100; } else { $Value = rand($Min,$Max); }
$this->addPoints($Value,$SerieName);
}
}
/* Test if we have valid data */
function containsData()
{
if (!isset($this->Data["Series"])) { return(FALSE); }
$Result = FALSE;
foreach($this->Data["Series"] as $Key => $Value)
{ if ( $this->Data["Abscissa"] != $Key && $this->Data["Series"][$Key]["isDrawable"]==TRUE) { $Result=TRUE; } }
return($Result);
}
/* Set the display mode of an Axis */
function setAxisDisplay($AxisID,$Mode=AXIS_FORMAT_DEFAULT,$Format=NULL)
{
if ( isset($this->Data["Axis"][$AxisID] ) )
{
$this->Data["Axis"][$AxisID]["Display"] = $Mode;
if ( $Format != NULL ) { $this->Data["Axis"][$AxisID]["Format"] = $Format; }
}
}
/* Set the position of an Axis */
function setAxisPosition($AxisID,$Position=AXIS_POSITION_LEFT)
{ if ( isset($this->Data["Axis"][$AxisID] ) ) { $this->Data["Axis"][$AxisID]["Position"] = $Position; } }
/* Associate an unit to an axis */
function setAxisUnit($AxisID,$Unit)
{ if ( isset($this->Data["Axis"][$AxisID] ) ) { $this->Data["Axis"][$AxisID]["Unit"] = $Unit; } }
/* Associate a name to an axis */
function setAxisName($AxisID,$Name)
{ if ( isset($this->Data["Axis"][$AxisID] ) ) { $this->Data["Axis"][$AxisID]["Name"] = $Name; } }
/* Associate a color to an axis */
function setAxisColor($AxisID,$Format)
{
$R = isset($Format["R"]) ? $Format["R"] : 0;
$G = isset($Format["G"]) ? $Format["G"] : 0;
$B = isset($Format["B"]) ? $Format["B"] : 0;
$Alpha = isset($Format["Alpha"]) ? $Format["Alpha"] : 100;
if ( isset($this->Data["Axis"][$AxisID] ) )
{
$this->Data["Axis"][$AxisID]["Color"]["R"] = $R;
$this->Data["Axis"][$AxisID]["Color"]["G"] = $G;
$this->Data["Axis"][$AxisID]["Color"]["B"] = $B;
$this->Data["Axis"][$AxisID]["Color"]["Alpha"] = $Alpha;
}
}
/* Design an axis as X or Y member */
function setAxisXY($AxisID,$Identity=AXIS_Y)
{ if ( isset($this->Data["Axis"][$AxisID] ) ) { $this->Data["Axis"][$AxisID]["Identity"] = $Identity; } }
/* Associate one data serie with one axis */
function setSerieOnAxis($Series,$AxisID)
{
if ( !is_array($Series) ) { $Series = $this->convertToArray($Series); }
foreach($Series as $Key => $Serie)
{
$PreviousAxis = $this->Data["Series"][$Serie]["Axis"];
/* Create missing axis */
if ( !isset($this->Data["Axis"][$AxisID] ) )
{ $this->Data["Axis"][$AxisID]["Position"] = AXIS_POSITION_LEFT; $this->Data["Axis"][$AxisID]["Identity"] = AXIS_Y;}
$this->Data["Series"][$Serie]["Axis"] = $AxisID;
/* Cleanup unused axis */
$Found = FALSE;
foreach($this->Data["Series"] as $SerieName => $Values) { if ( $Values["Axis"] == $PreviousAxis ) { $Found = TRUE; } }
if (!$Found) { unset($this->Data["Axis"][$PreviousAxis]); }
}
}
/* Define if a serie should be draw with ticks */
function setSerieTicks($Series,$Width=0)
{
if ( !is_array($Series) ) { $Series = $this->convertToArray($Series); }
foreach($Series as $Key => $Serie) { if ( isset($this->Data["Series"][$Serie]) ) { $this->Data["Series"][$Serie]["Ticks"] = $Width; } }
}
/* Define if a serie should be draw with a special weight */
function setSerieWeight($Series,$Weight=0)
{
if ( !is_array($Series) ) { $Series = $this->convertToArray($Series); }
foreach($Series as $Key => $Serie) { if ( isset($this->Data["Series"][$Serie]) ) { $this->Data["Series"][$Serie]["Weight"] = $Weight; } }
}
/* Returns the palette of the given serie */
function getSeriePalette($Serie)
{
if ( !isset($this->Data["Series"][$Serie]) ) { return(NULL); }
$Result = "";
$Result["R"] = $this->Data["Series"][$Serie]["Color"]["R"];
$Result["G"] = $this->Data["Series"][$Serie]["Color"]["G"];
$Result["B"] = $this->Data["Series"][$Serie]["Color"]["B"];
$Result["Alpha"] = $this->Data["Series"][$Serie]["Color"]["Alpha"];
return($Result);
}
/* Set the color of one serie */
function setPalette($Series,$Format=NULL)
{
if ( !is_array($Series) ) { $Series = $this->convertToArray($Series); }
foreach($Series as $Key => $Serie)
{
$R = isset($Format["R"]) ? $Format["R"] : 0;
$G = isset($Format["G"]) ? $Format["G"] : 0;
$B = isset($Format["B"]) ? $Format["B"] : 0;
$Alpha = isset($Format["Alpha"]) ? $Format["Alpha"] : 100;
if ( isset($this->Data["Series"][$Serie]) )
{
$OldR = $this->Data["Series"][$Serie]["Color"]["R"]; $OldG = $this->Data["Series"][$Serie]["Color"]["G"]; $OldB = $this->Data["Series"][$Serie]["Color"]["B"];
$this->Data["Series"][$Serie]["Color"]["R"] = $R;
$this->Data["Series"][$Serie]["Color"]["G"] = $G;
$this->Data["Series"][$Serie]["Color"]["B"] = $B;
$this->Data["Series"][$Serie]["Color"]["Alpha"] = $Alpha;
/* Do reverse processing on the internal palette array */
foreach ($this->Palette as $Key => $Value)
{ if ($Value["R"] == $OldR && $Value["G"] == $OldG && $Value["B"] == $OldB) { $this->Palette[$Key]["R"] = $R; $this->Palette[$Key]["G"] = $G; $this->Palette[$Key]["B"] = $B; $this->Palette[$Key]["Alpha"] = $Alpha;} }
}
}
}
/* Load a palette file */
function loadPalette($FileName,$Overwrite=FALSE)
{
if ( !file_exists($FileName) ) { return(-1); }
if ( $Overwrite ) { $this->Palette = ""; }
$fileHandle = @fopen($FileName, "r");
if (!$fileHandle) { return(-1); }
while (!feof($fileHandle))
{
$buffer = fgets($fileHandle, 4096);
if ( preg_match("/,/",$buffer) )
{
list($R,$G,$B,$Alpha) = preg_split("/,/",$buffer);
if ( $this->Palette == "" ) { $ID = 0; } else { $ID = count($this->Palette); }
$this->Palette[$ID] = array("R"=>$R,"G"=>$G,"B"=>$B,"Alpha"=>$Alpha);
}
}
fclose($fileHandle);
/* Apply changes to current series */
$ID = 0;
if ( isset($this->Data["Series"]))
{
foreach($this->Data["Series"] as $Key => $Value)
{
if ( !isset($this->Palette[$ID]) )
$this->Data["Series"][$Key]["Color"] = array("R"=>0,"G"=>0,"B"=>0,"Alpha"=>0);
else
$this->Data["Series"][$Key]["Color"] = $this->Palette[$ID];
$ID++;
}
}
}
/* Initialise a given scatter serie */
function initScatterSerie($ID)
{
if ( isset($this->Data["ScatterSeries"][$ID]) ) { return(0); }
$this->Data["ScatterSeries"][$ID]["Description"] = "Scatter ".$ID;
$this->Data["ScatterSeries"][$ID]["isDrawable"] = TRUE;
$this->Data["ScatterSeries"][$ID]["Picture"] = NULL;
$this->Data["ScatterSeries"][$ID]["Ticks"] = 0;
$this->Data["ScatterSeries"][$ID]["Weight"] = 0;
if ( isset($this->Palette[$ID]) )
$this->Data["ScatterSeries"][$ID]["Color"] = $this->Palette[$ID];
else
{
$this->Data["ScatterSeries"][$ID]["Color"]["R"] = rand(0,255);
$this->Data["ScatterSeries"][$ID]["Color"]["G"] = rand(0,255);
$this->Data["ScatterSeries"][$ID]["Color"]["B"] = rand(0,255);
$this->Data["ScatterSeries"][$ID]["Color"]["Alpha"] = 100;
}
}
/* Initialise a given serie */
function initialise($Serie)
{
if ( isset($this->Data["Series"]) ) { $ID = count($this->Data["Series"]); } else { $ID = 0; }
$this->Data["Series"][$Serie]["Description"] = $Serie;
$this->Data["Series"][$Serie]["isDrawable"] = TRUE;
$this->Data["Series"][$Serie]["Picture"] = NULL;
$this->Data["Series"][$Serie]["Max"] = NULL;
$this->Data["Series"][$Serie]["Min"] = NULL;
$this->Data["Series"][$Serie]["Axis"] = 0;
$this->Data["Series"][$Serie]["Ticks"] = 0;
$this->Data["Series"][$Serie]["Weight"] = 0;
$this->Data["Series"][$Serie]["Shape"] = SERIE_SHAPE_FILLEDCIRCLE;
if ( isset($this->Palette[$ID]) )
$this->Data["Series"][$Serie]["Color"] = $this->Palette[$ID];
else
{
$this->Data["Series"][$Serie]["Color"]["R"] = rand(0,255);
$this->Data["Series"][$Serie]["Color"]["G"] = rand(0,255);
$this->Data["Series"][$Serie]["Color"]["B"] = rand(0,255);
$this->Data["Series"][$Serie]["Color"]["Alpha"] = 100;
}
}
function normalize($NormalizationFactor=100,$UnitChange=NULL,$Round=1)
{
$Abscissa = $this->Data["Abscissa"];
$SelectedSeries = "";
$MaxVal = 0;
foreach($this->Data["Axis"] as $AxisID => $Axis)
{
if ( $UnitChange != NULL ) { $this->Data["Axis"][$AxisID]["Unit"] = $UnitChange; }
foreach($this->Data["Series"] as $SerieName => $Serie)
{
if ($Serie["Axis"] == $AxisID && $Serie["isDrawable"] == TRUE && $SerieName != $Abscissa)
{
$SelectedSeries[$SerieName] = $SerieName;
if ( count($Serie["Data"] ) > $MaxVal ) { $MaxVal = count($Serie["Data"]); }
}
}
}
for($i=0;$i<=$MaxVal-1;$i++)
{
$Factor = 0;
foreach ($SelectedSeries as $Key => $SerieName )
{
$Value = $this->Data["Series"][$SerieName]["Data"][$i];
if ( $Value != VOID )
$Factor = $Factor + abs($Value);
}
if ( $Factor != 0 )
{
$Factor = $NormalizationFactor / $Factor;
foreach ($SelectedSeries as $Key => $SerieName )
{
$Value = $this->Data["Series"][$SerieName]["Data"][$i];
if ( $Value != VOID && $Factor != $NormalizationFactor )
$this->Data["Series"][$SerieName]["Data"][$i] = round(abs($Value)*$Factor,$Round);
elseif ( $Value == VOID || $Value == 0 )
$this->Data["Series"][$SerieName]["Data"][$i] = VOID;
elseif ( $Factor == $NormalizationFactor )
$this->Data["Series"][$SerieName]["Data"][$i] = $NormalizationFactor;
}
}
}
foreach ($SelectedSeries as $Key => $SerieName )
{
$this->Data["Series"][$SerieName]["Max"] = max($this->stripVOID($this->Data["Series"][$SerieName]["Data"]));
$this->Data["Series"][$SerieName]["Min"] = min($this->stripVOID($this->Data["Series"][$SerieName]["Data"]));
}
}
/* Load data from a CSV (or similar) data source */
function importFromCSV($FileName,$Options="")
{
$Delimiter = isset($Options["Delimiter"]) ? $Options["Delimiter"] : ",";
$GotHeader = isset($Options["GotHeader"]) ? $Options["GotHeader"] : FALSE;
$SkipColumns = isset($Options["SkipColumns"]) ? $Options["SkipColumns"] : array(-1);
$DefaultSerieName = isset($Options["DefaultSerieName"]) ? $Options["DefaultSerieName"] : "Serie";
$Handle = @fopen($FileName,"r");
if ($Handle)
{
$HeaderParsed = FALSE; $SerieNames = "";
while (!feof($Handle))
{
$Buffer = fgets($Handle, 4096);
$Buffer = str_replace(chr(10),"",$Buffer);
$Buffer = str_replace(chr(13),"",$Buffer);
$Values = preg_split("/".$Delimiter."/",$Buffer);
if ( $Buffer != "" )
{
if ( $GotHeader && !$HeaderParsed )
{
foreach($Values as $Key => $Name) { if ( !in_array($Key,$SkipColumns) ) { $SerieNames[$Key] = $Name; } }
$HeaderParsed = TRUE;
}
else
{
if ($SerieNames == "" ) { foreach($Values as $Key => $Name) { if ( !in_array($Key,$SkipColumns) ) { $SerieNames[$Key] = $DefaultSerieName.$Key; } } }
foreach($Values as $Key => $Value) { if ( !in_array($Key,$SkipColumns) ) { $this->addPoints($Value,$SerieNames[$Key]); } }
}
}
}
fclose($Handle);
}
}
/* Create a dataset based on a formula */
function createFunctionSerie($SerieName,$Formula="",$Options="")
{
$MinX = isset($Options["MinX"]) ? $Options["MinX"] : -10;
$MaxX = isset($Options["MaxX"]) ? $Options["MaxX"] : 10;
$XStep = isset($Options["XStep"]) ? $Options["XStep"] : 1;
$AutoDescription = isset($Options["AutoDescription"]) ? $Options["AutoDescription"] : FALSE;
$RecordAbscissa = isset($Options["RecordAbscissa"]) ? $Options["RecordAbscissa"] : FALSE;
$AbscissaSerie = isset($Options["AbscissaSerie"]) ? $Options["AbscissaSerie"] : "Abscissa";
if ( $Formula == "" ) { return(0); }
$Result = ""; $Abscissa = "";
for($i=$MinX; $i<=$MaxX; $i=$i+$XStep)
{
$Expression = "\$return = '!'.(".str_replace("z",$i,$Formula).");";
if ( @eval($Expression) === FALSE ) { $return = VOID; }
if ( $return == "!" ) { $return = VOID; } else { $return = $this->right($return,strlen($return)-1); }
if ( $return == "NAN" ) { $return = VOID; }
if ( $return == "INF" ) { $return = VOID; }
if ( $return == "-INF" ) { $return = VOID; }
$Abscissa[] = $i;
$Result[] = $return;
}
$this->addPoints($Result,$SerieName);
if ( $AutoDescription ) { $this->setSerieDescription($SerieName,$Formula); }
if ( $RecordAbscissa ) { $this->addPoints($Abscissa,$AbscissaSerie); }
}
function negateValues($Series)
{
if ( !is_array($Series) ) { $Series = $this->convertToArray($Series); }
foreach($Series as $Key => $SerieName)
{
if (isset($this->Data["Series"][$SerieName]))
{
$Data = "";
foreach($this->Data["Series"][$SerieName]["Data"] as $Key => $Value)
{ if ( $Value == VOID ) { $Data[] = VOID; } else { $Data[] = -$Value; } }
$this->Data["Series"][$SerieName]["Data"] = $Data;
$this->Data["Series"][$SerieName]["Max"] = max($this->stripVOID($this->Data["Series"][$SerieName]["Data"]));
$this->Data["Series"][$SerieName]["Min"] = min($this->stripVOID($this->Data["Series"][$SerieName]["Data"]));
}
}
}
/* Return the data & configuration of the series */
function getData()
{ return($this->Data); }
/* Save a palette element */
function savePalette($ID,$Color)
{ $this->Palette[$ID] = $Color; }
/* Return the palette of the series */
function getPalette()
{ return($this->Palette); }
/* Called by the scaling algorithm to save the config */
function saveAxisConfig($Axis) { $this->Data["Axis"]=$Axis; }
/* Save the Y Margin if set */
function saveYMargin($Value) { $this->Data["YMargin"]=$Value; }
/* Save extended configuration to the pData object */
function saveExtendedData($Tag,$Values) { $this->Data["Extended"][$Tag]=$Values; }
/* Called by the scaling algorithm to save the orientation of the scale */
function saveOrientation($Orientation) { $this->Data["Orientation"]=$Orientation; }
/* Convert a string to a single elements array */
function convertToArray($Value)
{ $Values = ""; $Values[] = $Value; return($Values); }
/* Class string wrapper */
function __toString()
{ return("pData object."); }
function left($value,$NbChar) { return substr($value,0,$NbChar); }
function right($value,$NbChar) { return substr($value,strlen($value)-$NbChar,$NbChar); }
function mid($value,$Depart,$NbChar) { return substr($value,$Depart-1,$NbChar); }
}
?>

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,472 @@
<?php
/*
pDraw - pChart core class
Version : 2.1.4
Made by : Jean-Damien POGOLOTTI
Last Update : 19/01/2014
This file can be distributed under the license you can find at :
http://www.pchart.net/license
You can find the whole class documentation on the pChart web site.
*/
/* The GD extension is mandatory */
if (!extension_loaded('gd') && !extension_loaded('gd2'))
{
echo "GD extension must be loaded. \r\n";
exit();
}
/* Image map handling */
define("IMAGE_MAP_STORAGE_FILE" , 680001);
define("IMAGE_MAP_STORAGE_SESSION" , 680002);
/* Last generated chart layout */
define("CHART_LAST_LAYOUT_REGULAR" , 680011);
define("CHART_LAST_LAYOUT_STACKED" , 680012);
/* ImageMap string delimiter */
define("IMAGE_MAP_DELIMITER" , chr(1));
class pImage extends pDraw
{
/* Image settings, size, quality, .. */
var $XSize = NULL; // Width of the picture
var $YSize = NULL; // Height of the picture
var $Picture = NULL; // GD picture object
var $Antialias = TRUE; // Turn antialias on or off
var $AntialiasQuality = 0; // Quality of the antialiasing implementation (0-1)
var $Mask = ""; // Already drawn pixels mask (Filled circle implementation)
var $TransparentBackground = FALSE; // Just to know if we need to flush the alpha channels when rendering
/* Graph area settings */
var $GraphAreaX1 = NULL; // Graph area X origin
var $GraphAreaY1 = NULL; // Graph area Y origin
var $GraphAreaX2 = NULL; // Graph area bottom right X position
var $GraphAreaY2 = NULL; // Graph area bottom right Y position
/* Scale settings */
var $ScaleMinDivHeight = 20; // Minimum height for scame divs
/* Font properties */
var $FontName = "fonts/GeosansLight.ttf"; // Default font file
var $FontSize = 12; // Default font size
var $FontBox = NULL; // Return the bounding box of the last written string
var $FontColorR = 0; // Default color settings
var $FontColorG = 0; // Default color settings
var $FontColorB = 0; // Default color settings
var $FontColorA = 100; // Default transparency
/* Shadow properties */
var $Shadow = FALSE; // Turn shadows on or off
var $ShadowX = NULL; // X Offset of the shadow
var $ShadowY = NULL; // Y Offset of the shadow
var $ShadowR = NULL; // R component of the shadow
var $ShadowG = NULL; // G component of the shadow
var $ShadowB = NULL; // B component of the shadow
var $Shadowa = NULL; // Alpha level of the shadow
/* Image map */
var $ImageMap = NULL; // Aray containing the image map
var $ImageMapIndex = "pChart"; // Name of the session array
var $ImageMapStorageMode = NULL; // Save the current imagemap storage mode
var $ImageMapAutoDelete = TRUE; // Automatic deletion of the image map temp files
/* Data Set */
var $DataSet = NULL; // Attached dataset
/* Last generated chart info */
var $LastChartLayout = CHART_LAST_LAYOUT_REGULAR; // Last layout : regular or stacked
/* Class constructor */
function pImage($XSize,$YSize,$DataSet=NULL,$TransparentBackground=FALSE)
{
$this->TransparentBackground = $TransparentBackground;
if ( $DataSet != NULL ) { $this->DataSet = $DataSet; }
$this->XSize = $XSize;
$this->YSize = $YSize;
$this->Picture = imagecreatetruecolor($XSize,$YSize);
if ( $this->TransparentBackground )
{
imagealphablending($this->Picture,FALSE);
imagefilledrectangle($this->Picture, 0,0,$XSize, $YSize, imagecolorallocatealpha($this->Picture, 255, 255, 255, 127));
imagealphablending($this->Picture,TRUE);
imagesavealpha($this->Picture,true);
}
else
{
$C_White = $this->AllocateColor($this->Picture,255,255,255);
imagefilledrectangle($this->Picture,0,0,$XSize,$YSize,$C_White);
}
}
/* Enable / Disable and set shadow properties */
function setShadow($Enabled=TRUE,$Format="")
{
$X = isset($Format["X"]) ? $Format["X"] : 2;
$Y = isset($Format["Y"]) ? $Format["Y"] : 2;
$R = isset($Format["R"]) ? $Format["R"] : 0;
$G = isset($Format["G"]) ? $Format["G"] : 0;
$B = isset($Format["B"]) ? $Format["B"] : 0;
$Alpha = isset($Format["Alpha"]) ? $Format["Alpha"] : 10;
$this->Shadow = $Enabled;
$this->ShadowX = $X;
$this->ShadowY = $Y;
$this->ShadowR = $R;
$this->ShadowG = $G;
$this->ShadowB = $B;
$this->Shadowa = $Alpha;
}
/* Set the graph area position */
function setGraphArea($X1,$Y1,$X2,$Y2)
{
if ( $X2 < $X1 || $X1 == $X2 || $Y2 < $Y1 || $Y1 == $Y2 ) { return(-1); }
$this->GraphAreaX1 = $X1; $this->DataSet->Data["GraphArea"]["X1"] = $X1;
$this->GraphAreaY1 = $Y1; $this->DataSet->Data["GraphArea"]["Y1"] = $Y1;
$this->GraphAreaX2 = $X2; $this->DataSet->Data["GraphArea"]["X2"] = $X2;
$this->GraphAreaY2 = $Y2; $this->DataSet->Data["GraphArea"]["Y2"] = $Y2;
}
/* Return the width of the picture */
function getWidth()
{ return($this->XSize); }
/* Return the heigth of the picture */
function getHeight()
{ return($this->YSize); }
/* Render the picture to a file */
function render($FileName)
{
if ( $this->TransparentBackground ) { imagealphablending($this->Picture,false); imagesavealpha($this->Picture,true); }
imagepng($this->Picture,$FileName);
}
/* Render the picture to a web browser stream */
function stroke($BrowserExpire=FALSE)
{
if ( $this->TransparentBackground ) { imagealphablending($this->Picture,false); imagesavealpha($this->Picture,true); }
if ( $BrowserExpire )
{
header("Expires: Mon, 26 Jul 1997 05:00:00 GMT");
header("Cache-Control: no-cache");
header("Pragma: no-cache");
}
header('Content-type: image/png');
imagepng($this->Picture);
}
/* Automatic output method based on the calling interface */
function autoOutput($FileName="output.png")
{
if (php_sapi_name() == "cli")
$this->Render($FileName);
else
$this->Stroke();
}
/* Return the length between two points */
function getLength($X1,$Y1,$X2,$Y2)
{ return(sqrt(pow(max($X1,$X2)-min($X1,$X2),2)+pow(max($Y1,$Y2)-min($Y1,$Y2),2))); }
/* Return the orientation of a line */
function getAngle($X1,$Y1,$X2,$Y2)
{
$Opposite = $Y2 - $Y1; $Adjacent = $X2 - $X1;$Angle = rad2deg(atan2($Opposite,$Adjacent));
if ($Angle > 0) { return($Angle); } else { return(360-abs($Angle)); }
}
/* Return the surrounding box of text area */
function getTextBox_deprecated($X,$Y,$FontName,$FontSize,$Angle,$Text)
{
$Size = imagettfbbox($FontSize,$Angle,$FontName,$Text);
$Width = $this->getLength($Size[0],$Size[1],$Size[2],$Size[3])+1;
$Height = $this->getLength($Size[2],$Size[3],$Size[4],$Size[5])+1;
$RealPos[0]["X"] = $X; $RealPos[0]["Y"] = $Y;
$RealPos[1]["X"] = cos((360-$Angle)*PI/180)*$Width + $RealPos[0]["X"]; $RealPos[1]["Y"] = sin((360-$Angle)*PI/180)*$Width + $RealPos[0]["Y"];
$RealPos[2]["X"] = cos((270-$Angle)*PI/180)*$Height + $RealPos[1]["X"]; $RealPos[2]["Y"] = sin((270-$Angle)*PI/180)*$Height + $RealPos[1]["Y"];
$RealPos[3]["X"] = cos((180-$Angle)*PI/180)*$Width + $RealPos[2]["X"]; $RealPos[3]["Y"] = sin((180-$Angle)*PI/180)*$Width + $RealPos[2]["Y"];
$RealPos[TEXT_ALIGN_BOTTOMLEFT]["X"] = $RealPos[0]["X"]; $RealPos[TEXT_ALIGN_BOTTOMLEFT]["Y"] = $RealPos[0]["Y"];
$RealPos[TEXT_ALIGN_BOTTOMRIGHT]["X"] = $RealPos[1]["X"]; $RealPos[TEXT_ALIGN_BOTTOMRIGHT]["Y"] = $RealPos[1]["Y"];
return($RealPos);
}
/* Return the surrounding box of text area */
function getTextBox($X,$Y,$FontName,$FontSize,$Angle,$Text)
{
$coords = imagettfbbox($FontSize, 0, $FontName, $Text);
$a = deg2rad($Angle); $ca = cos($a); $sa = sin($a); $RealPos = array();
for($i = 0; $i < 7; $i += 2)
{
$RealPos[$i/2]["X"] = $X + round($coords[$i] * $ca + $coords[$i+1] * $sa);
$RealPos[$i/2]["Y"] = $Y + round($coords[$i+1] * $ca - $coords[$i] * $sa);
}
$RealPos[TEXT_ALIGN_BOTTOMLEFT]["X"] = $RealPos[0]["X"]; $RealPos[TEXT_ALIGN_BOTTOMLEFT]["Y"] = $RealPos[0]["Y"];
$RealPos[TEXT_ALIGN_BOTTOMRIGHT]["X"] = $RealPos[1]["X"]; $RealPos[TEXT_ALIGN_BOTTOMRIGHT]["Y"] = $RealPos[1]["Y"];
$RealPos[TEXT_ALIGN_TOPLEFT]["X"] = $RealPos[3]["X"]; $RealPos[TEXT_ALIGN_TOPLEFT]["Y"] = $RealPos[3]["Y"];
$RealPos[TEXT_ALIGN_TOPRIGHT]["X"] = $RealPos[2]["X"]; $RealPos[TEXT_ALIGN_TOPRIGHT]["Y"] = $RealPos[2]["Y"];
$RealPos[TEXT_ALIGN_BOTTOMMIDDLE]["X"] = ($RealPos[1]["X"]-$RealPos[0]["X"])/2+$RealPos[0]["X"]; $RealPos[TEXT_ALIGN_BOTTOMMIDDLE]["Y"] = ($RealPos[0]["Y"]-$RealPos[1]["Y"])/2+$RealPos[1]["Y"];
$RealPos[TEXT_ALIGN_TOPMIDDLE]["X"] = ($RealPos[2]["X"]-$RealPos[3]["X"])/2+$RealPos[3]["X"]; $RealPos[TEXT_ALIGN_TOPMIDDLE]["Y"] = ($RealPos[3]["Y"]-$RealPos[2]["Y"])/2+$RealPos[2]["Y"];
$RealPos[TEXT_ALIGN_MIDDLELEFT]["X"] = ($RealPos[0]["X"]-$RealPos[3]["X"])/2+$RealPos[3]["X"]; $RealPos[TEXT_ALIGN_MIDDLELEFT]["Y"] = ($RealPos[0]["Y"]-$RealPos[3]["Y"])/2+$RealPos[3]["Y"];
$RealPos[TEXT_ALIGN_MIDDLERIGHT]["X"] = ($RealPos[1]["X"]-$RealPos[2]["X"])/2+$RealPos[2]["X"]; $RealPos[TEXT_ALIGN_MIDDLERIGHT]["Y"] = ($RealPos[1]["Y"]-$RealPos[2]["Y"])/2+$RealPos[2]["Y"];
$RealPos[TEXT_ALIGN_MIDDLEMIDDLE]["X"] = ($RealPos[1]["X"]-$RealPos[3]["X"])/2+$RealPos[3]["X"]; $RealPos[TEXT_ALIGN_MIDDLEMIDDLE]["Y"] = ($RealPos[0]["Y"]-$RealPos[2]["Y"])/2+$RealPos[2]["Y"];
return($RealPos);
}
/* Set current font properties */
function setFontProperties($Format="")
{
$R = isset($Format["R"]) ? $Format["R"] : -1;
$G = isset($Format["G"]) ? $Format["G"] : -1;
$B = isset($Format["B"]) ? $Format["B"] : -1;
$Alpha = isset($Format["Alpha"]) ? $Format["Alpha"] : 100;
$FontName = isset($Format["FontName"]) ? $Format["FontName"] : NULL;
$FontSize = isset($Format["FontSize"]) ? $Format["FontSize"] : NULL;
if ( $R != -1) { $this->FontColorR = $R; }
if ( $G != -1) { $this->FontColorG = $G; }
if ( $B != -1) { $this->FontColorB = $B; }
if ( $Alpha != NULL) { $this->FontColorA = $Alpha; }
if ( $FontName != NULL )
$this->FontName = $FontName;
if ( $FontSize != NULL )
$this->FontSize = $FontSize;
}
/* Returns the 1st decimal values (used to correct AA bugs) */
function getFirstDecimal($Value)
{
$Values = preg_split("/\./",$Value);
if ( isset($Values[1]) ) { return(substr($Values[1],0,1)); } else { return(0); }
}
/* Attach a dataset to your pChart Object */
function setDataSet(&$DataSet)
{ $this->DataSet = $DataSet; }
/* Print attached dataset contents to STDOUT */
function printDataSet()
{ print_r($this->DataSet); }
/* Initialise the image map methods */
function initialiseImageMap($Name="pChart",$StorageMode=IMAGE_MAP_STORAGE_SESSION,$UniqueID="imageMap",$StorageFolder="tmp")
{
$this->ImageMapIndex = $Name;
$this->ImageMapStorageMode = $StorageMode;
if ($StorageMode == IMAGE_MAP_STORAGE_SESSION)
{
if(!isset($_SESSION)) { session_start(); }
$_SESSION[$this->ImageMapIndex] = NULL;
}
elseif($StorageMode == IMAGE_MAP_STORAGE_FILE)
{
$this->ImageMapFileName = $UniqueID;
$this->ImageMapStorageFolder = $StorageFolder;
if (file_exists($StorageFolder."/".$UniqueID.".map")) { unlink($StorageFolder."/".$UniqueID.".map"); }
}
}
/* Add a zone to the image map */
function addToImageMap($Type,$Plots,$Color=NULL,$Title=NULL,$Message=NULL,$HTMLEncode=FALSE)
{
if ( $this->ImageMapStorageMode == NULL ) { $this->initialiseImageMap(); }
/* Encode the characters in the imagemap in HTML standards */
$Title = str_replace("&#8364;","\u20AC",$Title);
$Title = htmlentities($Title,ENT_QUOTES,"ISO-8859-15");
if ( $HTMLEncode )
{
$Message = htmlentities($Message,ENT_QUOTES,"ISO-8859-15");
$Message = str_replace("&lt;","<",$Message);
$Message = str_replace("&gt;",">",$Message);
}
if ( $this->ImageMapStorageMode == IMAGE_MAP_STORAGE_SESSION )
{
if(!isset($_SESSION)) { $this->initialiseImageMap(); }
$_SESSION[$this->ImageMapIndex][] = array($Type,$Plots,$Color,$Title,$Message);
}
elseif($this->ImageMapStorageMode == IMAGE_MAP_STORAGE_FILE)
{
$Handle = fopen($this->ImageMapStorageFolder."/".$this->ImageMapFileName.".map", 'a');
fwrite($Handle, $Type.IMAGE_MAP_DELIMITER.$Plots.IMAGE_MAP_DELIMITER.$Color.IMAGE_MAP_DELIMITER.$Title.IMAGE_MAP_DELIMITER.$Message."\r\n");
fclose($Handle);
}
}
/* Remove VOID values from an imagemap custom values array */
function removeVOIDFromArray($SerieName, $Values)
{
if ( !isset($this->DataSet->Data["Series"][$SerieName]) ) { return(-1); }
$Result = "";
foreach($this->DataSet->Data["Series"][$SerieName]["Data"] as $Key => $Value)
{ if ( $Value != VOID && isset($Values[$Key]) ) { $Result[] = $Values[$Key]; } }
return($Result);
}
/* Replace the title of one image map serie */
function replaceImageMapTitle($OldTitle, $NewTitle)
{
if ( $this->ImageMapStorageMode == NULL ) { return(-1); }
if ( is_array($NewTitle) ) { $NewTitle = $this->removeVOIDFromArray($OldTitle, $NewTitle); }
if ( $this->ImageMapStorageMode == IMAGE_MAP_STORAGE_SESSION )
{
if(!isset($_SESSION)) { return(-1); }
if ( is_array($NewTitle) )
{ $ID = 0; foreach($_SESSION[$this->ImageMapIndex] as $Key => $Settings) { if ( $Settings[3] == $OldTitle && isset($NewTitle[$ID])) { $_SESSION[$this->ImageMapIndex][$Key][3] = $NewTitle[$ID]; $ID++; } } }
else
{ foreach($_SESSION[$this->ImageMapIndex] as $Key => $Settings) { if ( $Settings[3] == $OldTitle ) { $_SESSION[$this->ImageMapIndex][$Key][3] = $NewTitle; } } }
}
elseif( $this->ImageMapStorageMode == IMAGE_MAP_STORAGE_FILE )
{
$TempArray = "";
$Handle = @fopen($this->ImageMapStorageFolder."/".$this->ImageMapFileName.".map", "r");
if ($Handle)
{
while (($Buffer = fgets($Handle, 4096)) !== false)
{
$Fields = preg_split("/".IMAGE_MAP_DELIMITER."/",str_replace(array(chr(10),chr(13)),"",$Buffer));
$TempArray[] = array($Fields[0],$Fields[1],$Fields[2],$Fields[3],$Fields[4]);
}
fclose($Handle);
if ( is_array($NewTitle) )
{ $ID = 0; foreach($TempArray as $Key => $Settings) { if ( $Settings[3] == $OldTitle && isset($NewTitle[$ID]) ) { $TempArray[$Key][3] = $NewTitle[$ID]; $ID++; } } }
else
{ foreach($TempArray as $Key => $Settings) { if ( $Settings[3] == $OldTitle ) { $TempArray[$Key][3] = $NewTitle; } } }
$Handle = fopen($this->ImageMapStorageFolder."/".$this->ImageMapFileName.".map", 'w');
foreach($TempArray as $Key => $Settings)
{ fwrite($Handle, $Settings[0].IMAGE_MAP_DELIMITER.$Settings[1].IMAGE_MAP_DELIMITER.$Settings[2].IMAGE_MAP_DELIMITER.$Settings[3].IMAGE_MAP_DELIMITER.$Settings[4]."\r\n"); }
fclose($Handle);
}
}
}
/* Replace the values of the image map contents */
function replaceImageMapValues($Title, $Values)
{
if ( $this->ImageMapStorageMode == NULL ) { return(-1); }
$Values = $this->removeVOIDFromArray($Title, $Values);
$ID = 0;
if ( $this->ImageMapStorageMode == IMAGE_MAP_STORAGE_SESSION )
{
if(!isset($_SESSION)) { return(-1); }
foreach($_SESSION[$this->ImageMapIndex] as $Key => $Settings) { if ( $Settings[3] == $Title ) { if ( isset($Values[$ID]) ) { $_SESSION[$this->ImageMapIndex][$Key][4] = $Values[$ID]; } $ID++; } }
}
elseif( $this->ImageMapStorageMode == IMAGE_MAP_STORAGE_FILE )
{
$TempArray = "";
$Handle = @fopen($this->ImageMapStorageFolder."/".$this->ImageMapFileName.".map", "r");
if ($Handle)
{
while (($Buffer = fgets($Handle, 4096)) !== false)
{
$Fields = preg_split("/".IMAGE_MAP_DELIMITER."/",str_replace(array(chr(10),chr(13)),"",$Buffer));
$TempArray[] = array($Fields[0],$Fields[1],$Fields[2],$Fields[3],$Fields[4]);
}
fclose($Handle);
foreach($TempArray as $Key => $Settings) { if ( $Settings[3] == $Title ) { if ( isset($Values[$ID]) ) { $TempArray[$Key][4] = $Values[$ID]; } $ID++; } }
$Handle = fopen($this->ImageMapStorageFolder."/".$this->ImageMapFileName.".map", 'w');
foreach($TempArray as $Key => $Settings)
{ fwrite($Handle, $Settings[0].IMAGE_MAP_DELIMITER.$Settings[1].IMAGE_MAP_DELIMITER.$Settings[2].IMAGE_MAP_DELIMITER.$Settings[3].IMAGE_MAP_DELIMITER.$Settings[4]."\r\n"); }
fclose($Handle);
}
}
}
/* Dump the image map */
function dumpImageMap($Name="pChart",$StorageMode=IMAGE_MAP_STORAGE_SESSION,$UniqueID="imageMap",$StorageFolder="tmp")
{
$this->ImageMapIndex = $Name;
$this->ImageMapStorageMode = $StorageMode;
if ( $this->ImageMapStorageMode == IMAGE_MAP_STORAGE_SESSION )
{
if(!isset($_SESSION)) { session_start(); }
if ( $_SESSION[$Name] != NULL )
{
foreach($_SESSION[$Name] as $Key => $Params)
{ echo $Params[0].IMAGE_MAP_DELIMITER.$Params[1].IMAGE_MAP_DELIMITER.$Params[2].IMAGE_MAP_DELIMITER.$Params[3].IMAGE_MAP_DELIMITER.$Params[4]."\r\n"; }
}
}
elseif( $this->ImageMapStorageMode == IMAGE_MAP_STORAGE_FILE )
{
if (file_exists($StorageFolder."/".$UniqueID.".map"))
{
$Handle = @fopen($StorageFolder."/".$UniqueID.".map", "r");
if ($Handle) { while (($Buffer = fgets($Handle, 4096)) !== false) { echo $Buffer; } }
fclose($Handle);
if ( $this->ImageMapAutoDelete ) { unlink($StorageFolder."/".$UniqueID.".map"); }
}
}
/* When the image map is returned to the client, the script ends */
exit();
}
/* Return the HTML converted color from the RGB composite values */
function toHTMLColor($R,$G,$B)
{
$R=intval($R); $G=intval($G); $B=intval($B);
$R=dechex($R<0?0:($R>255?255:$R)); $G=dechex($G<0?0:($G>255?255:$G));$B=dechex($B<0?0:($B>255?255:$B));
$Color="#".(strlen($R) < 2?'0':'').$R; $Color.=(strlen($G) < 2?'0':'').$G; $Color.= (strlen($B) < 2?'0':'').$B;
return($Color);
}
/* Reverse an array of points */
function reversePlots($Plots)
{
$Result = "";
for($i=count($Plots)-2;$i>=0;$i=$i-2) { $Result[] = $Plots[$i]; $Result[] = $Plots[$i+1]; }
return($Result);
}
/* Mirror Effect */
function drawAreaMirror($X,$Y,$Width,$Height,$Format="")
{
$StartAlpha = isset($Format["StartAlpha"]) ? $Format["StartAlpha"] : 80;
$EndAlpha = isset($Format["EndAlpha"]) ? $Format["EndAlpha"] : 0;
$AlphaStep = ($StartAlpha-$EndAlpha)/$Height;
$Picture = imagecreatetruecolor($this->XSize,$this->YSize);
imagecopy($Picture,$this->Picture,0,0,0,0,$this->XSize,$this->YSize);
for($i=1;$i<=$Height;$i++)
{
if ( $Y+($i-1) < $this->YSize && $Y-$i > 0 ) { imagecopymerge($Picture,$this->Picture,$X,$Y+($i-1),$X,$Y-$i,$Width,1,$StartAlpha-$AlphaStep*$i); }
}
imagecopy($this->Picture,$Picture,0,0,0,0,$this->XSize,$this->YSize);
}
}
?>

View File

@@ -0,0 +1,241 @@
<?php
/*
pIndicator - class to draw indicators
Version : 2.1.4
Made by : Jean-Damien POGOLOTTI
Last Update : 19/01/2014
This file can be distributed under the license you can find at :
http://www.pchart.net/license
You can find the whole class documentation on the pChart web site.
*/
define("INDICATOR_CAPTION_DEFAULT" , 700001);
define("INDICATOR_CAPTION_EXTENDED" , 700002);
define("INDICATOR_CAPTION_INSIDE" , 700011);
define("INDICATOR_CAPTION_BOTTOM" , 700012);
define("INDICATOR_VALUE_BUBBLE" , 700021);
define("INDICATOR_VALUE_LABEL" , 700022);
/* pIndicator class definition */
class pIndicator
{
var $pChartObject;
/* Class creator */
function pIndicator($pChartObject)
{
$this->pChartObject = $pChartObject;
}
/* Draw an indicator */
function draw($X,$Y,$Width,$Height,$Format="")
{
$Values = isset($Format["Values"]) ? $Format["Values"] : VOID;
$IndicatorSections = isset($Format["IndicatorSections"]) ? $Format["IndicatorSections"] : NULL;
$ValueDisplay = isset($Format["ValueDisplay"]) ? $Format["ValueDisplay"] : INDICATOR_VALUE_BUBBLE;
$SectionsMargin = isset($Format["SectionsMargin"]) ? $Format["SectionsMargin"] : 4;
$DrawLeftHead = isset($Format["DrawLeftHead"]) ? $Format["DrawLeftHead"] : TRUE;
$DrawRightHead = isset($Format["DrawRightHead"]) ? $Format["DrawRightHead"] : TRUE;
$HeadSize = isset($Format["HeadSize"]) ? $Format["HeadSize"] : floor($Height/4);
$TextPadding = isset($Format["TextPadding"]) ? $Format["TextPadding"] : 4;
$CaptionLayout = isset($Format["CaptionLayout"]) ? $Format["CaptionLayout"] : INDICATOR_CAPTION_EXTENDED;
$CaptionPosition = isset($Format["CaptionPosition"]) ? $Format["CaptionPosition"] : INDICATOR_CAPTION_INSIDE;
$CaptionColorFactor = isset($Format["CaptionColorFactor"]) ? $Format["CaptionColorFactor"] : NULL;
$CaptionR = isset($Format["CaptionR"]) ? $Format["CaptionR"] : 255;
$CaptionG = isset($Format["CaptionG"]) ? $Format["CaptionG"] : 255;
$CaptionB = isset($Format["CaptionB"]) ? $Format["CaptionB"] : 255;
$CaptionAlpha = isset($Format["CaptionAlpha"]) ? $Format["CaptionAlpha"] : 100;
$SubCaptionColorFactor = isset($Format["SubCaptionColorFactor"]) ? $Format["SubCaptionColorFactor"] : NULL;
$SubCaptionR = isset($Format["SubCaptionR"]) ? $Format["SubCaptionR"] : 50;
$SubCaptionG = isset($Format["SubCaptionG"]) ? $Format["SubCaptionG"] : 50;
$SubCaptionB = isset($Format["SubCaptionB"]) ? $Format["SubCaptionB"] : 50;
$SubCaptionAlpha = isset($Format["SubCaptionAlpha"]) ? $Format["SubCaptionAlpha"] : 100;
$ValueFontName = isset($Format["ValueFontName"]) ? $Format["ValueFontName"] : $this->pChartObject->FontName;
$ValueFontSize = isset($Format["ValueFontSize"]) ? $Format["ValueFontSize"] : $this->pChartObject->FontSize;
$CaptionFontName = isset($Format["CaptionFontName"]) ? $Format["CaptionFontName"] : $this->pChartObject->FontName;
$CaptionFontSize = isset($Format["CaptionFontSize"]) ? $Format["CaptionFontSize"] : $this->pChartObject->FontSize;
$Unit = isset($Format["Unit"]) ? $Format["Unit"] : "";
/* Convert the Values to display to an array if needed */
if ( !is_array($Values) ) { $Value = $Values; $Values = ""; $Values[] = $Value; }
/* No section, let's die */
if ( $IndicatorSections == NULL ) { return(0); }
/* Determine indicator visual configuration */
$OverallMin = $IndicatorSections[0]["End"]; $OverallMax = $IndicatorSections[0]["Start"];
foreach ($IndicatorSections as $Key => $Settings)
{
if ( $Settings["End"] > $OverallMax ) { $OverallMax = $Settings["End"]; }
if ( $Settings["Start"] < $OverallMin ) { $OverallMin = $Settings["Start"]; }
}
$RealWidth = $Width - (count($IndicatorSections)-1)*$SectionsMargin;
$XScale = $RealWidth / ($OverallMax-$OverallMin);
$X1 = $X; $ValuesPos = "";
foreach ($IndicatorSections as $Key => $Settings)
{
$Color = array("R"=>$Settings["R"],"G"=>$Settings["G"],"B"=>$Settings["B"]);
$Caption = $Settings["Caption"];
$SubCaption = $Settings["Start"]." - ".$Settings["End"];
$X2 = $X1 + ($Settings["End"] - $Settings["Start"]) * $XScale;
if ( $Key == 0 && $DrawLeftHead )
{
$Poly = ""; $Poly[] = $X1-1; $Poly[] = $Y; $Poly[] = $X1-1; $Poly[] = $Y+$Height; $Poly[] = $X1-1-$HeadSize; $Poly[] = $Y+($Height/2);
$this->pChartObject->drawPolygon($Poly,$Color);
$this->pChartObject->drawLine($X1-2,$Y,$X1-2-$HeadSize,$Y+($Height/2),$Color);
$this->pChartObject->drawLine($X1-2,$Y+$Height,$X1-2-$HeadSize,$Y+($Height/2),$Color);
}
/* Determine the position of the breaks */
$Break = "";
foreach($Values as $iKey => $Value)
{
if ( $Value >= $Settings["Start"] && $Value <= $Settings["End"] )
{
$XBreak = $X1 + ($Value - $Settings["Start"]) * $XScale;
$ValuesPos[$Value] = $XBreak;
$Break[] = floor($XBreak);
}
}
if ( $ValueDisplay == INDICATOR_VALUE_LABEL )
{
if ( $Break == "" )
$this->pChartObject->drawFilledRectangle($X1,$Y,$X2,$Y+$Height,$Color);
else
{
sort($Break);
$Poly = ""; $Poly[] = $X1; $Poly[] = $Y; $LastPointWritten = FALSE;
foreach($Break as $iKey => $Value)
{
if ( $Value-5 >= $X1 )
{ $Poly[] = $Value-5; $Poly[] = $Y; }
elseif ($X1 - ($Value-5) > 0 )
{
$Offset = $X1 - ($Value-5);
$Poly = ""; $Poly[] = $X1; $Poly[] = $Y + $Offset;
}
$Poly[] = $Value; $Poly[] = $Y+5;
if ( $Value+5 <= $X2 )
{ $Poly[] = $Value+5; $Poly[] = $Y; }
elseif (($Value+5) > $X2 )
{
$Offset = ($Value+5) - $X2;
$Poly[] = $X2; $Poly[] = $Y + $Offset;
$LastPointWritten = TRUE;
}
}
if ( !$LastPointWritten ) { $Poly[] = $X2; $Poly[] = $Y; }
$Poly[] = $X2; $Poly[] = $Y+$Height;
$Poly[] = $X1; $Poly[] = $Y+$Height;
$this->pChartObject->drawPolygon($Poly,$Color);
}
}
else
$this->pChartObject->drawFilledRectangle($X1,$Y,$X2,$Y+$Height,$Color);
if ( $Key == count($IndicatorSections)-1 && $DrawRightHead )
{
$Poly = ""; $Poly[] = $X2+1; $Poly[] = $Y; $Poly[] = $X2+1; $Poly[] = $Y+$Height; $Poly[] = $X2+1+$HeadSize; $Poly[] = $Y+($Height/2);
$this->pChartObject->drawPolygon($Poly,$Color);
$this->pChartObject->drawLine($X2+1,$Y,$X2+1+$HeadSize,$Y+($Height/2),$Color);
$this->pChartObject->drawLine($X2+1,$Y+$Height,$X2+1+$HeadSize,$Y+($Height/2),$Color);
}
if ( $CaptionPosition == INDICATOR_CAPTION_INSIDE )
{
$TxtPos = $this->pChartObject->getTextBox($X1,$Y+$Height+$TextPadding,$CaptionFontName,$CaptionFontSize,0,$Caption);
$YOffset = ($TxtPos[0]["Y"] - $TxtPos[2]["Y"]) + $TextPadding;
if ( $CaptionLayout == INDICATOR_CAPTION_EXTENDED )
{
$TxtPos = $this->pChartObject->getTextBox($X1,$Y+$Height+$TextPadding,$CaptionFontName,$CaptionFontSize,0,$SubCaption);
$YOffset = $YOffset + ($TxtPos[0]["Y"] - $TxtPos[2]["Y"]) + $TextPadding*2;
}
$XOffset = $TextPadding;
}
else
{ $YOffset = 0; $XOffset = 0; }
if ( $CaptionColorFactor == NULL )
{ $CaptionColor = array("Align"=>TEXT_ALIGN_TOPLEFT,"FontName"=>$CaptionFontName,"FontSize"=>$CaptionFontSize,"R"=>$CaptionR,"G"=>$CaptionG,"B"=>$CaptionB,"Alpha"=>$CaptionAlpha); }
else
{ $CaptionColor = array("Align"=>TEXT_ALIGN_TOPLEFT,"FontName"=>$CaptionFontName,"FontSize"=>$CaptionFontSize,"R"=>$Settings["R"]+$CaptionColorFactor,"G"=>$Settings["G"]+$CaptionColorFactor,"B"=>$Settings["B"]+$CaptionColorFactor); }
if ( $SubCaptionColorFactor == NULL )
$SubCaptionColor = array("Align"=>TEXT_ALIGN_TOPLEFT,"FontName"=>$CaptionFontName,"FontSize"=>$CaptionFontSize,"R"=>$SubCaptionR,"G"=>$SubCaptionG,"B"=>$SubCaptionB,"Alpha"=>$SubCaptionAlpha);
else
$SubCaptionColor = array("Align"=>TEXT_ALIGN_TOPLEFT,"FontName"=>$CaptionFontName,"FontSize"=>$CaptionFontSize,"R"=>$Settings["R"]+$SubCaptionColorFactor,"G"=>$Settings["G"]+$SubCaptionColorFactor,"B"=>$Settings["B"]+$SubCaptionColorFactor);
$RestoreShadow = $this->pChartObject->Shadow;
$this->pChartObject->Shadow = FALSE;
if ( $CaptionLayout == INDICATOR_CAPTION_DEFAULT )
$this->pChartObject->drawText($X1,$Y+$Height+$TextPadding,$Caption,$CaptionColor);
elseif ( $CaptionLayout == INDICATOR_CAPTION_EXTENDED )
{
$TxtPos = $this->pChartObject->getTextBox($X1,$Y+$Height+$TextPadding,$CaptionFontName,$CaptionFontSize,0,$Caption);
$CaptionHeight = $TxtPos[0]["Y"] - $TxtPos[2]["Y"];
$this->pChartObject->drawText($X1+$XOffset,$Y+$Height-$YOffset+$TextPadding,$Caption,$CaptionColor);
$this->pChartObject->drawText($X1+$XOffset,$Y+$Height-$YOffset+$CaptionHeight+$TextPadding*2,$SubCaption,$SubCaptionColor);
}
$this->pChartObject->Shadow = $RestoreShadow;
$X1 = $X2 + $SectionsMargin;
}
$RestoreShadow = $this->pChartObject->Shadow;
$this->pChartObject->Shadow = FALSE;
foreach($Values as $Key => $Value)
{
if ( $Value >= $OverallMin && $Value <= $OverallMax )
{
foreach ($IndicatorSections as $Key => $Settings)
{
if ( $Value >= $Settings["Start"] && $Value <= $Settings["End"] )
{
$X1 = $ValuesPos[$Value]; //$X + $Key*$SectionsMargin + ($Value - $OverallMin) * $XScale;
if ( $ValueDisplay == INDICATOR_VALUE_BUBBLE )
{
$TxtPos = $this->pChartObject->getTextBox($X1,$Y,$ValueFontName,$ValueFontSize,0,$Value.$Unit);
$Radius = floor(($TxtPos[1]["X"] - $TxtPos[0]["X"] + $TextPadding*4)/2);
$this->pChartObject->drawFilledCircle($X1,$Y,$Radius+4,array("R"=>$Settings["R"]+20,"G"=>$Settings["G"]+20,"B"=>$Settings["B"]+20));
$this->pChartObject->drawFilledCircle($X1,$Y,$Radius,array("R"=>255,"G"=>255,"B"=>255));
$TextSettings = array("Align"=>TEXT_ALIGN_MIDDLEMIDDLE,"FontName"=>$ValueFontName,"FontSize"=>$ValueFontSize);
$this->pChartObject->drawText($X1-1,$Y-1,$Value.$Unit,$TextSettings);
}
elseif( $ValueDisplay == INDICATOR_VALUE_LABEL )
{
$Caption = "";
$Caption[] = array("Format"=>array("R"=>$Settings["R"],"G"=>$Settings["G"],"B"=>$Settings["B"],"Alpha"=>100),"Caption"=>$Value.$Unit);
$this->pChartObject->drawLabelBox(floor($X1),floor($Y)+2,"Value - ".$Settings["Caption"],$Caption);
}
}
$X1 = $X2 + $SectionsMargin;
}
}
}
$this->pChartObject->Shadow = $RestoreShadow;
}
}
?>

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,681 @@
<?php
/*
pRadar - class to draw radar charts
Version : 2.1.4
Made by : Jean-Damien POGOLOTTI
Last Update : 19/01/2014
This file can be distributed under the license you can find at :
http://www.pchart.net/license
You can find the whole class documentation on the pChart web site.
*/
define("SEGMENT_HEIGHT_AUTO" , 690001);
define("RADAR_LAYOUT_STAR" , 690011);
define("RADAR_LAYOUT_CIRCLE" , 690012);
define("RADAR_LABELS_ROTATED" , 690021);
define("RADAR_LABELS_HORIZONTAL" , 690022);
/* pRadar class definition */
class pRadar
{
var $pChartObject;
/* Class creator */
function pRadar()
{ }
/* Draw a radar chart */
function drawRadar($Object,$Values,$Format="")
{
$this->pChartObject = $Object;
$FixedMax = isset($Format["FixedMax"]) ? $Format["FixedMax"] : VOID;
$AxisR = isset($Format["AxisR"]) ? $Format["AxisR"] : 60;
$AxisG = isset($Format["AxisG"]) ? $Format["AxisG"] : 60;
$AxisB = isset($Format["AxisB"]) ? $Format["AxisB"] : 60;
$AxisAlpha = isset($Format["AxisAlpha"]) ? $Format["AxisAlpha"] : 50;
$AxisRotation = isset($Format["AxisRotation"]) ? $Format["AxisRotation"] : 0;
$DrawTicks = isset($Format["DrawTicks"]) ? $Format["DrawTicks"] : TRUE;
$TicksLength = isset($Format["TicksLength"]) ? $Format["TicksLength"] : 2;
$DrawAxisValues = isset($Format["DrawAxisValues"]) ? $Format["DrawAxisValues"] : TRUE;
$AxisBoxRounded = isset($Format["AxisBoxRounded"]) ? $Format["AxisBoxRounded"] : TRUE;
$AxisFontName = isset($Format["AxisFontName"]) ? $Format["AxisFontName"] : $this->pChartObject->FontName;
$AxisFontSize = isset($Format["AxisFontSize"]) ? $Format["AxisFontSize"] : $this->pChartObject->FontSize;
$WriteValues = isset($Format["WriteValues"]) ? $Format["WriteValues"] : FALSE;
$WriteValuesInBubble = isset($Format["WriteValuesInBubble"]) ? $Format["WriteValuesInBubble"] : TRUE;
$ValueFontName = isset($Format["ValueFontName"]) ? $Format["ValueFontName"] : $this->pChartObject->FontName;
$ValueFontSize = isset($Format["ValueFontSize"]) ? $Format["ValueFontSize"] : $this->pChartObject->FontSize;
$ValuePadding = isset($Format["ValuePadding"]) ? $Format["ValuePadding"] : 4;
$OuterBubbleRadius = isset($Format["OuterBubbleRadius"]) ? $Format["OuterBubbleRadius"] : 2;
$OuterBubbleR = isset($Format["OuterBubbleR"]) ? $Format["OuterBubbleR"] : VOID;
$OuterBubbleG = isset($Format["OuterBubbleG"]) ? $Format["OuterBubbleG"] : VOID;
$OuterBubbleB = isset($Format["OuterBubbleB"]) ? $Format["OuterBubbleB"] : VOID;
$OuterBubbleAlpha = isset($Format["OuterBubbleAlpha"]) ? $Format["OuterBubbleAlpha"] : 100;
$InnerBubbleR = isset($Format["InnerBubbleR"]) ? $Format["InnerBubbleR"] : 255;
$InnerBubbleG = isset($Format["InnerBubbleG"]) ? $Format["InnerBubbleG"] : 255;
$InnerBubbleB = isset($Format["InnerBubbleB"]) ? $Format["InnerBubbleB"] : 255;
$InnerBubbleAlpha = isset($Format["InnerBubbleAlpha"]) ? $Format["InnerBubbleAlpha"] : 100;
$DrawBackground = isset($Format["DrawBackground"]) ? $Format["DrawBackground"] : TRUE;
$BackgroundR = isset($Format["BackgroundR"]) ? $Format["BackgroundR"] : 255;
$BackgroundG = isset($Format["BackgroundG"]) ? $Format["BackgroundG"] : 255;
$BackgroundB = isset($Format["BackgroundB"]) ? $Format["BackgroundB"] : 255;
$BackgroundAlpha = isset($Format["BackgroundAlpha"]) ? $Format["BackgroundAlpha"] : 50;
$BackgroundGradient= isset($Format["BackgroundGradient"]) ? $Format["BackgroundGradient"] : NULL;
$Layout = isset($Format["Layout"]) ? $Format["Layout"] : RADAR_LAYOUT_STAR;
$SegmentHeight = isset($Format["SegmentHeight"]) ? $Format["SegmentHeight"] : SEGMENT_HEIGHT_AUTO;
$Segments = isset($Format["Segments"]) ? $Format["Segments"] : 4;
$WriteLabels = isset($Format["WriteLabels"]) ? $Format["WriteLabels"] : TRUE;
$SkipLabels = isset($Format["SkipLabels"]) ? $Format["SkipLabels"] : 1;
$LabelMiddle = isset($Format["LabelMiddle"]) ? $Format["LabelMiddle"] : FALSE;
$LabelsBackground = isset($Format["LabelsBackground"]) ? $Format["LabelsBackground"] : TRUE;
$LabelsBGR = isset($Format["LabelsBGR"]) ? $Format["LabelsBGR"] : 255;
$LabelsBGG = isset($Format["LabelsBGR"]) ? $Format["LabelsBGG"] : 255;
$LabelsBGB = isset($Format["LabelsBGR"]) ? $Format["LabelsBGB"] : 255;
$LabelsBGAlpha = isset($Format["LabelsBGAlpha"]) ? $Format["LabelsBGAlpha"] : 50;
$LabelPos = isset($Format["LabelPos"]) ? $Format["LabelPos"] : RADAR_LABELS_ROTATED;
$LabelPadding = isset($Format["LabelPadding"]) ? $Format["LabelPadding"] : 4;
$DrawPoints = isset($Format["DrawPoints"]) ? $Format["DrawPoints"] : TRUE;
$PointRadius = isset($Format["PointRadius"]) ? $Format["PointRadius"] : 4;
$PointSurrounding = isset($Format["PointRadius"]) ? $Format["PointRadius"] : -30;
$DrawLines = isset($Format["DrawLines"]) ? $Format["DrawLines"] : TRUE;
$LineLoopStart = isset($Format["LineLoopStart"]) ? $Format["LineLoopStart"] : TRUE;
$DrawPoly = isset($Format["DrawPoly"]) ? $Format["DrawPoly"] : FALSE;
$PolyAlpha = isset($Format["PolyAlpha"]) ? $Format["PolyAlpha"] : 40;
$FontSize = $Object->FontSize;
$X1 = $Object->GraphAreaX1;
$Y1 = $Object->GraphAreaY1;
$X2 = $Object->GraphAreaX2;
$Y2 = $Object->GraphAreaY2;
$RecordImageMap = isset($Format["RecordImageMap"]) ? $Format["RecordImageMap"] : FALSE;
/* Cancel default tick length if ticks not enabled */
if ( $DrawTicks == FALSE ) { $TicksLength = 0; }
/* Data Processing */
$Data = $Values->getData();
$Palette = $Values->getPalette();
/* Catch the number of required axis */
$LabelSerie = $Data["Abscissa"];
if ( $LabelSerie != "" )
{ $Points = count($Data["Series"][$LabelSerie]["Data"]); }
else
{
$Points = 0;
foreach($Data["Series"] as $SerieName => $DataArray)
{ if ( count($DataArray["Data"]) > $Points ) { $Points = count($DataArray["Data"]); } }
}
/* Draw the axis */
$CenterX = ($X2-$X1)/2 + $X1;
$CenterY = ($Y2-$Y1)/2 + $Y1;
$EdgeHeight = min(($X2-$X1)/2,($Y2-$Y1)/2);
if ( $WriteLabels )
$EdgeHeight = $EdgeHeight - $FontSize - $LabelPadding - $TicksLength;
/* Determine the scale if set to automatic */
if ( $SegmentHeight == SEGMENT_HEIGHT_AUTO)
{
if ( $FixedMax != VOID )
$Max = $FixedMax;
else
{
$Max = 0;
foreach($Data["Series"] as $SerieName => $DataArray)
{
if ( $SerieName != $LabelSerie )
{
if ( max($DataArray["Data"]) > $Max ) { $Max = max($DataArray["Data"]); }
}
}
}
$MaxSegments = $EdgeHeight/20;
$Scale = $Object->computeScale(0,$Max,$MaxSegments,array(1,2,5));
$Segments = $Scale["Rows"];
$SegmentHeight = $Scale["RowHeight"];
}
if ( $LabelMiddle && $SkipLabels == 1 )
{ $Axisoffset = (360/$Points)/2; }
elseif ( $LabelMiddle && $SkipLabels != 1 )
{ $Axisoffset = (360/($Points/$SkipLabels))/2; }
elseif ( !$LabelMiddle )
{ $Axisoffset = 0; }
/* Background processing */
if ( $DrawBackground )
{
$RestoreShadow = $Object->Shadow;
$Object->Shadow = FALSE;
if ($BackgroundGradient == NULL)
{
if ( $Layout == RADAR_LAYOUT_STAR )
{
$Color = array("R"=>$BackgroundR,"G"=>$BackgroundG,"B"=>$BackgroundB,"Alpha"=>$BackgroundAlpha);
$PointArray = "";
for($i=0;$i<=360;$i=$i+(360/$Points))
{
$PointArray[] = cos(deg2rad($i+$AxisRotation)) * $EdgeHeight + $CenterX;
$PointArray[] = sin(deg2rad($i+$AxisRotation)) * $EdgeHeight + $CenterY;
}
$Object->drawPolygon($PointArray,$Color);
}
elseif ( $Layout == RADAR_LAYOUT_CIRCLE )
{
$Color = array("R"=>$BackgroundR,"G"=>$BackgroundG,"B"=>$BackgroundB,"Alpha"=>$BackgroundAlpha);
$Object->drawFilledCircle($CenterX,$CenterY,$EdgeHeight,$Color);
}
}
else
{
$GradientROffset = ($BackgroundGradient["EndR"] - $BackgroundGradient["StartR"]) / $Segments;
$GradientGOffset = ($BackgroundGradient["EndG"] - $BackgroundGradient["StartG"]) / $Segments;
$GradientBOffset = ($BackgroundGradient["EndB"] - $BackgroundGradient["StartB"]) / $Segments;
$GradientAlphaOffset = ($BackgroundGradient["EndAlpha"] - $BackgroundGradient["StartAlpha"]) / $Segments;
if ( $Layout == RADAR_LAYOUT_STAR )
{
for($j=$Segments;$j>=1;$j--)
{
$Color = array("R"=>$BackgroundGradient["StartR"]+$GradientROffset*$j,"G"=>$BackgroundGradient["StartG"]+$GradientGOffset*$j,"B"=>$BackgroundGradient["StartB"]+$GradientBOffset*$j,"Alpha"=>$BackgroundGradient["StartAlpha"]+$GradientAlphaOffset*$j);
$PointArray = "";
for($i=0;$i<=360;$i=$i+(360/$Points))
{
$PointArray[] = cos(deg2rad($i+$AxisRotation)) * ($EdgeHeight/$Segments)*$j + $CenterX;
$PointArray[] = sin(deg2rad($i+$AxisRotation)) * ($EdgeHeight/$Segments)*$j + $CenterY;
}
$Object->drawPolygon($PointArray,$Color);
}
}
elseif ( $Layout == RADAR_LAYOUT_CIRCLE )
{
for($j=$Segments;$j>=1;$j--)
{
$Color = array("R"=>$BackgroundGradient["StartR"]+$GradientROffset*$j,"G"=>$BackgroundGradient["StartG"]+$GradientGOffset*$j,"B"=>$BackgroundGradient["StartB"]+$GradientBOffset*$j,"Alpha"=>$BackgroundGradient["StartAlpha"]+$GradientAlphaOffset*$j);
$Object->drawFilledCircle($CenterX,$CenterY,($EdgeHeight/$Segments)*$j,$Color);
}
}
}
$Object->Shadow = $RestoreShadow;
}
/* Axis to axis lines */
$Color = array("R"=>$AxisR,"G"=>$AxisG,"B"=>$AxisB,"Alpha"=>$AxisAlpha);
$ColorDotted = array("R"=>$AxisR,"G"=>$AxisG,"B"=>$AxisB,"Alpha"=>$AxisAlpha*.8, "Ticks"=>2);
if ( $Layout == RADAR_LAYOUT_STAR )
{
for($j=1;$j<=$Segments;$j++)
{
for($i=0;$i<360;$i=$i+(360/$Points))
{
$EdgeX1 = cos(deg2rad($i+$AxisRotation)) * ($EdgeHeight/$Segments)*$j + $CenterX;
$EdgeY1 = sin(deg2rad($i+$AxisRotation)) * ($EdgeHeight/$Segments)*$j + $CenterY;
$EdgeX2 = cos(deg2rad($i+$AxisRotation+(360/$Points))) * ($EdgeHeight/$Segments)*$j + $CenterX;
$EdgeY2 = sin(deg2rad($i+$AxisRotation+(360/$Points))) * ($EdgeHeight/$Segments)*$j + $CenterY;
$Object->drawLine($EdgeX1,$EdgeY1,$EdgeX2,$EdgeY2,$Color);
}
}
}
elseif ( $Layout == RADAR_LAYOUT_CIRCLE )
{
for($j=1;$j<=$Segments;$j++)
{
$Radius = ($EdgeHeight/$Segments)*$j;
$Object->drawCircle($CenterX,$CenterY,$Radius,$Radius,$Color);
}
}
if ( $DrawAxisValues )
{
if ( $LabelsBackground )
$Options = array("DrawBox"=>TRUE, "Align"=>TEXT_ALIGN_MIDDLEMIDDLE,"BoxR"=>$LabelsBGR,"BoxG"=>$LabelsBGG,"BoxB"=>$LabelsBGB,"BoxAlpha"=>$LabelsBGAlpha);
else
$Options = array("Align"=>TEXT_ALIGN_MIDDLEMIDDLE);
if ( $AxisBoxRounded ) { $Options["BoxRounded"] = TRUE; }
$Options["FontName"] = $AxisFontName;
$Options["FontSize"] = $AxisFontSize;
$Angle = 360 / ($Points*2);
for($j=1;$j<=$Segments;$j++)
{
$Label = $j * $SegmentHeight;
if ( $Layout == RADAR_LAYOUT_CIRCLE )
{
$EdgeX1 = cos(deg2rad($Angle+$AxisRotation)) * ($EdgeHeight/$Segments)*$j + $CenterX;
$EdgeY1 = sin(deg2rad($Angle+$AxisRotation)) * ($EdgeHeight/$Segments)*$j + $CenterY;
}
elseif ( $Layout == RADAR_LAYOUT_STAR )
{
$EdgeX1 = cos(deg2rad($AxisRotation)) * ($EdgeHeight/$Segments)*$j + $CenterX;
$EdgeY1 = sin(deg2rad($AxisRotation)) * ($EdgeHeight/$Segments)*$j + $CenterY;
$EdgeX2 = cos(deg2rad((360 / $Points) + $AxisRotation)) * ($EdgeHeight/$Segments)*$j + $CenterX;
$EdgeY2 = sin(deg2rad((360 / $Points) + $AxisRotation)) * ($EdgeHeight/$Segments)*$j + $CenterY;
$EdgeX1 = ($EdgeX2 - $EdgeX1)/2 + $EdgeX1;
$EdgeY1 = ($EdgeY2 - $EdgeY1)/2 + $EdgeY1;
}
$Object->drawText($EdgeX1,$EdgeY1,$Label,$Options);
}
}
/* Axis lines */
$ID = 0;
for($i=0;$i<360;$i=$i+(360/$Points))
{
$EdgeX = cos(deg2rad($i+$AxisRotation)) * ($EdgeHeight+$TicksLength) + $CenterX;
$EdgeY = sin(deg2rad($i+$AxisRotation)) * ($EdgeHeight+$TicksLength) + $CenterY;
if ($ID % $SkipLabels == 0)
{ $Object->drawLine($CenterX,$CenterY,$EdgeX,$EdgeY,$Color); }
else
{ $Object->drawLine($CenterX,$CenterY,$EdgeX,$EdgeY,$ColorDotted); }
if ( $WriteLabels )
{
$LabelX = cos(deg2rad($i+$AxisRotation+$Axisoffset)) * ($EdgeHeight+$LabelPadding+$TicksLength) + $CenterX;
$LabelY = sin(deg2rad($i+$AxisRotation+$Axisoffset)) * ($EdgeHeight+$LabelPadding+$TicksLength) + $CenterY;
if ( $LabelSerie != "" )
{ $Label = isset($Data["Series"][$LabelSerie]["Data"][$ID]) ? $Data["Series"][$LabelSerie]["Data"][$ID] : ""; }
else
$Label = $ID;
if ($ID % $SkipLabels == 0)
{
if ( $LabelPos == RADAR_LABELS_ROTATED )
$Object->drawText($LabelX,$LabelY,$Label,array("Angle"=>(360-($i+$AxisRotation+$Axisoffset))-90,"Align"=>TEXT_ALIGN_BOTTOMMIDDLE));
else
{
if ( (floor($LabelX) == floor($CenterX)) && (floor($LabelY) < floor($CenterY)) ) { $Object->drawText($LabelX,$LabelY,$Label,array("Align"=>TEXT_ALIGN_BOTTOMMIDDLE)); }
if ( (floor($LabelX) > floor($CenterX)) && (floor($LabelY) < floor($CenterY)) ) { $Object->drawText($LabelX,$LabelY,$Label,array("Align"=>TEXT_ALIGN_BOTTOMLEFT)); }
if ( (floor($LabelX) > floor($CenterX)) && (floor($LabelY) == floor($CenterY)) ) { $Object->drawText($LabelX,$LabelY,$Label,array("Align"=>TEXT_ALIGN_MIDDLELEFT)); }
if ( (floor($LabelX) > floor($CenterX)) && (floor($LabelY) > floor($CenterY)) ) { $Object->drawText($LabelX,$LabelY,$Label,array("Align"=>TEXT_ALIGN_TOPLEFT)); }
if ( (floor($LabelX) < floor($CenterX)) && (floor($LabelY) < floor($CenterY)) ) { $Object->drawText($LabelX,$LabelY,$Label,array("Align"=>TEXT_ALIGN_BOTTOMRIGHT)); }
if ( (floor($LabelX) < floor($CenterX)) && (floor($LabelY) == floor($CenterY)) ) { $Object->drawText($LabelX,$LabelY,$Label,array("Align"=>TEXT_ALIGN_MIDDLERIGHT)); }
if ( (floor($LabelX) < floor($CenterX)) && (floor($LabelY) > floor($CenterY)) ) { $Object->drawText($LabelX,$LabelY,$Label,array("Align"=>TEXT_ALIGN_TOPRIGHT)); }
if ( (floor($LabelX) == floor($CenterX)) && (floor($LabelY) > floor($CenterY)) ) { $Object->drawText($LabelX,$LabelY,$Label,array("Align"=>TEXT_ALIGN_TOPMIDDLE)); }
}
}
}
$ID++;
}
/* Compute the plots position */
$ID = 0; $Plot = "";
foreach($Data["Series"] as $SerieName => $DataS)
{
if ( $SerieName != $LabelSerie )
{
$Color = array("R"=>$Palette[$ID]["R"],"G"=>$Palette[$ID]["G"],"B"=>$Palette[$ID]["B"],"Alpha"=>$Palette[$ID]["Alpha"],"Surrounding"=>$PointSurrounding);
foreach($DataS["Data"] as $Key => $Value)
{
$Angle = (360/$Points) * $Key;
$Length = ($EdgeHeight/($Segments*$SegmentHeight))*$Value;
$X = cos(deg2rad($Angle+$AxisRotation)) * $Length + $CenterX;
$Y = sin(deg2rad($Angle+$AxisRotation)) * $Length + $CenterY;
$Plot[$ID][] = array($X,$Y,$Value);
if ( $RecordImageMap ) { $this->pChartObject->addToImageMap("CIRCLE",floor($X).",".floor($Y).",".floor($PointRadius),$this->pChartObject->toHTMLColor($Palette[$ID]["R"],$Palette[$ID]["G"],$Palette[$ID]["B"]),$DataS["Description"],$Data["Series"][$LabelSerie]["Data"][$Key]." = ".$Value); }
}
$ID++;
}
}
/* Draw all that stuff! */
foreach($Plot as $ID => $Points)
{
$Color = array("R"=>$Palette[$ID]["R"],"G"=>$Palette[$ID]["G"],"B"=>$Palette[$ID]["B"],"Alpha"=>$Palette[$ID]["Alpha"],"Surrounding"=>$PointSurrounding);
/* Draw the polygons */
if ( $DrawPoly )
{
if ($PolyAlpha != NULL)
$Color = array("R"=>$Palette[$ID]["R"],"G"=>$Palette[$ID]["G"],"B"=>$Palette[$ID]["B"],"Alpha"=>$PolyAlpha,"Surrounding"=>$PointSurrounding);
$PointsArray = "";
for($i=0; $i<count($Points);$i++)
{ $PointsArray[] = $Points[$i][0]; $PointsArray[] = $Points[$i][1]; }
$Object->drawPolygon($PointsArray,$Color);
}
$Color = array("R"=>$Palette[$ID]["R"],"G"=>$Palette[$ID]["G"],"B"=>$Palette[$ID]["B"],"Alpha"=>$Palette[$ID]["Alpha"],"Surrounding"=>$PointSurrounding);
/* Bubble and labels settings */
$TextSettings = array("Align"=>TEXT_ALIGN_MIDDLEMIDDLE,"FontName"=>$ValueFontName,"FontSize"=>$ValueFontSize,"R"=>$Palette[$ID]["R"],"G"=>$Palette[$ID]["G"],"B"=>$Palette[$ID]["B"]);
$InnerColor = array("R"=>$InnerBubbleR,"G"=>$InnerBubbleG,"B"=>$InnerBubbleB,"Alpha"=>$InnerBubbleAlpha);
if ( $OuterBubbleR != VOID )
$OuterColor = array("R"=>$OuterBubbleR,"G"=>$OuterBubbleG,"B"=>$OuterBubbleB,"Alpha"=>$OuterBubbleAlpha);
else
$OuterColor = array("R"=>$Palette[$ID]["R"]+20,"G"=>$Palette[$ID]["G"]+20,"B"=>$Palette[$ID]["B"]+20,"Alpha"=>$Palette[$ID]["Alpha"]);
/* Loop to the starting points if asked */
if ( $LineLoopStart && $DrawLines )
$Object->drawLine($Points[count($Points)-1][0],$Points[count($Points)-1][1],$Points[0][0],$Points[0][1],$Color);
/* Draw the lines & points */
for($i=0; $i<count($Points);$i++)
{
if ( $DrawLines && $i < count($Points)-1)
$Object->drawLine($Points[$i][0],$Points[$i][1],$Points[$i+1][0],$Points[$i+1][1],$Color);
if ( $DrawPoints )
$Object->drawFilledCircle($Points[$i][0],$Points[$i][1],$PointRadius,$Color);
if ( $WriteValuesInBubble && $WriteValues )
{
$TxtPos = $this->pChartObject->getTextBox($Points[$i][0],$Points[$i][1],$ValueFontName,$ValueFontSize,0,$Points[$i][2]);
$Radius = floor(($TxtPos[1]["X"] - $TxtPos[0]["X"] + $ValuePadding*2)/2);
$this->pChartObject->drawFilledCircle($Points[$i][0],$Points[$i][1],$Radius+$OuterBubbleRadius,$OuterColor);
$this->pChartObject->drawFilledCircle($Points[$i][0],$Points[$i][1],$Radius,$InnerColor);
}
if ( $WriteValues )
$this->pChartObject->drawText($Points[$i][0]-1,$Points[$i][1]-1,$Points[$i][2],$TextSettings);
}
}
}
/* Draw a radar chart */
function drawPolar($Object,$Values,$Format="")
{
$this->pChartObject = $Object;
$FixedMax = isset($Format["FixedMax"]) ? $Format["FixedMax"] : VOID;
$AxisR = isset($Format["AxisR"]) ? $Format["AxisR"] : 60;
$AxisG = isset($Format["AxisG"]) ? $Format["AxisG"] : 60;
$AxisB = isset($Format["AxisB"]) ? $Format["AxisB"] : 60;
$AxisAlpha = isset($Format["AxisAlpha"]) ? $Format["AxisAlpha"] : 50;
$AxisRotation = isset($Format["AxisRotation"]) ? $Format["AxisRotation"] : -90;
$DrawTicks = isset($Format["DrawTicks"]) ? $Format["DrawTicks"] : TRUE;
$TicksLength = isset($Format["TicksLength"]) ? $Format["TicksLength"] : 2;
$DrawAxisValues = isset($Format["DrawAxisValues"]) ? $Format["DrawAxisValues"] : TRUE;
$AxisBoxRounded = isset($Format["AxisBoxRounded"]) ? $Format["AxisBoxRounded"] : TRUE;
$AxisFontName = isset($Format["FontName"]) ? $Format["FontName"] : $this->pChartObject->FontName;
$AxisFontSize = isset($Format["FontSize"]) ? $Format["FontSize"] : $this->pChartObject->FontSize;
$WriteValues = isset($Format["WriteValues"]) ? $Format["WriteValues"] : FALSE;
$WriteValuesInBubble = isset($Format["WriteValuesInBubble"]) ? $Format["WriteValuesInBubble"] : TRUE;
$ValueFontName = isset($Format["ValueFontName"]) ? $Format["ValueFontName"] : $this->pChartObject->FontName;
$ValueFontSize = isset($Format["ValueFontSize"]) ? $Format["ValueFontSize"] : $this->pChartObject->FontSize;
$ValuePadding = isset($Format["ValuePadding"]) ? $Format["ValuePadding"] : 4;
$OuterBubbleRadius = isset($Format["OuterBubbleRadius"]) ? $Format["OuterBubbleRadius"] : 2;
$OuterBubbleR = isset($Format["OuterBubbleR"]) ? $Format["OuterBubbleR"] : VOID;
$OuterBubbleG = isset($Format["OuterBubbleG"]) ? $Format["OuterBubbleG"] : VOID;
$OuterBubbleB = isset($Format["OuterBubbleB"]) ? $Format["OuterBubbleB"] : VOID;
$OuterBubbleAlpha = isset($Format["OuterBubbleAlpha"]) ? $Format["OuterBubbleAlpha"] : 100;
$InnerBubbleR = isset($Format["InnerBubbleR"]) ? $Format["InnerBubbleR"] : 255;
$InnerBubbleG = isset($Format["InnerBubbleG"]) ? $Format["InnerBubbleG"] : 255;
$InnerBubbleB = isset($Format["InnerBubbleB"]) ? $Format["InnerBubbleB"] : 255;
$InnerBubbleAlpha = isset($Format["InnerBubbleAlpha"]) ? $Format["InnerBubbleAlpha"] : 100;
$DrawBackground = isset($Format["DrawBackground"]) ? $Format["DrawBackground"] : TRUE;
$BackgroundR = isset($Format["BackgroundR"]) ? $Format["BackgroundR"] : 255;
$BackgroundG = isset($Format["BackgroundG"]) ? $Format["BackgroundG"] : 255;
$BackgroundB = isset($Format["BackgroundB"]) ? $Format["BackgroundB"] : 255;
$BackgroundAlpha = isset($Format["BackgroundAlpha"]) ? $Format["BackgroundAlpha"] : 50;
$BackgroundGradient= isset($Format["BackgroundGradient"]) ? $Format["BackgroundGradient"] : NULL;
$AxisSteps = isset($Format["AxisSteps"]) ? $Format["AxisSteps"] : 20;
$SegmentHeight = isset($Format["SegmentHeight"]) ? $Format["SegmentHeight"] : SEGMENT_HEIGHT_AUTO;
$Segments = isset($Format["Segments"]) ? $Format["Segments"] : 4;
$WriteLabels = isset($Format["WriteLabels"]) ? $Format["WriteLabels"] : TRUE;
$LabelsBackground = isset($Format["LabelsBackground"]) ? $Format["LabelsBackground"] : TRUE;
$LabelsBGR = isset($Format["LabelsBGR"]) ? $Format["LabelsBGR"] : 255;
$LabelsBGG = isset($Format["LabelsBGR"]) ? $Format["LabelsBGG"] : 255;
$LabelsBGB = isset($Format["LabelsBGR"]) ? $Format["LabelsBGB"] : 255;
$LabelsBGAlpha = isset($Format["LabelsBGAlpha"]) ? $Format["LabelsBGAlpha"] : 50;
$LabelPos = isset($Format["LabelPos"]) ? $Format["LabelPos"] : RADAR_LABELS_ROTATED;
$LabelPadding = isset($Format["LabelPadding"]) ? $Format["LabelPadding"] : 4;
$DrawPoints = isset($Format["DrawPoints"]) ? $Format["DrawPoints"] : TRUE;
$PointRadius = isset($Format["PointRadius"]) ? $Format["PointRadius"] : 4;
$PointSurrounding = isset($Format["PointRadius"]) ? $Format["PointRadius"] : -30;
$DrawLines = isset($Format["DrawLines"]) ? $Format["DrawLines"] : TRUE;
$LineLoopStart = isset($Format["LineLoopStart"]) ? $Format["LineLoopStart"] : FALSE;
$DrawPoly = isset($Format["DrawPoly"]) ? $Format["DrawPoly"] : FALSE;
$PolyAlpha = isset($Format["PolyAlpha"]) ? $Format["PolyAlpha"] : NULL;
$FontSize = $Object->FontSize;
$X1 = $Object->GraphAreaX1;
$Y1 = $Object->GraphAreaY1;
$X2 = $Object->GraphAreaX2;
$Y2 = $Object->GraphAreaY2;
$RecordImageMap = isset($Format["RecordImageMap"]) ? $Format["RecordImageMap"] : FALSE;
if ( $AxisBoxRounded ) { $DrawAxisValues = TRUE; }
/* Cancel default tick length if ticks not enabled */
if ( $DrawTicks == FALSE ) { $TicksLength = 0; }
/* Data Processing */
$Data = $Values->getData();
$Palette = $Values->getPalette();
/* Catch the number of required axis */
$LabelSerie = $Data["Abscissa"];
if ( $LabelSerie != "" )
{ $Points = count($Data["Series"][$LabelSerie]["Data"]); }
else
{
$Points = 0;
foreach($Data["Series"] as $SerieName => $DataArray)
{ if ( count($DataArray["Data"]) > $Points ) { $Points = count($DataArray["Data"]); } }
}
/* Draw the axis */
$CenterX = ($X2-$X1)/2 + $X1;
$CenterY = ($Y2-$Y1)/2 + $Y1;
$EdgeHeight = min(($X2-$X1)/2,($Y2-$Y1)/2);
if ( $WriteLabels )
$EdgeHeight = $EdgeHeight - $FontSize - $LabelPadding - $TicksLength;
/* Determine the scale if set to automatic */
if ( $SegmentHeight == SEGMENT_HEIGHT_AUTO)
{
if ( $FixedMax != VOID )
$Max = $FixedMax;
else
{
$Max = 0;
foreach($Data["Series"] as $SerieName => $DataArray)
{
if ( $SerieName != $LabelSerie )
{
if ( max($DataArray["Data"]) > $Max ) { $Max = max($DataArray["Data"]); }
}
}
}
$MaxSegments = $EdgeHeight/20;
$Scale = $Object->computeScale(0,$Max,$MaxSegments,array(1,2,5));
$Segments = $Scale["Rows"];
$SegmentHeight = $Scale["RowHeight"];
}
/* Background processing */
if ( $DrawBackground )
{
$RestoreShadow = $Object->Shadow;
$Object->Shadow = FALSE;
if ($BackgroundGradient == NULL)
{
$Color = array("R"=>$BackgroundR,"G"=>$BackgroundG,"B"=>$BackgroundB,"Alpha"=>$BackgroundAlpha);
$Object->drawFilledCircle($CenterX,$CenterY,$EdgeHeight,$Color);
}
else
{
$GradientROffset = ($BackgroundGradient["EndR"] - $BackgroundGradient["StartR"]) / $Segments;
$GradientGOffset = ($BackgroundGradient["EndG"] - $BackgroundGradient["StartG"]) / $Segments;
$GradientBOffset = ($BackgroundGradient["EndB"] - $BackgroundGradient["StartB"]) / $Segments;
$GradientAlphaOffset = ($BackgroundGradient["EndAlpha"] - $BackgroundGradient["StartAlpha"]) / $Segments;
for($j=$Segments;$j>=1;$j--)
{
$Color = array("R"=>$BackgroundGradient["StartR"]+$GradientROffset*$j,"G"=>$BackgroundGradient["StartG"]+$GradientGOffset*$j,"B"=>$BackgroundGradient["StartB"]+$GradientBOffset*$j,"Alpha"=>$BackgroundGradient["StartAlpha"]+$GradientAlphaOffset*$j);
$Object->drawFilledCircle($CenterX,$CenterY,($EdgeHeight/$Segments)*$j,$Color);
}
}
$Object->Shadow = $RestoreShadow;
}
/* Axis to axis lines */
$Color = array("R"=>$AxisR,"G"=>$AxisG,"B"=>$AxisB,"Alpha"=>$AxisAlpha);
for($j=1;$j<=$Segments;$j++)
{
$Radius = ($EdgeHeight/$Segments)*$j;
$Object->drawCircle($CenterX,$CenterY,$Radius,$Radius,$Color);
}
if ( $DrawAxisValues )
{
if ( $LabelsBackground )
$Options = array("DrawBox"=>TRUE, "Align"=>TEXT_ALIGN_MIDDLEMIDDLE,"BoxR"=>$LabelsBGR,"BoxG"=>$LabelsBGG,"BoxB"=>$LabelsBGB,"BoxAlpha"=>$LabelsBGAlpha);
else
$Options = array("Align"=>TEXT_ALIGN_MIDDLEMIDDLE);
if ( $AxisBoxRounded ) { $Options["BoxRounded"] = TRUE; }
$Options["FontName"] = $AxisFontName;
$Options["FontSize"] = $AxisFontSize;
$Angle = 360 / ($Points*2);
for($j=1;$j<=$Segments;$j++)
{
$EdgeX1 = cos(deg2rad($Angle+$AxisRotation)) * ($EdgeHeight/$Segments)*$j + $CenterX;
$EdgeY1 = sin(deg2rad($Angle+$AxisRotation)) * ($EdgeHeight/$Segments)*$j + $CenterY;
$Label = $j*$SegmentHeight;
$Object->drawText($EdgeX1,$EdgeY1,$Label,$Options);
}
}
/* Axis lines */
$ID = 0;
for($i=0;$i<=359;$i=$i+$AxisSteps)
{
$EdgeX = cos(deg2rad($i+$AxisRotation)) * ($EdgeHeight+$TicksLength) + $CenterX;
$EdgeY = sin(deg2rad($i+$AxisRotation)) * ($EdgeHeight+$TicksLength) + $CenterY;
$Object->drawLine($CenterX,$CenterY,$EdgeX,$EdgeY,$Color);
if ( $WriteLabels )
{
$LabelX = cos(deg2rad($i+$AxisRotation)) * ($EdgeHeight+$LabelPadding+$TicksLength) + $CenterX;
$LabelY = sin(deg2rad($i+$AxisRotation)) * ($EdgeHeight+$LabelPadding+$TicksLength) + $CenterY;
$Label = $i."°";
if ( $LabelPos == RADAR_LABELS_ROTATED )
$Object->drawText($LabelX,$LabelY,$Label,array("Angle"=>(360-$i),"Align"=>TEXT_ALIGN_BOTTOMMIDDLE));
else
{
if ( (floor($LabelX) == floor($CenterX)) && (floor($LabelY) < floor($CenterY)) ) { $Object->drawText($LabelX,$LabelY,$Label,array("Align"=>TEXT_ALIGN_BOTTOMMIDDLE)); }
if ( (floor($LabelX) > floor($CenterX)) && (floor($LabelY) < floor($CenterY)) ) { $Object->drawText($LabelX,$LabelY,$Label,array("Align"=>TEXT_ALIGN_BOTTOMLEFT)); }
if ( (floor($LabelX) > floor($CenterX)) && (floor($LabelY) == floor($CenterY)) ) { $Object->drawText($LabelX,$LabelY,$Label,array("Align"=>TEXT_ALIGN_MIDDLELEFT)); }
if ( (floor($LabelX) > floor($CenterX)) && (floor($LabelY) > floor($CenterY)) ) { $Object->drawText($LabelX,$LabelY,$Label,array("Align"=>TEXT_ALIGN_TOPLEFT)); }
if ( (floor($LabelX) < floor($CenterX)) && (floor($LabelY) < floor($CenterY)) ) { $Object->drawText($LabelX,$LabelY,$Label,array("Align"=>TEXT_ALIGN_BOTTOMRIGHT)); }
if ( (floor($LabelX) < floor($CenterX)) && (floor($LabelY) == floor($CenterY)) ) { $Object->drawText($LabelX,$LabelY,$Label,array("Align"=>TEXT_ALIGN_MIDDLERIGHT)); }
if ( (floor($LabelX) < floor($CenterX)) && (floor($LabelY) > floor($CenterY)) ) { $Object->drawText($LabelX,$LabelY,$Label,array("Align"=>TEXT_ALIGN_TOPRIGHT)); }
if ( (floor($LabelX) == floor($CenterX)) && (floor($LabelY) > floor($CenterY)) ) { $Object->drawText($LabelX,$LabelY,$Label,array("Align"=>TEXT_ALIGN_TOPMIDDLE)); }
}
}
$ID++;
}
/* Compute the plots position */
$ID = 0; $Plot = "";
foreach($Data["Series"] as $SerieName => $DataSet)
{
if ( $SerieName != $LabelSerie )
{
$Color = array("R"=>$Palette[$ID]["R"],"G"=>$Palette[$ID]["G"],"B"=>$Palette[$ID]["B"],"Alpha"=>$Palette[$ID]["Alpha"],"Surrounding"=>$PointSurrounding);
foreach($DataSet["Data"] as $Key => $Value)
{
$Angle = $Data["Series"][$LabelSerie]["Data"][$Key];
$Length = ($EdgeHeight/($Segments*$SegmentHeight))*$Value;
$X = cos(deg2rad($Angle+$AxisRotation)) * $Length + $CenterX;
$Y = sin(deg2rad($Angle+$AxisRotation)) * $Length + $CenterY;
if ( $RecordImageMap ) { $this->pChartObject->addToImageMap("CIRCLE",floor($X).",".floor($Y).",".floor($PointRadius),$this->pChartObject->toHTMLColor($Palette[$ID]["R"],$Palette[$ID]["G"],$Palette[$ID]["B"]),$DataSet["Description"],$Data["Series"][$LabelSerie]["Data"][$Key]."&deg = ".$Value); }
$Plot[$ID][] = array($X,$Y,$Value);
}
$ID++;
}
}
/* Draw all that stuff! */
foreach($Plot as $ID => $Points)
{
$Color = array("R"=>$Palette[$ID]["R"],"G"=>$Palette[$ID]["G"],"B"=>$Palette[$ID]["B"],"Alpha"=>$Palette[$ID]["Alpha"],"Surrounding"=>$PointSurrounding);
/* Draw the polygons */
if ( $DrawPoly )
{
if ($PolyAlpha != NULL)
$Color = array("R"=>$Palette[$ID]["R"],"G"=>$Palette[$ID]["G"],"B"=>$Palette[$ID]["B"],"Alpha"=>$PolyAlpha,"Surrounding"=>$PointSurrounding);
$PointsArray = "";
for($i=0; $i<count($Points);$i++)
{ $PointsArray[] = $Points[$i][0]; $PointsArray[] = $Points[$i][1]; }
$Object->drawPolygon($PointsArray,$Color);
}
$Color = array("R"=>$Palette[$ID]["R"],"G"=>$Palette[$ID]["G"],"B"=>$Palette[$ID]["B"],"Alpha"=>$Palette[$ID]["Alpha"],"Surrounding"=>$PointSurrounding);
/* Bubble and labels settings */
$TextSettings = array("Align"=>TEXT_ALIGN_MIDDLEMIDDLE,"FontName"=>$ValueFontName,"FontSize"=>$ValueFontSize,"R"=>$Palette[$ID]["R"],"G"=>$Palette[$ID]["G"],"B"=>$Palette[$ID]["B"]);
$InnerColor = array("R"=>$InnerBubbleR,"G"=>$InnerBubbleG,"B"=>$InnerBubbleB,"Alpha"=>$InnerBubbleAlpha);
if ( $OuterBubbleR != VOID )
$OuterColor = array("R"=>$OuterBubbleR,"G"=>$OuterBubbleG,"B"=>$OuterBubbleB,"Alpha"=>$OuterBubbleAlpha);
else
$OuterColor = array("R"=>$Palette[$ID]["R"]+20,"G"=>$Palette[$ID]["G"]+20,"B"=>$Palette[$ID]["B"]+20,"Alpha"=>$Palette[$ID]["Alpha"]);
/* Loop to the starting points if asked */
if ( $LineLoopStart && $DrawLines )
$Object->drawLine($Points[count($Points)-1][0],$Points[count($Points)-1][1],$Points[0][0],$Points[0][1],$Color);
/* Draw the lines & points */
for($i=0; $i<count($Points);$i++)
{
if ( $DrawLines && $i < count($Points)-1)
$Object->drawLine($Points[$i][0],$Points[$i][1],$Points[$i+1][0],$Points[$i+1][1],$Color);
if ( $DrawPoints )
$Object->drawFilledCircle($Points[$i][0],$Points[$i][1],$PointRadius,$Color);
if ( $WriteValuesInBubble && $WriteValues )
{
$TxtPos = $this->pChartObject->getTextBox($Points[$i][0],$Points[$i][1],$ValueFontName,$ValueFontSize,0,$Points[$i][2]);
$Radius = floor(($TxtPos[1]["X"] - $TxtPos[0]["X"] + $ValuePadding*2)/2);
$this->pChartObject->drawFilledCircle($Points[$i][0],$Points[$i][1],$Radius+$OuterBubbleRadius,$OuterColor);
$this->pChartObject->drawFilledCircle($Points[$i][0],$Points[$i][1],$Radius,$InnerColor);
}
if ( $WriteValues )
$this->pChartObject->drawText($Points[$i][0]-1,$Points[$i][1]-1,$Points[$i][2],$TextSettings);
}
}
}
}
?>

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,131 @@
<?php
/*
pSplit - class to draw spline splitted charts
Version : 2.1.4
Made by : Jean-Damien POGOLOTTI
Last Update : 19/01/2014
This file can be distributed under the license you can find at :
http://www.pchart.net/license
You can find the whole class documentation on the pChart web site.
*/
define("TEXT_POS_TOP" , 690001);
define("TEXT_POS_RIGHT" , 690002);
/* pSplit class definition */
class pSplit
{
var $pChartObject;
/* Class creator */
function pSplit()
{ }
/* Create the encoded string */
function drawSplitPath($Object,$Values,$Format="")
{
$this->pChartObject = $Object;
$Spacing = isset($Format["Spacing"]) ? $Format["Spacing"] : 20;
$TextPadding = isset($Format["TextPadding"]) ? $Format["TextPadding"] : 2;
$TextPos = isset($Format["TextPos"]) ? $Format["TextPos"] : TEXT_POS_TOP;
$Surrounding = isset($Format["Surrounding"]) ? $Format["Surrounding"] : NULL;
$Force = isset($Format["Force"]) ? $Format["Force"] : 70;
$Segments = isset($Format["Segments"]) ? $Format["Segments"] : 15;
$FontSize = $Object->FontSize;
$X1 = $Object->GraphAreaX1;
$Y1 = $Object->GraphAreaY1;
$X2 = $Object->GraphAreaX2;
$Y2 = $Object->GraphAreaY2;
/* Data Processing */
$Data = $Values->getData();
$Palette = $Values->getPalette();
$LabelSerie = $Data["Abscissa"];
$DataSerie = "";
foreach($Data["Series"] as $SerieName => $Value)
{ if ( $SerieName != $LabelSerie && $DataSerie == "" ) { $DataSerie = $SerieName; } }
$DataSerieSum = array_sum($Data["Series"][$DataSerie]["Data"]);
$DataSerieCount = count($Data["Series"][$DataSerie]["Data"]);
/* Scale Processing */
if ( $TextPos == TEXT_POS_RIGHT )
$YScale = (($Y2-$Y1) - (($DataSerieCount+1)*$Spacing)) / $DataSerieSum;
else
$YScale = (($Y2-$Y1) - ($DataSerieCount*$Spacing)) / $DataSerieSum;
$LeftHeight = $DataSerieSum * $YScale;
/* Re-compute graph width depending of the text mode choosen */
if ( $TextPos == TEXT_POS_RIGHT )
{
$MaxWidth = 0;
foreach($Data["Series"][$LabelSerie]["Data"] as $Key => $Label)
{
$Boundardies = $Object->getTextBox(0,0,$Object->FontName,$Object->FontSize,0,$Label);
if ( $Boundardies[1]["X"] > $MaxWidth ) { $MaxWidth = $Boundardies[1]["X"] + $TextPadding*2; }
}
$X2 = $X2 - $MaxWidth;
}
/* Drawing */
$LeftY = ((($Y2-$Y1) / 2) + $Y1) - ($LeftHeight/2);
$RightY = $Y1;
$VectorX = (($X2-$X1) / 2);
foreach($Data["Series"][$DataSerie]["Data"] as $Key => $Value)
{
if ( isset($Data["Series"][$LabelSerie]["Data"][$Key]) )
$Label = $Data["Series"][$LabelSerie]["Data"][$Key];
else
$Label = "-";
$LeftY1 = $LeftY;
$LeftY2 = $LeftY + $Value * $YScale;
$RightY1 = $RightY + $Spacing;
$RightY2 = $RightY + $Spacing + $Value * $YScale;;
$Settings = array("R"=>$Palette[$Key]["R"],"G"=>$Palette[$Key]["G"],"B"=>$Palette[$Key]["B"],"Alpha"=>$Palette[$Key]["Alpha"],"NoDraw"=>TRUE,"Segments"=>$Segments,"Surrounding"=>$Surrounding);
$PolyGon = "";
$Angle = $Object->getAngle($X2,$RightY1,$X1,$LeftY1);
$VectorX1 = cos(deg2rad($Angle+90)) * $Force + ($X2-$X1)/2 + $X1;
$VectorY1 = sin(deg2rad($Angle+90)) * $Force + ($RightY1-$LeftY1)/2 + $LeftY1;
$VectorX2 = cos(deg2rad($Angle-90)) * $Force + ($X2-$X1)/2 + $X1;
$VectorY2 = sin(deg2rad($Angle-90)) * $Force + ($RightY1-$LeftY1)/2 + $LeftY1;
$Points = $Object->drawBezier($X1,$LeftY1,$X2,$RightY1,$VectorX1,$VectorY1,$VectorX2,$VectorY2,$Settings);
foreach($Points as $Key => $Pos) { $PolyGon[] = $Pos["X"]; $PolyGon[] = $Pos["Y"]; }
$Angle = $Object->getAngle($X2,$RightY2,$X1,$LeftY2);
$VectorX1 = cos(deg2rad($Angle+90)) * $Force + ($X2-$X1)/2 +$X1;
$VectorY1 = sin(deg2rad($Angle+90)) * $Force + ($RightY2-$LeftY2)/2 + $LeftY2;
$VectorX2 = cos(deg2rad($Angle-90)) * $Force + ($X2-$X1)/2 +$X1;
$VectorY2 = sin(deg2rad($Angle-90)) * $Force + ($RightY2-$LeftY2)/2 + $LeftY2;
$Points = $Object->drawBezier($X1,$LeftY2,$X2,$RightY2,$VectorX1,$VectorY1,$VectorX2,$VectorY2,$Settings);
$Points = array_reverse($Points);
foreach($Points as $Key => $Pos) { $PolyGon[] = $Pos["X"]; $PolyGon[] = $Pos["Y"]; }
$Object->drawPolygon($PolyGon,$Settings);
if ( $TextPos == TEXT_POS_RIGHT )
$Object->drawText($X2+$TextPadding,($RightY2-$RightY1)/2+$RightY1,$Label,array("Align"=>TEXT_ALIGN_MIDDLELEFT));
else
$Object->drawText($X2,$RightY1-$TextPadding,$Label,array("Align"=>TEXT_ALIGN_BOTTOMRIGHT));
$LeftY = $LeftY2;
$RightY = $RightY2;
}
}
}
?>

View File

@@ -0,0 +1,868 @@
<?php
/*
pSpring - class to draw spring graphs
Version : 2.1.4
Made by : Jean-Damien POGOLOTTI
Last Update : 19/01/2014
This file can be distributed under the license you can find at :
http://www.pchart.net/license
You can find the whole class documentation on the pChart web site.
*/
define("NODE_TYPE_FREE" , 690001);
define("NODE_TYPE_CENTRAL" , 690002);
define("NODE_SHAPE_CIRCLE" , 690011);
define("NODE_SHAPE_TRIANGLE" , 690012);
define("NODE_SHAPE_SQUARE" , 690013);
define("ALGORITHM_RANDOM" , 690021);
define("ALGORITHM_WEIGHTED" , 690022);
define("ALGORITHM_CIRCULAR" , 690023);
define("ALGORITHM_CENTRAL" , 690024);
define("LABEL_CLASSIC" , 690031);
define("LABEL_LIGHT" , 690032);
/* pSpring class definition */
class pSpring
{
var $History;
var $pChartObject;
var $Data;
var $Links;
var $X1;
var $Y1;
var $X2;
var $Y2;
var $AutoComputeFreeZone;
var $Labels;
/* Class creator */
function pSpring()
{
/* Initialise data arrays */
$this->Data = "";
$this->Links = "";
/* Set nodes defaults */
$this->Default["R"] = 255;
$this->Default["G"] = 255;
$this->Default["B"] = 255;
$this->Default["Alpha"] = 100;
$this->Default["BorderR"] = 0;
$this->Default["BorderG"] = 0;
$this->Default["BorderB"] = 0;
$this->Default["BorderAlpha"] = 100;
$this->Default["Surrounding"] = NULL;
$this->Default["BackgroundR"] = 255;
$this->Default["BackgroundG"] = 255;
$this->Default["BackgroundB"] = 255;
$this->Default["BackgroundAlpha"] = 0;
$this->Default["Force"] = 1;
$this->Default["NodeType"] = NODE_TYPE_FREE;
$this->Default["Size"] = 5;
$this->Default["Shape"] = NODE_SHAPE_CIRCLE;
$this->Default["FreeZone"] = 40;
$this->Default["LinkR"] = 0;
$this->Default["LinkG"] = 0;
$this->Default["LinkB"] = 0;
$this->Default["LinkAlpha"] = 0;
$this->Labels["Type"] = LABEL_CLASSIC;
$this->Labels["R"] = 0;
$this->Labels["G"] = 0;
$this->Labels["B"] = 0;
$this->Labels["Alpha"] = 100;
$this->AutoComputeFreeZone = FALSE;
}
/* Set default links options */
function setLinkDefaults($Settings="")
{
if ( isset($Settings["R"]) ) { $this->Default["LinkR"] = $Settings["R"]; }
if ( isset($Settings["G"]) ) { $this->Default["LinkG"] = $Settings["G"]; }
if ( isset($Settings["B"]) ) { $this->Default["LinkB"] = $Settings["B"]; }
if ( isset($Settings["Alpha"]) ) { $this->Default["LinkAlpha"] = $Settings["Alpha"]; }
}
/* Set default links options */
function setLabelsSettings($Settings="")
{
if ( isset($Settings["Type"]) ) { $this->Labels["Type"] = $Settings["Type"]; }
if ( isset($Settings["R"]) ) { $this->Labels["R"] = $Settings["R"]; }
if ( isset($Settings["G"]) ) { $this->Labels["G"] = $Settings["G"]; }
if ( isset($Settings["B"]) ) { $this->Labels["B"] = $Settings["B"]; }
if ( isset($Settings["Alpha"]) ) { $this->Labels["Alpha"] = $Settings["Alpha"]; }
}
/* Auto compute the FreeZone size based on the number of connections */
function autoFreeZone()
{
/* Check connections reciprocity */
foreach($this->Data as $Key => $Settings)
{
if ( isset($Settings["Connections"]) )
{ $this->Data[$Key]["FreeZone"] = count($Settings["Connections"])*10 + 20; }
else
{ $this->Data[$Key]["FreeZone"] = 20; }
}
}
/* Set link properties */
function linkProperties($FromNode,$ToNode,$Settings)
{
if ( !isset($this->Data[$FromNode]) ) { return(0); }
if ( !isset($this->Data[$ToNode]) ) { return(0); }
$R = isset($Settings["R"]) ? $Settings["R"] : 0;
$G = isset($Settings["G"]) ? $Settings["G"] : 0;
$B = isset($Settings["B"]) ? $Settings["B"] : 0;
$Alpha = isset($Settings["Alpha"]) ? $Settings["Alpha"] : 100;
$Name = isset($Settings["Name"]) ? $Settings["Name"] : NULL;
$Ticks = isset($Settings["Ticks"]) ? $Settings["Ticks"] : NULL;
$this->Links[$FromNode][$ToNode]["R"] = $R; $this->Links[$ToNode][$FromNode]["R"] = $R;
$this->Links[$FromNode][$ToNode]["G"] = $G; $this->Links[$ToNode][$FromNode]["G"] = $G;
$this->Links[$FromNode][$ToNode]["B"] = $B; $this->Links[$ToNode][$FromNode]["B"] = $B;
$this->Links[$FromNode][$ToNode]["Alpha"] = $Alpha; $this->Links[$ToNode][$FromNode]["Alpha"] = $Alpha;
$this->Links[$FromNode][$ToNode]["Name"] = $Name; $this->Links[$ToNode][$FromNode]["Name"] = $Name;
$this->Links[$FromNode][$ToNode]["Ticks"] = $Ticks; $this->Links[$ToNode][$FromNode]["Ticks"] = $Ticks;
}
function setNodeDefaults($Settings="")
{
if ( isset($Settings["R"]) ) { $this->Default["R"] = $Settings["R"]; }
if ( isset($Settings["G"]) ) { $this->Default["G"] = $Settings["G"]; }
if ( isset($Settings["B"]) ) { $this->Default["B"] = $Settings["B"]; }
if ( isset($Settings["Alpha"]) ) { $this->Default["Alpha"] = $Settings["Alpha"]; }
if ( isset($Settings["BorderR"]) ) { $this->Default["BorderR"] = $Settings["BorderR"]; }
if ( isset($Settings["BorderG"]) ) { $this->Default["BorderG"] = $Settings["BorderG"]; }
if ( isset($Settings["BorderB"]) ) { $this->Default["BorderB"] = $Settings["BorderB"]; }
if ( isset($Settings["BorderAlpha"]) ) { $this->Default["BorderAlpha"] = $Settings["BorderAlpha"]; }
if ( isset($Settings["Surrounding"]) ) { $this->Default["Surrounding"] = $Settings["Surrounding"]; }
if ( isset($Settings["BackgroundR"]) ) { $this->Default["BackgroundR"] = $Settings["BackgroundR"]; }
if ( isset($Settings["BackgroundG"]) ) { $this->Default["BackgroundG"] = $Settings["BackgroundG"]; }
if ( isset($Settings["BackgroundB"]) ) { $this->Default["BackgroundB"] = $Settings["BackgroundB"]; }
if ( isset($Settings["BackgroundAlpha"]) ) { $this->Default["BackgroundAlpha"] = $Settings["BackgroundAlpha"]; }
if ( isset($Settings["NodeType"]) ) { $this->Default["NodeType"] = $Settings["NodeType"]; }
if ( isset($Settings["Size"]) ) { $this->Default["Size"] = $Settings["Size"]; }
if ( isset($Settings["Shape"]) ) { $this->Default["Shape"] = $Settings["Shape"]; }
if ( isset($Settings["FreeZone"]) ) { $this->Default["FreeZone"] = $Settings["FreeZone"]; }
}
/* Add a node */
function addNode($NodeID,$Settings="")
{
/* if the node already exists, ignore */
if (isset($this->Data[$NodeID])) { return(0); }
$Name = isset($Settings["Name"]) ? $Settings["Name"] : "Node ".$NodeID;
$Connections = isset($Settings["Connections"]) ? $Settings["Connections"] : NULL;
$R = isset($Settings["R"]) ? $Settings["R"] : $this->Default["R"];
$G = isset($Settings["G"]) ? $Settings["G"] : $this->Default["G"];
$B = isset($Settings["B"]) ? $Settings["B"] : $this->Default["B"];
$Alpha = isset($Settings["Alpha"]) ? $Settings["Alpha"] : $this->Default["Alpha"];
$BorderR = isset($Settings["BorderR"]) ? $Settings["BorderR"] : $this->Default["BorderR"];
$BorderG = isset($Settings["BorderG"]) ? $Settings["BorderG"] : $this->Default["BorderG"];
$BorderB = isset($Settings["BorderB"]) ? $Settings["BorderB"] : $this->Default["BorderB"];
$BorderAlpha = isset($Settings["BorderAlpha"]) ? $Settings["BorderAlpha"] : $this->Default["BorderAlpha"];
$Surrounding = isset($Settings["Surrounding"]) ? $Settings["Surrounding"] : $this->Default["Surrounding"];
$BackgroundR = isset($Settings["BackgroundR"]) ? $Settings["BackgroundR"] : $this->Default["BackgroundR"];
$BackgroundG = isset($Settings["BackgroundG"]) ? $Settings["BackgroundG"] : $this->Default["BackgroundG"];
$BackgroundB = isset($Settings["BackgroundB"]) ? $Settings["BackgroundB"] : $this->Default["BackgroundB"];
$BackgroundAlpha = isset($Settings["BackgroundAlpha"]) ? $Settings["BackgroundAlpha"] : $this->Default["BackgroundAlpha"];
$Force = isset($Settings["Force"]) ? $Settings["Force"] : $this->Default["Force"];
$NodeType = isset($Settings["NodeType"]) ? $Settings["NodeType"] : $this->Default["NodeType"];
$Size = isset($Settings["Size"]) ? $Settings["Size"] : $this->Default["Size"];
$Shape = isset($Settings["Shape"]) ? $Settings["Shape"] : $this->Default["Shape"];
$FreeZone = isset($Settings["FreeZone"]) ? $Settings["FreeZone"] : $this->Default["FreeZone"];
if ( $Surrounding != NULL ) { $BorderR = $R + $Surrounding; $BorderG = $G + $Surrounding; $BorderB = $B + $Surrounding; }
$this->Data[$NodeID]["R"] = $R; $this->Data[$NodeID]["G"] = $G; $this->Data[$NodeID]["B"] = $B; $this->Data[$NodeID]["Alpha"] = $Alpha;
$this->Data[$NodeID]["BorderR"] = $BorderR; $this->Data[$NodeID]["BorderG"] = $BorderG; $this->Data[$NodeID]["BorderB"] = $BorderB; $this->Data[$NodeID]["BorderAlpha"] = $BorderAlpha;
$this->Data[$NodeID]["BackgroundR"] = $BackgroundR; $this->Data[$NodeID]["BackgroundG"] = $BackgroundG; $this->Data[$NodeID]["BackgroundB"] = $BackgroundB; $this->Data[$NodeID]["BackgroundAlpha"] = $BackgroundAlpha;
$this->Data[$NodeID]["Name"] = $Name;
$this->Data[$NodeID]["Force"] = $Force;
$this->Data[$NodeID]["Type"] = $NodeType;
$this->Data[$NodeID]["Size"] = $Size;
$this->Data[$NodeID]["Shape"] = $Shape;
$this->Data[$NodeID]["FreeZone"] = $FreeZone;
if ( $Connections != NULL )
{
if ( is_array($Connections ) )
{
foreach($Connections as $Key => $Value)
$this->Data[$NodeID]["Connections"][] = $Value;
}
else
$this->Data[$NodeID]["Connections"][] = $Connections;
}
}
/* Set color attribute for a list of nodes */
function setNodesColor($Nodes,$Settings="")
{
if ( is_array($Nodes) )
{
foreach ($Nodes as $Key => $NodeID)
{
if (isset($this->Data[$NodeID]) )
{
if ( isset($Settings["R"]) ) { $this->Data[$NodeID]["R"] = $Settings["R"]; }
if ( isset($Settings["G"]) ) { $this->Data[$NodeID]["G"] = $Settings["G"]; }
if ( isset($Settings["B"]) ) { $this->Data[$NodeID]["B"] = $Settings["B"]; }
if ( isset($Settings["Alpha"]) ) { $this->Data[$NodeID]["Alpha"] = $Settings["Alpha"]; }
if ( isset($Settings["BorderR"]) ) { $this->Data[$NodeID]["BorderR"] = $Settings["BorderR"]; }
if ( isset($Settings["BorderG"]) ) { $this->Data[$NodeID]["BorderG"] = $Settings["BorderG"]; }
if ( isset($Settings["BorderB"]) ) { $this->Data[$NodeID]["BorderB"] = $Settings["BorderB"]; }
if ( isset($Settings["BorderAlpha"]) ) { $this->Data[$NodeID]["BorderAlpha"] = $Settings["BorderAlpha"]; }
if ( isset($Settings["Surrounding"]) ) { $this->Data[$NodeID]["BorderR"] = $this->Data[$NodeID]["R"] + $Settings["Surrounding"]; $this->Data[$NodeID]["BorderG"] = $this->Data[$NodeID]["G"] + $Settings["Surrounding"]; $this->Data[$NodeID]["BorderB"] = $this->Data[$NodeID]["B"] + $Settings["Surrounding"]; }
}
}
}
else
{
if ( isset($Settings["R"]) ) { $this->Data[$Nodes]["R"] = $Settings["R"]; }
if ( isset($Settings["G"]) ) { $this->Data[$Nodes]["G"] = $Settings["G"]; }
if ( isset($Settings["B"]) ) { $this->Data[$Nodes]["B"] = $Settings["B"]; }
if ( isset($Settings["Alpha"]) ) { $this->Data[$Nodes]["Alpha"] = $Settings["Alpha"]; }
if ( isset($Settings["BorderR"]) ) { $this->Data[$Nodes]["BorderR"] = $Settings["BorderR"]; }
if ( isset($Settings["BorderG"]) ) { $this->Data[$Nodes]["BorderG"] = $Settings["BorderG"]; }
if ( isset($Settings["BorderB"]) ) { $this->Data[$Nodes]["BorderB"] = $Settings["BorderB"]; }
if ( isset($Settings["BorderAlpha"]) ) { $this->Data[$Nodes]["BorderAlpha"] = $Settings["BorderAlpha"]; }
if ( isset($Settings["Surrounding"]) ) { $this->Data[$Nodes]["BorderR"] = $this->Data[$NodeID]["R"] + $Settings["Surrounding"]; $this->Data[$NodeID]["BorderG"] = $this->Data[$NodeID]["G"] + $Settings["Surrounding"]; $this->Data[$NodeID]["BorderB"] = $this->Data[$NodeID]["B"] + $Settings["Surrounding"]; }
}
}
/* Returns all the nodes details */
function dumpNodes()
{ return($this->Data); }
/* Check if a connection exists and create it if required */
function checkConnection($SourceID, $TargetID)
{
if ( isset($this->Data[$SourceID]["Connections"]) )
{
foreach ($this->Data[$SourceID]["Connections"] as $Key => $ConnectionID)
{ if ( $TargetID == $ConnectionID ) { return(TRUE); } }
}
$this->Data[$SourceID]["Connections"][] = $TargetID;
}
/* Get the median linked nodes position */
function getMedianOffset($Key,$X,$Y)
{
$Cpt = 1;
if ( isset($this->Data[$Key]["Connections"]) )
{
foreach($this->Data[$Key]["Connections"] as $ID => $NodeID)
{
if ( isset($this->Data[$NodeID]["X"]) && isset($this->Data[$NodeID]["Y"]) )
{
$X = $X + $this->Data[$NodeID]["X"];
$Y = $Y + $this->Data[$NodeID]["Y"];
$Cpt++;
}
}
}
return(array("X"=>$X/$Cpt,"Y"=>$Y/$Cpt));
}
/* Return the ID of the attached partner with the biggest weight */
function getBiggestPartner($Key)
{
if ( !isset($this->Data[$Key]["Connections"]) ) { return(""); }
$MaxWeight = 0; $Result = "";
foreach($this->Data[$Key]["Connections"] as $Key => $PeerID)
{
if ( $this->Data[$PeerID]["Weight"] > $MaxWeight )
{ $MaxWeight = $this->Data[$PeerID]["Weight"]; $Result = $PeerID; }
}
return($Result);
}
/* Do the initial node positions computing pass */
function firstPass($Algorithm)
{
$CenterX = ($this->X2 - $this->X1) / 2 + $this->X1;
$CenterY = ($this->Y2 - $this->Y1) / 2 + $this->Y1;
/* Check connections reciprocity */
foreach($this->Data as $Key => $Settings)
{
if ( isset($Settings["Connections"]) )
{
foreach($Settings["Connections"] as $ID => $ConnectionID)
$this->checkConnection($ConnectionID,$Key);
}
}
if ( $this->AutoComputeFreeZone ) { $this->autoFreeZone(); }
/* Get the max number of connections */
$MaxConnections = 0;
foreach($this->Data as $Key => $Settings)
{ if ( isset($Settings["Connections"]) ) { if ( $MaxConnections < count($Settings["Connections"] ) ) { $MaxConnections = count($Settings["Connections"]); } } }
if ( $Algorithm == ALGORITHM_WEIGHTED )
{
foreach($this->Data as $Key => $Settings)
{
if ( $Settings["Type"] == NODE_TYPE_CENTRAL ) { $this->Data[$Key]["X"] = $CenterX; $this->Data[$Key]["Y"] = $CenterY; }
if ( $Settings["Type"] == NODE_TYPE_FREE )
{
if ( isset($Settings["Connections"]) )
{ $Connections = count($Settings["Connections"]); }
else
{ $Connections = 0; }
$Ring = $MaxConnections - $Connections;
$Angle = rand(0,360);
$this->Data[$Key]["X"] = cos(deg2rad($Angle)) * ($Ring*$this->RingSize) + $CenterX;
$this->Data[$Key]["Y"] = sin(deg2rad($Angle)) * ($Ring*$this->RingSize) + $CenterY;
}
}
}
elseif ( $Algorithm == ALGORITHM_CENTRAL )
{
/* Put a weight on each nodes */
foreach($this->Data as $Key => $Settings)
{
if ( isset($Settings["Connections"]) )
$this->Data[$Key]["Weight"] = count($Settings["Connections"]);
else
$this->Data[$Key]["Weight"] = 0;
}
$MaxConnections = $MaxConnections + 1;
for($i=$MaxConnections;$i>=0;$i--)
{
foreach($this->Data as $Key => $Settings)
{
if ( $Settings["Type"] == NODE_TYPE_CENTRAL ) { $this->Data[$Key]["X"] = $CenterX; $this->Data[$Key]["Y"] = $CenterY; }
if ( $Settings["Type"] == NODE_TYPE_FREE )
{
if ( isset($Settings["Connections"]) )
{ $Connections = count($Settings["Connections"]); }
else
{ $Connections = 0; }
if ( $Connections == $i )
{
$BiggestPartner = $this->getBiggestPartner($Key);
if ( $BiggestPartner != "" )
{
$Ring = $this->Data[$BiggestPartner]["FreeZone"];
$Weight = $this->Data[$BiggestPartner]["Weight"];
$AngleDivision = 360 / $this->Data[$BiggestPartner]["Weight"];
$Done = FALSE; $Tries = 0;
while (!$Done && $Tries <= $Weight*2)
{
$Tries++;
$Angle = floor(rand(0,$Weight)*$AngleDivision);
if ( !isset($this->Data[$BiggestPartner]["Angular"][$Angle]) || !isset($this->Data[$BiggestPartner]["Angular"]) )
{
$this->Data[$BiggestPartner]["Angular"][$Angle] = $Angle;
$Done = TRUE;
}
}
if ( !$Done )
{ $Angle = rand(0,360); $this->Data[$BiggestPartner]["Angular"][$Angle] = $Angle; }
$X = cos(deg2rad($Angle)) * ($Ring) + $this->Data[$BiggestPartner]["X"];
$Y = sin(deg2rad($Angle)) * ($Ring) + $this->Data[$BiggestPartner]["Y"];
$this->Data[$Key]["X"] = $X;
$this->Data[$Key]["Y"] = $Y;
}
}
}
}
}
}
elseif ( $Algorithm == ALGORITHM_CIRCULAR )
{
$MaxConnections = $MaxConnections + 1;
for($i=$MaxConnections;$i>=0;$i--)
{
foreach($this->Data as $Key => $Settings)
{
if ( $Settings["Type"] == NODE_TYPE_CENTRAL ) { $this->Data[$Key]["X"] = $CenterX; $this->Data[$Key]["Y"] = $CenterY; }
if ( $Settings["Type"] == NODE_TYPE_FREE )
{
if ( isset($Settings["Connections"]) )
{ $Connections = count($Settings["Connections"]); }
else
{ $Connections = 0; }
if ( $Connections == $i )
{
$Ring = $MaxConnections - $Connections;
$Angle = rand(0,360);
$X = cos(deg2rad($Angle)) * ($Ring*$this->RingSize) + $CenterX;
$Y = sin(deg2rad($Angle)) * ($Ring*$this->RingSize) + $CenterY;
$MedianOffset = $this->getMedianOffset($Key,$X,$Y);
$this->Data[$Key]["X"] = $MedianOffset["X"];
$this->Data[$Key]["Y"] = $MedianOffset["Y"];
}
}
}
}
}
elseif ( $Algorithm == ALGORITHM_RANDOM )
{
foreach($this->Data as $Key => $Settings)
{
if ( $Settings["Type"] == NODE_TYPE_FREE )
{
$this->Data[$Key]["X"] = $CenterX + rand(-20,20);
$this->Data[$Key]["Y"] = $CenterY + rand(-20,20);
}
if ( $Settings["Type"] == NODE_TYPE_CENTRAL ) { $this->Data[$Key]["X"] = $CenterX; $this->Data[$Key]["Y"] = $CenterY; }
}
}
}
/* Compute one pass */
function doPass()
{
/* Compute vectors */
foreach($this->Data as $Key => $Settings)
{
if ( $Settings["Type"] != NODE_TYPE_CENTRAL )
{
unset($this->Data[$Key]["Vectors"]);
$X1 = $Settings["X"];
$Y1 = $Settings["Y"];
/* Repulsion vectors */
foreach($this->Data as $Key2 => $Settings2)
{
if ( $Key != $Key2 )
{
$X2 = $this->Data[$Key2]["X"];
$Y2 = $this->Data[$Key2]["Y"];
$FreeZone = $this->Data[$Key2]["FreeZone"];
$Distance = $this->getDistance($X1,$Y1,$X2,$Y2);
$Angle = $this->getAngle($X1,$Y1,$X2,$Y2) + 180;
/* Nodes too close, repulsion occurs */
if ( $Distance < $FreeZone )
{
$Force = log(pow(2,$FreeZone-$Distance));
if ( $Force > 1 )
{ $this->Data[$Key]["Vectors"][] = array("Type"=>"R","Angle"=>$Angle % 360,"Force"=>$Force); }
}
}
}
/* Attraction vectors */
if ( isset($Settings["Connections"]) )
{
foreach($Settings["Connections"] as $ID => $NodeID)
{
if ( isset($this->Data[$NodeID]) )
{
$X2 = $this->Data[$NodeID]["X"];
$Y2 = $this->Data[$NodeID]["Y"];
$FreeZone = $this->Data[$Key2]["FreeZone"];
$Distance = $this->getDistance($X1,$Y1,$X2,$Y2);
$Angle = $this->getAngle($X1,$Y1,$X2,$Y2);
if ( $Distance > $FreeZone )
$Force = log(($Distance-$FreeZone)+1);
else
{ $Force = log(($FreeZone-$Distance)+1); ($Angle = $Angle + 180); }
if ( $Force > 1 )
$this->Data[$Key]["Vectors"][] = array("Type"=>"A","Angle"=>$Angle % 360,"Force"=>$Force);
}
}
}
}
}
/* Move the nodes accoding to the vectors */
foreach($this->Data as $Key => $Settings)
{
$X = $Settings["X"];
$Y = $Settings["Y"];
if ( isset($Settings["Vectors"]) && $Settings["Type"] != NODE_TYPE_CENTRAL )
{
foreach($Settings["Vectors"] as $ID => $Vector)
{
$Type = $Vector["Type"];
$Force = $Vector["Force"];
$Angle = $Vector["Angle"];
$Factor = $Type == "A" ? $this->MagneticForceA : $this->MagneticForceR;
$X = cos(deg2rad($Angle)) * $Force * $Factor + $X;
$Y = sin(deg2rad($Angle)) * $Force * $Factor + $Y;
}
}
$this->Data[$Key]["X"] = $X;
$this->Data[$Key]["Y"] = $Y;
}
}
function lastPass()
{
/* Put everything inside the graph area */
foreach($this->Data as $Key => $Settings)
{
$X = $Settings["X"];
$Y = $Settings["Y"];
if ( $X < $this->X1 ) { $X = $this->X1; }
if ( $X > $this->X2 ) { $X = $this->X2; }
if ( $Y < $this->Y1 ) { $Y = $this->Y1; }
if ( $Y > $this->Y2 ) { $Y = $this->Y2; }
$this->Data[$Key]["X"] = $X;
$this->Data[$Key]["Y"] = $Y;
}
/* Dump all links */
$Links = "";
foreach($this->Data as $Key => $Settings)
{
$X1 = $Settings["X"];
$Y1 = $Settings["Y"];
if ( isset($Settings["Connections"]) )
{
foreach ($Settings["Connections"] as $ID => $NodeID)
{
if ( isset($this->Data[$NodeID]) )
{
$X2 = $this->Data[$NodeID]["X"];
$Y2 = $this->Data[$NodeID]["Y"];
$Links[] = array("X1"=>$X1,"Y1"=>$Y1,"X2"=>$X2,"Y2"=>$Y2,"Source"=>$Settings["Name"],"Destination"=>$this->Data[$NodeID]["Name"]);
}
}
}
}
/* Check collisions */
$Conflicts = 0;
foreach($this->Data as $Key => $Settings)
{
$X1 = $Settings["X"];
$Y1 = $Settings["Y"];
if ( isset($Settings["Connections"]) )
{
foreach ($Settings["Connections"] as $ID => $NodeID)
{
if ( isset($this->Data[$NodeID]) )
{
$X2 = $this->Data[$NodeID]["X"];
$Y2 = $this->Data[$NodeID]["Y"];
foreach($Links as $IDLinks => $Link)
{
$X3 = $Link["X1"]; $Y3 = $Link["Y1"]; $X4 = $Link["X2"]; $Y4 = $Link["Y2"];
if ( !($X1 == $X3 && $X2 == $X4 && $Y1 == $Y3 && $Y2 == $Y4 ) )
{
if ( $this->intersect($X1,$Y1,$X2,$Y2,$X3,$Y3,$X4,$Y4) )
{
if ( $Link["Source"] != $Settings["Name"] && $Link["Source"] != $this->Data[$NodeID]["Name"] && $Link["Destination"] != $Settings["Name"] && $Link["Destination"] != $this->Data[$NodeID]["Name"] )
{ $Conflicts++; }
}
}
}
}
}
}
}
return($Conflicts/2);
}
/* Center the graph */
function center()
{
/* Determine the real center */
$TargetCenterX = ($this->X2 - $this->X1) / 2 + $this->X1;
$TargetCenterY = ($this->Y2 - $this->Y1) / 2 + $this->Y1;
/* Get current boundaries */
$XMin = $this->X2; $XMax = $this->X1;
$YMin = $this->Y2; $YMax = $this->Y1;
foreach($this->Data as $Key => $Settings)
{
$X = $Settings["X"];
$Y = $Settings["Y"];
if ( $X < $XMin) { $XMin = $X; }
if ( $X > $XMax) { $XMax = $X; }
if ( $Y < $YMin) { $YMin = $Y; }
if ( $Y > $YMax) { $YMax = $Y; }
}
$CurrentCenterX = ($XMax - $XMin) / 2 + $XMin;
$CurrentCenterY = ($YMax - $YMin) / 2 + $YMin;
/* Compute the offset to apply */
$XOffset = $TargetCenterX - $CurrentCenterX;
$YOffset = $TargetCenterY - $CurrentCenterY;
/* Correct the points position */
foreach($this->Data as $Key => $Settings)
{
$this->Data[$Key]["X"] = $Settings["X"] + $XOffset;
$this->Data[$Key]["Y"] = $Settings["Y"] + $YOffset;
}
}
/* Create the encoded string */
function drawSpring($Object,$Settings="")
{
$this->pChartObject = $Object;
$Pass = isset($Settings["Pass"]) ? $Settings["Pass"] : 50;
$Retries = isset($Settings["Retry"]) ? $Settings["Retry"] : 10;
$this->MagneticForceA = isset($Settings["MagneticForceA"]) ? $Settings["MagneticForceA"] : 1.5;
$this->MagneticForceR = isset($Settings["MagneticForceR"]) ? $Settings["MagneticForceR"] : 2;
$this->RingSize = isset($Settings["RingSize"]) ? $Settings["RingSize"] : 40;
$DrawVectors = isset($Settings["DrawVectors"]) ? $Settings["DrawVectors"] : FALSE;
$DrawQuietZone = isset($Settings["DrawQuietZone"]) ? $Settings["DrawQuietZone"] : FALSE;
$CenterGraph = isset($Settings["CenterGraph"]) ? $Settings["CenterGraph"] : TRUE;
$TextPadding = isset($Settings["TextPadding"]) ? $Settings["TextPadding"] : 4;
$Algorithm = isset($Settings["Algorithm"]) ? $Settings["Algorithm"] : ALGORITHM_WEIGHTED;
$FontSize = $Object->FontSize;
$this->X1 = $Object->GraphAreaX1;
$this->Y1 = $Object->GraphAreaY1;
$this->X2 = $Object->GraphAreaX2;
$this->Y2 = $Object->GraphAreaY2;
$Conflicts = 1; $Jobs = 0; $this->History["MinimumConflicts"] = -1;
while ($Conflicts != 0 && $Jobs < $Retries )
{
$Jobs++;
/* Compute the initial settings */
$this->firstPass($Algorithm);
/* Apply the vectors */
if ( $Pass > 0 )
{
for ($i=0; $i<=$Pass; $i++) { $this->doPass(); }
}
$Conflicts = $this->lastPass();
if ( $this->History["MinimumConflicts"] == -1 || $Conflicts < $this->History["MinimumConflicts"] )
{ $this->History["MinimumConflicts"] = $Conflicts; $this->History["Result"] = $this->Data; }
}
$Conflicts = $this->History["MinimumConflicts"];
$this->Data = $this->History["Result"];
if ( $CenterGraph ) { $this->center(); }
/* Draw the connections */
$Drawn = "";
foreach($this->Data as $Key => $Settings)
{
$X = $Settings["X"];
$Y = $Settings["Y"];
if ( isset($Settings["Connections"]) )
{
foreach ($Settings["Connections"] as $ID => $NodeID)
{
if ( !isset($Drawn[$Key]) ) { $Drawn[$Key] = ""; }
if ( !isset($Drawn[$NodeID]) ) { $Drawn[$NodeID] = ""; }
if ( isset($this->Data[$NodeID]) && !isset($Drawn[$Key][$NodeID]) && !isset($Drawn[$NodeID][$Key]) )
{
$Color = array("R"=>$this->Default["LinkR"],"G"=>$this->Default["LinkG"],"B"=>$this->Default["LinkB"],"Alpha"=>$this->Default["Alpha"]);
if ( $this->Links != "" )
{
if ( isset($this->Links[$Key][$NodeID]["R"]) )
{ $Color = array("R"=>$this->Links[$Key][$NodeID]["R"],"G"=>$this->Links[$Key][$NodeID]["G"],"B"=>$this->Links[$Key][$NodeID]["B"],"Alpha"=>$this->Links[$Key][$NodeID]["Alpha"]); }
if ( isset($this->Links[$Key][$NodeID]["Ticks"]) )
{ $Color["Ticks"] = $this->Links[$Key][$NodeID]["Ticks"]; }
}
$X2 = $this->Data[$NodeID]["X"];
$Y2 = $this->Data[$NodeID]["Y"];
$this->pChartObject->drawLine($X,$Y,$X2,$Y2,$Color);
$Drawn[$Key][$NodeID] = TRUE;
if ( isset($this->Links) && $this->Links != "" )
{
if ( isset($this->Links[$Key][$NodeID]["Name"]) || isset($this->Links[$NodeID][$Key]["Name"]) )
{
$Name = isset($this->Links[$Key][$NodeID]["Name"]) ? $this->Links[$Key][$NodeID]["Name"] : $this->Links[$NodeID][$Key]["Name"];
$TxtX = ($X2 - $X)/2 + $X;
$TxtY = ($Y2 - $Y)/2 + $Y;
if ( $X <= $X2 )
$Angle = (360-$this->getAngle($X,$Y,$X2,$Y2)) % 360;
else
$Angle = (360-$this->getAngle($X2,$Y2,$X,$Y)) % 360;
$Settings = $Color;
$Settings["Angle"] = $Angle;
$Settings["Align"] = TEXT_ALIGN_BOTTOMMIDDLE;
$this->pChartObject->drawText($TxtX,$TxtY,$Name,$Settings);
}
}
}
}
}
}
/* Draw the quiet zones */
if ( $DrawQuietZone )
{
foreach($this->Data as $Key => $Settings)
{
$X = $Settings["X"];
$Y = $Settings["Y"];
$FreeZone = $Settings["FreeZone"];
$this->pChartObject->drawFilledCircle($X,$Y,$FreeZone,array("R"=>0,"G"=>0,"B"=>0,"Alpha"=>2));
}
}
/* Draw the nodes */
foreach($this->Data as $Key => $Settings)
{
$X = $Settings["X"];
$Y = $Settings["Y"];
$Name = $Settings["Name"];
$FreeZone = $Settings["FreeZone"];
$Shape = $Settings["Shape"];
$Size = $Settings["Size"];
$Color = array("R"=>$Settings["R"],"G"=>$Settings["G"],"B"=>$Settings["B"],"Alpha"=>$Settings["Alpha"],"BorderR"=>$Settings["BorderR"],"BorderG"=>$Settings["BorderG"],"BorderB"=>$Settings["BorderB"],"BorderApha"=>$Settings["BorderAlpha"]);
if ( $Shape == NODE_SHAPE_CIRCLE )
{
$this->pChartObject->drawFilledCircle($X,$Y,$Size,$Color);
}
elseif ( $Shape == NODE_SHAPE_TRIANGLE )
{
$Points = "";
$Points[] = cos(deg2rad(270)) * $Size + $X; $Points[] = sin(deg2rad(270)) * $Size + $Y;
$Points[] = cos(deg2rad(45)) * $Size + $X; $Points[] = sin(deg2rad(45)) * $Size + $Y;
$Points[] = cos(deg2rad(135)) * $Size + $X; $Points[] = sin(deg2rad(135)) * $Size + $Y;
$this->pChartObject->drawPolygon($Points,$Color);
}
elseif ( $Shape == NODE_SHAPE_SQUARE )
{
$Offset = $Size/2; $Size = $Size / 2;
$this->pChartObject->drawFilledRectangle($X-$Offset,$Y-$Offset,$X+$Offset,$Y+$Offset,$Color);
}
if ( $Name != "" )
{
$LabelOptions = array("R"=>$this->Labels["R"],"G"=>$this->Labels["G"],"B"=>$this->Labels["B"],"Alpha"=>$this->Labels["Alpha"]);
if ( $this->Labels["Type"] == LABEL_LIGHT )
{
$LabelOptions["Align"] = TEXT_ALIGN_BOTTOMLEFT;
$this->pChartObject->drawText($X,$Y,$Name,$LabelOptions);
}
elseif ( $this->Labels["Type"] == LABEL_CLASSIC )
{
$LabelOptions["Align"] = TEXT_ALIGN_TOPMIDDLE;
$LabelOptions["DrawBox"] = TRUE;
$LabelOptions["BoxAlpha"] = 50;
$LabelOptions["BorderOffset"] = 4;
$LabelOptions["RoundedRadius"] = 3;
$LabelOptions["BoxRounded"] = TRUE;
$LabelOptions["NoShadow"] = TRUE;
$this->pChartObject->drawText($X,$Y+$Size+$TextPadding,$Name,$LabelOptions);
}
}
}
/* Draw the vectors */
if ( $DrawVectors )
{
foreach($this->Data as $Key => $Settings)
{
$X1 = $Settings["X"];
$Y1 = $Settings["Y"];
if ( isset($Settings["Vectors"]) && $Settings["Type"] != NODE_TYPE_CENTRAL )
{
foreach($Settings["Vectors"] as $ID => $Vector)
{
$Type = $Vector["Type"];
$Force = $Vector["Force"];
$Angle = $Vector["Angle"];
$Factor = $Type == "A" ? $this->MagneticForceA : $this->MagneticForceR;
$Color = $Type == "A" ? array("FillR"=>255,"FillG"=>0,"FillB"=>0) : array("FillR"=>0,"FillG"=>255,"FillB"=>0);
$X2 = cos(deg2rad($Angle)) * $Force * $Factor + $X1;
$Y2 = sin(deg2rad($Angle)) * $Force * $Factor + $Y1;
$this->pChartObject->drawArrow($X1,$Y1,$X2,$Y2,$Color);
}
}
}
}
return(array("Pass"=>$Jobs,"Conflicts"=>$Conflicts));
}
/* Return the distance between two points */
function getDistance($X1,$Y1,$X2,$Y2)
{ return (sqrt(($X2-$X1)*($X2-$X1)+($Y2-$Y1)*($Y2-$Y1))); }
/* Return the angle made by a line and the X axis */
function getAngle($X1,$Y1,$X2,$Y2)
{
$Opposite = $Y2 - $Y1; $Adjacent = $X2 - $X1;$Angle = rad2deg(atan2($Opposite,$Adjacent));
if ($Angle > 0) { return($Angle); } else { return(360-abs($Angle)); }
}
function intersect($X1,$Y1,$X2,$Y2,$X3,$Y3,$X4,$Y4)
{
$A = (($X3 * $Y4 - $X4 * $Y3) * ($X1 - $X2) - ($X1 * $Y2 - $X2 * $Y1) * ($X3 - $X4));
$B = (($Y1 - $Y2) * ($X3 - $X4) - ($Y3 - $Y4) * ($X1 - $X2));
if ( $B == 0 ) { return(FALSE); }
$Xi = $A / $B;
$C = ($X1 - $X2);
if ( $C == 0 ) { return(FALSE); }
$Yi = $Xi * (($Y1 - $Y2)/$C) + (($X1 * $Y2 - $X2 * $Y1)/$C);
if ( $Xi >= min($X1,$X2) && $Xi >= min($X3,$X4) && $Xi <= max($X1,$X2) && $Xi <= max($X3,$X4))
{
if ( $Yi >= min($Y1,$Y2) && $Yi >= min($Y3,$Y4) && $Yi <= max($Y1,$Y2) && $Yi <= max($Y3,$Y4))
{ return(TRUE); }
}
return(FALSE);
}
}
?>

View File

@@ -0,0 +1,216 @@
<?php
/*
pStock - class to draw stock charts
Version : 2.1.4
Made by : Jean-Damien POGOLOTTI
Last Update : 19/01/2014
This file can be distributed under the license you can find at :
http://www.pchart.net/license
You can find the whole class documentation on the pChart web site.
*/
define("STOCK_MISSING_SERIE" , 180001);
/* pStock class definition */
class pStock
{
var $pChartObject;
var $pDataObject;
/* Class creator */
function pStock($pChartObject,$pDataObject)
{
$this->pChartObject = $pChartObject;
$this->pDataObject = $pDataObject;
}
/* Draw a stock chart */
function drawStockChart($Format="")
{
$SerieOpen = isset($Format["SerieOpen"]) ? $Format["SerieOpen"] : "Open";
$SerieClose = isset($Format["SerieClose"]) ? $Format["SerieClose"] : "Close";
$SerieMin = isset($Format["SerieMin"]) ? $Format["SerieMin"] : "Min";
$SerieMax = isset($Format["SerieMax"]) ? $Format["SerieMax"] : "Max";
$SerieMedian = isset($Format["SerieMedian"]) ? $Format["SerieMedian"] : NULL;
$LineWidth = isset($Format["LineWidth"]) ? $Format["LineWidth"] : 1;
$LineR = isset($Format["LineR"]) ? $Format["LineR"] : 0;
$LineG = isset($Format["LineG"]) ? $Format["LineG"] : 0;
$LineB = isset($Format["LineB"]) ? $Format["LineB"] : 0;
$LineAlpha = isset($Format["LineAlpha"]) ? $Format["LineAlpha"] : 100;
$ExtremityWidth = isset($Format["ExtremityWidth"]) ? $Format["ExtremityWidth"] : 1;
$ExtremityLength = isset($Format["ExtremityLength"]) ? $Format["ExtremityLength"] : 3;
$ExtremityR = isset($Format["ExtremityR"]) ? $Format["ExtremityR"] : 0;
$ExtremityG = isset($Format["ExtremityG"]) ? $Format["ExtremityG"] : 0;
$ExtremityB = isset($Format["ExtremityB"]) ? $Format["ExtremityB"] : 0;
$ExtremityAlpha = isset($Format["ExtremityAlpha"]) ? $Format["ExtremityAlpha"] : 100;
$BoxWidth = isset($Format["BoxWidth"]) ? $Format["BoxWidth"] : 8;
$BoxUpR = isset($Format["BoxUpR"]) ? $Format["BoxUpR"] : 188;
$BoxUpG = isset($Format["BoxUpG"]) ? $Format["BoxUpG"] : 224;
$BoxUpB = isset($Format["BoxUpB"]) ? $Format["BoxUpB"] : 46;
$BoxUpAlpha = isset($Format["BoxUpAlpha"]) ? $Format["BoxUpAlpha"] : 100;
$BoxUpSurrounding = isset($Format["BoxUpSurrounding"]) ? $Format["BoxUpSurrounding"] : NULL;
$BoxUpBorderR = isset($Format["BoxUpBorderR"]) ? $Format["BoxUpBorderR"] : $BoxUpR-20;
$BoxUpBorderG = isset($Format["BoxUpBorderG"]) ? $Format["BoxUpBorderG"] : $BoxUpG-20;
$BoxUpBorderB = isset($Format["BoxUpBorderB"]) ? $Format["BoxUpBorderB"] : $BoxUpB-20;
$BoxUpBorderAlpha = isset($Format["BoxUpBorderAlpha"]) ? $Format["BoxUpBorderAlpha"] : 100;
$BoxDownR = isset($Format["BoxDownR"]) ? $Format["BoxDownR"] : 224;
$BoxDownG = isset($Format["BoxDownG"]) ? $Format["BoxDownG"] : 100;
$BoxDownB = isset($Format["BoxDownB"]) ? $Format["BoxDownB"] : 46;
$BoxDownAlpha = isset($Format["BoxDownAlpha"]) ? $Format["BoxDownAlpha"] : 100;
$BoxDownSurrounding= isset($Format["BoxDownSurrounding"]) ? $Format["BoxDownSurrounding"] : NULL;
$BoxDownBorderR = isset($Format["BoxDownBorderR"]) ? $Format["BoxDownBorderR"] : $BoxDownR-20;
$BoxDownBorderG = isset($Format["BoxDownBorderG"]) ? $Format["BoxDownBorderG"] : $BoxDownG-20;
$BoxDownBorderB = isset($Format["BoxDownBorderB"]) ? $Format["BoxDownBorderB"] : $BoxDownB-20;
$BoxDownBorderAlpha= isset($Format["BoxDownBorderAlpha"]) ? $Format["BoxDownBorderAlpha"] : 100;
$ShadowOnBoxesOnly = isset($Format["ShadowOnBoxesOnly"]) ? $Format["ShadowOnBoxesOnly"] : TRUE;
$MedianR = isset($Format["MedianR"]) ? $Format["MedianR"] : 255;
$MedianG = isset($Format["MedianG"]) ? $Format["MedianG"] : 0;
$MedianB = isset($Format["MedianB"]) ? $Format["MedianB"] : 0;
$MedianAlpha = isset($Format["MedianAlpha"]) ? $Format["MedianAlpha"] : 100;
$RecordImageMap = isset($Format["RecordImageMap"]) ? $Format["RecordImageMap"] : FALSE;
$ImageMapTitle = isset($Format["ImageMapTitle"]) ? $Format["ImageMapTitle"] : "Stock Chart";
/* Data Processing */
$Data = $this->pDataObject->getData();
$Palette = $this->pDataObject->getPalette();
if ( $BoxUpSurrounding != NULL ) { $BoxUpBorderR = $BoxUpR + $BoxUpSurrounding; $BoxUpBorderG = $BoxUpG + $BoxUpSurrounding; $BoxUpBorderB = $BoxUpB + $BoxUpSurrounding; }
if ( $BoxDownSurrounding != NULL ) { $BoxDownBorderR = $BoxDownR + $BoxDownSurrounding; $BoxDownBorderG = $BoxDownG + $BoxDownSurrounding; $BoxDownBorderB = $BoxDownB + $BoxDownSurrounding; }
if ( $LineWidth != 1 ) { $LineOffset = $LineWidth / 2; }
$BoxOffset = $BoxWidth / 2;
$Data = $this->pChartObject->DataSet->getData();
list($XMargin,$XDivs) = $this->pChartObject->scaleGetXSettings();
if ( !isset($Data["Series"][$SerieOpen]) || !isset($Data["Series"][$SerieClose]) || !isset($Data["Series"][$SerieMin]) || !isset($Data["Series"][$SerieMax]) )
return(STOCK_MISSING_SERIE);
$Plots = "";
foreach($Data["Series"][$SerieOpen]["Data"] as $Key => $Value)
{
$Point = "";
if ( isset($Data["Series"][$SerieClose]["Data"][$Key]) || isset($Data["Series"][$SerieMin]["Data"][$Key]) || isset($Data["Series"][$SerieMax]["Data"][$Key]) )
$Point = array($Value,$Data["Series"][$SerieClose]["Data"][$Key],$Data["Series"][$SerieMin]["Data"][$Key],$Data["Series"][$SerieMax]["Data"][$Key]);
if ( $SerieMedian != NULL && isset($Data["Series"][$SerieMedian]["Data"][$Key]) )
$Point[] = $Data["Series"][$SerieMedian]["Data"][$Key];
$Plots[] = $Point;
}
$AxisID = $Data["Series"][$SerieOpen]["Axis"];
$Mode = $Data["Axis"][$AxisID]["Display"];
$Format = $Data["Axis"][$AxisID]["Format"];
$Unit = $Data["Axis"][$AxisID]["Unit"];
$YZero = $this->pChartObject->scaleComputeY(0,array("AxisID"=>$AxisID));
$XStep = ($this->pChartObject->GraphAreaX2-$this->pChartObject->GraphAreaX1-$XMargin*2)/$XDivs;
$X = $this->pChartObject->GraphAreaX1 + $XMargin;
$Y = $this->pChartObject->GraphAreaY1 + $XMargin;
$LineSettings = array("R"=>$LineR,"G"=>$LineG,"B"=>$LineB,"Alpha"=>$LineAlpha);
$ExtremitySettings = array("R"=>$ExtremityR,"G"=>$ExtremityG,"B"=>$ExtremityB,"Alpha"=>$ExtremityAlpha);
$BoxUpSettings = array("R"=>$BoxUpR,"G"=>$BoxUpG,"B"=>$BoxUpB,"Alpha"=>$BoxUpAlpha,"BorderR"=>$BoxUpBorderR,"BorderG"=>$BoxUpBorderG,"BorderB"=>$BoxUpBorderB,"BorderAlpha"=>$BoxUpBorderAlpha);
$BoxDownSettings = array("R"=>$BoxDownR,"G"=>$BoxDownG,"B"=>$BoxDownB,"Alpha"=>$BoxDownAlpha,"BorderR"=>$BoxDownBorderR,"BorderG"=>$BoxDownBorderG,"BorderB"=>$BoxDownBorderB,"BorderAlpha"=>$BoxDownBorderAlpha);
$MedianSettings = array("R"=>$MedianR,"G"=>$MedianG,"B"=>$MedianB,"Alpha"=>$MedianAlpha);
foreach($Plots as $Key =>$Points)
{
$PosArray = $this->pChartObject->scaleComputeY($Points,array("AxisID"=>$AxisID));
$Values = "Open :".$Data["Series"][$SerieOpen]["Data"][$Key]."<BR>Close : ".$Data["Series"][$SerieClose]["Data"][$Key]."<BR>Min : ".$Data["Series"][$SerieMin]["Data"][$Key]."<BR>Max : ".$Data["Series"][$SerieMax]["Data"][$Key]."<BR>";
if ( $SerieMedian != NULL ) { $Values = $Values."Median : ".$Data["Series"][$SerieMedian]["Data"][$Key]."<BR>"; }
if ( $PosArray[0] > $PosArray[1] ) { $ImageMapColor = $this->pChartObject->toHTMLColor($BoxUpR,$BoxUpG,$BoxUpB); } else { $ImageMapColor = $this->pChartObject->toHTMLColor($BoxDownR,$BoxDownG,$BoxDownB); }
if ( $Data["Orientation"] == SCALE_POS_LEFTRIGHT )
{
if ( $YZero > $this->pChartObject->GraphAreaY2-1 ) { $YZero = $this->pChartObject->GraphAreaY2-1; }
if ( $YZero < $this->pChartObject->GraphAreaY1+1 ) { $YZero = $this->pChartObject->GraphAreaY1+1; }
if ( $XDivs == 0 ) { $XStep = 0; } else { $XStep = ($this->pChartObject->GraphAreaX2-$this->pChartObject->GraphAreaX1-$XMargin*2)/$XDivs; }
if ( $ShadowOnBoxesOnly ) { $RestoreShadow = $this->pChartObject->Shadow; $this->pChartObject->Shadow = FALSE; }
if ( $LineWidth == 1 )
$this->pChartObject->drawLine($X,$PosArray[2],$X,$PosArray[3],$LineSettings);
else
$this->pChartObject->drawFilledRectangle($X-$LineOffset,$PosArray[2],$X+$LineOffset,$PosArray[3],$LineSettings);
if ( $ExtremityWidth == 1 )
{
$this->pChartObject->drawLine($X-$ExtremityLength,$PosArray[2],$X+$ExtremityLength,$PosArray[2],$ExtremitySettings);
$this->pChartObject->drawLine($X-$ExtremityLength,$PosArray[3],$X+$ExtremityLength,$PosArray[3],$ExtremitySettings);
if ( $RecordImageMap ) { $this->pChartObject->addToImageMap("RECT",floor($X-$ExtremityLength).",".floor($PosArray[2]).",".floor($X+$ExtremityLength).",".floor($PosArray[3]),$ImageMapColor,$ImageMapTitle,$Values); }
}
else
{
$this->pChartObject->drawFilledRectangle($X-$ExtremityLength,$PosArray[2],$X+$ExtremityLength,$PosArray[2]-$ExtremityWidth,$ExtremitySettings);
$this->pChartObject->drawFilledRectangle($X-$ExtremityLength,$PosArray[3],$X+$ExtremityLength,$PosArray[3]+$ExtremityWidth,$ExtremitySettings);
if ( $RecordImageMap ) { $this->pChartObject->addToImageMap("RECT",floor($X-$ExtremityLength).",".floor($PosArray[2]-$ExtremityWidth).",".floor($X+$ExtremityLength).",".floor($PosArray[3]+$ExtremityWidth),$ImageMapColor,$ImageMapTitle,$Values); }
}
if ( $ShadowOnBoxesOnly ) { $this->pChartObject->Shadow = $RestoreShadow; }
if ( $PosArray[0] > $PosArray[1] )
$this->pChartObject->drawFilledRectangle($X-$BoxOffset,$PosArray[0],$X+$BoxOffset,$PosArray[1],$BoxUpSettings);
else
$this->pChartObject->drawFilledRectangle($X-$BoxOffset,$PosArray[0],$X+$BoxOffset,$PosArray[1],$BoxDownSettings);
if ( isset($PosArray[4]) )
$this->pChartObject->drawLine($X-$ExtremityLength,$PosArray[4],$X+$ExtremityLength,$PosArray[4],$MedianSettings);
$X = $X + $XStep;
}
elseif ( $Data["Orientation"] == SCALE_POS_TOPBOTTOM )
{
if ( $YZero > $this->pChartObject->GraphAreaX2-1 ) { $YZero = $this->pChartObject->GraphAreaX2-1; }
if ( $YZero < $this->pChartObject->GraphAreaX1+1 ) { $YZero = $this->pChartObject->GraphAreaX1+1; }
if ( $XDivs == 0 ) { $XStep = 0; } else { $XStep = ($this->pChartObject->GraphAreaY2-$this->pChartObject->GraphAreaY1-$XMargin*2)/$XDivs; }
if ( $LineWidth == 1 )
$this->pChartObject->drawLine($PosArray[2],$Y,$PosArray[3],$Y,$LineSettings);
else
$this->pChartObject->drawFilledRectangle($PosArray[2],$Y-$LineOffset,$PosArray[3],$Y+$LineOffset,$LineSettings);
if ( $ShadowOnBoxesOnly ) { $RestoreShadow = $this->pChartObject->Shadow; $this->pChartObject->Shadow = FALSE; }
if ( $ExtremityWidth == 1 )
{
$this->pChartObject->drawLine($PosArray[2],$Y-$ExtremityLength,$PosArray[2],$Y+$ExtremityLength,$ExtremitySettings);
$this->pChartObject->drawLine($PosArray[3],$Y-$ExtremityLength,$PosArray[3],$Y+$ExtremityLength,$ExtremitySettings);
if ( $RecordImageMap ) { $this->pChartObject->addToImageMap("RECT",floor($PosArray[2]).",".floor($Y-$ExtremityLength).",".floor($PosArray[3]).",".floor($Y+$ExtremityLength),$ImageMapColor,$ImageMapTitle,$Values); }
}
else
{
$this->pChartObject->drawFilledRectangle($PosArray[2],$Y-$ExtremityLength,$PosArray[2]-$ExtremityWidth,$Y+$ExtremityLength,$ExtremitySettings);
$this->pChartObject->drawFilledRectangle($PosArray[3],$Y-$ExtremityLength,$PosArray[3]+$ExtremityWidth,$Y+$ExtremityLength,$ExtremitySettings);
if ( $RecordImageMap ) { $this->pChartObject->addToImageMap("RECT",floor($PosArray[2]-$ExtremityWidth).",".floor($Y-$ExtremityLength).",".floor($PosArray[3]+$ExtremityWidth).",".floor($Y+$ExtremityLength),$ImageMapColor,$ImageMapTitle,$Values); }
}
if ( $ShadowOnBoxesOnly ) { $this->pChartObject->Shadow = $RestoreShadow; }
if ( $PosArray[0] < $PosArray[1] )
$this->pChartObject->drawFilledRectangle($PosArray[0],$Y-$BoxOffset,$PosArray[1],$Y+$BoxOffset,$BoxUpSettings);
else
$this->pChartObject->drawFilledRectangle($PosArray[0],$Y-$BoxOffset,$PosArray[1],$Y+$BoxOffset,$BoxDownSettings);
if ( isset($PosArray[4]) )
$this->pChartObject->drawLine($PosArray[4],$Y-$ExtremityLength,$PosArray[4],$Y+$ExtremityLength,$MedianSettings);
$Y = $Y + $XStep;
}
}
}
}
?>

View File

@@ -0,0 +1,315 @@
<?php
/*
pSurface - class to draw surface charts
Version : 2.1.4
Made by : Jean-Damien POGOLOTTI
Last Update : 19/01/2014
This file can be distributed under the license you can find at :
http://www.pchart.net/license
You can find the whole class documentation on the pChart web site.
*/
define("UNKNOWN" , 0.123456789);
define("IGNORED" , -1);
define("LABEL_POSITION_LEFT" , 880001);
define("LABEL_POSITION_RIGHT" , 880002);
define("LABEL_POSITION_TOP" , 880003);
define("LABEL_POSITION_BOTTOM" , 880004);
/* pStock class definition */
class pSurface
{
var $pChartObject;
var $GridSizeX;
var $GridSizeY;
var $Points;
/* Class creator */
function pSurface($pChartObject)
{
$this->pChartObject = $pChartObject;
$this->GridSize = 10;
$this->Points = "";
}
/* Define the grid size and initialise the 2D matrix */
function setGrid($XSize=10,$YSize=10)
{
for($X=0; $X<=$XSize; $X++) { for($Y=0; $Y<=$YSize; $Y++) { $this->Points[$X][$Y]=UNKNOWN; } }
$this->GridSizeX = $XSize;
$this->GridSizeY = $YSize;
}
/* Add a point on the grid */
function addPoint($X,$Y,$Value,$Force=TRUE)
{
if ( $X < 0 || $X >$this->GridSizeX ) { return(0); }
if ( $Y < 0 || $Y >$this->GridSizeY ) { return(0); }
if ( $this->Points[$X][$Y] == UNKNOWN || $Force )
$this->Points[$X][$Y] = $Value;
elseif ( $this->Points[$X][$Y] == UNKNOWN )
$this->Points[$X][$Y] = $Value;
else
$this->Points[$X][$Y] = ($this->Points[$X][$Y] + $Value)/2;
}
/* Write the X labels */
function writeXLabels($Format="")
{
$R = isset($Format["R"]) ? $Format["R"] : $this->pChartObject->FontColorR;
$G = isset($Format["G"]) ? $Format["G"] : $this->pChartObject->FontColorG;
$B = isset($Format["B"]) ? $Format["B"] : $this->pChartObject->FontColorB;
$Alpha = isset($Format["Alpha"]) ? $Format["Alpha"] : $this->pChartObject->FontColorA;
$Angle = isset($Format["Angle"]) ? $Format["Angle"] : 0;
$Padding = isset($Format["Padding"]) ? $Format["Padding"] : 5;
$Position = isset($Format["Position"]) ? $Format["Position"] : LABEL_POSITION_TOP;
$Labels = isset($Format["Labels"]) ? $Format["Labels"] : NULL;
$CountOffset = isset($Format["CountOffset"]) ? $Format["CountOffset"] : 0;
if ( $Labels != NULL && !is_array($Labels) ) { $Label = $Labels; $Labels = ""; $Labels[] = $Label; }
$X0 = $this->pChartObject->GraphAreaX1;
$XSize = ($this->pChartObject->GraphAreaX2 - $this->pChartObject->GraphAreaX1) / ($this->GridSizeX+1);
$Settings = array("Angle"=>$Angle,"R"=>$R,"G"=>$G,"B"=>$B,"Alpha"=>$Alpha);
if ( $Position == LABEL_POSITION_TOP )
{
$YPos = $this->pChartObject->GraphAreaY1 - $Padding;
if ($Angle == 0 ) { $Settings["Align"] = TEXT_ALIGN_BOTTOMMIDDLE; }
if ($Angle != 0 ) { $Settings["Align"] = TEXT_ALIGN_MIDDLELEFT; }
}
elseif ( $Position == LABEL_POSITION_BOTTOM )
{
$YPos = $this->pChartObject->GraphAreaY2 + $Padding;
if ($Angle == 0 ) { $Settings["Align"] = TEXT_ALIGN_TOPMIDDLE; }
if ($Angle != 0 ) { $Settings["Align"] = TEXT_ALIGN_MIDDLERIGHT; }
}
else
return(-1);
for($X=0;$X<=$this->GridSizeX;$X++)
{
$XPos = floor($X0+$X*$XSize + $XSize/2);
if( $Labels == NULL || !isset($Labels[$X]) )
$Value = $X+$CountOffset;
else
$Value = $Labels[$X];
$this->pChartObject->drawText($XPos,$YPos,$Value,$Settings);
}
}
/* Write the Y labels */
function writeYLabels($Format="")
{
$R = isset($Format["R"]) ? $Format["R"] : $this->pChartObject->FontColorR;
$G = isset($Format["G"]) ? $Format["G"] : $this->pChartObject->FontColorG;
$B = isset($Format["B"]) ? $Format["B"] : $this->pChartObject->FontColorB;
$Alpha = isset($Format["Alpha"]) ? $Format["Alpha"] : $this->pChartObject->FontColorA;
$Angle = isset($Format["Angle"]) ? $Format["Angle"] : 0;
$Padding = isset($Format["Padding"]) ? $Format["Padding"] : 5;
$Position = isset($Format["Position"]) ? $Format["Position"] : LABEL_POSITION_LEFT;
$Labels = isset($Format["Labels"]) ? $Format["Labels"] : NULL;
$CountOffset = isset($Format["CountOffset"]) ? $Format["CountOffset"] : 0;
if ( $Labels != NULL && !is_array($Labels) ) { $Label = $Labels; $Labels = ""; $Labels[] = $Label; }
$Y0 = $this->pChartObject->GraphAreaY1;
$YSize = ($this->pChartObject->GraphAreaY2 - $this->pChartObject->GraphAreaY1) / ($this->GridSizeY+1);
$Settings = array("Angle"=>$Angle,"R"=>$R,"G"=>$G,"B"=>$B,"Alpha"=>$Alpha);
if ( $Position == LABEL_POSITION_LEFT )
{ $XPos = $this->pChartObject->GraphAreaX1 - $Padding; $Settings["Align"] = TEXT_ALIGN_MIDDLERIGHT; }
elseif ( $Position == LABEL_POSITION_RIGHT )
{ $XPos = $this->pChartObject->GraphAreaX2 + $Padding; $Settings["Align"] = TEXT_ALIGN_MIDDLELEFT; }
else
return(-1);
for($Y=0;$Y<=$this->GridSizeY;$Y++)
{
$YPos = floor($Y0+$Y*$YSize + $YSize/2);
if( $Labels == NULL || !isset($Labels[$Y]) )
$Value = $Y+$CountOffset;
else
$Value = $Labels[$Y];
$this->pChartObject->drawText($XPos,$YPos,$Value,$Settings);
}
}
/* Draw the area arround the specified Threshold */
function drawContour($Threshold,$Format="")
{
$R = isset($Format["R"]) ? $Format["R"] : 0;
$G = isset($Format["G"]) ? $Format["G"] : 0;
$B = isset($Format["B"]) ? $Format["B"] : 0;
$Alpha = isset($Format["Alpha"]) ? $Format["Alpha"] : 100;
$Ticks = isset($Format["Ticks"]) ? $Format["Ticks"] : 3;
$Padding = isset($Format["Padding"]) ? $Format["Padding"] : 0;
$X0 = $this->pChartObject->GraphAreaX1;
$Y0 = $this->pChartObject->GraphAreaY1;
$XSize = ($this->pChartObject->GraphAreaX2 - $this->pChartObject->GraphAreaX1) / ($this->GridSizeX+1);
$YSize = ($this->pChartObject->GraphAreaY2 - $this->pChartObject->GraphAreaY1) / ($this->GridSizeY+1);
$Color = array("R"=>$R,"G"=>$G,"B"=>$B,"Alpha"=>$Alpha,"Ticks"=>$Ticks);
for($X=0;$X<=$this->GridSizeX;$X++)
{
for($Y=0;$Y<=$this->GridSizeY;$Y++)
{
$Value = $this->Points[$X][$Y];
if ( $Value != UNKNOWN && $Value != IGNORED && $Value >= $Threshold)
{
$X1 = floor($X0+$X*$XSize)+$Padding;
$Y1 = floor($Y0+$Y*$YSize)+$Padding;
$X2 = floor($X0+$X*$XSize+$XSize);
$Y2 = floor($Y0+$Y*$YSize+$YSize);
if ( $X > 0 && $this->Points[$X-1][$Y] != UNKNOWN && $this->Points[$X-1][$Y] != IGNORED && $this->Points[$X-1][$Y] < $Threshold)
$this->pChartObject->drawLine($X1,$Y1,$X1,$Y2,$Color);
if ( $Y > 0 && $this->Points[$X][$Y-1] != UNKNOWN && $this->Points[$X][$Y-1] != IGNORED && $this->Points[$X][$Y-1] < $Threshold)
$this->pChartObject->drawLine($X1,$Y1,$X2,$Y1,$Color);
if ( $X < $this->GridSizeX && $this->Points[$X+1][$Y] != UNKNOWN && $this->Points[$X+1][$Y] != IGNORED && $this->Points[$X+1][$Y] < $Threshold)
$this->pChartObject->drawLine($X2,$Y1,$X2,$Y2,$Color);
if ( $Y < $this->GridSizeY && $this->Points[$X][$Y+1] != UNKNOWN && $this->Points[$X][$Y+1] != IGNORED && $this->Points[$X][$Y+1] < $Threshold)
$this->pChartObject->drawLine($X1,$Y2,$X2,$Y2,$Color);
}
}
}
}
/* Draw the surface chart */
function drawSurface($Format="")
{
$Palette = isset($Format["Palette"]) ? $Format["Palette"] : NULL;
$ShadeR1 = isset($Format["ShadeR1"]) ? $Format["ShadeR1"] : 77;
$ShadeG1 = isset($Format["ShadeG1"]) ? $Format["ShadeG1"] : 205;
$ShadeB1 = isset($Format["ShadeB1"]) ? $Format["ShadeB1"] : 21;
$ShadeA1 = isset($Format["ShadeA1"]) ? $Format["ShadeA1"] : 40;
$ShadeR2 = isset($Format["ShadeR2"]) ? $Format["ShadeR2"] : 227;
$ShadeG2 = isset($Format["ShadeG2"]) ? $Format["ShadeG2"] : 135;
$ShadeB2 = isset($Format["ShadeB2"]) ? $Format["ShadeB2"] : 61;
$ShadeA2 = isset($Format["ShadeA2"]) ? $Format["ShadeA2"] : 100;
$Border = isset($Format["Border"]) ? $Format["Border"] : FALSE;
$BorderR = isset($Format["BorderR"]) ? $Format["BorderR"] : 0;
$BorderG = isset($Format["BorderG"]) ? $Format["BorderG"] : 0;
$BorderB = isset($Format["BorderB"]) ? $Format["BorderB"] : 0;
$Surrounding = isset($Format["Surrounding"]) ? $Format["Surrounding"] : -1;
$Padding = isset($Format["Padding"]) ? $Format["Padding"] : 1;
$X0 = $this->pChartObject->GraphAreaX1;
$Y0 = $this->pChartObject->GraphAreaY1;
$XSize = ($this->pChartObject->GraphAreaX2 - $this->pChartObject->GraphAreaX1) / ($this->GridSizeX+1);
$YSize = ($this->pChartObject->GraphAreaY2 - $this->pChartObject->GraphAreaY1) / ($this->GridSizeY+1);
for($X=0;$X<=$this->GridSizeX;$X++)
{
for($Y=0;$Y<=$this->GridSizeY;$Y++)
{
$Value = $this->Points[$X][$Y];
if ( $Value != UNKNOWN && $Value != IGNORED )
{
$X1 = floor($X0+$X*$XSize)+$Padding;
$Y1 = floor($Y0+$Y*$YSize)+$Padding;
$X2 = floor($X0+$X*$XSize+$XSize);
$Y2 = floor($Y0+$Y*$YSize+$YSize);
if ( $Palette != NULL )
{
if ( isset($Palette[$Value]) && isset($Palette[$Value]["R"]) ) { $R = $Palette[$Value]["R"]; } else { $R = 0; }
if ( isset($Palette[$Value]) && isset($Palette[$Value]["G"]) ) { $G = $Palette[$Value]["G"]; } else { $G = 0; }
if ( isset($Palette[$Value]) && isset($Palette[$Value]["B"]) ) { $B = $Palette[$Value]["B"]; } else { $B = 0; }
if ( isset($Palette[$Value]) && isset($Palette[$Value]["Alpha"]) ) { $Alpha = $Palette[$Value]["Alpha"]; } else { $Alpha = 1000; }
}
else
{
$R = (($ShadeR2-$ShadeR1)/100)*$Value + $ShadeR1;
$G = (($ShadeG2-$ShadeG1)/100)*$Value + $ShadeG1;
$B = (($ShadeB2-$ShadeB1)/100)*$Value + $ShadeB1;
$Alpha = (($ShadeA2-$ShadeA1)/100)*$Value + $ShadeA1;
}
$Settings = array("R"=>$R,"G"=>$G,"B"=>$B,"Alpha"=>$Alpha);
if ( $Border ) { $Settings["BorderR"] = $BorderR; $Settings["BorderG"] = $BorderG; $Settings["BorderB"] = $BorderB; }
if ( $Surrounding != -1 ) { $Settings["BorderR"] = $R+$Surrounding; $Settings["BorderG"] = $G+$Surrounding; $Settings["BorderB"] = $B+$Surrounding; }
$this->pChartObject->drawFilledRectangle($X1,$Y1,$X2-1,$Y2-1,$Settings);
}
}
}
}
/* Compute the missing points */
function computeMissing()
{
$Missing = "";
for($X=0;$X<=$this->GridSizeX;$X++)
{
for($Y=0;$Y<=$this->GridSizeY;$Y++)
{
if ( $this->Points[$X][$Y] == UNKNOWN )
$Missing[] = $X.",".$Y;
}
}
shuffle($Missing);
foreach($Missing as $Key => $Pos)
{
$Pos = preg_split("/,/",$Pos);
$X = $Pos[0];
$Y = $Pos[1];
if ( $this->Points[$X][$Y] == UNKNOWN )
{
$NearestNeighbor = $this->getNearestNeighbor($X,$Y);
$Value = 0; $Points = 0;
for($Xi=$X-$NearestNeighbor;$Xi<=$X+$NearestNeighbor;$Xi++)
{
for($Yi=$Y-$NearestNeighbor;$Yi<=$Y+$NearestNeighbor;$Yi++)
{
if ($Xi >=0 && $Yi >= 0 && $Xi <= $this->GridSizeX && $Yi <= $this->GridSizeY && $this->Points[$Xi][$Yi] != UNKNOWN && $this->Points[$Xi][$Yi] != IGNORED)
{
$Value = $Value + $this->Points[$Xi][$Yi]; $Points++;
}
}
}
if ( $Points != 0 ) { $this->Points[$X][$Y] = $Value / $Points; }
}
}
}
/* Return the nearest Neighbor distance of a point */
function getNearestNeighbor($Xp,$Yp)
{
$Nearest = UNKNOWN;
for($X=0;$X<=$this->GridSizeX;$X++)
{
for($Y=0;$Y<=$this->GridSizeY;$Y++)
{
if ( $this->Points[$X][$Y] != UNKNOWN && $this->Points[$X][$Y] != IGNORED )
{
$DistanceX = max($Xp,$X)-min($Xp,$X);
$DistanceY = max($Yp,$Y)-min($Yp,$Y);
$Distance = max($DistanceX,$DistanceY);
if ( $Distance < $Nearest || $Nearest == UNKNOWN ) { $Nearest = $Distance; }
}
}
}
return($Nearest);
}
}
?>

View File

@@ -0,0 +1,107 @@
0;32;11011001100
1;33;11001101100
2;34;11001100110
3;35;10010011000
4;36;10010001100
5;37;10001001100
6;38;10011001000
7;39;10011000100
8;40;10001100100
9;41;11001001000
10;42;11001000100
11;43;11000100100
12;44;10110011100
13;45;10011011100
14;46;10011001110
15;47;10111001100
16;48;10011101100
17;49;10011100110
18;50;11001110010
19;51;11001011100
20;52;11001001110
21;53;11011100100
22;54;11001110100
23;55;11101101110
24;56;11101001100
25;57;11100101100
26;58;11100100110
27;59;11101100100
28;60;11100110100
29;61;11100110010
30;62;11011011000
31;63;11011000110
32;64;11000110110
33;65;10100011000
34;66;10001011000
35;67;10001000110
36;68;10110001000
37;69;10001101000
38;70;10001100010
39;71;11010001000
40;72;11000101000
41;73;11000100010
42;74;10110111000
43;75;10110001110
44;76;10001101110
45;77;10111011000
46;78;10111000110
47;79;10001110110
48;80;11101110110
49;81;11010001110
50;82;11000101110
51;83;11011101000
52;84;11011100010
53;85;11011101110
54;86;11101011000
55;87;11101000110
56;88;11100010110
57;89;11101101000
58;90;11101100010
59;91;11100011010
60;92;11101111010
61;93;11001000010
62;94;11110001010
63;95;10100110000
64;96;10100001100
65;97;10010110000
66;98;10010000110
67;99;10000101100
68;100;10000100110
69;101;10110010000
70;102;10110000100
71;103;10011010000
72;104;10011000010
73;105;10000110100
74;106;10000110010
75;107;11000010010
76;108;11001010000
77;109;11110111010
78;110;11000010100
79;111;10001111010
80;112;10100111100
81;113;10010111100
82;114;10010011110
83;115;10111100100
84;116;10011110100
85;117;10011110010
86;118;11110100100
87;119;11110010100
88;120;11110010010
89;121;11011011110
90;122;11011110110
91;123;11110110110
92;124;10101111000
93;125;10100011110
94;126;10001011110
95;200;10111101000
96;201;10111100010
97;202;11110101000
98;203;11110100010
99;204;10111011110
100;205;10111101110
101;206;11101011110
102;207;11110101110
103;208;11010000100
104;209;11010010000
105;210;11010011100
106;211;1100011101011

View File

@@ -0,0 +1,44 @@
0;101001101101
1;110100101011
2;101100101011
3;110110010101
4;101001101011
5;110100110101
6;101100110101
7;101001011011
8;110100101101
9;101100101101
A;110101001011
B;101101001011
C;110110100101
D;101011001011
E;110101100101
F;101101100101
G;101010011011
H;110101001101
I;101101001101
J;101011001101
K;110101010011
L;101101010011
M;110110101001
N;101011010011
O;110101101001
P;101101101001
Q;101010110011
R;110101011001
S;101101011001
T;101011011001
U;110010101011
V;100110101011
W;110011010101
X;100101101011
Y;110010110101
Z;100110110101
-;100101011011
.;110010101101
;100110101101
$;100100100101
/;100100101001
+;100101001001
%;101001001001
*;100101101101

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@@ -0,0 +1,6 @@
185,106,154,100
216,137,184,100
156,192,137,100
216,243,201,100
253,232,215,100
255,255,255,100

View File

@@ -0,0 +1,6 @@
109,152,171,100
0,39,94,100
254,183,41,100
168,177,184,100
255,255,255,100
0,0,0,100

View File

@@ -0,0 +1,6 @@
242,245,237,100
255,194,0,100
255,91,0,100
184,0,40,100
132,0,46,100
74,192,242,100

View File

@@ -0,0 +1,6 @@
155,225,251,100
197,239,253,100
189,32,49,100
35,31,32,100
255,255,255,100
0,98,149,100

View File

@@ -0,0 +1,7 @@
239,210,121,100
149,203,233,100
2,71,105,100
175,215,117,100
44,87,0,100
222,157,127,100

View File

@@ -0,0 +1,6 @@
25,78,132,100
59,107,156,100
31,36,42,100
55,65,74,100
96,187,34,100
242,186,187,100

View File

@@ -0,0 +1,6 @@
117,113,22,100
174,188,33,100
217,219,86,100
0,71,127,100
76,136,190,100
141,195,233,100

View File

@@ -0,0 +1,6 @@
146,123,81,100
168,145,102,100
128,195,28,100
188,221,90,100
255,121,0,100
251,179,107,100

View File

@@ -0,0 +1,6 @@
253,184,19,100
246,139,31,100
241,112,34,100
98,194,204,100
228,246,248,100
238,246,108,100

22
www/lib/smarty-3.1.30/.gitattributes vendored Normal file
View File

@@ -0,0 +1,22 @@
# Auto detect text files and perform LF normalization
* text=auto
# Custom for Visual Studio
*.cs diff=csharp
*.sln merge=union
*.csproj merge=union
*.vbproj merge=union
*.fsproj merge=union
*.dbproj merge=union
# Standard to msysgit
*.doc diff=astextplain
*.DOC diff=astextplain
*.docx diff=astextplain
*.DOCX diff=astextplain
*.dot diff=astextplain
*.DOT diff=astextplain
*.pdf diff=astextplain
*.PDF diff=astextplain
*.rtf diff=astextplain
*.RTF diff=astextplain

222
www/lib/smarty-3.1.30/.gitignore vendored Normal file
View File

@@ -0,0 +1,222 @@
#################
## Eclipse
#################
*.pydevproject
.project
.metadata
bin/
tmp/
*.tmp
*.bak
*.swp
*~.nib
local.properties
.classpath
.settings/
.loadpath
# External tool builders
.externalToolBuilders/
# Locally stored "Eclipse launch configurations"
*.launch
# CDT-specific
.cproject
# PDT-specific
.buildpath
#################
## Visual Studio
#################
## Ignore Visual Studio temporary files, build results, and
## files generated by popular Visual Studio add-ons.
# User-specific files
*.suo
*.user
*.sln.docstates
# Build results
[Dd]ebug/
[Rr]elease/
x64/
build/
[Bb]in/
[Oo]bj/
# MSTest test Results
[Tt]est[Rr]esult*/
[Bb]uild[Ll]og.*
*_i.c
*_p.c
*.ilk
*.meta
*.obj
*.pch
*.pdb
*.pgc
*.pgd
*.rsp
*.sbr
*.tlb
*.tli
*.tlh
*.tmp
*.tmp_proj
*.log
*.vspscc
*.vssscc
.builds
*.pidb
*.log
*.scc
# Visual C++ cache files
ipch/
*.aps
*.ncb
*.opensdf
*.sdf
*.cachefile
# Visual Studio profiler
*.psess
*.vsp
*.vspx
# Guidance Automation Toolkit
*.gpState
# ReSharper is a .NET coding add-in
_ReSharper*/
*.[Rr]e[Ss]harper
# TeamCity is a build add-in
_TeamCity*
# DotCover is a Code Coverage Tool
*.dotCover
# NCrunch
*.ncrunch*
.*crunch*.local.xml
# Installshield output folder
[Ee]xpress/
# DocProject is a documentation generator add-in
DocProject/buildhelp/
DocProject/Help/*.HxT
DocProject/Help/*.HxC
DocProject/Help/*.hhc
DocProject/Help/*.hhk
DocProject/Help/*.hhp
DocProject/Help/Html2
DocProject/Help/html
# Click-Once directory
publish/
# Publish Web Output
*.Publish.xml
*.pubxml
# NuGet Packages Directory
## TODO: If you have NuGet Package Restore enabled, uncomment the next line
#packages/
# Windows Azure Build Output
csx
*.build.csdef
# Windows Store app package directory
AppPackages/
# Others
sql/
*.Cache
ClientBin/
[Ss]tyle[Cc]op.*
~$*
*~
*.dbmdl
*.[Pp]ublish.xml
*.pfx
*.publishsettings
# RIA/Silverlight projects
Generated_Code/
# Backup & report files from converting an old project file to a newer
# Visual Studio version. Backup files are not needed, because we have git ;-)
_UpgradeReport_Files/
Backup*/
UpgradeLog*.XML
UpgradeLog*.htm
# SQL Server files
App_Data/*.mdf
App_Data/*.ldf
#############
## Windows detritus
#############
# Windows image file caches
Thumbs.db
ehthumbs.db
# Folder config file
Desktop.ini
# Recycle Bin used on file shares
$RECYCLE.BIN/
# Mac crap
.DS_Store
#############
## Python
#############
*.py[co]
# Packages
*.egg
*.egg-info
dist/
build/
eggs/
parts/
var/
sdist/
develop-eggs/
.installed.cfg
# Installer logs
pip-log.txt
# Unit test / coverage reports
.coverage
.tox
#Translations
*.mo
#Mr Developer
.mr.developer.cfg
.idea/
.idea\
# Smarty
lexer/*.php
lexer/*.out

View File

@@ -0,0 +1,18 @@
language: php
php:
- 5.3
- 5.4
- 5.5
- 5.6
allow_failures:
- php: hhvm
install:
- git clone --depth=50 --branch=master git://github.com/smarty-php/smarty-phpunit.git
script:
- cd smarty-phpunit
- phpunit ./

View File

@@ -0,0 +1,107 @@
<?php
/**
* Smarty Autoloader
*
* @package Smarty
*/
/**
* Smarty Autoloader
*
* @package Smarty
* @author Uwe Tews
* Usage:
* require_once '...path/Autoloader.php';
* Smarty_Autoloader::register();
* $smarty = new Smarty();
* Note: This autoloader is not needed if you use Composer.
* Composer will automatically add the classes of the Smarty package to it common autoloader.
*/
class Smarty_Autoloader
{
/**
* Filepath to Smarty root
*
* @var string
*/
public static $SMARTY_DIR = '';
/**
* Filepath to Smarty internal plugins
*
* @var string
*/
public static $SMARTY_SYSPLUGINS_DIR = '';
/**
* Array with Smarty core classes and their filename
*
* @var array
*/
public static $rootClasses = array('smarty' => 'Smarty.class.php', 'smartybc' => 'SmartyBC.class.php',);
/**
* Registers Smarty_Autoloader backward compatible to older installations.
*
* @param bool $prepend Whether to prepend the autoloader or not.
*/
public static function registerBC($prepend = false)
{
/**
* register the class autoloader
*/
if (!defined('SMARTY_SPL_AUTOLOAD')) {
define('SMARTY_SPL_AUTOLOAD', 0);
}
if (SMARTY_SPL_AUTOLOAD &&
set_include_path(get_include_path() . PATH_SEPARATOR . SMARTY_SYSPLUGINS_DIR) !== false
) {
$registeredAutoLoadFunctions = spl_autoload_functions();
if (!isset($registeredAutoLoadFunctions[ 'spl_autoload' ])) {
spl_autoload_register();
}
} else {
self::register($prepend);
}
}
/**
* Registers Smarty_Autoloader as an SPL autoloader.
*
* @param bool $prepend Whether to prepend the autoloader or not.
*/
public static function register($prepend = false)
{
self::$SMARTY_DIR = defined('SMARTY_DIR') ? SMARTY_DIR : dirname(__FILE__) . DIRECTORY_SEPARATOR;
self::$SMARTY_SYSPLUGINS_DIR = defined('SMARTY_SYSPLUGINS_DIR') ? SMARTY_SYSPLUGINS_DIR :
self::$SMARTY_DIR . 'sysplugins' . DIRECTORY_SEPARATOR;
if (version_compare(phpversion(), '5.3.0', '>=')) {
spl_autoload_register(array(__CLASS__, 'autoload'), true, $prepend);
} else {
spl_autoload_register(array(__CLASS__, 'autoload'));
}
}
/**
* Handles auto loading of classes.
*
* @param string $class A class name.
*/
public static function autoload($class)
{
$_class = strtolower($class);
if (strpos($_class, 'smarty') !== 0) {
return;
}
$file = self::$SMARTY_SYSPLUGINS_DIR . $_class . '.php';
if (is_file($file)) {
include $file;
} else if (isset(self::$rootClasses[ $_class ])) {
$file = self::$SMARTY_DIR . self::$rootClasses[ $_class ];
if (is_file($file)) {
include $file;
}
}
return;
}
}

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,455 @@
<?php
/**
* Project: Smarty: the PHP compiling template engine
* File: SmartyBC.class.php
* SVN: $Id: $
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
* This library 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
* Lesser General Public License for more details.
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
* For questions, help, comments, discussion, etc., please join the
* Smarty mailing list. Send a blank e-mail to
* smarty-discussion-subscribe@googlegroups.com
*
* @link http://www.smarty.net/
* @copyright 2008 New Digital Group, Inc.
* @author Monte Ohrt <monte at ohrt dot com>
* @author Uwe Tews
* @author Rodney Rehm
* @package Smarty
*/
/**
* @ignore
*/
require_once(dirname(__FILE__) . '/Smarty.class.php');
/**
* Smarty Backward Compatibility Wrapper Class
*
* @package Smarty
*/
class SmartyBC extends Smarty
{
/**
* Smarty 2 BC
*
* @var string
*/
public $_version = self::SMARTY_VERSION;
/**
* This is an array of directories where trusted php scripts reside.
*
* @var array
*/
public $trusted_dir = array();
/**
* Initialize new SmartyBC object
*
*/
public function __construct()
{
parent::__construct();
}
/**
* wrapper for assign_by_ref
*
* @param string $tpl_var the template variable name
* @param mixed &$value the referenced value to assign
*/
public function assign_by_ref($tpl_var, &$value)
{
$this->assignByRef($tpl_var, $value);
}
/**
* wrapper for append_by_ref
*
* @param string $tpl_var the template variable name
* @param mixed &$value the referenced value to append
* @param boolean $merge flag if array elements shall be merged
*/
public function append_by_ref($tpl_var, &$value, $merge = false)
{
$this->appendByRef($tpl_var, $value, $merge);
}
/**
* clear the given assigned template variable.
*
* @param string $tpl_var the template variable to clear
*/
public function clear_assign($tpl_var)
{
$this->clearAssign($tpl_var);
}
/**
* Registers custom function to be used in templates
*
* @param string $function the name of the template function
* @param string $function_impl the name of the PHP function to register
* @param bool $cacheable
* @param mixed $cache_attrs
*/
public function register_function($function, $function_impl, $cacheable = true, $cache_attrs = null)
{
$this->registerPlugin('function', $function, $function_impl, $cacheable, $cache_attrs);
}
/**
* Unregister custom function
*
* @param string $function name of template function
*/
public function unregister_function($function)
{
$this->unregisterPlugin('function', $function);
}
/**
* Registers object to be used in templates
*
* @param string $object name of template object
* @param object $object_impl the referenced PHP object to register
* @param array $allowed list of allowed methods (empty = all)
* @param boolean $smarty_args smarty argument format, else traditional
* @param array $block_methods list of methods that are block format
*
* @throws SmartyException
* @internal param array $block_functs list of methods that are block format
*/
public function register_object($object, $object_impl, $allowed = array(), $smarty_args = true,
$block_methods = array())
{
settype($allowed, 'array');
settype($smarty_args, 'boolean');
$this->registerObject($object, $object_impl, $allowed, $smarty_args, $block_methods);
}
/**
* Unregister object
*
* @param string $object name of template object
*/
public function unregister_object($object)
{
$this->unregisterObject($object);
}
/**
* Registers block function to be used in templates
*
* @param string $block name of template block
* @param string $block_impl PHP function to register
* @param bool $cacheable
* @param mixed $cache_attrs
*/
public function register_block($block, $block_impl, $cacheable = true, $cache_attrs = null)
{
$this->registerPlugin('block', $block, $block_impl, $cacheable, $cache_attrs);
}
/**
* Unregister block function
*
* @param string $block name of template function
*/
public function unregister_block($block)
{
$this->unregisterPlugin('block', $block);
}
/**
* Registers compiler function
*
* @param string $function name of template function
* @param string $function_impl name of PHP function to register
* @param bool $cacheable
*/
public function register_compiler_function($function, $function_impl, $cacheable = true)
{
$this->registerPlugin('compiler', $function, $function_impl, $cacheable);
}
/**
* Unregister compiler function
*
* @param string $function name of template function
*/
public function unregister_compiler_function($function)
{
$this->unregisterPlugin('compiler', $function);
}
/**
* Registers modifier to be used in templates
*
* @param string $modifier name of template modifier
* @param string $modifier_impl name of PHP function to register
*/
public function register_modifier($modifier, $modifier_impl)
{
$this->registerPlugin('modifier', $modifier, $modifier_impl);
}
/**
* Unregister modifier
*
* @param string $modifier name of template modifier
*/
public function unregister_modifier($modifier)
{
$this->unregisterPlugin('modifier', $modifier);
}
/**
* Registers a resource to fetch a template
*
* @param string $type name of resource
* @param array $functions array of functions to handle resource
*/
public function register_resource($type, $functions)
{
$this->registerResource($type, $functions);
}
/**
* Unregister a resource
*
* @param string $type name of resource
*/
public function unregister_resource($type)
{
$this->unregisterResource($type);
}
/**
* Registers a prefilter function to apply
* to a template before compiling
*
* @param callable $function
*/
public function register_prefilter($function)
{
$this->registerFilter('pre', $function);
}
/**
* Unregister a prefilter function
*
* @param callable $function
*/
public function unregister_prefilter($function)
{
$this->unregisterFilter('pre', $function);
}
/**
* Registers a postfilter function to apply
* to a compiled template after compilation
*
* @param callable $function
*/
public function register_postfilter($function)
{
$this->registerFilter('post', $function);
}
/**
* Unregister a postfilter function
*
* @param callable $function
*/
public function unregister_postfilter($function)
{
$this->unregisterFilter('post', $function);
}
/**
* Registers an output filter function to apply
* to a template output
*
* @param callable $function
*/
public function register_outputfilter($function)
{
$this->registerFilter('output', $function);
}
/**
* Unregister an outputfilter function
*
* @param callable $function
*/
public function unregister_outputfilter($function)
{
$this->unregisterFilter('output', $function);
}
/**
* load a filter of specified type and name
*
* @param string $type filter type
* @param string $name filter name
*/
public function load_filter($type, $name)
{
$this->loadFilter($type, $name);
}
/**
* clear cached content for the given template and cache id
*
* @param string $tpl_file name of template file
* @param string $cache_id name of cache_id
* @param string $compile_id name of compile_id
* @param string $exp_time expiration time
*
* @return boolean
*/
public function clear_cache($tpl_file = null, $cache_id = null, $compile_id = null, $exp_time = null)
{
return $this->clearCache($tpl_file, $cache_id, $compile_id, $exp_time);
}
/**
* clear the entire contents of cache (all templates)
*
* @param string $exp_time expire time
*
* @return boolean
*/
public function clear_all_cache($exp_time = null)
{
return $this->clearCache(null, null, null, $exp_time);
}
/**
* test to see if valid cache exists for this template
*
* @param string $tpl_file name of template file
* @param string $cache_id
* @param string $compile_id
*
* @return boolean
*/
public function is_cached($tpl_file, $cache_id = null, $compile_id = null)
{
return $this->isCached($tpl_file, $cache_id, $compile_id);
}
/**
* clear all the assigned template variables.
*/
public function clear_all_assign()
{
$this->clearAllAssign();
}
/**
* clears compiled version of specified template resource,
* or all compiled template files if one is not specified.
* This function is for advanced use only, not normally needed.
*
* @param string $tpl_file
* @param string $compile_id
* @param string $exp_time
*
* @return boolean results of {@link smarty_core_rm_auto()}
*/
public function clear_compiled_tpl($tpl_file = null, $compile_id = null, $exp_time = null)
{
return $this->clearCompiledTemplate($tpl_file, $compile_id, $exp_time);
}
/**
* Checks whether requested template exists.
*
* @param string $tpl_file
*
* @return boolean
*/
public function template_exists($tpl_file)
{
return $this->templateExists($tpl_file);
}
/**
* Returns an array containing template variables
*
* @param string $name
*
* @return array
*/
public function get_template_vars($name = null)
{
return $this->getTemplateVars($name);
}
/**
* Returns an array containing config variables
*
* @param string $name
*
* @return array
*/
public function get_config_vars($name = null)
{
return $this->getConfigVars($name);
}
/**
* load configuration values
*
* @param string $file
* @param string $section
* @param string $scope
*/
public function config_load($file, $section = null, $scope = 'global')
{
$this->ConfigLoad($file, $section, $scope);
}
/**
* return a reference to a registered object
*
* @param string $name
*
* @return object
*/
public function get_registered_object($name)
{
return $this->getRegisteredObject($name);
}
/**
* clear configuration values
*
* @param string $var
*/
public function clear_config($var = null)
{
$this->clearConfig($var);
}
/**
* trigger Smarty error
*
* @param string $error_msg
* @param integer $error_type
*/
public function trigger_error($error_msg, $error_type = E_USER_WARNING)
{
trigger_error("Smarty error: $error_msg", $error_type);
}
}

View File

@@ -0,0 +1,160 @@
{capture name='_smarty_debug' assign=debug_output}
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en">
<head>
<title>Smarty Debug Console</title>
<style type="text/css">
{literal}
body, h1, h2, h3, td, th, p {
font-family: sans-serif;
font-weight: normal;
font-size: 0.9em;
margin: 1px;
padding: 0;
}
h1 {
margin: 0;
text-align: left;
padding: 2px;
background-color: #f0c040;
color: black;
font-weight: bold;
font-size: 1.2em;
}
h2 {
background-color: #9B410E;
color: white;
text-align: left;
font-weight: bold;
padding: 2px;
border-top: 1px solid black;
}
h3 {
text-align: left;
font-weight: bold;
color: black;
font-size: 0.7em;
padding: 2px;
}
body {
background: black;
}
p, table, div {
background: #f0ead8;
}
p {
margin: 0;
font-style: italic;
text-align: center;
}
table {
width: 100%;
}
th, td {
font-family: monospace;
vertical-align: top;
text-align: left;
}
td {
color: green;
}
.odd {
background-color: #eeeeee;
}
.even {
background-color: #fafafa;
}
.exectime {
font-size: 0.8em;
font-style: italic;
}
#bold div {
color: black;
font-weight: bold;
}
#blue h3 {
color: blue;
}
#normal div {
color: black;
font-weight: normal;
}
#table_assigned_vars th {
color: blue;
font-weight: bold;
}
#table_config_vars th {
color: maroon;
}
{/literal}
</style>
</head>
<body>
<h1>Smarty {Smarty::SMARTY_VERSION} Debug Console
- {if isset($template_name)}{$template_name|debug_print_var nofilter} {/if}{if !empty($template_data)}Total Time {$execution_time|string_format:"%.5f"}{/if}</h1>
{if !empty($template_data)}
<h2>included templates &amp; config files (load time in seconds)</h2>
<div>
{foreach $template_data as $template}
<font color=brown>{$template.name}</font>
<br>&nbsp;&nbsp;<span class="exectime">
(compile {$template['compile_time']|string_format:"%.5f"}) (render {$template['render_time']|string_format:"%.5f"}) (cache {$template['cache_time']|string_format:"%.5f"})
</span>
<br>
{/foreach}
</div>
{/if}
<h2>assigned template variables</h2>
<table id="table_assigned_vars">
{foreach $assigned_vars as $vars}
<tr class="{if $vars@iteration % 2 eq 0}odd{else}even{/if}">
<td><h3><font color=blue>${$vars@key}</font></h3>
{if isset($vars['nocache'])}<b>Nocache</b></br>{/if}
{if isset($vars['scope'])}<b>Origin:</b> {$vars['scope']|debug_print_var nofilter}{/if}
</td>
<td><h3>Value</h3>{$vars['value']|debug_print_var:10:80 nofilter}</td>
<td>{if isset($vars['attributes'])}<h3>Attributes</h3>{$vars['attributes']|debug_print_var nofilter} {/if}</td>
{/foreach}
</table>
<h2>assigned config file variables</h2>
<table id="table_config_vars">
{foreach $config_vars as $vars}
<tr class="{if $vars@iteration % 2 eq 0}odd{else}even{/if}">
<td><h3><font color=blue>#{$vars@key}#</font></h3>
{if isset($vars['scope'])}<b>Origin:</b> {$vars['scope']|debug_print_var nofilter}{/if}
</td>
<td>{$vars['value']|debug_print_var:10:80 nofilter}</td>
</tr>
{/foreach}
</table>
</body>
</html>
{/capture}
<script type="text/javascript">
{$id = '__Smarty__'}
{if $display_mode}{$id = "$offset$template_name"|md5}{/if}
_smarty_console = window.open("", "console{$id}", "width=1024,height=600,left={$offset},top={$offset},resizable,scrollbars=yes");
_smarty_console.document.write("{$debug_output|escape:'javascript' nofilter}");
_smarty_console.document.close();
</script>

View File

@@ -0,0 +1,120 @@
<?php
/**
* smarty-gettext.php - Gettext support for smarty
*
* ------------------------------------------------------------------------- *
* This library is free software; you can redistribute it and/or *
* modify it under the terms of the GNU Lesser General Public *
* License as published by the Free Software Foundation; either *
* version 2.1 of the License, or (at your option) any later version. *
* *
* This library 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 *
* Lesser General Public License for more details. *
* *
* You should have received a copy of the GNU Lesser General Public *
* License along with this library; if not, write to the Free Software *
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA *
* ------------------------------------------------------------------------- *
*
* To register as a smarty block function named 't', use:
* $smarty->register_block('t', 'smarty_translate');
*
* @package smarty-gettext
* @version $Id: block.t.php 4737 2013-12-11 06:29:51Z gullevek $
* @link http://smarty-gettext.sf.net/
* @author Sagi Bashari <sagi@boom.org.il>
* @copyright 2004 Sagi Bashari
*/
/**
* Replace arguments in a string with their values. Arguments are represented by % followed by their number.
*
* @param string Source string
* @param mixed Arguments, can be passed in an array or through single variables.
* @returns string Modified string
*/
function strarg($str)
{
$tr = array();
$p = 0;
for ($i=1; $i < func_num_args(); $i++) {
$arg = func_get_arg($i);
if (is_array($arg)) {
foreach ($arg as $aarg) {
$tr['%'.++$p] = $aarg;
}
} else {
$tr['%'.++$p] = $arg;
}
}
return strtr($str, $tr);
}
/**
* Smarty block function, provides gettext support for smarty.
*
* The block content is the text that should be translated.
*
* Any parameter that is sent to the function will be represented as %n in the translation text,
* where n is 1 for the first parameter. The following parameters are reserved:
* - escape - sets escape mode:
* - 'html' for HTML escaping, this is the default.
* - 'js' for javascript escaping.
* - 'no'/'off'/0 - turns off escaping
* - plural - The plural version of the text (2nd parameter of ngettext())
* - count - The item count for plural mode (3rd parameter of ngettext())
*/
// cs modified: __ calls instead of direct gettext calls
function smarty_block_t($params, $text, $template, &$repeat)
{
if ($text) {
$text = stripslashes($text);
// set escape mode
if (isset($params['escape'])) {
$escape = $params['escape'];
unset($params['escape']);
}
// set plural version
if (isset($params['plural'])) {
$plural = $params['plural'];
unset($params['plural']);
// set count
if (isset($params['count'])) {
$count = $params['count'];
unset($params['count']);
}
}
// use plural if required parameters are set
if (isset($count) && isset($plural)) {
$text = $template->l10n->__ngettext($text, $plural, $count);
} else { // use normal
$text = $template->l10n->__($text);
}
// run strarg if there are parameters
if (count($params)) {
$text = strarg($text, $params);
}
if (!isset($escape) || $escape == 'html') { // html escape, default
$text = nl2br(htmlspecialchars($text));
} elseif (isset($escape) && ($escape == 'javascript' || $escape == 'js')) { // javascript escape
$text = str_replace('\'','\\\'',stripslashes($text));
}
return $text;
}
}
?>

View File

@@ -0,0 +1,112 @@
<?php
/**
* Smarty plugin to format text blocks
*
* @package Smarty
* @subpackage PluginsBlock
*/
/**
* Smarty {textformat}{/textformat} block plugin
* Type: block function<br>
* Name: textformat<br>
* Purpose: format text a certain way with preset styles
* or custom wrap/indent settings<br>
* Params:
* <pre>
* - style - string (email)
* - indent - integer (0)
* - wrap - integer (80)
* - wrap_char - string ("\n")
* - indent_char - string (" ")
* - wrap_boundary - boolean (true)
* </pre>
*
* @link http://www.smarty.net/manual/en/language.function.textformat.php {textformat}
* (Smarty online manual)
*
* @param array $params parameters
* @param string $content contents of the block
* @param Smarty_Internal_Template $template template object
* @param boolean &$repeat repeat flag
*
* @return string content re-formatted
* @author Monte Ohrt <monte at ohrt dot com>
*/
function smarty_block_textformat($params, $content, $template, &$repeat)
{
if (is_null($content)) {
return;
}
$style = null;
$indent = 0;
$indent_first = 0;
$indent_char = ' ';
$wrap = 80;
$wrap_char = "\n";
$wrap_cut = false;
$assign = null;
foreach ($params as $_key => $_val) {
switch ($_key) {
case 'style':
case 'indent_char':
case 'wrap_char':
case 'assign':
$$_key = (string) $_val;
break;
case 'indent':
case 'indent_first':
case 'wrap':
$$_key = (int) $_val;
break;
case 'wrap_cut':
$$_key = (bool) $_val;
break;
default:
trigger_error("textformat: unknown attribute '$_key'");
}
}
if ($style == 'email') {
$wrap = 72;
}
// split into paragraphs
$_paragraphs = preg_split('![\r\n]{2}!', $content);
foreach ($_paragraphs as &$_paragraph) {
if (!$_paragraph) {
continue;
}
// convert mult. spaces & special chars to single space
$_paragraph =
preg_replace(array('!\s+!' . Smarty::$_UTF8_MODIFIER, '!(^\s+)|(\s+$)!' . Smarty::$_UTF8_MODIFIER),
array(' ', ''), $_paragraph);
// indent first line
if ($indent_first > 0) {
$_paragraph = str_repeat($indent_char, $indent_first) . $_paragraph;
}
// wordwrap sentences
if (Smarty::$_MBSTRING) {
require_once(SMARTY_PLUGINS_DIR . 'shared.mb_wordwrap.php');
$_paragraph = smarty_mb_wordwrap($_paragraph, $wrap - $indent, $wrap_char, $wrap_cut);
} else {
$_paragraph = wordwrap($_paragraph, $wrap - $indent, $wrap_char, $wrap_cut);
}
// indent lines
if ($indent > 0) {
$_paragraph = preg_replace('!^!m', str_repeat($indent_char, $indent), $_paragraph);
}
}
$_output = implode($wrap_char . $wrap_char, $_paragraphs);
if ($assign) {
$template->assign($assign, $_output);
} else {
return $_output;
}
}

View File

@@ -0,0 +1,73 @@
<?php
/**
* Smarty plugin
*
* @package Smarty
* @subpackage PluginsFunction
*/
/**
* Smarty {counter} function plugin
* Type: function<br>
* Name: counter<br>
* Purpose: print out a counter value
*
* @author Monte Ohrt <monte at ohrt dot com>
* @link http://www.smarty.net/manual/en/language.function.counter.php {counter}
* (Smarty online manual)
*
* @param array $params parameters
* @param Smarty_Internal_Template $template template object
*
* @return string|null
*/
function smarty_function_counter($params, $template)
{
static $counters = array();
$name = (isset($params[ 'name' ])) ? $params[ 'name' ] : 'default';
if (!isset($counters[ $name ])) {
$counters[ $name ] = array('start' => 1, 'skip' => 1, 'direction' => 'up', 'count' => 1);
}
$counter =& $counters[ $name ];
if (isset($params[ 'start' ])) {
$counter[ 'start' ] = $counter[ 'count' ] = (int) $params[ 'start' ];
}
if (!empty($params[ 'assign' ])) {
$counter[ 'assign' ] = $params[ 'assign' ];
}
if (isset($counter[ 'assign' ])) {
$template->assign($counter[ 'assign' ], $counter[ 'count' ]);
}
if (isset($params[ 'print' ])) {
$print = (bool) $params[ 'print' ];
} else {
$print = empty($counter[ 'assign' ]);
}
if ($print) {
$retval = $counter[ 'count' ];
} else {
$retval = null;
}
if (isset($params[ 'skip' ])) {
$counter[ 'skip' ] = $params[ 'skip' ];
}
if (isset($params[ 'direction' ])) {
$counter[ 'direction' ] = $params[ 'direction' ];
}
if ($counter[ 'direction' ] == "down") {
$counter[ 'count' ] -= $counter[ 'skip' ];
} else {
$counter[ 'count' ] += $counter[ 'skip' ];
}
return $retval;
}

View File

@@ -0,0 +1,105 @@
<?php
/**
* Smarty plugin
*
* @package Smarty
* @subpackage PluginsFunction
*/
/**
* Smarty {cycle} function plugin
* Type: function<br>
* Name: cycle<br>
* Date: May 3, 2002<br>
* Purpose: cycle through given values<br>
* Params:
* <pre>
* - name - name of cycle (optional)
* - values - comma separated list of values to cycle, or an array of values to cycle
* (this can be left out for subsequent calls)
* - reset - boolean - resets given var to true
* - print - boolean - print var or not. default is true
* - advance - boolean - whether or not to advance the cycle
* - delimiter - the value delimiter, default is ","
* - assign - boolean, assigns to template var instead of printed.
* </pre>
* Examples:<br>
* <pre>
* {cycle values="#eeeeee,#d0d0d0d"}
* {cycle name=row values="one,two,three" reset=true}
* {cycle name=row}
* </pre>
*
* @link http://www.smarty.net/manual/en/language.function.cycle.php {cycle}
* (Smarty online manual)
* @author Monte Ohrt <monte at ohrt dot com>
* @author credit to Mark Priatel <mpriatel@rogers.com>
* @author credit to Gerard <gerard@interfold.com>
* @author credit to Jason Sweat <jsweat_php@yahoo.com>
* @version 1.3
*
* @param array $params parameters
* @param Smarty_Internal_Template $template template object
*
* @return string|null
*/
function smarty_function_cycle($params, $template)
{
static $cycle_vars;
$name = (empty($params[ 'name' ])) ? 'default' : $params[ 'name' ];
$print = (isset($params[ 'print' ])) ? (bool) $params[ 'print' ] : true;
$advance = (isset($params[ 'advance' ])) ? (bool) $params[ 'advance' ] : true;
$reset = (isset($params[ 'reset' ])) ? (bool) $params[ 'reset' ] : false;
if (!isset($params[ 'values' ])) {
if (!isset($cycle_vars[ $name ][ 'values' ])) {
trigger_error("cycle: missing 'values' parameter");
return;
}
} else {
if (isset($cycle_vars[ $name ][ 'values' ]) && $cycle_vars[ $name ][ 'values' ] != $params[ 'values' ]) {
$cycle_vars[ $name ][ 'index' ] = 0;
}
$cycle_vars[ $name ][ 'values' ] = $params[ 'values' ];
}
if (isset($params[ 'delimiter' ])) {
$cycle_vars[ $name ][ 'delimiter' ] = $params[ 'delimiter' ];
} elseif (!isset($cycle_vars[ $name ][ 'delimiter' ])) {
$cycle_vars[ $name ][ 'delimiter' ] = ',';
}
if (is_array($cycle_vars[ $name ][ 'values' ])) {
$cycle_array = $cycle_vars[ $name ][ 'values' ];
} else {
$cycle_array = explode($cycle_vars[ $name ][ 'delimiter' ], $cycle_vars[ $name ][ 'values' ]);
}
if (!isset($cycle_vars[ $name ][ 'index' ]) || $reset) {
$cycle_vars[ $name ][ 'index' ] = 0;
}
if (isset($params[ 'assign' ])) {
$print = false;
$template->assign($params[ 'assign' ], $cycle_array[ $cycle_vars[ $name ][ 'index' ] ]);
}
if ($print) {
$retval = $cycle_array[ $cycle_vars[ $name ][ 'index' ] ];
} else {
$retval = null;
}
if ($advance) {
if ($cycle_vars[ $name ][ 'index' ] >= count($cycle_array) - 1) {
$cycle_vars[ $name ][ 'index' ] = 0;
} else {
$cycle_vars[ $name ][ 'index' ] ++;
}
}
return $retval;
}

View File

@@ -0,0 +1,221 @@
<?php
/**
* Smarty plugin
*
* @package Smarty
* @subpackage PluginsFunction
*/
/**
* Smarty {fetch} plugin
* Type: function<br>
* Name: fetch<br>
* Purpose: fetch file, web or ftp data and display results
*
* @link http://www.smarty.net/manual/en/language.function.fetch.php {fetch}
* (Smarty online manual)
* @author Monte Ohrt <monte at ohrt dot com>
*
* @param array $params parameters
* @param Smarty_Internal_Template $template template object
*
* @throws SmartyException
* @return string|null if the assign parameter is passed, Smarty assigns the result to a template variable
*/
function smarty_function_fetch($params, $template)
{
if (empty($params[ 'file' ])) {
trigger_error("[plugin] fetch parameter 'file' cannot be empty", E_USER_NOTICE);
return;
}
// strip file protocol
if (stripos($params[ 'file' ], 'file://') === 0) {
$params[ 'file' ] = substr($params[ 'file' ], 7);
}
$protocol = strpos($params[ 'file' ], '://');
if ($protocol !== false) {
$protocol = strtolower(substr($params[ 'file' ], 0, $protocol));
}
if (isset($template->smarty->security_policy)) {
if ($protocol) {
// remote resource (or php stream, …)
if (!$template->smarty->security_policy->isTrustedUri($params[ 'file' ])) {
return;
}
} else {
// local file
if (!$template->smarty->security_policy->isTrustedResourceDir($params[ 'file' ])) {
return;
}
}
}
$content = '';
if ($protocol == 'http') {
// http fetch
if ($uri_parts = parse_url($params[ 'file' ])) {
// set defaults
$host = $server_name = $uri_parts[ 'host' ];
$timeout = 30;
$accept = "image/gif, image/x-xbitmap, image/jpeg, image/pjpeg, */*";
$agent = "Smarty Template Engine " . Smarty::SMARTY_VERSION;
$referer = "";
$uri = !empty($uri_parts[ 'path' ]) ? $uri_parts[ 'path' ] : '/';
$uri .= !empty($uri_parts[ 'query' ]) ? '?' . $uri_parts[ 'query' ] : '';
$_is_proxy = false;
if (empty($uri_parts[ 'port' ])) {
$port = 80;
} else {
$port = $uri_parts[ 'port' ];
}
if (!empty($uri_parts[ 'user' ])) {
$user = $uri_parts[ 'user' ];
}
if (!empty($uri_parts[ 'pass' ])) {
$pass = $uri_parts[ 'pass' ];
}
// loop through parameters, setup headers
foreach ($params as $param_key => $param_value) {
switch ($param_key) {
case "file":
case "assign":
case "assign_headers":
break;
case "user":
if (!empty($param_value)) {
$user = $param_value;
}
break;
case "pass":
if (!empty($param_value)) {
$pass = $param_value;
}
break;
case "accept":
if (!empty($param_value)) {
$accept = $param_value;
}
break;
case "header":
if (!empty($param_value)) {
if (!preg_match('![\w\d-]+: .+!', $param_value)) {
trigger_error("[plugin] invalid header format '" . $param_value . "'", E_USER_NOTICE);
return;
} else {
$extra_headers[] = $param_value;
}
}
break;
case "proxy_host":
if (!empty($param_value)) {
$proxy_host = $param_value;
}
break;
case "proxy_port":
if (!preg_match('!\D!', $param_value)) {
$proxy_port = (int) $param_value;
} else {
trigger_error("[plugin] invalid value for attribute '" . $param_key . "'", E_USER_NOTICE);
return;
}
break;
case "agent":
if (!empty($param_value)) {
$agent = $param_value;
}
break;
case "referer":
if (!empty($param_value)) {
$referer = $param_value;
}
break;
case "timeout":
if (!preg_match('!\D!', $param_value)) {
$timeout = (int) $param_value;
} else {
trigger_error("[plugin] invalid value for attribute '" . $param_key . "'", E_USER_NOTICE);
return;
}
break;
default:
trigger_error("[plugin] unrecognized attribute '" . $param_key . "'", E_USER_NOTICE);
return;
}
}
if (!empty($proxy_host) && !empty($proxy_port)) {
$_is_proxy = true;
$fp = fsockopen($proxy_host, $proxy_port, $errno, $errstr, $timeout);
} else {
$fp = fsockopen($server_name, $port, $errno, $errstr, $timeout);
}
if (!$fp) {
trigger_error("[plugin] unable to fetch: $errstr ($errno)", E_USER_NOTICE);
return;
} else {
if ($_is_proxy) {
fputs($fp, 'GET ' . $params[ 'file' ] . " HTTP/1.0\r\n");
} else {
fputs($fp, "GET $uri HTTP/1.0\r\n");
}
if (!empty($host)) {
fputs($fp, "Host: $host\r\n");
}
if (!empty($accept)) {
fputs($fp, "Accept: $accept\r\n");
}
if (!empty($agent)) {
fputs($fp, "User-Agent: $agent\r\n");
}
if (!empty($referer)) {
fputs($fp, "Referer: $referer\r\n");
}
if (isset($extra_headers) && is_array($extra_headers)) {
foreach ($extra_headers as $curr_header) {
fputs($fp, $curr_header . "\r\n");
}
}
if (!empty($user) && !empty($pass)) {
fputs($fp, "Authorization: BASIC " . base64_encode("$user:$pass") . "\r\n");
}
fputs($fp, "\r\n");
while (!feof($fp)) {
$content .= fgets($fp, 4096);
}
fclose($fp);
$csplit = preg_split("!\r\n\r\n!", $content, 2);
$content = $csplit[ 1 ];
if (!empty($params[ 'assign_headers' ])) {
$template->assign($params[ 'assign_headers' ], preg_split("!\r\n!", $csplit[ 0 ]));
}
}
} else {
trigger_error("[plugin fetch] unable to parse URL, check syntax", E_USER_NOTICE);
return;
}
} else {
$content = @file_get_contents($params[ 'file' ]);
if ($content === false) {
throw new SmartyException("{fetch} cannot read resource '" . $params[ 'file' ] . "'");
}
}
if (!empty($params[ 'assign' ])) {
$template->assign($params[ 'assign' ], $content);
} else {
return $content;
}
}

View File

@@ -0,0 +1,256 @@
<?php
/**
* Smarty plugin
*
* @package Smarty
* @subpackage PluginsFunction
*/
/**
* Smarty {html_checkboxes} function plugin
* File: function.html_checkboxes.php<br>
* Type: function<br>
* Name: html_checkboxes<br>
* Date: 24.Feb.2003<br>
* Purpose: Prints out a list of checkbox input types<br>
* Examples:
* <pre>
* {html_checkboxes values=$ids output=$names}
* {html_checkboxes values=$ids name='box' separator='<br>' output=$names}
* {html_checkboxes values=$ids checked=$checked separator='<br>' output=$names}
* </pre>
* Params:
* <pre>
* - name (optional) - string default "checkbox"
* - values (required) - array
* - options (optional) - associative array
* - checked (optional) - array default not set
* - separator (optional) - ie <br> or &nbsp;
* - output (optional) - the output next to each checkbox
* - assign (optional) - assign the output as an array to this variable
* - escape (optional) - escape the content (not value), defaults to true
* </pre>
*
* @link http://www.smarty.net/manual/en/language.function.html.checkboxes.php {html_checkboxes}
* (Smarty online manual)
* @author Christopher Kvarme <christopher.kvarme@flashjab.com>
* @author credits to Monte Ohrt <monte at ohrt dot com>
* @version 1.0
*
* @param array $params parameters
* @param object $template template object
*
* @return string
* @uses smarty_function_escape_special_chars()
*/
function smarty_function_html_checkboxes($params, $template)
{
require_once(SMARTY_PLUGINS_DIR . 'shared.escape_special_chars.php');
$name = 'checkbox';
$values = null;
$options = null;
$selected = array();
$separator = '';
$escape = true;
$labels = true;
$label_ids = false;
$output = null;
$pos = null;
$extra = '';
foreach ($params as $_key => $_val) {
switch ($_key) {
case 'name':
case 'separator':
$$_key = (string) $_val;
break;
case 'escape':
case 'labels':
case 'label_ids':
$$_key = (bool) $_val;
break;
case 'options':
$$_key = (array) $_val;
break;
case 'values':
case 'output':
$$_key = array_values((array) $_val);
break;
case 'checked':
case 'selected':
if (is_array($_val)) {
$selected = array();
foreach ($_val as $_sel) {
if (is_object($_sel)) {
if (method_exists($_sel, "__toString")) {
$_sel = smarty_function_escape_special_chars((string) $_sel->__toString());
} else {
trigger_error("html_checkboxes: selected attribute contains an object of class '" .
get_class($_sel) . "' without __toString() method", E_USER_NOTICE);
continue;
}
} else {
$_sel = smarty_function_escape_special_chars((string) $_sel);
}
$selected[ $_sel ] = true;
}
} elseif (is_object($_val)) {
if (method_exists($_val, "__toString")) {
$selected = smarty_function_escape_special_chars((string) $_val->__toString());
} else {
trigger_error("html_checkboxes: selected attribute is an object of class '" . get_class($_val) .
"' without __toString() method", E_USER_NOTICE);
}
} else {
$selected = smarty_function_escape_special_chars((string) $_val);
}
break;
case 'checkboxes':
trigger_error('html_checkboxes: the use of the "checkboxes" attribute is deprecated, use "options" instead',
E_USER_WARNING);
$options = (array) $_val;
break;
case 'assign':
break;
case 'pos':
$$_key = array_values((array)$_val);
break;
case 'strict':
break;
case 'disabled':
case 'readonly':
if (!empty($params[ 'strict' ])) {
if (!is_scalar($_val)) {
trigger_error("html_options: $_key attribute must be a scalar, only boolean true or string '$_key' will actually add the attribute",
E_USER_NOTICE);
}
if ($_val === true || $_val === $_key) {
$extra .= ' ' . $_key . '="' . smarty_function_escape_special_chars($_key) . '"';
}
break;
}
// omit break; to fall through!
default:
if (!is_array($_val)) {
$extra .= ' ' . $_key . '="' . smarty_function_escape_special_chars($_val) . '"';
} else {
trigger_error("html_checkboxes: extra attribute '$_key' cannot be an array", E_USER_NOTICE);
}
break;
}
}
if (!isset($options) && !isset($values)) {
return '';
} /* raise error here? */
$_html_result = array();
if (isset($options)) {
foreach ($options as $_key => $_val) {
$_pos = isset($pos[ $_key ]) ? $pos[ $_key ] : '';
$_html_result[] =
smarty_function_html_checkboxes_output($name, $_key, $_val, $selected, $extra, $separator, $labels,
$label_ids, $_pos, $escape);
}
} else {
foreach ($values as $_i => $_key) {
$_val = isset($output[ $_i ]) ? $output[ $_i ] : '';
$_pos = isset($pos[ $_i ]) ? $pos[ $_i ] : '';
$_html_result[] =
smarty_function_html_checkboxes_output($name, $_key, $_val, $selected, $extra, $separator, $labels,
$label_ids, $_pos, $escape);
}
}
if (!empty($params[ 'assign' ])) {
$template->assign($params[ 'assign' ], $_html_result);
} else {
return implode("\n", $_html_result);
}
}
function smarty_function_html_checkboxes_output($name, $value, $output, $selected, $extra, $separator, $labels,
$label_ids, $pos, $escape = true)
{
$_output = '';
if (is_object($value)) {
if (method_exists($value, "__toString")) {
$value = (string) $value->__toString();
} else {
trigger_error("html_options: value is an object of class '" . get_class($value) .
"' without __toString() method", E_USER_NOTICE);
return '';
}
} else {
$value = (string) $value;
}
if (is_object($output)) {
if (method_exists($output, "__toString")) {
$output = (string) $output->__toString();
} else {
trigger_error("html_options: output is an object of class '" . get_class($output) .
"' without __toString() method", E_USER_NOTICE);
return '';
}
} else {
$output = (string) $output;
}
if ($labels) {
if ($label_ids) {
$_id = smarty_function_escape_special_chars(preg_replace('![^\w\-\.]!' . Smarty::$_UTF8_MODIFIER, '_',
$name . '_' . $value));
$_output .= '<label for="' . $_id . '">';
} else {
$_output .= '<label>';
}
}
$name = smarty_function_escape_special_chars($name);
$value = smarty_function_escape_special_chars($value);
if ($escape) {
$output = smarty_function_escape_special_chars($output);
}
$_output .= '<input type="checkbox" name="' . $name . '[' . $pos . ']" value="' . $value . '"';
if ($labels && $label_ids) {
$_output .= ' id="' . $_id . '"';
}
if (is_array($selected)) {
if (isset($selected[ $value ])) {
$_output .= ' checked="checked"';
}
} elseif ($value === $selected) {
$_output .= ' checked="checked"';
}
$_output .= $extra . ' />' . $output;
if ($labels) {
$_output .= '</label>';
}
$_output .= $separator;
return $_output;
}

View File

@@ -0,0 +1,164 @@
<?php
/**
* Smarty plugin
*
* @package Smarty
* @subpackage PluginsFunction
*/
/**
* Smarty {html_image} function plugin
* Type: function<br>
* Name: html_image<br>
* Date: Feb 24, 2003<br>
* Purpose: format HTML tags for the image<br>
* Examples: {html_image file="/images/masthead.gif"}<br>
* Output: <img src="/images/masthead.gif" width=400 height=23><br>
* Params:
* <pre>
* - file - (required) - file (and path) of image
* - height - (optional) - image height (default actual height)
* - width - (optional) - image width (default actual width)
* - basedir - (optional) - base directory for absolute paths, default is environment variable DOCUMENT_ROOT
* - path_prefix - prefix for path output (optional, default empty)
* </pre>
*
* @link http://www.smarty.net/manual/en/language.function.html.image.php {html_image}
* (Smarty online manual)
* @author Monte Ohrt <monte at ohrt dot com>
* @author credits to Duda <duda@big.hu>
* @version 1.0
*
* @param array $params parameters
* @param Smarty_Internal_Template $template template object
*
* @throws SmartyException
* @return string
* @uses smarty_function_escape_special_chars()
*/
function smarty_function_html_image($params, $template)
{
require_once(SMARTY_PLUGINS_DIR . 'shared.escape_special_chars.php');
$alt = '';
$file = '';
$height = '';
$width = '';
$extra = '';
$prefix = '';
$suffix = '';
$path_prefix = '';
$basedir = isset($_SERVER[ 'DOCUMENT_ROOT' ]) ? $_SERVER[ 'DOCUMENT_ROOT' ] : '';
foreach ($params as $_key => $_val) {
switch ($_key) {
case 'file':
case 'height':
case 'width':
case 'dpi':
case 'path_prefix':
case 'basedir':
$$_key = $_val;
break;
case 'alt':
if (!is_array($_val)) {
$$_key = smarty_function_escape_special_chars($_val);
} else {
throw new SmartyException ("html_image: extra attribute '$_key' cannot be an array", E_USER_NOTICE);
}
break;
case 'link':
case 'href':
$prefix = '<a href="' . $_val . '">';
$suffix = '</a>';
break;
default:
if (!is_array($_val)) {
$extra .= ' ' . $_key . '="' . smarty_function_escape_special_chars($_val) . '"';
} else {
throw new SmartyException ("html_image: extra attribute '$_key' cannot be an array", E_USER_NOTICE);
}
break;
}
}
if (empty($file)) {
trigger_error("html_image: missing 'file' parameter", E_USER_NOTICE);
return;
}
if ($file[ 0 ] == '/') {
$_image_path = $basedir . $file;
} else {
$_image_path = $file;
}
// strip file protocol
if (stripos($params[ 'file' ], 'file://') === 0) {
$params[ 'file' ] = substr($params[ 'file' ], 7);
}
$protocol = strpos($params[ 'file' ], '://');
if ($protocol !== false) {
$protocol = strtolower(substr($params[ 'file' ], 0, $protocol));
}
if (isset($template->smarty->security_policy)) {
if ($protocol) {
// remote resource (or php stream, …)
if (!$template->smarty->security_policy->isTrustedUri($params[ 'file' ])) {
return;
}
} else {
// local file
if (!$template->smarty->security_policy->isTrustedResourceDir($_image_path)) {
return;
}
}
}
if (!isset($params[ 'width' ]) || !isset($params[ 'height' ])) {
// FIXME: (rodneyrehm) getimagesize() loads the complete file off a remote resource, use custom [jpg,png,gif]header reader!
if (!$_image_data = @getimagesize($_image_path)) {
if (!file_exists($_image_path)) {
trigger_error("html_image: unable to find '$_image_path'", E_USER_NOTICE);
return;
} elseif (!is_readable($_image_path)) {
trigger_error("html_image: unable to read '$_image_path'", E_USER_NOTICE);
return;
} else {
trigger_error("html_image: '$_image_path' is not a valid image file", E_USER_NOTICE);
return;
}
}
if (!isset($params[ 'width' ])) {
$width = $_image_data[ 0 ];
}
if (!isset($params[ 'height' ])) {
$height = $_image_data[ 1 ];
}
}
if (isset($params[ 'dpi' ])) {
if (strstr($_SERVER[ 'HTTP_USER_AGENT' ], 'Mac')) {
// FIXME: (rodneyrehm) wrong dpi assumption
// don't know who thought this up… even if it was true in 1998, it's definitely wrong in 2011.
$dpi_default = 72;
} else {
$dpi_default = 96;
}
$_resize = $dpi_default / $params[ 'dpi' ];
$width = round($width * $_resize);
$height = round($height * $_resize);
}
return $prefix . '<img src="' . $path_prefix . $file . '" alt="' . $alt . '" width="' . $width . '" height="' .
$height . '"' . $extra . ' />' . $suffix;
}

View File

@@ -0,0 +1,210 @@
<?php
/**
* Smarty plugin
*
* @package Smarty
* @subpackage PluginsFunction
*/
/**
* Smarty {html_options} function plugin
* Type: function<br>
* Name: html_options<br>
* Purpose: Prints the list of <option> tags generated from
* the passed parameters<br>
* Params:
* <pre>
* - name (optional) - string default "select"
* - values (required) - if no options supplied) - array
* - options (required) - if no values supplied) - associative array
* - selected (optional) - string default not set
* - output (required) - if not options supplied) - array
* - id (optional) - string default not set
* - class (optional) - string default not set
* </pre>
*
* @link http://www.smarty.net/manual/en/language.function.html.options.php {html_image}
* (Smarty online manual)
* @author Monte Ohrt <monte at ohrt dot com>
* @author Ralf Strehle (minor optimization) <ralf dot strehle at yahoo dot de>
*
* @param array $params parameters
*
* @return string
* @uses smarty_function_escape_special_chars()
*/
function smarty_function_html_options($params)
{
require_once(SMARTY_PLUGINS_DIR . 'shared.escape_special_chars.php');
$name = null;
$values = null;
$options = null;
$selected = null;
$output = null;
$id = null;
$class = null;
$label = true;
$extra = '';
foreach ($params as $_key => $_val) {
switch ($_key) {
case 'name':
case 'class':
case 'id':
$$_key = (string) $_val;
break;
case 'options':
$options = (array) $_val;
break;
case 'values':
case 'output':
$$_key = array_values((array) $_val);
break;
case 'selected':
if (is_array($_val)) {
$selected = array();
foreach ($_val as $_sel) {
if (is_object($_sel)) {
if (method_exists($_sel, "__toString")) {
$_sel = smarty_function_escape_special_chars((string) $_sel->__toString());
} else {
trigger_error("html_options: selected attribute contains an object of class '" .
get_class($_sel) . "' without __toString() method", E_USER_NOTICE);
continue;
}
} else {
$_sel = smarty_function_escape_special_chars((string) $_sel);
}
$selected[ $_sel ] = true;
}
} elseif (is_object($_val)) {
if (method_exists($_val, "__toString")) {
$selected = smarty_function_escape_special_chars((string) $_val->__toString());
} else {
trigger_error("html_options: selected attribute is an object of class '" . get_class($_val) .
"' without __toString() method", E_USER_NOTICE);
}
} else {
$selected = smarty_function_escape_special_chars((string) $_val);
}
break;
case 'label':
if ($_val == 'true' || $_val == 'false')
$$_key = (string)$_val;
break;
case 'strict':
break;
case 'disabled':
case 'readonly':
if (!empty($params[ 'strict' ])) {
if (!is_scalar($_val)) {
trigger_error("html_options: $_key attribute must be a scalar, only boolean true or string '$_key' will actually add the attribute",
E_USER_NOTICE);
}
if ($_val === true || $_val === $_key) {
$extra .= ' ' . $_key . '="' . smarty_function_escape_special_chars($_key) . '"';
}
break;
}
// omit break; to fall through!
default:
if (!is_array($_val)) {
$extra .= ' ' . $_key . '="' . smarty_function_escape_special_chars($_val) . '"';
} else {
trigger_error("html_options: extra attribute '$_key' cannot be an array", E_USER_NOTICE);
}
break;
}
}
if (!isset($options) && !isset($values)) {
/* raise error here? */
return '';
}
$_html_result = '';
$_idx = 0;
if (isset($options)) {
foreach ($options as $_key => $_val) {
$_html_result .= smarty_function_html_options_optoutput($_key, $_val, $selected, $id, $class, $label, $_idx);
}
} else {
foreach ($values as $_i => $_key) {
$_val = isset($output[ $_i ]) ? $output[ $_i ] : '';
$_html_result .= smarty_function_html_options_optoutput($_key, $_val, $selected, $id, $class, $label, $_idx);
}
}
if (!empty($name)) {
$_html_class = !empty($class) ? ' class="' . $class . '"' : '';
$_html_id = !empty($id) ? ' id="' . $id . '"' : '';
$_html_result =
'<select name="' . $name . '"' . $_html_class . $_html_id . $extra . '>' . "\n" . $_html_result .
'</select>' . "\n";
}
return $_html_result;
}
function smarty_function_html_options_optoutput($key, $value, $selected, $id, $class, $label, &$idx)
{
if (!is_array($value)) {
$_key = smarty_function_escape_special_chars($key);
$_html_result = '<option' . (($label == 'true') ? ' label="' . smarty_function_escape_special_chars($value) . '"' : '') . ' value="' . $_key . '"';
if (is_array($selected)) {
if (isset($selected[ $_key ])) {
$_html_result .= ' selected="selected"';
}
} elseif ($_key === $selected) {
$_html_result .= ' selected="selected"';
}
$_html_class = !empty($class) ? ' class="' . $class . ' option"' : '';
$_html_id = !empty($id) ? ' id="' . $id . '-' . $idx . '"' : '';
if (is_object($value)) {
if (method_exists($value, "__toString")) {
$value = smarty_function_escape_special_chars((string) $value->__toString());
} else {
trigger_error("html_options: value is an object of class '" . get_class($value) .
"' without __toString() method", E_USER_NOTICE);
return '';
}
} else {
$value = smarty_function_escape_special_chars((string) $value);
}
$_html_result .= $_html_class . $_html_id . '>' . $value . '</option>' . "\n";
$idx ++;
} else {
$_idx = 0;
$_html_result =
smarty_function_html_options_optgroup($key, $value, $selected, !empty($id) ? ($id . '-' . $idx) : null,
$class, $label, $_idx);
$idx ++;
}
return $_html_result;
}
function smarty_function_html_options_optgroup($key, $values, $selected, $id, $class, $label, &$idx)
{
$optgroup_html = '<optgroup label="' . smarty_function_escape_special_chars($key) . '">' . "\n";
foreach ($values as $key => $value) {
$optgroup_html .= smarty_function_html_options_optoutput($key, $value, $selected, $id, $class, $label, $idx);
}
$optgroup_html .= "</optgroup>\n";
return $optgroup_html;
}

View File

@@ -0,0 +1,232 @@
<?php
/**
* Smarty plugin
*
* @package Smarty
* @subpackage PluginsFunction
*/
/**
* Smarty {html_radios} function plugin
* File: function.html_radios.php<br>
* Type: function<br>
* Name: html_radios<br>
* Date: 24.Feb.2003<br>
* Purpose: Prints out a list of radio input types<br>
* Params:
* <pre>
* - name (optional) - string default "radio"
* - values (required) - array
* - options (required) - associative array
* - checked (optional) - array default not set
* - separator (optional) - ie <br> or &nbsp;
* - output (optional) - the output next to each radio button
* - assign (optional) - assign the output as an array to this variable
* - escape (optional) - escape the content (not value), defaults to true
* </pre>
* Examples:
* <pre>
* {html_radios values=$ids output=$names}
* {html_radios values=$ids name='box' separator='<br>' output=$names}
* {html_radios values=$ids checked=$checked separator='<br>' output=$names}
* </pre>
*
* @link http://smarty.php.net/manual/en/language.function.html.radios.php {html_radios}
* (Smarty online manual)
* @author Christopher Kvarme <christopher.kvarme@flashjab.com>
* @author credits to Monte Ohrt <monte at ohrt dot com>
* @version 1.0
*
* @param array $params parameters
* @param Smarty_Internal_Template $template template object
*
* @return string
* @uses smarty_function_escape_special_chars()
*/
function smarty_function_html_radios($params, $template)
{
require_once(SMARTY_PLUGINS_DIR . 'shared.escape_special_chars.php');
$name = 'radio';
$values = null;
$options = null;
$selected = null;
$separator = '';
$escape = true;
$labels = true;
$label_ids = false;
$output = null;
$extra = '';
foreach ($params as $_key => $_val) {
switch ($_key) {
case 'name':
case 'separator':
$$_key = (string) $_val;
break;
case 'checked':
case 'selected':
if (is_array($_val)) {
trigger_error('html_radios: the "' . $_key . '" attribute cannot be an array', E_USER_WARNING);
} elseif (is_object($_val)) {
if (method_exists($_val, "__toString")) {
$selected = smarty_function_escape_special_chars((string) $_val->__toString());
} else {
trigger_error("html_radios: selected attribute is an object of class '" . get_class($_val) .
"' without __toString() method", E_USER_NOTICE);
}
} else {
$selected = (string) $_val;
}
break;
case 'escape':
case 'labels':
case 'label_ids':
$$_key = (bool) $_val;
break;
case 'options':
$$_key = (array) $_val;
break;
case 'values':
case 'output':
$$_key = array_values((array) $_val);
break;
case 'radios':
trigger_error('html_radios: the use of the "radios" attribute is deprecated, use "options" instead',
E_USER_WARNING);
$options = (array) $_val;
break;
case 'assign':
break;
case 'strict':
break;
case 'disabled':
case 'readonly':
if (!empty($params[ 'strict' ])) {
if (!is_scalar($_val)) {
trigger_error("html_options: $_key attribute must be a scalar, only boolean true or string '$_key' will actually add the attribute",
E_USER_NOTICE);
}
if ($_val === true || $_val === $_key) {
$extra .= ' ' . $_key . '="' . smarty_function_escape_special_chars($_key) . '"';
}
break;
}
// omit break; to fall through!
default:
if (!is_array($_val)) {
$extra .= ' ' . $_key . '="' . smarty_function_escape_special_chars($_val) . '"';
} else {
trigger_error("html_radios: extra attribute '$_key' cannot be an array", E_USER_NOTICE);
}
break;
}
}
if (!isset($options) && !isset($values)) {
/* raise error here? */
return '';
}
$_html_result = array();
if (isset($options)) {
foreach ($options as $_key => $_val) {
$_html_result[] =
smarty_function_html_radios_output($name, $_key, $_val, $selected, $extra, $separator, $labels,
$label_ids, $escape);
}
} else {
foreach ($values as $_i => $_key) {
$_val = isset($output[ $_i ]) ? $output[ $_i ] : '';
$_html_result[] =
smarty_function_html_radios_output($name, $_key, $_val, $selected, $extra, $separator, $labels,
$label_ids, $escape);
}
}
if (!empty($params[ 'assign' ])) {
$template->assign($params[ 'assign' ], $_html_result);
} else {
return implode("\n", $_html_result);
}
}
function smarty_function_html_radios_output($name, $value, $output, $selected, $extra, $separator, $labels, $label_ids,
$escape)
{
$_output = '';
if (is_object($value)) {
if (method_exists($value, "__toString")) {
$value = (string) $value->__toString();
} else {
trigger_error("html_options: value is an object of class '" . get_class($value) .
"' without __toString() method", E_USER_NOTICE);
return '';
}
} else {
$value = (string) $value;
}
if (is_object($output)) {
if (method_exists($output, "__toString")) {
$output = (string) $output->__toString();
} else {
trigger_error("html_options: output is an object of class '" . get_class($output) .
"' without __toString() method", E_USER_NOTICE);
return '';
}
} else {
$output = (string) $output;
}
if ($labels) {
if ($label_ids) {
$_id = smarty_function_escape_special_chars(preg_replace('![^\w\-\.]!' . Smarty::$_UTF8_MODIFIER, '_',
$name . '_' . $value));
$_output .= '<label for="' . $_id . '">';
} else {
$_output .= '<label>';
}
}
$name = smarty_function_escape_special_chars($name);
$value = smarty_function_escape_special_chars($value);
if ($escape) {
$output = smarty_function_escape_special_chars($output);
}
$_output .= '<input type="radio" name="' . $name . '" value="' . $value . '"';
if ($labels && $label_ids) {
$_output .= ' id="' . $_id . '"';
}
if ($value === $selected) {
$_output .= ' checked="checked"';
}
$_output .= $extra . ' />' . $output;
if ($labels) {
$_output .= '</label>';
}
$_output .= $separator;
return $_output;
}

View File

@@ -0,0 +1,391 @@
<?php
/**
* Smarty plugin
*
* @package Smarty
* @subpackage PluginsFunction
*/
/**
* @ignore
*/
require_once(SMARTY_PLUGINS_DIR . 'shared.escape_special_chars.php');
/**
* @ignore
*/
require_once(SMARTY_PLUGINS_DIR . 'shared.make_timestamp.php');
/**
* Smarty {html_select_date} plugin
* Type: function<br>
* Name: html_select_date<br>
* Purpose: Prints the dropdowns for date selection.
* ChangeLog:
* <pre>
* - 1.0 initial release
* - 1.1 added support for +/- N syntax for begin
* and end year values. (Monte)
* - 1.2 added support for yyyy-mm-dd syntax for
* time value. (Jan Rosier)
* - 1.3 added support for choosing format for
* month values (Gary Loescher)
* - 1.3.1 added support for choosing format for
* day values (Marcus Bointon)
* - 1.3.2 support negative timestamps, force year
* dropdown to include given date unless explicitly set (Monte)
* - 1.3.4 fix behaviour of 0000-00-00 00:00:00 dates to match that
* of 0000-00-00 dates (cybot, boots)
* - 2.0 complete rewrite for performance,
* added attributes month_names, *_id
* </pre>
*
* @link http://www.smarty.net/manual/en/language.function.html.select.date.php {html_select_date}
* (Smarty online manual)
* @version 2.0
* @author Andrei Zmievski
* @author Monte Ohrt <monte at ohrt dot com>
* @author Rodney Rehm
*
* @param array $params parameters
*
* @return string
*/
function smarty_function_html_select_date($params)
{
// generate timestamps used for month names only
static $_month_timestamps = null;
static $_current_year = null;
if ($_month_timestamps === null) {
$_current_year = date('Y');
$_month_timestamps = array();
for ($i = 1; $i <= 12; $i ++) {
$_month_timestamps[ $i ] = mktime(0, 0, 0, $i, 1, 2000);
}
}
/* Default values. */
$prefix = "Date_";
$start_year = null;
$end_year = null;
$display_days = true;
$display_months = true;
$display_years = true;
$month_format = "%B";
/* Write months as numbers by default GL */
$month_value_format = "%m";
$day_format = "%02d";
/* Write day values using this format MB */
$day_value_format = "%d";
$year_as_text = false;
/* Display years in reverse order? Ie. 2000,1999,.... */
$reverse_years = false;
/* Should the select boxes be part of an array when returned from PHP?
e.g. setting it to "birthday", would create "birthday[Day]",
"birthday[Month]" & "birthday[Year]". Can be combined with prefix */
$field_array = null;
/* <select size>'s of the different <select> tags.
If not set, uses default dropdown. */
$day_size = null;
$month_size = null;
$year_size = null;
/* Unparsed attributes common to *ALL* the <select>/<input> tags.
An example might be in the template: all_extra ='class ="foo"'. */
$all_extra = null;
/* Separate attributes for the tags. */
$day_extra = null;
$month_extra = null;
$year_extra = null;
/* Order in which to display the fields.
"D" -> day, "M" -> month, "Y" -> year. */
$field_order = 'MDY';
/* String printed between the different fields. */
$field_separator = "\n";
$option_separator = "\n";
$time = null;
// $all_empty = null;
// $day_empty = null;
// $month_empty = null;
// $year_empty = null;
$extra_attrs = '';
$all_id = null;
$day_id = null;
$month_id = null;
$year_id = null;
foreach ($params as $_key => $_value) {
switch ($_key) {
case 'time':
if (!is_array($_value) && $_value !== null) {
$time = smarty_make_timestamp($_value);
}
break;
case 'month_names':
if (is_array($_value) && count($_value) == 12) {
$$_key = $_value;
} else {
trigger_error("html_select_date: month_names must be an array of 12 strings", E_USER_NOTICE);
}
break;
case 'prefix':
case 'field_array':
case 'start_year':
case 'end_year':
case 'day_format':
case 'day_value_format':
case 'month_format':
case 'month_value_format':
case 'day_size':
case 'month_size':
case 'year_size':
case 'all_extra':
case 'day_extra':
case 'month_extra':
case 'year_extra':
case 'field_order':
case 'field_separator':
case 'option_separator':
case 'all_empty':
case 'month_empty':
case 'day_empty':
case 'year_empty':
case 'all_id':
case 'month_id':
case 'day_id':
case 'year_id':
$$_key = (string) $_value;
break;
case 'display_days':
case 'display_months':
case 'display_years':
case 'year_as_text':
case 'reverse_years':
$$_key = (bool) $_value;
break;
default:
if (!is_array($_value)) {
$extra_attrs .= ' ' . $_key . '="' . smarty_function_escape_special_chars($_value) . '"';
} else {
trigger_error("html_select_date: extra attribute '$_key' cannot be an array", E_USER_NOTICE);
}
break;
}
}
// Note: date() is faster than strftime()
// Note: explode(date()) is faster than date() date() date()
if (isset($params[ 'time' ]) && is_array($params[ 'time' ])) {
if (isset($params[ 'time' ][ $prefix . 'Year' ])) {
// $_REQUEST[$field_array] given
foreach (array('Y' => 'Year', 'm' => 'Month', 'd' => 'Day') as $_elementKey => $_elementName) {
$_variableName = '_' . strtolower($_elementName);
$$_variableName =
isset($params[ 'time' ][ $prefix . $_elementName ]) ? $params[ 'time' ][ $prefix . $_elementName ] :
date($_elementKey);
}
} elseif (isset($params[ 'time' ][ $field_array ][ $prefix . 'Year' ])) {
// $_REQUEST given
foreach (array('Y' => 'Year', 'm' => 'Month', 'd' => 'Day') as $_elementKey => $_elementName) {
$_variableName = '_' . strtolower($_elementName);
$$_variableName = isset($params[ 'time' ][ $field_array ][ $prefix . $_elementName ]) ?
$params[ 'time' ][ $field_array ][ $prefix . $_elementName ] : date($_elementKey);
}
} else {
// no date found, use NOW
list($_year, $_month, $_day) = $time = explode('-', date('Y-m-d'));
}
} elseif ($time === null) {
if (array_key_exists('time', $params)) {
$_year = $_month = $_day = $time = null;
} else {
list($_year, $_month, $_day) = $time = explode('-', date('Y-m-d'));
}
} else {
list($_year, $_month, $_day) = $time = explode('-', date('Y-m-d', $time));
}
// make syntax "+N" or "-N" work with $start_year and $end_year
// Note preg_match('!^(\+|\-)\s*(\d+)$!', $end_year, $match) is slower than trim+substr
foreach (array('start', 'end') as $key) {
$key .= '_year';
$t = $$key;
if ($t === null) {
$$key = (int) $_current_year;
} elseif ($t[ 0 ] == '+') {
$$key = (int) ($_current_year + (int) trim(substr($t, 1)));
} elseif ($t[ 0 ] == '-') {
$$key = (int) ($_current_year - (int) trim(substr($t, 1)));
} else {
$$key = (int) $$key;
}
}
// flip for ascending or descending
if (($start_year > $end_year && !$reverse_years) || ($start_year < $end_year && $reverse_years)) {
$t = $end_year;
$end_year = $start_year;
$start_year = $t;
}
// generate year <select> or <input>
if ($display_years) {
$_extra = '';
$_name = $field_array ? ($field_array . '[' . $prefix . 'Year]') : ($prefix . 'Year');
if ($all_extra) {
$_extra .= ' ' . $all_extra;
}
if ($year_extra) {
$_extra .= ' ' . $year_extra;
}
if ($year_as_text) {
$_html_years =
'<input type="text" name="' . $_name . '" value="' . $_year . '" size="4" maxlength="4"' . $_extra .
$extra_attrs . ' />';
} else {
$_html_years = '<select name="' . $_name . '"';
if ($year_id !== null || $all_id !== null) {
$_html_years .= ' id="' . smarty_function_escape_special_chars($year_id !== null ?
($year_id ? $year_id : $_name) :
($all_id ? ($all_id . $_name) :
$_name)) . '"';
}
if ($year_size) {
$_html_years .= ' size="' . $year_size . '"';
}
$_html_years .= $_extra . $extra_attrs . '>' . $option_separator;
if (isset($year_empty) || isset($all_empty)) {
$_html_years .= '<option value="">' . (isset($year_empty) ? $year_empty : $all_empty) . '</option>' .
$option_separator;
}
$op = $start_year > $end_year ? - 1 : 1;
for ($i = $start_year; $op > 0 ? $i <= $end_year : $i >= $end_year; $i += $op) {
$_html_years .= '<option value="' . $i . '"' . ($_year == $i ? ' selected="selected"' : '') . '>' . $i .
'</option>' . $option_separator;
}
$_html_years .= '</select>';
}
}
// generate month <select> or <input>
if ($display_months) {
$_extra = '';
$_name = $field_array ? ($field_array . '[' . $prefix . 'Month]') : ($prefix . 'Month');
if ($all_extra) {
$_extra .= ' ' . $all_extra;
}
if ($month_extra) {
$_extra .= ' ' . $month_extra;
}
$_html_months = '<select name="' . $_name . '"';
if ($month_id !== null || $all_id !== null) {
$_html_months .= ' id="' . smarty_function_escape_special_chars($month_id !== null ?
($month_id ? $month_id : $_name) :
($all_id ? ($all_id . $_name) :
$_name)) . '"';
}
if ($month_size) {
$_html_months .= ' size="' . $month_size . '"';
}
$_html_months .= $_extra . $extra_attrs . '>' . $option_separator;
if (isset($month_empty) || isset($all_empty)) {
$_html_months .= '<option value="">' . (isset($month_empty) ? $month_empty : $all_empty) . '</option>' .
$option_separator;
}
for ($i = 1; $i <= 12; $i ++) {
$_val = sprintf('%02d', $i);
$_text = isset($month_names) ? smarty_function_escape_special_chars($month_names[ $i ]) :
($month_format == "%m" ? $_val : strftime($month_format, $_month_timestamps[ $i ]));
$_value = $month_value_format == "%m" ? $_val : strftime($month_value_format, $_month_timestamps[ $i ]);
$_html_months .= '<option value="' . $_value . '"' . ($_val == $_month ? ' selected="selected"' : '') .
'>' . $_text . '</option>' . $option_separator;
}
$_html_months .= '</select>';
}
// generate day <select> or <input>
if ($display_days) {
$_extra = '';
$_name = $field_array ? ($field_array . '[' . $prefix . 'Day]') : ($prefix . 'Day');
if ($all_extra) {
$_extra .= ' ' . $all_extra;
}
if ($day_extra) {
$_extra .= ' ' . $day_extra;
}
$_html_days = '<select name="' . $_name . '"';
if ($day_id !== null || $all_id !== null) {
$_html_days .= ' id="' .
smarty_function_escape_special_chars($day_id !== null ? ($day_id ? $day_id : $_name) :
($all_id ? ($all_id . $_name) : $_name)) . '"';
}
if ($day_size) {
$_html_days .= ' size="' . $day_size . '"';
}
$_html_days .= $_extra . $extra_attrs . '>' . $option_separator;
if (isset($day_empty) || isset($all_empty)) {
$_html_days .= '<option value="">' . (isset($day_empty) ? $day_empty : $all_empty) . '</option>' .
$option_separator;
}
for ($i = 1; $i <= 31; $i ++) {
$_val = sprintf('%02d', $i);
$_text = $day_format == '%02d' ? $_val : sprintf($day_format, $i);
$_value = $day_value_format == '%02d' ? $_val : sprintf($day_value_format, $i);
$_html_days .= '<option value="' . $_value . '"' . ($_val == $_day ? ' selected="selected"' : '') . '>' .
$_text . '</option>' . $option_separator;
}
$_html_days .= '</select>';
}
// order the fields for output
$_html = '';
for ($i = 0; $i <= 2; $i ++) {
switch ($field_order[ $i ]) {
case 'Y':
case 'y':
if (isset($_html_years)) {
if ($_html) {
$_html .= $field_separator;
}
$_html .= $_html_years;
}
break;
case 'm':
case 'M':
if (isset($_html_months)) {
if ($_html) {
$_html .= $field_separator;
}
$_html .= $_html_months;
}
break;
case 'd':
case 'D':
if (isset($_html_days)) {
if ($_html) {
$_html .= $field_separator;
}
$_html .= $_html_days;
}
break;
}
}
return $_html;
}

View File

@@ -0,0 +1,366 @@
<?php
/**
* Smarty plugin
*
* @package Smarty
* @subpackage PluginsFunction
*/
/**
* @ignore
*/
require_once(SMARTY_PLUGINS_DIR . 'shared.escape_special_chars.php');
/**
* @ignore
*/
require_once(SMARTY_PLUGINS_DIR . 'shared.make_timestamp.php');
/**
* Smarty {html_select_time} function plugin
* Type: function<br>
* Name: html_select_time<br>
* Purpose: Prints the dropdowns for time selection
*
* @link http://www.smarty.net/manual/en/language.function.html.select.time.php {html_select_time}
* (Smarty online manual)
* @author Roberto Berto <roberto@berto.net>
* @author Monte Ohrt <monte AT ohrt DOT com>
*
* @param array $params parameters
*
* @return string
* @uses smarty_make_timestamp()
*/
function smarty_function_html_select_time($params)
{
$prefix = "Time_";
$field_array = null;
$field_separator = "\n";
$option_separator = "\n";
$time = null;
$display_hours = true;
$display_minutes = true;
$display_seconds = true;
$display_meridian = true;
$hour_format = '%02d';
$hour_value_format = '%02d';
$minute_format = '%02d';
$minute_value_format = '%02d';
$second_format = '%02d';
$second_value_format = '%02d';
$hour_size = null;
$minute_size = null;
$second_size = null;
$meridian_size = null;
$all_empty = null;
$hour_empty = null;
$minute_empty = null;
$second_empty = null;
$meridian_empty = null;
$all_id = null;
$hour_id = null;
$minute_id = null;
$second_id = null;
$meridian_id = null;
$use_24_hours = true;
$minute_interval = 1;
$second_interval = 1;
$extra_attrs = '';
$all_extra = null;
$hour_extra = null;
$minute_extra = null;
$second_extra = null;
$meridian_extra = null;
foreach ($params as $_key => $_value) {
switch ($_key) {
case 'time':
if (!is_array($_value) && $_value !== null) {
$time = smarty_make_timestamp($_value);
}
break;
case 'prefix':
case 'field_array':
case 'field_separator':
case 'option_separator':
case 'all_extra':
case 'hour_extra':
case 'minute_extra':
case 'second_extra':
case 'meridian_extra':
case 'all_empty':
case 'hour_empty':
case 'minute_empty':
case 'second_empty':
case 'meridian_empty':
case 'all_id':
case 'hour_id':
case 'minute_id':
case 'second_id':
case 'meridian_id':
case 'hour_format':
case 'hour_value_format':
case 'minute_format':
case 'minute_value_format':
case 'second_format':
case 'second_value_format':
$$_key = (string) $_value;
break;
case 'display_hours':
case 'display_minutes':
case 'display_seconds':
case 'display_meridian':
case 'use_24_hours':
$$_key = (bool) $_value;
break;
case 'minute_interval':
case 'second_interval':
case 'hour_size':
case 'minute_size':
case 'second_size':
case 'meridian_size':
$$_key = (int) $_value;
break;
default:
if (!is_array($_value)) {
$extra_attrs .= ' ' . $_key . '="' . smarty_function_escape_special_chars($_value) . '"';
} else {
trigger_error("html_select_date: extra attribute '$_key' cannot be an array", E_USER_NOTICE);
}
break;
}
}
if (isset($params[ 'time' ]) && is_array($params[ 'time' ])) {
if (isset($params[ 'time' ][ $prefix . 'Hour' ])) {
// $_REQUEST[$field_array] given
foreach (array('H' => 'Hour', 'i' => 'Minute', 's' => 'Second') as $_elementKey => $_elementName) {
$_variableName = '_' . strtolower($_elementName);
$$_variableName =
isset($params[ 'time' ][ $prefix . $_elementName ]) ? $params[ 'time' ][ $prefix . $_elementName ] :
date($_elementKey);
}
$_meridian =
isset($params[ 'time' ][ $prefix . 'Meridian' ]) ? (' ' . $params[ 'time' ][ $prefix . 'Meridian' ]) :
'';
$time = strtotime($_hour . ':' . $_minute . ':' . $_second . $_meridian);
list($_hour, $_minute, $_second) = $time = explode('-', date('H-i-s', $time));
} elseif (isset($params[ 'time' ][ $field_array ][ $prefix . 'Hour' ])) {
// $_REQUEST given
foreach (array('H' => 'Hour', 'i' => 'Minute', 's' => 'Second') as $_elementKey => $_elementName) {
$_variableName = '_' . strtolower($_elementName);
$$_variableName = isset($params[ 'time' ][ $field_array ][ $prefix . $_elementName ]) ?
$params[ 'time' ][ $field_array ][ $prefix . $_elementName ] : date($_elementKey);
}
$_meridian = isset($params[ 'time' ][ $field_array ][ $prefix . 'Meridian' ]) ?
(' ' . $params[ 'time' ][ $field_array ][ $prefix . 'Meridian' ]) : '';
$time = strtotime($_hour . ':' . $_minute . ':' . $_second . $_meridian);
list($_hour, $_minute, $_second) = $time = explode('-', date('H-i-s', $time));
} else {
// no date found, use NOW
list($_year, $_month, $_day) = $time = explode('-', date('Y-m-d'));
}
} elseif ($time === null) {
if (array_key_exists('time', $params)) {
$_hour = $_minute = $_second = $time = null;
} else {
list($_hour, $_minute, $_second) = $time = explode('-', date('H-i-s'));
}
} else {
list($_hour, $_minute, $_second) = $time = explode('-', date('H-i-s', $time));
}
// generate hour <select>
if ($display_hours) {
$_html_hours = '';
$_extra = '';
$_name = $field_array ? ($field_array . '[' . $prefix . 'Hour]') : ($prefix . 'Hour');
if ($all_extra) {
$_extra .= ' ' . $all_extra;
}
if ($hour_extra) {
$_extra .= ' ' . $hour_extra;
}
$_html_hours = '<select name="' . $_name . '"';
if ($hour_id !== null || $all_id !== null) {
$_html_hours .= ' id="' .
smarty_function_escape_special_chars($hour_id !== null ? ($hour_id ? $hour_id : $_name) :
($all_id ? ($all_id . $_name) : $_name)) . '"';
}
if ($hour_size) {
$_html_hours .= ' size="' . $hour_size . '"';
}
$_html_hours .= $_extra . $extra_attrs . '>' . $option_separator;
if (isset($hour_empty) || isset($all_empty)) {
$_html_hours .= '<option value="">' . (isset($hour_empty) ? $hour_empty : $all_empty) . '</option>' .
$option_separator;
}
$start = $use_24_hours ? 0 : 1;
$end = $use_24_hours ? 23 : 12;
for ($i = $start; $i <= $end; $i ++) {
$_val = sprintf('%02d', $i);
$_text = $hour_format == '%02d' ? $_val : sprintf($hour_format, $i);
$_value = $hour_value_format == '%02d' ? $_val : sprintf($hour_value_format, $i);
if (!$use_24_hours) {
$_hour12 = $_hour == 0 ? 12 : ($_hour <= 12 ? $_hour : $_hour - 12);
}
$selected = $_hour !== null ? ($use_24_hours ? $_hour == $_val : $_hour12 == $_val) : null;
$_html_hours .= '<option value="' . $_value . '"' . ($selected ? ' selected="selected"' : '') . '>' .
$_text . '</option>' . $option_separator;
}
$_html_hours .= '</select>';
}
// generate minute <select>
if ($display_minutes) {
$_html_minutes = '';
$_extra = '';
$_name = $field_array ? ($field_array . '[' . $prefix . 'Minute]') : ($prefix . 'Minute');
if ($all_extra) {
$_extra .= ' ' . $all_extra;
}
if ($minute_extra) {
$_extra .= ' ' . $minute_extra;
}
$_html_minutes = '<select name="' . $_name . '"';
if ($minute_id !== null || $all_id !== null) {
$_html_minutes .= ' id="' . smarty_function_escape_special_chars($minute_id !== null ?
($minute_id ? $minute_id : $_name) :
($all_id ? ($all_id . $_name) :
$_name)) . '"';
}
if ($minute_size) {
$_html_minutes .= ' size="' . $minute_size . '"';
}
$_html_minutes .= $_extra . $extra_attrs . '>' . $option_separator;
if (isset($minute_empty) || isset($all_empty)) {
$_html_minutes .= '<option value="">' . (isset($minute_empty) ? $minute_empty : $all_empty) . '</option>' .
$option_separator;
}
$selected = $_minute !== null ? ($_minute - $_minute % $minute_interval) : null;
for ($i = 0; $i <= 59; $i += $minute_interval) {
$_val = sprintf('%02d', $i);
$_text = $minute_format == '%02d' ? $_val : sprintf($minute_format, $i);
$_value = $minute_value_format == '%02d' ? $_val : sprintf($minute_value_format, $i);
$_html_minutes .= '<option value="' . $_value . '"' . ($selected === $i ? ' selected="selected"' : '') .
'>' . $_text . '</option>' . $option_separator;
}
$_html_minutes .= '</select>';
}
// generate second <select>
if ($display_seconds) {
$_html_seconds = '';
$_extra = '';
$_name = $field_array ? ($field_array . '[' . $prefix . 'Second]') : ($prefix . 'Second');
if ($all_extra) {
$_extra .= ' ' . $all_extra;
}
if ($second_extra) {
$_extra .= ' ' . $second_extra;
}
$_html_seconds = '<select name="' . $_name . '"';
if ($second_id !== null || $all_id !== null) {
$_html_seconds .= ' id="' . smarty_function_escape_special_chars($second_id !== null ?
($second_id ? $second_id : $_name) :
($all_id ? ($all_id . $_name) :
$_name)) . '"';
}
if ($second_size) {
$_html_seconds .= ' size="' . $second_size . '"';
}
$_html_seconds .= $_extra . $extra_attrs . '>' . $option_separator;
if (isset($second_empty) || isset($all_empty)) {
$_html_seconds .= '<option value="">' . (isset($second_empty) ? $second_empty : $all_empty) . '</option>' .
$option_separator;
}
$selected = $_second !== null ? ($_second - $_second % $second_interval) : null;
for ($i = 0; $i <= 59; $i += $second_interval) {
$_val = sprintf('%02d', $i);
$_text = $second_format == '%02d' ? $_val : sprintf($second_format, $i);
$_value = $second_value_format == '%02d' ? $_val : sprintf($second_value_format, $i);
$_html_seconds .= '<option value="' . $_value . '"' . ($selected === $i ? ' selected="selected"' : '') .
'>' . $_text . '</option>' . $option_separator;
}
$_html_seconds .= '</select>';
}
// generate meridian <select>
if ($display_meridian && !$use_24_hours) {
$_html_meridian = '';
$_extra = '';
$_name = $field_array ? ($field_array . '[' . $prefix . 'Meridian]') : ($prefix . 'Meridian');
if ($all_extra) {
$_extra .= ' ' . $all_extra;
}
if ($meridian_extra) {
$_extra .= ' ' . $meridian_extra;
}
$_html_meridian = '<select name="' . $_name . '"';
if ($meridian_id !== null || $all_id !== null) {
$_html_meridian .= ' id="' . smarty_function_escape_special_chars($meridian_id !== null ?
($meridian_id ? $meridian_id :
$_name) :
($all_id ? ($all_id . $_name) :
$_name)) . '"';
}
if ($meridian_size) {
$_html_meridian .= ' size="' . $meridian_size . '"';
}
$_html_meridian .= $_extra . $extra_attrs . '>' . $option_separator;
if (isset($meridian_empty) || isset($all_empty)) {
$_html_meridian .= '<option value="">' . (isset($meridian_empty) ? $meridian_empty : $all_empty) .
'</option>' . $option_separator;
}
$_html_meridian .= '<option value="am"' . ($_hour > 0 && $_hour < 12 ? ' selected="selected"' : '') .
'>AM</option>' . $option_separator . '<option value="pm"' .
($_hour < 12 ? '' : ' selected="selected"') . '>PM</option>' . $option_separator .
'</select>';
}
$_html = '';
foreach (array('_html_hours', '_html_minutes', '_html_seconds', '_html_meridian') as $k) {
if (isset($$k)) {
if ($_html) {
$_html .= $field_separator;
}
$_html .= $$k;
}
}
return $_html;
}

View File

@@ -0,0 +1,176 @@
<?php
/**
* Smarty plugin
*
* @package Smarty
* @subpackage PluginsFunction
*/
/**
* Smarty {html_table} function plugin
* Type: function<br>
* Name: html_table<br>
* Date: Feb 17, 2003<br>
* Purpose: make an html table from an array of data<br>
* Params:
* <pre>
* - loop - array to loop through
* - cols - number of columns, comma separated list of column names
* or array of column names
* - rows - number of rows
* - table_attr - table attributes
* - th_attr - table heading attributes (arrays are cycled)
* - tr_attr - table row attributes (arrays are cycled)
* - td_attr - table cell attributes (arrays are cycled)
* - trailpad - value to pad trailing cells with
* - caption - text for caption element
* - vdir - vertical direction (default: "down", means top-to-bottom)
* - hdir - horizontal direction (default: "right", means left-to-right)
* - inner - inner loop (default "cols": print $loop line by line,
* $loop will be printed column by column otherwise)
* </pre>
* Examples:
* <pre>
* {table loop=$data}
* {table loop=$data cols=4 tr_attr='"bgcolor=red"'}
* {table loop=$data cols="first,second,third" tr_attr=$colors}
* </pre>
*
* @author Monte Ohrt <monte at ohrt dot com>
* @author credit to Messju Mohr <messju at lammfellpuschen dot de>
* @author credit to boots <boots dot smarty at yahoo dot com>
* @version 1.1
* @link http://www.smarty.net/manual/en/language.function.html.table.php {html_table}
* (Smarty online manual)
*
* @param array $params parameters
*
* @return string
*/
function smarty_function_html_table($params)
{
$table_attr = 'border="1"';
$tr_attr = '';
$th_attr = '';
$td_attr = '';
$cols = $cols_count = 3;
$rows = 3;
$trailpad = '&nbsp;';
$vdir = 'down';
$hdir = 'right';
$inner = 'cols';
$caption = '';
$loop = null;
if (!isset($params[ 'loop' ])) {
trigger_error("html_table: missing 'loop' parameter", E_USER_WARNING);
return;
}
foreach ($params as $_key => $_value) {
switch ($_key) {
case 'loop':
$$_key = (array) $_value;
break;
case 'cols':
if (is_array($_value) && !empty($_value)) {
$cols = $_value;
$cols_count = count($_value);
} elseif (!is_numeric($_value) && is_string($_value) && !empty($_value)) {
$cols = explode(',', $_value);
$cols_count = count($cols);
} elseif (!empty($_value)) {
$cols_count = (int) $_value;
} else {
$cols_count = $cols;
}
break;
case 'rows':
$$_key = (int) $_value;
break;
case 'table_attr':
case 'trailpad':
case 'hdir':
case 'vdir':
case 'inner':
case 'caption':
$$_key = (string) $_value;
break;
case 'tr_attr':
case 'td_attr':
case 'th_attr':
$$_key = $_value;
break;
}
}
$loop_count = count($loop);
if (empty($params[ 'rows' ])) {
/* no rows specified */
$rows = ceil($loop_count / $cols_count);
} elseif (empty($params[ 'cols' ])) {
if (!empty($params[ 'rows' ])) {
/* no cols specified, but rows */
$cols_count = ceil($loop_count / $rows);
}
}
$output = "<table $table_attr>\n";
if (!empty($caption)) {
$output .= '<caption>' . $caption . "</caption>\n";
}
if (is_array($cols)) {
$cols = ($hdir == 'right') ? $cols : array_reverse($cols);
$output .= "<thead><tr>\n";
for ($r = 0; $r < $cols_count; $r ++) {
$output .= '<th' . smarty_function_html_table_cycle('th', $th_attr, $r) . '>';
$output .= $cols[ $r ];
$output .= "</th>\n";
}
$output .= "</tr></thead>\n";
}
$output .= "<tbody>\n";
for ($r = 0; $r < $rows; $r ++) {
$output .= "<tr" . smarty_function_html_table_cycle('tr', $tr_attr, $r) . ">\n";
$rx = ($vdir == 'down') ? $r * $cols_count : ($rows - 1 - $r) * $cols_count;
for ($c = 0; $c < $cols_count; $c ++) {
$x = ($hdir == 'right') ? $rx + $c : $rx + $cols_count - 1 - $c;
if ($inner != 'cols') {
/* shuffle x to loop over rows*/
$x = floor($x / $cols_count) + ($x % $cols_count) * $rows;
}
if ($x < $loop_count) {
$output .= "<td" . smarty_function_html_table_cycle('td', $td_attr, $c) . ">" . $loop[ $x ] . "</td>\n";
} else {
$output .= "<td" . smarty_function_html_table_cycle('td', $td_attr, $c) . ">$trailpad</td>\n";
}
}
$output .= "</tr>\n";
}
$output .= "</tbody>\n";
$output .= "</table>\n";
return $output;
}
function smarty_function_html_table_cycle($name, $var, $no)
{
if (!is_array($var)) {
$ret = $var;
} else {
$ret = $var[ $no % count($var) ];
}
return ($ret) ? ' ' . $ret : '';
}

View File

@@ -0,0 +1,153 @@
<?php
/**
* Smarty plugin
*
* @package Smarty
* @subpackage PluginsFunction
*/
/**
* Smarty {mailto} function plugin
* Type: function<br>
* Name: mailto<br>
* Date: May 21, 2002
* Purpose: automate mailto address link creation, and optionally encode them.<br>
* Params:
* <pre>
* - address - (required) - e-mail address
* - text - (optional) - text to display, default is address
* - encode - (optional) - can be one of:
* * none : no encoding (default)
* * javascript : encode with javascript
* * javascript_charcode : encode with javascript charcode
* * hex : encode with hexidecimal (no javascript)
* - cc - (optional) - address(es) to carbon copy
* - bcc - (optional) - address(es) to blind carbon copy
* - subject - (optional) - e-mail subject
* - newsgroups - (optional) - newsgroup(s) to post to
* - followupto - (optional) - address(es) to follow up to
* - extra - (optional) - extra tags for the href link
* </pre>
* Examples:
* <pre>
* {mailto address="me@domain.com"}
* {mailto address="me@domain.com" encode="javascript"}
* {mailto address="me@domain.com" encode="hex"}
* {mailto address="me@domain.com" subject="Hello to you!"}
* {mailto address="me@domain.com" cc="you@domain.com,they@domain.com"}
* {mailto address="me@domain.com" extra='class="mailto"'}
* </pre>
*
* @link http://www.smarty.net/manual/en/language.function.mailto.php {mailto}
* (Smarty online manual)
* @version 1.2
* @author Monte Ohrt <monte at ohrt dot com>
* @author credits to Jason Sweat (added cc, bcc and subject functionality)
*
* @param array $params parameters
*
* @return string
*/
function smarty_function_mailto($params)
{
static $_allowed_encoding =
array('javascript' => true, 'javascript_charcode' => true, 'hex' => true, 'none' => true);
$extra = '';
if (empty($params[ 'address' ])) {
trigger_error("mailto: missing 'address' parameter", E_USER_WARNING);
return;
} else {
$address = $params[ 'address' ];
}
$text = $address;
// netscape and mozilla do not decode %40 (@) in BCC field (bug?)
// so, don't encode it.
$search = array('%40', '%2C');
$replace = array('@', ',');
$mail_parms = array();
foreach ($params as $var => $value) {
switch ($var) {
case 'cc':
case 'bcc':
case 'followupto':
if (!empty($value)) {
$mail_parms[] = $var . '=' . str_replace($search, $replace, rawurlencode($value));
}
break;
case 'subject':
case 'newsgroups':
$mail_parms[] = $var . '=' . rawurlencode($value);
break;
case 'extra':
case 'text':
$$var = $value;
default:
}
}
if ($mail_parms) {
$address .= '?' . join('&', $mail_parms);
}
$encode = (empty($params[ 'encode' ])) ? 'none' : $params[ 'encode' ];
if (!isset($_allowed_encoding[ $encode ])) {
trigger_error("mailto: 'encode' parameter must be none, javascript, javascript_charcode or hex",
E_USER_WARNING);
return;
}
// FIXME: (rodneyrehm) document.write() excues me what? 1998 has passed!
if ($encode == 'javascript') {
$string = 'document.write(\'<a href="mailto:' . $address . '" ' . $extra . '>' . $text . '</a>\');';
$js_encode = '';
for ($x = 0, $_length = strlen($string); $x < $_length; $x ++) {
$js_encode .= '%' . bin2hex($string[ $x ]);
}
return '<script type="text/javascript">eval(unescape(\'' . $js_encode . '\'))</script>';
} elseif ($encode == 'javascript_charcode') {
$string = '<a href="mailto:' . $address . '" ' . $extra . '>' . $text . '</a>';
for ($x = 0, $y = strlen($string); $x < $y; $x ++) {
$ord[] = ord($string[ $x ]);
}
$_ret = "<script type=\"text/javascript\" language=\"javascript\">\n" . "{document.write(String.fromCharCode(" .
implode(',', $ord) . "))" . "}\n" . "</script>\n";
return $_ret;
} elseif ($encode == 'hex') {
preg_match('!^(.*)(\?.*)$!', $address, $match);
if (!empty($match[ 2 ])) {
trigger_error("mailto: hex encoding does not work with extra attributes. Try javascript.", E_USER_WARNING);
return;
}
$address_encode = '';
for ($x = 0, $_length = strlen($address); $x < $_length; $x ++) {
if (preg_match('!\w!' . Smarty::$_UTF8_MODIFIER, $address[ $x ])) {
$address_encode .= '%' . bin2hex($address[ $x ]);
} else {
$address_encode .= $address[ $x ];
}
}
$text_encode = '';
for ($x = 0, $_length = strlen($text); $x < $_length; $x ++) {
$text_encode .= '&#x' . bin2hex($text[ $x ]) . ';';
}
$mailto = "&#109;&#97;&#105;&#108;&#116;&#111;&#58;";
return '<a href="' . $mailto . $address_encode . '" ' . $extra . '>' . $text_encode . '</a>';
} else {
// no encoding
return '<a href="mailto:' . $address . '" ' . $extra . '>' . $text . '</a>';
}
}

View File

@@ -0,0 +1,104 @@
<?php
/**
* Smarty plugin
* This plugin is only for Smarty2 BC
*
* @package Smarty
* @subpackage PluginsFunction
*/
/**
* Smarty {math} function plugin
* Type: function<br>
* Name: math<br>
* Purpose: handle math computations in template
*
* @link http://www.smarty.net/manual/en/language.function.math.php {math}
* (Smarty online manual)
* @author Monte Ohrt <monte at ohrt dot com>
*
* @param array $params parameters
* @param Smarty_Internal_Template $template template object
*
* @return string|null
*/
function smarty_function_math($params, $template)
{
static $_allowed_funcs =
array('int' => true, 'abs' => true, 'ceil' => true, 'cos' => true, 'exp' => true, 'floor' => true,
'log' => true, 'log10' => true, 'max' => true, 'min' => true, 'pi' => true, 'pow' => true, 'rand' => true,
'round' => true, 'sin' => true, 'sqrt' => true, 'srand' => true, 'tan' => true);
// be sure equation parameter is present
if (empty($params[ 'equation' ])) {
trigger_error("math: missing equation parameter", E_USER_WARNING);
return;
}
$equation = $params[ 'equation' ];
// make sure parenthesis are balanced
if (substr_count($equation, "(") != substr_count($equation, ")")) {
trigger_error("math: unbalanced parenthesis", E_USER_WARNING);
return;
}
// disallow backticks
if (strpos($equation, '`') !== false) {
trigger_error("math: backtick character not allowed in equation", E_USER_WARNING);
return;
}
// also disallow dollar signs
if (strpos($equation, '$') !== false) {
trigger_error("math: dollar signs not allowed in equation", E_USER_WARNING);
return;
}
// match all vars in equation, make sure all are passed
preg_match_all('!(?:0x[a-fA-F0-9]+)|([a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*)!', $equation, $match);
foreach ($match[ 1 ] as $curr_var) {
if ($curr_var && !isset($params[ $curr_var ]) && !isset($_allowed_funcs[ $curr_var ])) {
trigger_error("math: function call $curr_var not allowed", E_USER_WARNING);
return;
}
}
foreach ($params as $key => $val) {
if ($key != "equation" && $key != "format" && $key != "assign") {
// make sure value is not empty
if (strlen($val) == 0) {
trigger_error("math: parameter $key is empty", E_USER_WARNING);
return;
}
if (!is_numeric($val)) {
trigger_error("math: parameter $key: is not numeric", E_USER_WARNING);
return;
}
$equation = preg_replace("/\b$key\b/", " \$params['$key'] ", $equation);
}
}
$smarty_math_result = null;
eval("\$smarty_math_result = " . $equation . ";");
if (empty($params[ 'format' ])) {
if (empty($params[ 'assign' ])) {
return $smarty_math_result;
} else {
$template->assign($params[ 'assign' ], $smarty_math_result);
}
} else {
if (empty($params[ 'assign' ])) {
printf($params[ 'format' ], $smarty_math_result);
} else {
$template->assign($params[ 'assign' ], sprintf($params[ 'format' ], $smarty_math_result));
}
}
}

View File

@@ -0,0 +1,119 @@
<?php
/**
* Smarty plugin
* @package Smarty
* @subpackage plugins
*/
/**
* Smarty {popup} function plugin
*
* Type: function<br>
* Name: popup<br>
* Purpose: make text pop up in windows via overlib
* @link http://smarty.php.net/manual/en/language.function.popup.php {popup}
* (Smarty online manual)
* @author Monte Ohrt <monte at ohrt dot com>
* @param array
* @param Smarty
* @return string
*/
function smarty_function_popup($params, &$smarty)
{
$append = '';
foreach ($params as $_key=>$_value) {
switch ($_key) {
case 'text':
case 'trigger':
case 'function':
case 'inarray':
$$_key = (string)$_value;
if ($_key == 'function' || $_key == 'inarray')
$append .= ',' . strtoupper($_key) . ",'$_value'";
break;
case 'caption':
case 'closetext':
case 'status':
$append .= ',' . strtoupper($_key) . ",'" . str_replace("'","\'",$_value) . "'";
break;
case 'fgcolor':
case 'bgcolor':
case 'textcolor':
case 'capcolor':
case 'closecolor':
case 'textfont':
case 'captionfont':
case 'closefont':
case 'fgbackground':
case 'bgbackground':
case 'caparray':
case 'capicon':
case 'background':
case 'frame':
$append .= ',' . strtoupper($_key) . ",'$_value'";
break;
case 'textsize':
case 'captionsize':
case 'closesize':
case 'width':
case 'height':
case 'border':
case 'offsetx':
case 'offsety':
case 'snapx':
case 'snapy':
case 'fixx':
case 'fixy':
case 'padx':
case 'pady':
case 'timeout':
case 'delay':
$append .= ',' . strtoupper($_key) . ",$_value";
break;
case 'sticky':
case 'left':
case 'right':
case 'center':
case 'above':
case 'below':
case 'noclose':
case 'autostatus':
case 'autostatuscap':
case 'fullhtml':
case 'hauto':
case 'vauto':
case 'mouseoff':
case 'followmouse':
case 'closeclick':
if ($_value) $append .= ',' . strtoupper($_key);
break;
default:
$smarty->trigger_error("[popup] unknown parameter $_key", E_USER_WARNING);
}
}
if (empty($text) && !isset($inarray) && empty($function)) {
$smarty->trigger_error("overlib: attribute 'text' or 'inarray' or 'function' required");
return false;
}
if (empty($trigger)) { $trigger = "onmouseover"; }
$retval = $trigger . '="return overlib(\''.preg_replace(array("!'!","![\r\n]!"),array("\'",'\r'),$text).'\'';
$retval .= $append . ');"';
if ($trigger == 'onmouseover')
$retval .= ' onmouseout="nd();"';
return $retval;
}
/* vim: set expandtab: */
?>

View File

@@ -0,0 +1,40 @@
<?php
/**
* Smarty plugin
* @package Smarty
* @subpackage plugins
*/
/**
* Smarty {popup_init} function plugin
*
* Type: function<br>
* Name: popup_init<br>
* Purpose: initialize overlib
* @link http://smarty.php.net/manual/en/language.function.popup.init.php {popup_init}
* (Smarty online manual)
* @author Monte Ohrt <monte at ohrt dot com>
* @param array
* @param Smarty
* @return string
*/
function smarty_function_popup_init($params, &$smarty)
{
$zindex = 1000;
if (!empty($params['zindex'])) {
$zindex = $params['zindex'];
}
if (!empty($params['src'])) {
return '<div id="overDiv" style="position:absolute; visibility:hidden; z-index:'.$zindex.';"></div>' . "\n"
. '<script type="text/javascript" language="JavaScript" src="'.$params['src'].'"></script>' . "\n";
} else {
$smarty->trigger_error("popup_init: missing src parameter");
}
}
/* vim: set expandtab: */
?>

View File

@@ -0,0 +1,101 @@
<?php
/**
* Smarty plugin
*
* @package Smarty
* @subpackage PluginsModifier
*/
/**
* Smarty capitalize modifier plugin
* Type: modifier<br>
* Name: capitalize<br>
* Purpose: capitalize words in the string
* {@internal {$string|capitalize:true:true} is the fastest option for MBString enabled systems }}
*
* @param string $string string to capitalize
* @param boolean $uc_digits also capitalize "x123" to "X123"
* @param boolean $lc_rest capitalize first letters, lowercase all following letters "aAa" to "Aaa"
*
* @return string capitalized string
* @author Monte Ohrt <monte at ohrt dot com>
* @author Rodney Rehm
*/
function smarty_modifier_capitalize($string, $uc_digits = false, $lc_rest = false)
{
if (Smarty::$_MBSTRING) {
if ($lc_rest) {
// uppercase (including hyphenated words)
$upper_string = mb_convert_case($string, MB_CASE_TITLE, Smarty::$_CHARSET);
} else {
// uppercase word breaks
$upper_string = preg_replace_callback("!(^|[^\p{L}'])([\p{Ll}])!S" . Smarty::$_UTF8_MODIFIER,
'smarty_mod_cap_mbconvert_cb', $string);
}
// check uc_digits case
if (!$uc_digits) {
if (preg_match_all("!\b([\p{L}]*[\p{N}]+[\p{L}]*)\b!" . Smarty::$_UTF8_MODIFIER, $string, $matches,
PREG_OFFSET_CAPTURE)) {
foreach ($matches[ 1 ] as $match) {
$upper_string =
substr_replace($upper_string, mb_strtolower($match[ 0 ], Smarty::$_CHARSET), $match[ 1 ],
strlen($match[ 0 ]));
}
}
}
$upper_string =
preg_replace_callback("!((^|\s)['\"])(\w)!" . Smarty::$_UTF8_MODIFIER, 'smarty_mod_cap_mbconvert2_cb',
$upper_string);
return $upper_string;
}
// lowercase first
if ($lc_rest) {
$string = strtolower($string);
}
// uppercase (including hyphenated words)
$upper_string =
preg_replace_callback("!(^|[^\p{L}'])([\p{Ll}])!S" . Smarty::$_UTF8_MODIFIER, 'smarty_mod_cap_ucfirst_cb',
$string);
// check uc_digits case
if (!$uc_digits) {
if (preg_match_all("!\b([\p{L}]*[\p{N}]+[\p{L}]*)\b!" . Smarty::$_UTF8_MODIFIER, $string, $matches,
PREG_OFFSET_CAPTURE)) {
foreach ($matches[ 1 ] as $match) {
$upper_string =
substr_replace($upper_string, strtolower($match[ 0 ]), $match[ 1 ], strlen($match[ 0 ]));
}
}
}
$upper_string = preg_replace_callback("!((^|\s)['\"])(\w)!" . Smarty::$_UTF8_MODIFIER, 'smarty_mod_cap_ucfirst2_cb',
$upper_string);
return $upper_string;
}
/*
*
* Bug: create_function() use exhausts memory when used in long loops
* Fix: use declared functions for callbacks instead of using create_function()
* Note: This can be fixed using anonymous functions instead, but that requires PHP >= 5.3
*
* @author Kyle Renfrow
*/
function smarty_mod_cap_mbconvert_cb($matches)
{
return stripslashes($matches[ 1 ]) . mb_convert_case(stripslashes($matches[ 2 ]), MB_CASE_UPPER, Smarty::$_CHARSET);
}
function smarty_mod_cap_mbconvert2_cb($matches)
{
return stripslashes($matches[ 1 ]) . mb_convert_case(stripslashes($matches[ 3 ]), MB_CASE_UPPER, Smarty::$_CHARSET);
}
function smarty_mod_cap_ucfirst_cb($matches)
{
return stripslashes($matches[ 1 ]) . ucfirst(stripslashes($matches[ 2 ]));
}
function smarty_mod_cap_ucfirst2_cb($matches)
{
return stripslashes($matches[ 1 ]) . ucfirst(stripslashes($matches[ 3 ]));
}

View File

@@ -0,0 +1,65 @@
<?php
/**
* Smarty plugin
*
* @package Smarty
* @subpackage PluginsModifier
*/
/**
* Smarty date_format modifier plugin
* Type: modifier<br>
* Name: date_format<br>
* Purpose: format datestamps via strftime<br>
* Input:<br>
* - string: input date string
* - format: strftime format for output
* - default_date: default date if $string is empty
*
* @link http://www.smarty.net/manual/en/language.modifier.date.format.php date_format (Smarty online manual)
* @author Monte Ohrt <monte at ohrt dot com>
*
* @param string $string input date string
* @param string $format strftime format for output
* @param string $default_date default date if $string is empty
* @param string $formatter either 'strftime' or 'auto'
*
* @return string |void
* @uses smarty_make_timestamp()
*/
function smarty_modifier_date_format($string, $format = null, $default_date = '', $formatter = 'auto')
{
if ($format === null) {
$format = Smarty::$_DATE_FORMAT;
}
/**
* require_once the {@link shared.make_timestamp.php} plugin
*/
require_once(SMARTY_PLUGINS_DIR . 'shared.make_timestamp.php');
if ($string != '' && $string != '0000-00-00' && $string != '0000-00-00 00:00:00') {
$timestamp = smarty_make_timestamp($string);
} elseif ($default_date != '') {
$timestamp = smarty_make_timestamp($default_date);
} else {
return;
}
if ($formatter == 'strftime' || ($formatter == 'auto' && strpos($format, '%') !== false)) {
if (DS == '\\') {
$_win_from = array('%D', '%h', '%n', '%r', '%R', '%t', '%T');
$_win_to = array('%m/%d/%y', '%b', "\n", '%I:%M:%S %p', '%H:%M', "\t", '%H:%M:%S');
if (strpos($format, '%e') !== false) {
$_win_from[] = '%e';
$_win_to[] = sprintf('%\' 2d', date('j', $timestamp));
}
if (strpos($format, '%l') !== false) {
$_win_from[] = '%l';
$_win_to[] = sprintf('%\' 2d', date('h', $timestamp));
}
$format = str_replace($_win_from, $_win_to, $format);
}
return strftime($format, $timestamp);
} else {
return date($format, $timestamp);
}
}

View File

@@ -0,0 +1,112 @@
<?php
/**
* Smarty plugin
*
* @package Smarty
* @subpackage Debug
*/
/**
* Smarty debug_print_var modifier plugin
* Type: modifier<br>
* Name: debug_print_var<br>
* Purpose: formats variable contents for display in the console
*
* @author Monte Ohrt <monte at ohrt dot com>
*
* @param array|object $var variable to be formatted
* @param int $max maximum recursion depth if $var is an array or object
* @param int $length maximum string length if $var is a string
* @param int $depth actual recursion depth
* @param array $objects processed objects in actual depth to prevent recursive object processing
*
* @return string
*/
function smarty_modifier_debug_print_var($var, $max = 10, $length = 40, $depth = 0, $objects = array())
{
$_replace = array("\n" => '\n', "\r" => '\r', "\t" => '\t');
switch (gettype($var)) {
case 'array' :
$results = '<b>Array (' . count($var) . ')</b>';
if ($depth == $max) {
break;
}
foreach ($var as $curr_key => $curr_val) {
$results .= '<br>' . str_repeat('&nbsp;', $depth * 2) . '<b>' . strtr($curr_key, $_replace) .
'</b> =&gt; ' .
smarty_modifier_debug_print_var($curr_val, $max, $length, ++ $depth, $objects);
$depth --;
}
break;
case 'object' :
$object_vars = get_object_vars($var);
$results = '<b>' . get_class($var) . ' Object (' . count($object_vars) . ')</b>';
if (in_array($var, $objects)) {
$results .= ' called recursive';
break;
}
if ($depth == $max) {
break;
}
$objects[] = $var;
foreach ($object_vars as $curr_key => $curr_val) {
$results .= '<br>' . str_repeat('&nbsp;', $depth * 2) . '<b> -&gt;' . strtr($curr_key, $_replace) .
'</b> = ' . smarty_modifier_debug_print_var($curr_val, $max, $length, ++ $depth, $objects);
$depth --;
}
break;
case 'boolean' :
case 'NULL' :
case 'resource' :
if (true === $var) {
$results = 'true';
} elseif (false === $var) {
$results = 'false';
} elseif (null === $var) {
$results = 'null';
} else {
$results = htmlspecialchars((string) $var);
}
$results = '<i>' . $results . '</i>';
break;
case 'integer' :
case 'float' :
$results = htmlspecialchars((string) $var);
break;
case 'string' :
$results = strtr($var, $_replace);
if (Smarty::$_MBSTRING) {
if (mb_strlen($var, Smarty::$_CHARSET) > $length) {
$results = mb_substr($var, 0, $length - 3, Smarty::$_CHARSET) . '...';
}
} else {
if (isset($var[ $length ])) {
$results = substr($var, 0, $length - 3) . '...';
}
}
$results = htmlspecialchars('"' . $results . '"', ENT_QUOTES, Smarty::$_CHARSET);
break;
case 'unknown type' :
default :
$results = strtr((string) $var, $_replace);
if (Smarty::$_MBSTRING) {
if (mb_strlen($results, Smarty::$_CHARSET) > $length) {
$results = mb_substr($results, 0, $length - 3, Smarty::$_CHARSET) . '...';
}
} else {
if (strlen($results) > $length) {
$results = substr($results, 0, $length - 3) . '...';
}
}
$results = htmlspecialchars($results, ENT_QUOTES, Smarty::$_CHARSET);
}
return $results;
}

View File

@@ -0,0 +1,200 @@
<?php
/**
* Smarty plugin
*
* @package Smarty
* @subpackage PluginsModifier
*/
/**
* Smarty escape modifier plugin
* Type: modifier<br>
* Name: escape<br>
* Purpose: escape string for output
*
* @link http://www.smarty.net/docs/en/language.modifier.escape
* @author Monte Ohrt <monte at ohrt dot com>
*
* @param string $string input string
* @param string $esc_type escape type
* @param string $char_set character set, used for htmlspecialchars() or htmlentities()
* @param boolean $double_encode encode already encoded entitites again, used for htmlspecialchars() or htmlentities()
*
* @return string escaped input string
*/
function smarty_modifier_escape($string, $esc_type = 'html', $char_set = null, $double_encode = true)
{
static $_double_encode = null;
if ($_double_encode === null) {
$_double_encode = version_compare(PHP_VERSION, '5.2.3', '>=');
}
if (!$char_set) {
$char_set = Smarty::$_CHARSET;
}
switch ($esc_type) {
case 'html':
if ($_double_encode) {
// php >=5.3.2 - go native
return htmlspecialchars($string, ENT_QUOTES, $char_set, $double_encode);
} else {
if ($double_encode) {
// php <5.2.3 - only handle double encoding
return htmlspecialchars($string, ENT_QUOTES, $char_set);
} else {
// php <5.2.3 - prevent double encoding
$string = preg_replace('!&(#?\w+);!', '%%%SMARTY_START%%%\\1%%%SMARTY_END%%%', $string);
$string = htmlspecialchars($string, ENT_QUOTES, $char_set);
$string = str_replace(array('%%%SMARTY_START%%%', '%%%SMARTY_END%%%'), array('&', ';'), $string);
return $string;
}
}
case 'htmlall':
if (Smarty::$_MBSTRING) {
// mb_convert_encoding ignores htmlspecialchars()
if ($_double_encode) {
// php >=5.3.2 - go native
$string = htmlspecialchars($string, ENT_QUOTES, $char_set, $double_encode);
} else {
if ($double_encode) {
// php <5.2.3 - only handle double encoding
$string = htmlspecialchars($string, ENT_QUOTES, $char_set);
} else {
// php <5.2.3 - prevent double encoding
$string = preg_replace('!&(#?\w+);!', '%%%SMARTY_START%%%\\1%%%SMARTY_END%%%', $string);
$string = htmlspecialchars($string, ENT_QUOTES, $char_set);
$string =
str_replace(array('%%%SMARTY_START%%%', '%%%SMARTY_END%%%'), array('&', ';'), $string);
return $string;
}
}
// htmlentities() won't convert everything, so use mb_convert_encoding
return mb_convert_encoding($string, 'HTML-ENTITIES', $char_set);
}
// no MBString fallback
if ($_double_encode) {
return htmlentities($string, ENT_QUOTES, $char_set, $double_encode);
} else {
if ($double_encode) {
return htmlentities($string, ENT_QUOTES, $char_set);
} else {
$string = preg_replace('!&(#?\w+);!', '%%%SMARTY_START%%%\\1%%%SMARTY_END%%%', $string);
$string = htmlentities($string, ENT_QUOTES, $char_set);
$string = str_replace(array('%%%SMARTY_START%%%', '%%%SMARTY_END%%%'), array('&', ';'), $string);
return $string;
}
}
case 'url':
return rawurlencode($string);
case 'urlpathinfo':
return str_replace('%2F', '/', rawurlencode($string));
case 'quotes':
// escape unescaped single quotes
return preg_replace("%(?<!\\\\)'%", "\\'", $string);
case 'hex':
// escape every byte into hex
// Note that the UTF-8 encoded character ä will be represented as %c3%a4
$return = '';
$_length = strlen($string);
for ($x = 0; $x < $_length; $x ++) {
$return .= '%' . bin2hex($string[ $x ]);
}
return $return;
case 'hexentity':
$return = '';
if (Smarty::$_MBSTRING) {
require_once(SMARTY_PLUGINS_DIR . 'shared.mb_unicode.php');
$return = '';
foreach (smarty_mb_to_unicode($string, Smarty::$_CHARSET) as $unicode) {
$return .= '&#x' . strtoupper(dechex($unicode)) . ';';
}
return $return;
}
// no MBString fallback
$_length = strlen($string);
for ($x = 0; $x < $_length; $x ++) {
$return .= '&#x' . bin2hex($string[ $x ]) . ';';
}
return $return;
case 'decentity':
$return = '';
if (Smarty::$_MBSTRING) {
require_once(SMARTY_PLUGINS_DIR . 'shared.mb_unicode.php');
$return = '';
foreach (smarty_mb_to_unicode($string, Smarty::$_CHARSET) as $unicode) {
$return .= '&#' . $unicode . ';';
}
return $return;
}
// no MBString fallback
$_length = strlen($string);
for ($x = 0; $x < $_length; $x ++) {
$return .= '&#' . ord($string[ $x ]) . ';';
}
return $return;
case 'javascript':
// escape quotes and backslashes, newlines, etc.
return strtr($string, array('\\' => '\\\\', "'" => "\\'", '"' => '\\"', "\r" => '\\r', "\n" => '\\n',
'</' => '<\/'));
case 'mail':
if (Smarty::$_MBSTRING) {
require_once(SMARTY_PLUGINS_DIR . 'shared.mb_str_replace.php');
return smarty_mb_str_replace(array('@', '.'), array(' [AT] ', ' [DOT] '), $string);
}
// no MBString fallback
return str_replace(array('@', '.'), array(' [AT] ', ' [DOT] '), $string);
case 'nonstd':
// escape non-standard chars, such as ms document quotes
$return = '';
if (Smarty::$_MBSTRING) {
require_once(SMARTY_PLUGINS_DIR . 'shared.mb_unicode.php');
foreach (smarty_mb_to_unicode($string, Smarty::$_CHARSET) as $unicode) {
if ($unicode >= 126) {
$return .= '&#' . $unicode . ';';
} else {
$return .= chr($unicode);
}
}
return $return;
}
$_length = strlen($string);
for ($_i = 0; $_i < $_length; $_i ++) {
$_ord = ord(substr($string, $_i, 1));
// non-standard char, escape it
if ($_ord >= 126) {
$return .= '&#' . $_ord . ';';
} else {
$return .= substr($string, $_i, 1);
}
}
return $return;
default:
return $string;
}
}

View File

@@ -0,0 +1,58 @@
<?php
/**
* Smarty plugin
*
* @package Smarty
* @subpackage PluginsModifier
*/
/**
* Smarty regex_replace modifier plugin
* Type: modifier<br>
* Name: regex_replace<br>
* Purpose: regular expression search/replace
*
* @link http://smarty.php.net/manual/en/language.modifier.regex.replace.php
* regex_replace (Smarty online manual)
* @author Monte Ohrt <monte at ohrt dot com>
*
* @param string $string input string
* @param string|array $search regular expression(s) to search for
* @param string|array $replace string(s) that should be replaced
* @param int $limit the maximum number of replacements
*
* @return string
*/
function smarty_modifier_regex_replace($string, $search, $replace, $limit = - 1)
{
if (is_array($search)) {
foreach ($search as $idx => $s) {
$search[ $idx ] = _smarty_regex_replace_check($s);
}
} else {
$search = _smarty_regex_replace_check($search);
}
return preg_replace($search, $replace, $string, $limit);
}
/**
* @param string $search string(s) that should be replaced
*
* @return string
* @ignore
*/
function _smarty_regex_replace_check($search)
{
// null-byte injection detection
// anything behind the first null-byte is ignored
if (($pos = strpos($search, "\0")) !== false) {
$search = substr($search, 0, $pos);
}
// remove eval-modifier from $search
if (preg_match('!([a-zA-Z\s]+)$!s', $search, $match) && (strpos($match[ 1 ], 'e') !== false)) {
$search = substr($search, 0, - strlen($match[ 1 ])) . preg_replace('![e\s]+!', '', $match[ 1 ]);
}
return $search;
}

View File

@@ -0,0 +1,34 @@
<?php
/**
* Smarty plugin
*
* @package Smarty
* @subpackage PluginsModifier
*/
/**
* Smarty replace modifier plugin
* Type: modifier<br>
* Name: replace<br>
* Purpose: simple search/replace
*
* @link http://smarty.php.net/manual/en/language.modifier.replace.php replace (Smarty online manual)
* @author Monte Ohrt <monte at ohrt dot com>
* @author Uwe Tews
*
* @param string $string input string
* @param string $search text to search for
* @param string $replace replacement text
*
* @return string
*/
function smarty_modifier_replace($string, $search, $replace)
{
if (Smarty::$_MBSTRING) {
require_once(SMARTY_PLUGINS_DIR . 'shared.mb_str_replace.php');
return smarty_mb_str_replace($search, $replace, $string);
}
return str_replace($search, $replace, $string);
}

View File

@@ -0,0 +1,27 @@
<?php
/**
* Smarty plugin
*
* @package Smarty
* @subpackage PluginsModifier
*/
/**
* Smarty spacify modifier plugin
* Type: modifier<br>
* Name: spacify<br>
* Purpose: add spaces between characters in a string
*
* @link http://smarty.php.net/manual/en/language.modifier.spacify.php spacify (Smarty online manual)
* @author Monte Ohrt <monte at ohrt dot com>
*
* @param string $string input string
* @param string $spacify_char string to insert between characters.
*
* @return string
*/
function smarty_modifier_spacify($string, $spacify_char = ' ')
{
// well… what about charsets besides latin and UTF-8?
return implode($spacify_char, preg_split('//' . Smarty::$_UTF8_MODIFIER, $string, - 1, PREG_SPLIT_NO_EMPTY));
}

View File

@@ -0,0 +1,66 @@
<?php
/**
* Smarty plugin
*
* @package Smarty
* @subpackage PluginsModifier
*/
/**
* Smarty truncate modifier plugin
* Type: modifier<br>
* Name: truncate<br>
* Purpose: Truncate a string to a certain length if necessary,
* optionally splitting in the middle of a word, and
* appending the $etc string or inserting $etc into the middle.
*
* @link http://smarty.php.net/manual/en/language.modifier.truncate.php truncate (Smarty online manual)
* @author Monte Ohrt <monte at ohrt dot com>
*
* @param string $string input string
* @param integer $length length of truncated text
* @param string $etc end string
* @param boolean $break_words truncate at word boundary
* @param boolean $middle truncate in the middle of text
*
* @return string truncated string
*/
function smarty_modifier_truncate($string, $length = 80, $etc = '...', $break_words = false, $middle = false)
{
if ($length == 0) {
return '';
}
if (Smarty::$_MBSTRING) {
if (mb_strlen($string, Smarty::$_CHARSET) > $length) {
$length -= min($length, mb_strlen($etc, Smarty::$_CHARSET));
if (!$break_words && !$middle) {
$string = preg_replace('/\s+?(\S+)?$/' . Smarty::$_UTF8_MODIFIER, '',
mb_substr($string, 0, $length + 1, Smarty::$_CHARSET));
}
if (!$middle) {
return mb_substr($string, 0, $length, Smarty::$_CHARSET) . $etc;
}
return mb_substr($string, 0, $length / 2, Smarty::$_CHARSET) . $etc .
mb_substr($string, - $length / 2, $length, Smarty::$_CHARSET);
}
return $string;
}
// no MBString fallback
if (isset($string[ $length ])) {
$length -= min($length, strlen($etc));
if (!$break_words && !$middle) {
$string = preg_replace('/\s+?(\S+)?$/', '', substr($string, 0, $length + 1));
}
if (!$middle) {
return substr($string, 0, $length) . $etc;
}
return substr($string, 0, $length / 2) . $etc . substr($string, - $length / 2);
}
return $string;
}

View File

@@ -0,0 +1,29 @@
<?php
/**
* Smarty plugin
*
* @package Smarty
* @subpackage PluginsModifierCompiler
*/
/**
* Smarty cat modifier plugin
* Type: modifier<br>
* Name: cat<br>
* Date: Feb 24, 2003<br>
* Purpose: catenate a value to a variable<br>
* Input: string to catenate<br>
* Example: {$var|cat:"foo"}
*
* @link http://smarty.php.net/manual/en/language.modifier.cat.php cat
* (Smarty online manual)
* @author Uwe Tews
*
* @param array $params parameters
*
* @return string with compiled code
*/
function smarty_modifiercompiler_cat($params)
{
return '(' . implode(').(', $params) . ')';
}

View File

@@ -0,0 +1,32 @@
<?php
/**
* Smarty plugin
*
* @package Smarty
* @subpackage PluginsModifierCompiler
*/
/**
* Smarty count_characters modifier plugin
* Type: modifier<br>
* Name: count_characteres<br>
* Purpose: count the number of characters in a text
*
* @link http://www.smarty.net/manual/en/language.modifier.count.characters.php count_characters (Smarty online manual)
* @author Uwe Tews
*
* @param array $params parameters
*
* @return string with compiled code
*/
function smarty_modifiercompiler_count_characters($params)
{
if (!isset($params[ 1 ]) || $params[ 1 ] != 'true') {
return 'preg_match_all(\'/[^\s]/' . Smarty::$_UTF8_MODIFIER . '\',' . $params[ 0 ] . ', $tmp)';
}
if (Smarty::$_MBSTRING) {
return 'mb_strlen(' . $params[ 0 ] . ', \'' . addslashes(Smarty::$_CHARSET) . '\')';
}
// no MBString fallback
return 'strlen(' . $params[ 0 ] . ')';
}

View File

@@ -0,0 +1,27 @@
<?php
/**
* Smarty plugin
*
* @package Smarty
* @subpackage PluginsModifierCompiler
*/
/**
* Smarty count_paragraphs modifier plugin
* Type: modifier<br>
* Name: count_paragraphs<br>
* Purpose: count the number of paragraphs in a text
*
* @link http://www.smarty.net/manual/en/language.modifier.count.paragraphs.php
* count_paragraphs (Smarty online manual)
* @author Uwe Tews
*
* @param array $params parameters
*
* @return string with compiled code
*/
function smarty_modifiercompiler_count_paragraphs($params)
{
// count \r or \n characters
return '(preg_match_all(\'#[\r\n]+#\', ' . $params[ 0 ] . ', $tmp)+1)';
}

View File

@@ -0,0 +1,27 @@
<?php
/**
* Smarty plugin
*
* @package Smarty
* @subpackage PluginsModifierCompiler
*/
/**
* Smarty count_sentences modifier plugin
* Type: modifier<br>
* Name: count_sentences
* Purpose: count the number of sentences in a text
*
* @link http://www.smarty.net/manual/en/language.modifier.count.paragraphs.php
* count_sentences (Smarty online manual)
* @author Uwe Tews
*
* @param array $params parameters
*
* @return string with compiled code
*/
function smarty_modifiercompiler_count_sentences($params)
{
// find periods, question marks, exclamation marks with a word before but not after.
return 'preg_match_all("#\w[\.\?\!](\W|$)#S' . Smarty::$_UTF8_MODIFIER . '", ' . $params[ 0 ] . ', $tmp)';
}

View File

@@ -0,0 +1,32 @@
<?php
/**
* Smarty plugin
*
* @package Smarty
* @subpackage PluginsModifierCompiler
*/
/**
* Smarty count_words modifier plugin
* Type: modifier<br>
* Name: count_words<br>
* Purpose: count the number of words in a text
*
* @link http://www.smarty.net/manual/en/language.modifier.count.words.php count_words (Smarty online manual)
* @author Uwe Tews
*
* @param array $params parameters
*
* @return string with compiled code
*/
function smarty_modifiercompiler_count_words($params)
{
if (Smarty::$_MBSTRING) {
// return 'preg_match_all(\'#[\w\pL]+#' . Smarty::$_UTF8_MODIFIER . '\', ' . $params[0] . ', $tmp)';
// expression taken from http://de.php.net/manual/en/function.str-word-count.php#85592
return 'preg_match_all(\'/\p{L}[\p{L}\p{Mn}\p{Pd}\\\'\x{2019}]*/' . Smarty::$_UTF8_MODIFIER . '\', ' .
$params[ 0 ] . ', $tmp)';
}
// no MBString fallback
return 'str_word_count(' . $params[ 0 ] . ')';
}

View File

@@ -0,0 +1,35 @@
<?php
/**
* Smarty plugin
*
* @package Smarty
* @subpackage PluginsModifierCompiler
*/
/**
* Smarty default modifier plugin
* Type: modifier<br>
* Name: default<br>
* Purpose: designate default value for empty variables
*
* @link http://www.smarty.net/manual/en/language.modifier.default.php default (Smarty online manual)
* @author Uwe Tews
*
* @param array $params parameters
*
* @return string with compiled code
*/
function smarty_modifiercompiler_default($params)
{
$output = $params[ 0 ];
if (!isset($params[ 1 ])) {
$params[ 1 ] = "''";
}
array_shift($params);
foreach ($params as $param) {
$output = '(($tmp = @' . $output . ')===null||$tmp===\'\' ? ' . $param . ' : $tmp)';
}
return $output;
}

View File

@@ -0,0 +1,117 @@
<?php
/**
* Smarty plugin
*
* @package Smarty
* @subpackage PluginsModifierCompiler
*/
/**
* @ignore
*/
require_once(SMARTY_PLUGINS_DIR . 'shared.literal_compiler_param.php');
/**
* Smarty escape modifier plugin
* Type: modifier<br>
* Name: escape<br>
* Purpose: escape string for output
*
* @link http://www.smarty.net/docsv2/en/language.modifier.escape count_characters (Smarty online manual)
* @author Rodney Rehm
*
* @param array $params parameters
* @param $compiler
*
* @return string with compiled code
*/
function smarty_modifiercompiler_escape($params, $compiler)
{
static $_double_encode = null;
if ($_double_encode === null) {
$_double_encode = version_compare(PHP_VERSION, '5.2.3', '>=');
}
try {
$esc_type = smarty_literal_compiler_param($params, 1, 'html');
$char_set = smarty_literal_compiler_param($params, 2, Smarty::$_CHARSET);
$double_encode = smarty_literal_compiler_param($params, 3, true);
if (!$char_set) {
$char_set = Smarty::$_CHARSET;
}
switch ($esc_type) {
case 'html':
if ($_double_encode) {
return 'htmlspecialchars(' . $params[ 0 ] . ', ENT_QUOTES, ' . var_export($char_set, true) . ', ' .
var_export($double_encode, true) . ')';
} elseif ($double_encode) {
return 'htmlspecialchars(' . $params[ 0 ] . ', ENT_QUOTES, ' . var_export($char_set, true) . ')';
} else {
// fall back to modifier.escape.php
}
case 'htmlall':
if (Smarty::$_MBSTRING) {
if ($_double_encode) {
// php >=5.2.3 - go native
return 'mb_convert_encoding(htmlspecialchars(' . $params[ 0 ] . ', ENT_QUOTES, ' .
var_export($char_set, true) . ', ' . var_export($double_encode, true) .
'), "HTML-ENTITIES", ' . var_export($char_set, true) . ')';
} elseif ($double_encode) {
// php <5.2.3 - only handle double encoding
return 'mb_convert_encoding(htmlspecialchars(' . $params[ 0 ] . ', ENT_QUOTES, ' .
var_export($char_set, true) . '), "HTML-ENTITIES", ' . var_export($char_set, true) . ')';
} else {
// fall back to modifier.escape.php
}
}
// no MBString fallback
if ($_double_encode) {
// php >=5.2.3 - go native
return 'htmlentities(' . $params[ 0 ] . ', ENT_QUOTES, ' . var_export($char_set, true) . ', ' .
var_export($double_encode, true) . ')';
} elseif ($double_encode) {
// php <5.2.3 - only handle double encoding
return 'htmlentities(' . $params[ 0 ] . ', ENT_QUOTES, ' . var_export($char_set, true) . ')';
} else {
// fall back to modifier.escape.php
}
case 'url':
return 'rawurlencode(' . $params[ 0 ] . ')';
case 'urlpathinfo':
return 'str_replace("%2F", "/", rawurlencode(' . $params[ 0 ] . '))';
case 'quotes':
// escape unescaped single quotes
return 'preg_replace("%(?<!\\\\\\\\)\'%", "\\\'",' . $params[ 0 ] . ')';
case 'javascript':
// escape quotes and backslashes, newlines, etc.
return 'strtr(' . $params[ 0 ] .
', array("\\\\" => "\\\\\\\\", "\'" => "\\\\\'", "\"" => "\\\\\"", "\\r" => "\\\\r", "\\n" => "\\\n", "</" => "<\/" ))';
}
}
catch (SmartyException $e) {
// pass through to regular plugin fallback
}
// could not optimize |escape call, so fallback to regular plugin
if ($compiler->template->caching && ($compiler->tag_nocache | $compiler->nocache)) {
$compiler->parent_compiler->template->compiled->required_plugins[ 'nocache' ][ 'escape' ][ 'modifier' ][ 'file' ] =
SMARTY_PLUGINS_DIR . 'modifier.escape.php';
$compiler->parent_compiler->template->compiled->required_plugins[ 'nocache' ][ 'escape' ][ 'modifier' ][ 'function' ] =
'smarty_modifier_escape';
} else {
$compiler->parent_compiler->template->compiled->required_plugins[ 'compiled' ][ 'escape' ][ 'modifier' ][ 'file' ] =
SMARTY_PLUGINS_DIR . 'modifier.escape.php';
$compiler->parent_compiler->template->compiled->required_plugins[ 'compiled' ][ 'escape' ][ 'modifier' ][ 'function' ] =
'smarty_modifier_escape';
}
return 'smarty_modifier_escape(' . join(', ', $params) . ')';
}

View File

@@ -0,0 +1,33 @@
<?php
/**
* Smarty plugin
*
* @package Smarty
* @subpackage PluginsModifierCompiler
*/
/**
* Smarty from_charset modifier plugin
* Type: modifier<br>
* Name: from_charset<br>
* Purpose: convert character encoding from $charset to internal encoding
*
* @author Rodney Rehm
*
* @param array $params parameters
*
* @return string with compiled code
*/
function smarty_modifiercompiler_from_charset($params)
{
if (!Smarty::$_MBSTRING) {
// FIXME: (rodneyrehm) shouldn't this throw an error?
return $params[ 0 ];
}
if (!isset($params[ 1 ])) {
$params[ 1 ] = '"ISO-8859-1"';
}
return 'mb_convert_encoding(' . $params[ 0 ] . ', "' . addslashes(Smarty::$_CHARSET) . '", ' . $params[ 1 ] . ')';
}

Some files were not shown because too many files have changed in this diff Show More