src.dualinventive.com/mtinfo/dist/webroot/rc-4.05/include/utilities.php

2478 lines
61 KiB
PHP

<?php
/** \file include\utilities.php
* \brief DI webinterface framework utilities
* \author Rob Schalken, Core|Vision
* \version $Revision: 26247 $
* \date $Date: 2016-02-29 10:40:22 +0100 (Mon, 29 Feb 2016) $
*
* This file contains the framework utilities
*/
require_once("security.php");
require_once("definitions.php");
require_once("mail.php");
/**
* Check whether this is an action or a page
*
* Inputs:
* - href: posted link
*
* Return: 1 (action)/0 (Page)
*/
function action($href) {
$pos = strpos($href, "action/");
if ($pos === FALSE) {
$result = 0;
}
else {
if (is_file(page_path($href))) {
$result = 1;
}
}
return $result;
}
/**
* Create compleet page path
*
* Inputs:
* - page: posted link
*
* Return: compleet page path
*/
function page_path($page) {
return (SCRIPT_DIR . $page . ".php");
}
/**
* Recursive stripslahes function
*
* Inputs:
* - value Array which must be stripped
*
* Return: Stripped array
*/
function stripslashes_deep($value)
{
if(isset($value)) {
$value = is_array($value) ? array_map('stripslashes_deep', $value) : stripslashes($value);
}
return $value;
}
/**
* Valid Tel/Fax number
*
* Inputs:
* - Number Telelphone or faxnumber
* - Empty_valid An empty number also valid?
*
* Return: 1(OK)/0(Error)
*/
function valid_fax_tel($number, $empty_valid = 1)
{
if ($empty_valid) {
$result = ((preg_match("/^(\+?[0-9().-\s]{8,20}|(\*|#)[#*0-9().-\s]+)$/", $number)) || (!strlen($number)));
}
else {
$result = (preg_match("/^(\+?[0-9().-\s]{8,20}|(\*|#)[#*0-9().-\s]+)$/", $number));
}
return $result;
}
/**
* Valid email
*
* Inputs:
* - Email Email
* - Empty_valid An empty email also valid?
*
* Return: 1(OK)/0(Error)
*/
function valid_email($email, $empty_valid = 1)
{
if ($empty_valid) {
$result = ((preg_match("/^([.0-9a-z_-]+)@(([0-9a-z-]+\.)+[0-9a-z]{2,4})([,;]([.0-9a-z_-]+)@(([0-9a-z-]+\.)+[0-9a-z]{2,4}))*$/i", $email)) || (!strlen($email)));
}
else {
$result = (preg_match("/^([.0-9a-z_-]+)@(([0-9a-z-]+\.)+[0-9a-z]{2,4})([,;]([.0-9a-z_-]+)@(([0-9a-z-]+\.)+[0-9a-z]{2,4}))*$/i", $email));
}
return $result;
}
/**
* Valid geo
*
* Inputs:
* - geo Geo
* - Empty_valid An empty geo also valid?
* - components Number of components required (1 for compatibility or 2)
*
* Return: 1(OK)/0(Error)
*/
function valid_geo($geo, $empty_valid = TRUE, $n_components = 1)
{
if (($empty_valid) && (!strlen($geo))) {
return TRUE;
}
else {
if( preg_match("/^(([+]|[-])?[0-9]{1,3}(\.[0-9]{0,7})?)(\s*,\s*(([+]|[-])?[0-9]{1,3}(\.[0-9]{0,7})?))?$/", $geo, $coordinates) ) {
$test = array(1,5);
$result = count($coordinates) > $test[$n_components - 1];
foreach( $test as $i ) {
if( count($coordinates) > $i ) {
$value = 0.0 + $geo;
if( $value < -180 || $value > 180 ) $result = FALSE;
}
}
return $result;
}
else {
// error
return FALSE;
}
}
}
/**
* Valid value
*
* Inputs:
* - value value
* - digitsb digits before point
* - digitsa digits after point
* - Empty_valid An empty number also valid?
*
* Return: 1(OK)/0(Error)
*/
function valid_value($value, $empty_valid = 1, $digitsb = 10, $digitsa = 2)
{
$before = ($digitsb - $digitsa);
if ($empty_valid) {
$result = ((preg_match("/^[0-9]{0,$before}(\.[0-9]{0,$digitsa})?$/", $value)) || (!strlen($value)));
}
else {
$result = (preg_match("/^[0-9]{0,$before}(\.[0-9]{0,$digitsa})?$/", $value));
}
return $result;
}
/**
* Convert date
*
* Inputs:
* - date Input date/
* - from_unix Convert from (0) or to (1) unix timestamp
*
* Return: unix date
*/
function convert_date($date, $from_unix = 0)
{
if (strlen($date)) {
if ($from_unix) {
$result = date('Y-m-d', $date);
}
else {
$array = explode("-", $date);
$result = mktime(0,0,0,$array[1],$array[2],$array[0]);
}
}
else {
$result = "";
}
return $result;
}
/**
* Convert datetime
*
* Inputs:
* - date Input date/timestamp
* - from_unix Convert from (0) or to (1) unix timestamp
*
* Return: unix timestamp/date
*/
function convert_datetime($datetime, $from_unix = 0)
{
// Initial values
$result = "";
if (strlen($datetime)) {
if ($from_unix) {
// Y2K+38 BUG!!
if ($datetime < 2145913200) {
$result = date('Y-m-d H:i:s', $datetime);
}
else {
DBG("Y2K+38 BUG!");
}
}
else {
$array = explode(" ", $datetime);
$date = ((count($array) > 0) && strlen($array[0])) ? explode("-", $array[0]) : array("0","0","0");
$time = ((count($array) > 1) && strlen($array[1])) ? explode(":", $array[1]) : array("0","0","0");
$result = mktime(intval($time[0]),intval($time[1]),intval($time[2]),intval($date[1]),intval($date[2]),intval($date[0]));
}
}
return $result;
}
/**
* Convert date/time to ISO 8601 date/time string
*
* Inputs:
* - date Input date/timestamp
* - flags ISO8601_xxx flags (orred)
*
* Return: ISO 8601 formatted string
*/
define("ISO8601_DEFAULT", 0);
define("ISO8601_WITH_DATE", 0); // placeholder
define("ISO8601_WITH_TIME", 0); // placeholder
define("ISO8601_NO_DATE", 0x0001);
define("ISO8601_NO_TIME", 0x0002);
define("ISO8601_WITH_TZ", 0x0010);
function iso8601($datetime, $flags = ISO8601_DEFAULT)
{
if( !is_numeric($datetime) ) $datetime = convert_datetime($datetime, FALSE);
// Build format string
$fmt = "";
if( !($flags & ISO8601_NO_DATE) ) $fmt .= "%Y%m%d";
if( !($flags & (ISO8601_NO_DATE | ISO8601_NO_TIME)) ) $fmt .= "T";
if( !($flags & ISO8601_NO_TIME) ) $fmt .= "%H%M%S";
if( ($flags & ISO8601_WITH_TZ) ) $fmt .= "%z";
return strftime($fmt, $datetime);
}
/**
* Input is a date/time string?
*/
function is_date($str)
{
if( !is_string($str) ) return FALSE;
$t = strtotime($str);
return !($t === FALSE) && !($t < 0);
}
/**
* Valid start/end date
*
* Inputs:
* - start Start date
* - end End date
*
* Return: 1(OK)/0(Error)
*/
function valid_start_end_date($start, $end)
{
$result = 0;
if ((strlen($start)) && (strlen($end))) {
$start_stamp = convert_date($start);
$end_stamp = convert_date($end);
// Check if end date is not before start date
if ($start_stamp < $end_stamp) {
$result = 1;
}
}
else {
$result = 1;
}
return $result;
}
/**
* Valid gps timestamp
*
* Inputs:
* - timestamp
*
* Return: 1(OK)/0(Error)
*/
function valid_gps_timestamp($timestamp)
{
// Initial values
$result = 0;
if (strlen($timestamp)) {
$array = explode(" ", $timestamp);
$date = explode("-", $array[0]);
// No gps date => 1 jan 1970
$result = ($date[0] == 1970) ? 0 : 1;
if ($result) {
// 1 day after now?
$result = (convert_datetime($timestamp) >= convert_datetime(date('Y-m-d H:i:s')) + 86400) ? 0 : $result;
}
}
return $result;
}
/**
* Valid start/end datetime
*
* Inputs:
* - start_date Start date
* - start_time Start time
* - end_date End date
* - end_time End time
*
* Return: 1(OK)/0(Error)
*/
function valid_start_end_datetime($start_date, $start_time, $end_date, $end_time)
{
$result = 0;
if ((strlen($start_date)) && (strlen($end_date))) {
$start_stamp = convert_datetime($start_date . " " . $start_time);
$end_stamp = convert_datetime($end_date . " " . $end_time);
// Check if end date is not before start date
if ($start_stamp < $end_stamp) {
$result = 1;
}
}
else {
$result = 1;
}
return $result;
}
/**
* Valid timestamp
*
* Inputs:
* - begin Begin date/datetime
* - eind Eind date/datetime
* - datetime (1) datetime/ (0) date
*
* Return: 1(OK)/0(Error)
*/
function valid_timestamp($begin, $eind, $datetime = 0)
{
$result = 1;
// retrieve current timestamp
$current = ($datetime) ? convert_datetime(date('Y-m-d H:i:s')) : convert_date(date('Y-m-d'));
// Convert database begin/end stamp
$begin = ($datetime) ? convert_datetime($begin) : convert_date($begin);
$end = ($datetime) ? convert_datetime($eind) : convert_date($eind);
if ((strlen($begin)) && (strlen($end))) {
if (($current < $begin) || ($current > $end)) {
$result = 0;
}
}
else if (strlen($begin)) {
if ($current < $begin) {
$result = 0;
}
}
else if (strlen($end)) {
if ($current > $end) {
$result = 0;
}
}
return $result;
}
/**
* convert timeperiod => valid timeperiod
*
* Inputs:
* - begin Begin date/datetime
* - eind Eind date/datetime
* - begin_period Begin period
* - end_period End period
*
* Return: array containing begin/end
*/
function convert_timeperiod($begin, $end, $begin_period, $end_period)
{
$result = "";
// Convert begin/end stamps
$begin_period = (strlen($begin_period)) ? convert_datetime($begin_period) : "";
$end_period = (strlen($end_period)) ? convert_datetime($end_period) : "";
$begin = (strlen($begin)) ? convert_datetime($begin) : "";
$end = (strlen($end)) ? convert_datetime($end) : "";
// valid begin/end
if ((strlen($begin)) && (strlen($end))) {
if ((strlen($begin_period)) && (strlen($end_period))) {
// Valid?
if (($begin <= $end_period) && ($end >= $begin_period)) {
// Correct start time?
if ($begin < $begin_period) {
$begin = $begin_period;
}
// Correct end time?
if ($end > $end_period) {
$end = $end_period;
}
$result = array(convert_datetime($begin,1), convert_datetime($end,1));
}
}
else if (strlen($begin_period)) {
// Valid?
if ($end >= $begin_period) {
// Correct start time?
if ($begin < $begin_period) {
$begin = $begin_period;
}
$result = array(convert_datetime($begin,1), convert_datetime($end,1));
}
}
else if (strlen($end_period)) {
// Valid?
if ($begin <= $end_period) {
// Correct end time?
if ($end > $end_period) {
$end = $end_period;
}
$result = array(convert_datetime($begin,1), convert_datetime($end,1));
}
}
else {
$result = array(convert_datetime($begin,1), convert_datetime($end,1));
}
}
else if (strlen($begin)) {
if ((strlen($begin_period)) && (strlen($end_period))) {
if (($begin >= $begin_period) && ($begin <= $end_period)) {
$result = array(convert_datetime($begin,1), convert_datetime($end,1));
}
}
else if (strlen($begin_period)) {
if ($begin >= $begin_period) {
$result = array(convert_datetime($begin,1), convert_datetime($end,1));
}
}
else if (strlen($end_period)) {
if ($begin <= $end_period) {
$result = array(convert_datetime($begin,1), convert_datetime($end,1));
}
}
else {
$result = array(convert_datetime($begin,1), convert_datetime($end,1));
}
}
else if (strlen($end)) {
if ((strlen($begin_period)) && (strlen($end_period))) {
if (($end >= $begin_period) && ($end <= $end_period)) {
$result = array(convert_datetime($begin,1), convert_datetime($end,1));
}
}
else if (strlen($begin_period)) {
if ($end >= $begin_period) {
$result = array(convert_datetime($begin,1), convert_datetime($end,1));
}
}
else if (strlen($end_period)) {
if ($end >= $end_period) {
$result = array(convert_datetime($begin,1), convert_datetime($end,1));
}
}
else {
$result = array(convert_datetime($begin,1), convert_datetime($end,1));
}
}
return $result;
}
/**
* Get HREF for the current page
*/
function get_page_href()
{
$href = $_GET['href'];
if( is_valid_action() ) {
$href .= "&action=" . current_action();
$call_actions = previous_action();
if( $call_actions ) $href .= "&call_action=" . $call_actions;
}
$href .= (isset($_GET['page_project'])) ? "&page_project=" . urlencode($_GET['page_project']) : "";
return $href;
}
/**
* Get current action
*
* Inputs:
* - full Include, separated by colons, the previous action
* (as a sort of stack with previous actions)
*
* Returns:
* - Action for this page, or FALSE on error
*/
function current_action($full = FALSE)
{
global $_PAGE_INFO;
if( isset($_SESSION[$_PAGE_INFO['id']]['action']) ) {
$action = $_SESSION[$_PAGE_INFO['id']]['action'];
if( $full && ($previous_action = previous_action()) ) {
$action .= ":" . $previous_action;
}
return $action;
}
else {
return FALSE;
}
}
/**
* Get previous action ('call' action)
*
* Returns:
* - Action for this page, or FALSE on error
*/
function previous_action($skip = 0, $full = TRUE)
{
global $_PAGE_INFO;
if( isset($_SESSION[$_PAGE_INFO['id']]['call_action']) ) {
$call_stack = explode(":", $_SESSION[$_PAGE_INFO['id']]['call_action']);
if( $skip ) $call_stack = array_splice($call_stack, $skip);
if( $full ) {
return implode(":", $call_stack);
}
else {
return $call_stack[0];
}
}
else {
return FALSE;
}
}
/**
* Get previous action ('return' action)
*
* Returns:
* - Action for this page, or FALSE on error
*/
function return_action()
{
global $_PAGE_INFO;
if( isset($_SESSION[$_PAGE_INFO['id']]['return_action']) ) {
$call_stack = explode(":", $_SESSION[$_PAGE_INFO['id']]['return_action']);
// return only the top of the stack (could be the full 'current_action' on the previous page)
return $call_stack[0];
}
else
return FALSE;
}
/**
* Check action
*
* Inputs:
* - actions Actions to check ("or" functionality)
*
* Return: Boolean
*/
function is_valid_action()
{
global $_PAGE_INFO;
if( !$_SESSION[$_PAGE_INFO['id']]['action'] ) {
return FALSE;
}
else if( func_num_args() ) {
// Check arguments
$index = 1; // one-based, so the caller can check "if( is_valid_action() ) ..."
foreach( func_get_args() as $arg ) {
if( fnmatch($arg, $_SESSION[$_PAGE_INFO['id']]['action']) )
return $index;
$index++;
}
return FALSE;
}
else {
// yes, return action is set
return TRUE;
}
}
/**
* Check call action
*
* Inputs:
* - actions Actions to check ("or" functionality)
*
* Return: FALSE if not a call action, positive integer (position in the history with '1' being
* the previous page) when this is valid call action or TRUE when not searching for a
* specific action
*/
function is_valid_call()
{
global $_PAGE_INFO;
if( !$_SESSION[$_PAGE_INFO['id']]['call_action'] ) {
return FALSE;
}
else if( func_num_args() ) {
// Check arguments
$call_actions = explode(":", $_SESSION[$_PAGE_INFO['id']]['call_action']);
$index = 1; // one-based, so the caller can check "if( is_valid_call() ) ..."
foreach( func_get_args() as $arg ) {
foreach( $call_actions as $action )
if( fnmatch($arg, $action) )
return $index;
$index++;
}
return FALSE;
}
else {
// yes, call action(s) are set
return TRUE;
}
}
// As above, but for the "return_action"
function is_valid_return()
{
global $_PAGE_INFO;
if( !$_SESSION[$_PAGE_INFO['id']]['return_action'] ) {
return FALSE;
}
else if( func_num_args() ) {
// Check arguments
$index = 1; // one-based, so the caller can check "if( is_valid_return() ) ..."
foreach( func_get_args() as $arg ) {
if( fnmatch($arg, $_SESSION[$_PAGE_INFO['id']]['return_action']) )
return $index;
$index++;
}
return FALSE;
}
else {
// yes, return action is set
return TRUE;
}
}
/**
* Returning by pressing the back button?
*/
function is_valid_backbutton()
{
if( !$_SERVER['HTTP_REFERER'] ) {
return FALSE;
}
else {
$url = parse_url($_SERVER['HTTP_REFERER']);
parse_str($url['query'], $referer_get);
// Check arguments
if( $referer_get['call_action'] ) {
$referer_call_actions = explode(":", $referer_get['call_action']);
$index = 1; // one-based, so the caller can check "if( is_valid_call() ) ..."
if( func_num_args() ) {
foreach( func_get_args() as $arg ) {
foreach( $referer_call_actions as $action )
if( fnmatch($arg, $action) )
return $index;
$index++;
}
return FALSE;
}
else return TRUE;
}
else return FALSE;
}
}
/**
* Call history
*
* Returns:
* Call stack (array) in ascending order or FALSE when not available
*/
function call_history()
{
global $_PAGE_INFO;
if( $_SESSION[$_PAGE_INFO['id']]['call_action'] ) {
$call_actions = explode(":", $_SESSION[$_PAGE_INFO['id']]['call_action']);
return array_reverse($call_actions);
}
else return FALSE;
}
/**
* Get current recall
*/
function current_recall()
{
global $_PAGE_INFO;
if( isset($_SESSION[$_PAGE_INFO['id']]['recall']) )
return $_SESSION[$_PAGE_INFO['id']]['recall'];
else
return FALSE;
}
/**
* Check recall
*
* Inputs:
*
* Return: 1(OK)/0(Error)
*/
function is_valid_recall()
{
global $_PAGE_INFO;
if( !$_SESSION[$_PAGE_INFO['id']]['recall'] ) {
return FALSE;
}
else if( func_num_args() ) {
// Check arguments
$index = 1; // one-based, so the caller can check "if( is_valid_recall() ) ..."
foreach( func_get_args() as $arg ) {
if( fnmatch($arg, $_SESSION[$_PAGE_INFO['id']]['recall']) )
return $index;
$index++;
}
return FALSE;
}
else {
// yes, recall is set
return TRUE;
}
}
/**
* Store recall
*
* Return TRUE when a recall is set, FALSE if not
*/
function store_recall($array)
{
global $_PAGE_INFO;
// Clear old recall action
unset($_SESSION[$_PAGE_INFO['id']]['recall']);
// Find new recall action
if (is_array($array)) {
foreach ($array as $key => $value) {
$pos = strpos($key, "recall_");
if ($pos !== FALSE) {
if (isset($_SESSION[$_PAGE_INFO['id']]['recall'])) {
$_SESSION[$_PAGE_INFO['id']]['recall'] = $_SESSION[$_PAGE_INFO['id']]['recall'] . "," . substr($key, ($pos + strlen("recall_")));
}
else {
$_SESSION[$_PAGE_INFO['id']]['recall'] = substr($key, ($pos + strlen("recall_")));
}
}
}
}
return isset($_SESSION[$_PAGE_INFO['id']]['recall']);
}
/**
* Clear recall
*/
function clear_recall()
{
unset($_SESSION[$_PAGE_INFO['id']]['recall']);
}
/**
* Set a (new) recall
*/
function set_recall($recall)
{
global $_PAGE_INFO;
// Clear old recall action
unset($_SESSION[$_PAGE_INFO['id']]['recall']);
// Set the new one
$_SESSION[$_PAGE_INFO['id']]['recall'] = $recall;
}
/**
* Strip time from date_time value
*
* Inputs:
* - date_time Date time value
*/
function strip_time($date_time) {
$array = explode(" ", $date_time);
return $array[0];
}
/**
* Strip date from date_time value
*
* Inputs:
* - date_time Date time value
*/
function strip_date($date_time, $skip_seconds = 1) {
$array = explode(" ", $date_time);
if ($skip_seconds) {
if (isset($array[1])) {
$pos1 = strpos($array[1], ":");
$start = (is_integer($pos1)) ? ($pos1 + 1) : 0;
$pos2 = strpos($array[1], ":", $start);
$result = substr($array[1], 0, $pos2);
}
else {
$result = "";
}
}
else {
$result = $array[1];
}
return $result;
}
/**
* Is Read only?
*
* Inputs:
* - $ro_array Read-only array (actions) _or_ boolean
*
* Return: Is read-only (boolean)
*/
function is_ro($ro_array) {
if (is_array($ro_array)) {
return in_array(current_action(), $ro_array);
}
else if( $ro_array ) {
return TRUE;
}
return FALSE;
}
/**
* Store href history
*
*/
function store_history($href) {
global $_PAGE_INFO;
// Store new value
$_SESSION[$_PAGE_INFO['id']]['href_history_prev'] = $_SESSION[$_PAGE_INFO['id']]['href_history'];
$_SESSION[$_PAGE_INFO['id']]['href_history'] = $href;
}
/**
* Detect browser
*
* Return: String containing browser
*/
function browser()
{
$browser_user_agent = (isset($_SERVER['HTTP_USER_AGENT']) ? $_SERVER['HTTP_USER_AGENT'] : '');
if(strstr($browser_user_agent, "Opera"))
{
return "OPERA";
}
else if(strstr($browser_user_agent, "SeaMonkey/"))
{
return "SEAMONKEY";
}
else if(strstr($browser_user_agent, "Netscape/") || stristr($browser_user_agent, "Navigator/"))
{
return "NETSCAPE";
}
else if(strstr($browser_user_agent, "Firefox/"))
{
return "FIREFOX";
}
else if(strstr($browser_user_agent, "Chrome/") || strstr($browser_user_agent, "CriOS/"))
{
// Chrome (all flavours, including iOS i.e. Chrome on an iPad)
return "CHROME";
}
else if(strstr($browser_user_agent, "MSIE") || strstr($browser_user_agent, "Trident/"))
{
// f###ing morons... in IE11, IE isn't called IE anymore
return "IE";
}
else if(strstr($browser_user_agent, "Safari/"))
{
if(strstr($browser_user_agent, "Mobile/"))
return "iPAD";
else
return "SAFARI";
}
else if(strstr($browser_user_agent, "Gecko") || strstr($browser_user_agent, "Mozilla/"))
{
return "MOZILLA";
}
else
{
return "UNKNOWN";
}
}
/**
* Detect browser version
*
* Return: version
*/
function browser_version() {
$browser_user_agent = $_SERVER['HTTP_USER_AGENT'];
$browser = browser();
$version = FALSE; // fall-back; shouldn't be returned
if( $browser == "IE" ) {
if( preg_match('/MSIE ([0-9]+\.[0-9]+)/', $browser_user_agent, $version) ) {
$version = $version[1];
}
else if( preg_match('/Trident\/([0-9]+\.[0-9]+)/', $browser_user_agent, $version) ) {
// Microsoft _deliberatly_ fucked up the user agent string:
// http://blogs.msdn.com/b/ieinternals/archive/2013/09/21/internet-explorer-11-user-agent-string-ua-string-sniffing-compatibility-with-gecko-webkit.aspx
preg_match('/rv:([0-9]+\.[0-9]+)/', $browser_user_agent, $version);
$version = $version[1];
}
}
else {
preg_match('/' . $browser . '[ \/]([0-9]+\.[0-9]+)/i', $browser_user_agent, $version);
$version = $version[1];
}
if( $version === FALSE ) {
error_log("Couldn't obtain browser version from \"" . $browser_user_agent . "\"");
}
return $version;
}
/**
* Get browser CSS prefix
*/
function browser_css_prefix()
{
switch( browser() ) {
case "IE":
return "-ms-";
case "FIREFOX":
case "SEAMONKEY":
case "MOZILLA":
return "-moz-";
default:
return "-webkit-";
}
}
/**
* Mobile browser?
*/
function is_mobile_browser()
{
// Device is a mobile device when the user agent string contains the word
// "Mobile" (Android, Applem and perhaps others, possibly followed by a
// slash and a hex-code (Apple) or somthing else
return
preg_match("/\bMobile(\/\w*)?\b/", $_SERVER['HTTP_USER_AGENT']) > 0;
}
/**
* create a random code
*
* Return: String containing random code (number-char-number-etc.)
*/
function createRandomCode($nmr) {
$chars = "abcdefghijkmnpqrstuvwxyz";
$nums = "023456789";
srand((double)microtime()*1000000);
$i = 0;
$pass = '' ;
while ($i < $nmr) {
if ($i % 2) {
$num = rand() % 25;
$tmp = substr($chars, $num, 1);
}
else {
$num = rand() % 9;
$tmp = substr($nums, $num, 1);
}
$pass = $pass . $tmp;
$i++;
}
return $pass;
}
/**
* Check device
*
* Return: Ok (1)/error (0)
*/
function is_dev() {
GLOBAL $_PAGE_INFO;
// Initial result value
$result = 0;
// Retrieve number of arguments
$numargs = func_num_args();
if ($numargs) {
// Retrieve arguments
$arg_list = func_get_args();
// Check arguments
for ($i = 0; $i < $numargs; $i++) {
if (strtolower($_PAGE_INFO['MTinfo_device']) == strtolower($arg_list[$i])) {
// Result OK
$result = 1;
}
}
}
return $result;
}
/**
* Get microtime
*/
function microtime_float()
{
list($usec, $sec) = explode(" ", microtime());
return ((float)$usec + (float)$sec);
}
/**
* Sort multidimesional araay
*/
function array_sort($array, $keyname, $type = SORT_STRING, $asc_desc = SORT_ASC) {
$sort_array = array();
// Retrieve data
if (is_array($array)) {
foreach($array as $key => $data) {
array_push($sort_array, strtolower($data[$keyname]));
}
array_multisort($sort_array, $type, $asc_desc, $array);
}
return $array;
}
/**
* Copy an array
*/
function array_copy($array)
{
return array_slice($array, 0, count($array));
}
/**
* Remove duplicated keys, also for multidimesional arrays
*/
function arrayUnique($array, $preserveKeys = false)
{
// Unique Array for return
$arrayRewrite = array();
// Array with the md5 hashes
$arrayHashes = array();
foreach($array as $key => $item) {
// Serialize the current element and create a md5 hash
$hash = md5(serialize($item));
// If the md5 didn't come up yet, add the element to
// to arrayRewrite, otherwise drop it
if (!isset($arrayHashes[$hash])) {
// Save the current element hash
$arrayHashes[$hash] = $hash;
// Add element to the unique Array
if ($preserveKeys) {
$arrayRewrite[$key] = $item;
} else {
$arrayRewrite[] = $item;
}
}
}
return $arrayRewrite;
}
/**
* Remove extension
*/
function RemoveExtension($strName)
{
$ext = strrchr($strName, '.');
if($ext !== false)
{
$strName = substr($strName, 0, -strlen($ext));
}
return $strName;
}
/**
* Get extension
*/
function GetExtension($strName)
{
$ext = strrchr($strName, '.');
return $ext;
}
/**
* Retrieve all timezones
*/
function retrieve_timezones()
{
// Initial value
$result = "";
if (file_exists(TIME_ZONE_FILE)) {
// open file which contain timezones
$handle = fopen(TIME_ZONE_FILE, 'r');
while(!feof($handle)) {
// Read line
$line = fgets($handle);
if ($line[0] != "#") {
// Parse into result
if (!is_array($result)) {
$result = array();
}
// Split by tabs
$line_array = split("\t", $line);
if ((strlen($line_array[2])) && (strlen($line_array[0]))) {
array_push($result, array(timezone => str_replace("\n","",$line_array[2]), code => $line_array[0]));
}
}
}
// Add UTC
if (is_array($result)) {
array_push($result, array(timezone => "UTC"));
}
// Close file
fclose($handle);
}
return array_sort($result, "timezone");
}
/**
* Get random image
*/
function get_random_image($dir, $allowed_ext = array("jpg", "png", "gif", "bmp", "ico"))
{
// Create file array
$files = array();
// Existing dir?
if (is_dir($dir)) {
// Open handle
if ($handle = opendir($dir)) {
// Read all files from dir
while($file = readdir($handle)) {
// Get extension
$ext = strtolower(substr(strrchr($file, "."), 1));
// Allowed extension?
if ((!is_array($allowed_ext)) || (in_array($ext, $allowed_ext))) {
if (($file != ".") && ($file != "..") && !is_dir($file)) {
array_push($files, $dir . $file);
}
}
}
// Close handle
closedir($handle);
}
}
// Select (random) image
if (empty($files)) {
$result = "";
}
else {
srand((float) microtime() * 10000000);
$result = $files[array_rand($files, 1)];
}
// Return image
return $result;
}
/**
* Get all files
*/
function get_all_files($dir, $allowed_ext = "")
{
// Create file array
$files = array();
// Existing dir?
if (is_dir($dir)) {
// Open handle
if ($handle = opendir($dir)) {
// Read all files from dir
while($file = readdir($handle)) {
// Get extension
$ext = strtolower(substr(strrchr($file, "."), 1));
// Allowed extension?
if ((!is_array($allowed_ext)) || (in_array($ext, $allowed_ext))) {
if (($file != ".") && ($file != "..") && !is_dir($file)) {
array_push($files, $dir . $file);
}
}
}
// Close handle
closedir($handle);
}
}
// Sort array
sort($files);
// Return files
return $files;
}
/**
* Get all directories
*/
function get_all_dirs($dir)
{
// Create dir array
$dirs = array();
// Existing dir?
if ($handle = opendir($dir)) {
if ($handle !== FALSE) {
do {
$dir = readdir($handle);
// Skip '.'/'..'/CVS
if (($dir !== FALSE) && ($dir != ".") && ($dir != "..") && ($dir != "CVS")) {
array_push($dirs, $dir);
}
}
while($dir !== FALSE);
}
}
// Sort array
sort($dirs);
// Return dir
return $dirs;
}
/**
* Define number of lines and return array containing lines
*/
function nmr_lines($text, $chars_on_line)
{
// Initial value
$result = array();
$finished = 0;
$index = 0;
do {
// Initial values
$skip = 0;
$length = 0;
// Find carriage return
$pos_cr = strpos($text, "\n");
// Found carriage return?
if (($pos_cr !== FALSE) && ($pos_cr <= $chars_on_line)) {
// Split up line
$length = $pos_cr;
// Skip cr char
$skip = 1;
}
// EOL
else if (strlen($text) <= $chars_on_line) {
$length = strlen($text);
}
else {
// Find space
$pos_space = strpos($text, " ");
// Found space
if (($pos_space !== FALSE) && ($pos_space <= $chars_on_line)) {
// Skip space char
$skip = 1;
// Initial counter value
$counter = $pos_space;
do {
// Find another space
$pos_space = strpos($text, " ", $counter + 1);
// Find one within chars_on_line?
if (($pos_space !== FALSE) && ($pos_space <= $chars_on_line)) {
// increment offset
$counter = $pos_space;
}
else {
// Split up line
$length = $counter;
}
} while (!$length);
}
else {
// Split up line after chars_on_line
$length = (strlen($text) >= $chars_on_line) ? $chars_on_line : strlen($text);
}
}
// Parse result
$result[$index++] = substr($text, 0, $length);
// Adapt text
$text = substr($text, ($length + $skip));
// Finished?
$finished = (!strlen($text)) ? 1 : 0;
} while(!$finished);
return $result;
}
/**
* Shorten text
*/
define("SHORTEN_NONE", 0);
define("SHORTEN_CAPS", 0x01);
define("SHORTEN_NARROW", 0x02);
define("SHORTEN_ALL", 0x03);
// flags
define("SHORTEN_HTML", 0x10);
define("SHORTEN_NO_SUFFIX", 0x20); // don't add an ellipsis after the string
function shorten_text($value, $max_size = 25, $adjust = SHORTEN_NONE, $html = TRUE)
{
// Initial value
$result = array();
// override 'html' flag
if( ($adjust & SHORTEN_HTML) ) $html = TRUE;
if( $html ) {
// count html character entities as one character
$value_wo_html = preg_replace("/&.+;/U", "x", $value);
$max_size += strlen($value) - strlen($value_wo_html);
}
else $value_wo_html = $value;
// Determine value length
for( $i = 0, $n = 0; $i < strlen($value); $i++ ) {
// copy the first 'max_size' characters, minding HTML characters like "&amp;"
if( $html && substr($value, $i, 1) == "&" ) {
$char = substr($value, $i, 1);
do {
$char .= substr($value, ++$i, 1);
} while( substr($value, $i, 1) != ";" && $i < strlen($value) );
}
else {
$char = substr($value, $i, 1);
// Adjust for wide and narrow characters?
if( $adjust && $n < $max_size ) {
// Clip the name of an item in the menu structure (minding nearower letters)
// Capitals and lower case 'm' and 'w' are wide
if( ($adjust & SHORTEN_CAPS) ) {
$max_size -= preg_match_all("/([A-Zmw])/", $char, $dummy) * 1.2;
$max_size -= preg_match_all("/([MW])/", $char, $dummy) * 1.2;
}
// Compensate for narrow letters
if( ($adjust & SHORTEN_NARROW) ) {
$max_size += preg_match_all("/([.,;:il])/", $char, $dummy) / 1.2;
}
}
}
$result[$n++] = $char;
}
if( count($result) > $max_size ) {
if( ($adjust & SHORTEN_NO_SUFFIX) ) {
$result = array_splice($result, 0, $max_size);
}
else {
$result = array_splice($result, 0, $max_size - 2);
$result[] = ($html ? "&hellip;" : "...");
}
}
return implode("", $result);
}
/**
* Tablet?
*/
function is_tablet() {
return ((!isset($_COOKIE['screen_width'])) || (!strlen($_COOKIE['screen_width'])) || ($_COOKIE['screen_width'] >= 1024)) ? 0 : 1;
}
/**
* Write cookie
*/
function WriteCookie($key, $value, $remove = 0, $days = 100) {
if (!$remove) {
$datetime = time() + $days * (24 * 60 * 60);
}
else {
$datetime = time();
}
// Set secured/http only (only for 5.2.0 or higher) cookie
if (PHPValid(5,2,0)) {
setcookie($key, $value, $datetime, "/", "", TRUE, TRUE);
}
else {
setcookie($key, $value, $datetime, "/", "", TRUE);
}
}
/**
* Update globals
*/
function UpdateGlobals() {
global $_PAGE_INFO;
// First all root items
$items = array("i18n","valuta","base","base_path","skin_name","skin","logged_on");
foreach($items as $item) {
if (isset($_SESSION[$_PAGE_INFO['id']][$item])) {
$_PAGE_INFO[$item] = $_SESSION[$_PAGE_INFO['id']][$item];
}
}
// Next all login items
$items = array("user","customer","project");
foreach($items as $item) {
if (isset($_SESSION[$_PAGE_INFO['id']]['login'][$item]['id'])) {
$_PAGE_INFO['login'][$item]['id'] = $_SESSION[$_PAGE_INFO['id']]['login'][$item]['id'];
}
}
// Cache user rights
if( isset($_SESSION[$_PAGE_INFO['id']]['login']['user']['id']) ) {
$user = db_fetch_user($_SESSION[$_PAGE_INFO['id']]['login']['user']['id'],"",1);
$_PAGE_INFO['user']['rights'] = $user['rechten'];
}
}
/**
* Send RS3000 message
*/
function SendMessageRS3000($params = "") {
GLOBAL $_PAGE_INFO;
// Initial values
$message = "";
$split_char = ",";
// Send session id
$message = "id='" . $_PAGE_INFO['id'] ."'";
// Send i18n
if (isset($_PAGE_INFO['i18n'])) {
$message .= $split_char . "i18n='" . $_PAGE_INFO['i18n'] . "'";
}
// Send project id
if (isset($_PAGE_INFO['login']['project']['id'])) {
$message .= $split_char . "page_project='" . $_PAGE_INFO['login']['project']['id'] . "'";
}
// motd?
$motd = db_fetch_system_maint_mes($_PAGE_INFO['i18n']);
if (is_array($motd)) {
if (strlen($motd['onderhoud'])) {
$message .= $split_char . "motd='" . str_replace($split_char, " ", $motd['onderhoud']) . "'";
}
}
// Send params
if (is_array($params)) {
$message .= $split_char . implode($split_char, $params);
}
if (strlen($message)) {
if (LOG_RS) {
if ((!empty($_SESSION[$_PAGE_INFO['id']]['login']['imei'])) || (!empty($_SESSION[$_PAGE_INFO['id']]['login']['user']['id']))) {
$user_info = (!empty($_SESSION[$_PAGE_INFO['id']]['login']['user']['id'])) ? "user: " . $_SESSION[$_PAGE_INFO['id']]['login']['user']['id'] : "";
$imei_info = (!empty($_SESSION[$_PAGE_INFO['id']]['login']['imei'])) ? "imei: " . $_SESSION[$_PAGE_INFO['id']]['login']['imei'] : "";
$separator = ((!empty($_SESSION[$_PAGE_INFO['id']]['login']['imei'])) && (!empty($_SESSION[$_PAGE_INFO['id']]['login']['user']['id']))) ? ", " : "";
DBG("RS3000 (" . $user_info . $separator . $imei_info . "): " . $message);
}
else {
DBG("RS3000: " . $message);
}
}
echo $message;
}
}
/*
* Debug function
*/
function DBG($value, $email = "") {
// Get IP
$remote_addr = (isset($_SERVER['HTTP_X_FORWARDED_FOR'])) ? " (" . $_SERVER['HTTP_X_FORWARDED_FOR'] . ")" : ((isset($_SERVER['REMOTE_ADDR'])) ? " (" . $_SERVER['REMOTE_ADDR'] . ")" : "");
if (is_array($value)) {
$count = 0;
foreach($value as $key => $item) {
syslog(LOG_INFO, "MTinfo debug" . $remote_addr . ": " . (sprintf("%-15s",$key)) . ": " . (sprintf("%-50s",$item)) . "(" . ++$count . "/" . sizeof($value) . ")");
if (strlen($email)) {
if (valid_email($email, FALSE)) {
send_mail($email, "", "", "debug@dualinventive.com", "MTinfo debug", $value[$i] . "(" . $i . "/" . sizeof($value) . ")");
}
}
}
}
else if (strlen($value)) {
syslog(LOG_INFO, "MTinfo debug" . $remote_addr . ": " . $value);
if (strlen($email)) {
if (valid_email($email, FALSE)) {
send_mail($email, "", "", "debug@dualinventive.com", "MTinfo debug", $value);
}
}
}
}
/**
* Is this release candidate?
*
* Return: Release candidate (TRUE)/Release (FALSE)
*/
function is_ReleaseCandidate() {
GLOBAL $_RELEASE;
// Initial result value
$result = FALSE;
// Does the script name contain release candidate directory?
$result = (!strlen($_RELEASE['rc']['dir']) || stristr(realpath($_SERVER['SCRIPT_FILENAME']), $_RELEASE['rc']['dir']) === FALSE) ? FALSE : TRUE;
return $result;
}
/**
* Calculate duration
*
* Return: String containing duration
*/
function CalculateDuration($start, $end) {
$duration = convert_datetime($end) - convert_datetime($start);
$hours = (int)($duration / 3600);
$duration = (int)$duration - ($hours * 3600);
$minutes = (int)($duration / 60);
$duration = (int)$duration - ($minutes * 60);
$seconds = (int)($duration);
return sprintf("%02u:%02u:%02u", $hours, $minutes, $seconds);
}
/**
* Format a duration in seconds to a human readable string
*
* Inputs:
* - duration In seconds
* - format For future use. Currently, it is a boolean to indicate
* that the output should be in hours/minutes (when TRUE)
* or minutes/seconds (when FALSE)
*
* Returns a formatted string
*/
function FormatDuration($duration, $format /* currently a very limited boolean: show seconds */ = FALSE)
{
if( $duration >= 60 || $format ) {
if( $format ) {
// hours and minutes
return sprintf(_("FORMAT_ELAP_HOUR_MIN"), intval($duration / 3600), intval(($duration / 60) % 60));
}
else if( $duration >= 3600 ) {
// minutes and seconds
return sprintf(_("FORMAT_ELAP_HOUR_MIN_SEC"), intval($duration / 3600), intval(($duration / 60) % 60), intval($duration % 60));
}
else {
// minutes and seconds
return sprintf(_("FORMAT_ELAP_MIN_SEC"), intval($duration / 60), intval($duration % 60));
}
}
else {
// seconds only
return sprintf(_("FORMAT_ELAP_SEC"), intval($duration));
}
}
/**
* Convert a human readable string to a duration in seconds
* Returns FALSE when '$str' is invalid
*/
function ConvertDuration($str, $format /* as above */ = FALSE)
{
$pattern = _("REGEX_FORMAT_ELAP");
$pos = explode(",", _("REGEX_POS_ELAP"));
$n = preg_match($pattern, $str, $duration);
if( $n ) {
if( is_numeric($str) ) {
if( $format )
return $str * 3600;
else
return $str * 60;
}
else {
// hour:minute:second
$a1 = $duration[$pos[0]];
$a2 = $duration[$pos[1]];
$a3 = $duration[$pos[2]];
if( $duration[$pos[3]] == _("REGEX_TIME_SEP") ) {
if( strlen($a2) == 0 ) {
// hour:min or min:sec
if( $format )
return ($a1 * 3600) + ($a3 * 60);
else if( strlen($a3) == 0 )
return $a1; // seconds only
else
return ($a1 * 60) + $a3;
}
else {
// hour:min:sec
return ($a1 * 3600) + ($a2 * 60) + $a3;
}
}
else {
// human readable
return ($a1 * 3600) + ($a2 * 60) + $a3;
}
}
}
else return FALSE;
}
/**
* Next service date
*
* Return: String containing next service date
*/
function NextService($service, $sw3000) {
// Get next switch memory service date
$sw3000_service = strtotime(date("Y-m-d", strtotime($sw3000)) . " +4 years");
if (strlen($sw3000)) {
if ((!strlen($service)) || (convert_datetime($service) > $sw3000_service)) {
$service = convert_datetime($sw3000_service, TRUE);
}
}
return $service;
}
/**
* Hash a password
*
* See "CheckPassword()" below for notes and the history of this function.
*/
function HashPassword($input, $uid) {
// Salt which will be added to password
if( $uid ) {
// "random" salt as recommened by security audit (v1.0 of 20131023)
// the 'bcrypt' algorithm is not available, so we will resort to SHA-1
// with a "random" salt based on the user-id (which is random for any
// third party, so there is no reason not to...)
$uid = intval($uid);
$salt_prefix = "\x50\x31";
$salt_suffix = "\x53\x84";
for( $i = 0; $i <= 30; $i += 6 ) {
$salt_prefix .= chr(($uid >> $i) & 0xFF);
$salt_suffix .= chr(($uid >> (30 - $i)) & 0xFF);
}
return sha1($salt_prefix . strtolower($input) . $salt_suffix);
}
else {
$salt = "/$DI$/SALT&/";
return md5($salt . strtolower($input) . $salt);
}
}
/**
* Check password
*
* Input:
* - input User input (plain text)
* - password Encrypted/hashed password in the database to match
* - uid User identifier
* Returns:
* - FALSE or one of the defines below (which will evaluate to "TRUE" where needed)
*
* Notes and history:
* - The first version only matched MD5 hashes, but this was considered
* inadequate after the first security audit. A "salt" was added.
* - After the second security audit, a fixed salt was no longer adequate
* so the salt is now "randomized" (i.e. the user-id is added to the
* "salt" as this is hidden information and therefore sufficiently random
* as the purpose of the salt is to prevent that an external party can
* "guess" the passwords using a rainbow table or whichever other technique)
* - The recommended "bcrypt()" function is not documented (and the site
* "php.net" is down because theire HTTPS certificate has been revoked???).
* The function "crypt()", which does have an implementation of the blowfish
* algorithm, does not seem to return valid data on both 'arcfs12' and the
* 'rootnet' servers. The output should be used as 'salt' to check the
* user's password, but this does not work nor does it produce the same
* output as the examples??? Moreover, when the (obviously) incorrect output
* was used, it simply returned the "salt" as its output in a second run,
* regardless of the data (password) to hash.
* - An extra effort will be made to make sure that the encrypted passwords
* are not visible, so it will be impossible to match them against a
* "rainbow table". Note that the encrypted password were only "visible" in
* the HTML source of the "change user" (and the similar "change password")
* page and only when a user was logged in.
* - The fact that MD5 or SHA1 are "too quick" is <stike>nonsense</strike>
* disputable; see the comments made on the page below:
* "http://us3.php.net/manual/en/faq.passwords.php#faq.passwords.fasthash"
* Besides that, this only applies when an attacker gets hold of the database
* data (or hashed passwords in general) and this should be avoided at all
* cost as this would render any encryption void. Security starts at the
* front door.
*/
define("PASSWD_MD5", 1);
define("PASSWD_SALTED", 2);
define("PASSWD_RND_SALT", 3);
define("PASSWD_BCRYPT", 4); // perhaps some time in the future
// the next define is used during the login process to automatically upgrade
// the user's password to the recommended encryption; older encryptions
// (MD5, salted MD5) may be discontinued in the future and any user that
// hasn't logged on since this automatic upgrade has been effectuated, will
// not be able to do so when the old encryption methods are no longer
// supported
// NOTE / TO DO: the automatic upgrading of passwords must be activated
// when this functionality is in the live tree; NOT BEFORE!
define("PASSWD_RECOMMENDED_ENCRYPTION", 0);
// TO DO TO ACTIVATE AUTOMATIC UPGRADES: define("PASSWD_RECOMMENDED_ENCRYPTION", PASSWD_RND_SALT);
// display text for password; control characters would have been nice (because
// the user cannot enter those) but the browser (or HTTP RFC) filters those
// out, so no such luck there.
define("PASSWD_DISPLAY_TEXT", "sterretjes");
function CheckPassword($input, $password, $uid) {
if( !$uid ) return FALSE;
if( md5(strtolower($input)) == $password )
return PASSWD_MD5;
else if( HashPassword($input, NULL) == $password )
return PASSWD_SALTED;
else if( HashPassword($input, $uid) == $password )
return PASSWD_RND_SALT;
else
return FALSE;
}
/**
* Check password complexity
*
* Input
* - plain text password
*
* Returns: boolean (TRUE if the password is sufficiently complex, FALSE if not)
*
* Note: there are no rules at the moment, so this function only checks that
* the password is not empty.
*/
function CheckPasswordComplexity($input)
{
return strlen($input) > 0;
}
/**
* Check directory
*/
function CheckDirectory($allowedDir, $actualFile) {
// Initial values
$result = FALSE;
$actualFile = realpath(dirname($actualFile));
if (is_array($allowedDir)) {
foreach($allowedDir as $dir) {
$dir = realpath($dir);
if (($dir !== FALSE) && ($actualFile !== FALSE)) {
if ($dir == $actualFile) {
$result = TRUE;
}
}
}
}
else {
$allowedDir = realpath($allowedDir);
if (($allowedDir !== FALSE) && ($actualFile !== FALSE)) {
if ($allowedDir == $actualFile) {
$result = TRUE;
}
}
}
return $result;
}
/**
* Calculate Short circuit quality
*/
function CalcShortCircuitQuality($b_a_limit, $b_a_current) {
$val = (100 * (1 - (pow(($b_a_current - 0.125),4)/pow(($b_a_limit - 0.125),4))));
return ($val < 0) ? 0 : $val;
}
/**
* Check for active branch
*/
function ActiveBranch() {
global $_DEFAULT, $_HOSTNAME;
return in_array(file_get_contents($_DEFAULT['active_branch']), $_HOSTNAME);
}
/**
* Load page contents in-line
* (currently the same as "include")
*/
function PageLoadContents($php_script)
{
global $_PAGE_INFO;
include($php_script);
}
/**
* Build a valid URL
*
* - href Page to call
* - action Action
* - param Additional GET parameters as
* - a properly encoded string
* - an associated array (not encoded)
*/
function build_url($href, $action = FALSE, $param = FALSE)
{
global $_PAGE_INFO;
// build the URL
$url = "?id=" . $_PAGE_INFO['id'];
$url .= "&href=" . $href;
if( $action ) {
$url .= "&action=" . $action;
}
if( $_GET['page_project'] ) {
$url .= "&page_project=" . urlencode($_GET['page_project']);
}
if( $param ) {
if( is_array($param) ) {
foreach( $param as $key => $value )
$url .= "&" . $key . "=" . urlencode($value);
}
else {
// URL encoded string
$url .= "&" . $param;
}
}
return $url;
}
/**
* Redirect to a page
*
* Inputs:
* - href Page to call
* - action Action
* - param Additional GET parameters as
* - a properly encoded string
* - an associated array (not encoded)
* - target Target window (same window by default)
*/
function _page_redirect($href, $action = FALSE, $param = FALSE, $target = "_self")
{
global $_PAGE_INFO;
// build the URL
$url = build_url($href, $action, $param);
echo "<script type=\"text/javascript\">\n";
// "location.href" will _not_ set the browser history
if( FALSE /* fix for US-33, DITWS-10 */ && $target == "_self" ) {
echo "location.href='" . $url . "';\n";
}
else {
echo "window.open('" . $url . "','" . $target . "');\n";
}
echo "</script>\n";
}
function PageRedirect($href, $action = FALSE, $param = FALSE)
{
_page_redirect($href, $action, $param, "_self");
}
function PageNewWindow($href, $action, $param)
{
_page_redirect($href, $action, $param, "_blank");
}
function PageCall($href, $action = FALSE, $param = FALSE)
{
if( !$param ) {
$param = array();
}
else if( !is_array($param) ) {
parse_str($param, $param_array);
$param = $param_array;
}
$param['call_action'] = current_action(TRUE);
_page_redirect($href, $action, $param);
}
function PageReturn($href, $param)
{
if( !$param ) {
$param = array();
}
else if( !is_array($param) ) {
parse_str($param, $param_array);
$param = $param_array;
}
$param['return_action'] = current_action(TRUE);
_page_redirect($href, previous_action(), $param);
}
/**
* Object to array conversion
*/
function object_to_array($data)
{
if(is_array($data) || is_object($data))
{
$result = array();
foreach($data as $key => $value)
{
$result[$key] = object_to_array($value);
}
return $result;
}
return $data;
}
/**
* Get maximum value from an array
*/
function array_max($array, $key = NULL, $default = NULL)
{
unset($max);
if( is_array($array) ) {
if( is_null($key) ) {
foreach( $array as $item )
if( !isset($max) || $item > $max )
$max = $item;
}
else {
foreach( $array as $item )
if( !isset($max) || $item[$key] > $max )
$max = $item[$key];
}
}
// return the default when the array is empty (or non-existent)
if( !isset($max) && !is_null($default) )
return $default;
else
return $max;
}
/**
* Extended "is_null()"
*/
function _is_null($value)
{
return is_null($value) || $value == "NULL";
}
/*
* Re-order an associative array
*/
function _array_set_keys($a, $field)
{
$result = array();
foreach( $a as $value )
$result[$value[$field]] = $value;
return $result;
}
/**
* Improved 'explode()'. Returns an empty array when the input is an
* empty string.
*/
function _explode($delimiter, $string)
{
if( trim($string) === "" )
$a = array();
else {
$a = explode($delimiter, $string);
}
return $a;
}
/**
* Improved "implode()"
*/
function _implode($delimiter, $a, $callback = NULL)
{
if( !is_array($a) ) $a = array($a);
if( $callback )
foreach( $a as $i => $value )
$a[$i] = call_user_func($callback, $a[$i]);
return implode($delimiter, $a);
}
/**
* Encrypt data
*/
function encrypt($data, $password)
{
return base64_encode($password . $data);
}
/**
* Decrypt data
*/
function decrypt($data, $password)
{
return substr(base64_decode($data), strlen($password));
}
/**
* Check if current php version is valid (or higher of course)
*/
function PHPValid($major, $minor, $release)
{
// Initial value
$result = TRUE;
// Get php version
$version = phpversion();
// Difference between php versions
if (!is_array($version)) {
$version = explode('.', $version);
}
if ($major > $version[0]) {
$result = FALSE;
}
else if ($major == $version[0]) {
if ($minor > $version[1]) {
$result = FALSE;
}
else if ($minor == $version[1]) {
if ($release > $version[2]) {
$result = FALSE;
}
}
}
return $result;
}
/**
* Check if a string is serialized
* @param string $string
*/
function is_serial($string) {
return (@unserialize($string) !== false || $string == 'b:0;');
}
/**
* Encode characters when inserting into the database
*/
function specialchars($str, $db_insert = TRUE) {
if( $db_insert )
return addcslashes($str, "'");
else
return addslashes($str);
}
/**
* htmlspecialchars for array (recursive)
* @param string $string
*/
function htmlspecialchars_array(&$variable) {
foreach ($variable as &$value) {
if (!is_array($value)) {
$value = specialchars($value);
}
else {
htmlspecialchars_array($value);
}
}
}
/**
* htmlspecialchars_decode for array (recursive)
* @param string $string
*/
function htmlspecialchars_decode_array(&$variable) {
foreach ($variable as &$value) {
if (!is_array($value)) {
$value = htmlspecialchars_decode($value, ENT_QUOTES);
}
else {
htmlspecialchars_decode_array($value);
}
}
}
/**
* Remove spaces and other special characters for a filename
*/
function make_filename($text)
{
return preg_replace("(\s+|_+|\&[a-z0-9]+;|\&)", "_", $text);
}
/**
* The function 'array_column()' was introduced in PHP 5.5
*/
if( !function_exists("array_column") ) {
function array_column($array, $key, $index_key = NULL)
{
$column_data = array();
if( is_null($index_key) ) {
foreach( $array as $row ) {
$column_data[] = $row[$key];
}
}
else {
foreach( $array as $row ) {
$column_data[$row[$index_key]] = $row[$key];
}
}
return $column_data;
}
}
/**
* Report a (serious) exception in MTinfo
* - Log to 'syslog'
* - Send e-mail (optional)
* - Redirect (optional); will exit when redirected
*/
function report_error($msg, $redirect_url = FALSE, $send_mail = TRUE)
{
global $_PAGE_INFO, $_RELEASE;
$release = (is_ReleaseCandidate() ? "rc" : "release");
if( !$_PAGE_INFO['mtinfo-dev'] ) {
// log
DBG("Error: " . $msg);
// and send e-mail
if( $send_mail && $_RELEASE[$release]['e-mail'] && $_RELEASE[$release]['e-mail']['error'] ) {
send_mail(
$_RELEASE[$release]['e-mail']['error'], "", "", "error@dualinventive.com",
"MTinfo Warning (" . php_uname("n") . ")",
"<p><b>Message</b>:<br>" . $msg . "</p><p><b>Backtrace</b>:<br>" . calltrace("text/html", 1) . "</p>",
"", "", 1
);
}
if( $redirect_url ) {
header($redirect_url);
exit(0);
}
}
else {
// development site
echo "<h1>" . $msg . "</h1>\n";
echo "<p>" . calltrace("text/html") . "</p>\n";
}
}
/**
* Catch illegal access
* - Log to 'syslog'
* - Send e-mail
* - Log out the user forcefully (redirect user to the log-in page)
* - Exit immediately
*
* Parameters:
* - usermsg Message displayed to the user
* - logmsg Message for the log (can/should contain more
* detailed information; optional)
* Returns:
* Doesn't return
*/
function force_logout($usermsg, $logmsg = null)
{
global $_PAGE_INFO, $_RELEASE;
$release = (is_ReleaseCandidate() ? "rc" : "release");
// is there a more detailed log message? if not, show the same message
// as the user gets
if( is_null($logmsg) ) $logmsg = $usermsg;
// log
error_log($logmsg);
// do not forcefully log out the user when on the development site
if( !$_PAGE_INFO['mtinfo-dev'] ) {
// log
DBG($logmsg);
// and send e-mail
if( $_RELEASE[$release]['e-mail'] && $_RELEASE[$release]['e-mail']['abuse'] ) {
send_mail(
$_RELEASE[$release]['e-mail']['abuse'], "", "", "abuse@dualinventive.com",
"MTinfo Abuse Warning (" . php_uname("n") . ")",
"<p><b>Message</b>:<br>" . $logmsg . "</p><p><b>Backtrace</b>:<br>" . calltrace("text/html", 1) . "</p>",
"", "", 1
);
}
// display logout message
$_SESSION[$_PAGE_INFO['id']]['login_info']['errormsg'] = $usermsg;
$_SESSION[$_PAGE_INFO['id']]['login_info']['username'] = $_SESSION[$_PAGE_INFO['id']]['login']['user']['name'];
$_SESSION[$_PAGE_INFO['id']]['login_info']['customer'] = $_SESSION[$_PAGE_INFO['id']]['login']['customer']['name'];
// redirect page back to login page
PageRedirect(PAGE_LOGIN);
}
else {
// debug
echo "<h1>" . $logmsg . "</h1>\n";
echo "<p>" . calltrace("text/html") . "</p>\n";
}
// do not perform any further processing (user is redirected to the login page)
die($usermsg);
}
/**
* Support for error tracing: get the call trace as a string
*
* Inputs:
* - convert Convert output (string parameter: MIME type), currently
* only "html" and anything else is plain text
* - skip_frame Skip the first frames; by default only frame #0
* is skipped (the function 'backtrace()' itself)
*/
function calltrace($convert = FALSE, $skip_frame = 0, $print_args = TRUE)
{
$backtrace = "";
$frame = 0;
$call_trace = debug_backtrace();
foreach( $call_trace as $call ) {
if( $frame > $skip_frame ) {
$backtrace .= "#" . ($frame++ - $skip_frame - 1) . " ";
if( $print_args ) {
if( $call['class'] ) $backtrace .= $call['class'] . " ";
if( $call['object'] ) $backtrace .= serialize($call['object']);
}
else {
if( $call['object'] ) $backtrace .= get_class($call['object']);
}
$backtrace .= $call['type'] . $call['function'] . "(";
$sep = "";
if( $print_args && $call['args'] ) foreach( $call['args'] as $arg ) {
$backtrace .= $sep;
$sep = ",";
if( is_null($arg) ) $backtrace .= "NULL";
else if( is_string($arg) ) $backtrace .= "\"" . $arg . "\"";
else if( is_bool($arg) ) $backtrace .= ($arg ? "TRUE" : "FALSE");
else if( is_array($arg) ) $backtrace .= print_r($arg, TRUE);
else $backtrace .= $arg;
}
$backtrace .= ") [" . $call['file'] . ":" . $call['line'] . "]\n";
}
else {
// no use showing the "db_report_slow_query" frame
$frame++;
}
}
// convert output?
if( $convert ) switch( strtolower($convert) ) {
case "html":
case "text/html": // mime type :-)
$backtrace = nl2br(specialchars($backtrace));
break;
// default: text/plain
}
return $backtrace;
}
/**
* P()
* Acquire semaphore
*
* Inputs:
* - id: Semaphore identifier
*
* Return: Semaphore handle
*/
function db_sema_acquire($id) {
// Get sema id
$sem = sem_get(bin2hex($id), 1, 0600);
// Wait for semaphore
sem_acquire($sem);
// return handle
return $sem;
}
/**
* V()
* Release semaphore
*
* Inputs:
* - id: Semaphore handle
*
* Return: 1 (OK)/ 0(Error)
*/
function db_sema_release($handle) {
// Release semaphore
sem_release($handle);
return TRUE;
}
?>