2478 lines
61 KiB
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 "&"
|
|
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 ? "…" : "...");
|
|
}
|
|
}
|
|
|
|
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;
|
|
}
|
|
|
|
?>
|