mirror of
https://github.com/EGroupware/egroupware.git
synced 2024-12-02 21:07:12 +01:00
438 lines
12 KiB
PHP
Executable File
438 lines
12 KiB
PHP
Executable File
<?php
|
|
/**
|
|
* EGroupware create enviroment:
|
|
* - autoloader
|
|
* - exception handler
|
|
* - XSS and other security stuff
|
|
* - global functions (incl. deprecated ones, if /phpgwapi dir is there)
|
|
*
|
|
* @link http://www.egroupware.org
|
|
* @author Ralf Becker <RalfBecker-AT-outdoor-training.de>
|
|
* @package api
|
|
* @license http://opensource.org/licenses/gpl-license.php GPL - GNU General Public License
|
|
* @version $Id$
|
|
*/
|
|
|
|
use EGroupware\Api;
|
|
|
|
require_once dirname(__DIR__).'/autoload.php';
|
|
|
|
/**
|
|
* To ease PHP 8.0 migration
|
|
*/
|
|
if (!function_exists('get_magic_quotes_gpc'))
|
|
{
|
|
function get_magic_quotes_gpc()
|
|
{
|
|
return false;
|
|
}
|
|
}
|
|
|
|
/**
|
|
* applies stripslashes recursively on each element of an array
|
|
*
|
|
* @param array &$var
|
|
* @return array
|
|
*/
|
|
function array_stripslashes($var)
|
|
{
|
|
if (!is_array($var))
|
|
{
|
|
return stripslashes($var);
|
|
}
|
|
foreach($var as $key => $val)
|
|
{
|
|
$var[$key] = is_array($val) ? array_stripslashes($val) : stripslashes($val);
|
|
}
|
|
return $var;
|
|
}
|
|
|
|
/**
|
|
* Return the number of bytes of a string, independent of mbstring.func_overload
|
|
* AND the availability of mbstring
|
|
*
|
|
* @param string $str
|
|
* @return int
|
|
*/
|
|
function bytes($str)
|
|
{
|
|
static $func_overload = null;
|
|
|
|
if (is_null($func_overload)) $func_overload = extension_loaded('mbstring') ? ini_get('mbstring.func_overload') : 0;
|
|
|
|
return $func_overload & 2 ? mb_strlen($str,'ascii') : strlen($str);
|
|
}
|
|
|
|
/**
|
|
* mbstring.func_overload safe substr
|
|
*
|
|
* @param string $data
|
|
* @param int $offset
|
|
* @param int $len
|
|
* @return string
|
|
*/
|
|
function cut_bytes(&$data,$offset,$len=null)
|
|
{
|
|
static $func_overload = null;
|
|
|
|
if (is_null($func_overload)) $func_overload = extension_loaded('mbstring') ? ini_get('mbstring.func_overload') : 0;
|
|
|
|
if (is_null($len))
|
|
{
|
|
return $func_overload & 2 ? mb_substr($data,$offset,bytes($data),'ascii') : substr($data,$offset);
|
|
}
|
|
return $func_overload & 2 ? mb_substr($data,$offset,$len,'ascii') : substr($data,$offset,$len);
|
|
}
|
|
|
|
if (!function_exists('imap_rfc822_parse_adrlist'))
|
|
{
|
|
/**
|
|
* parses a (comma-separated) address string
|
|
*
|
|
* Examples:
|
|
* - Joe Doe <doe@example.com>
|
|
* - "Doe, Joe" <doe@example.com>
|
|
* - "\'Joe Doe\'" <doe@example.com> // actually not necessary to quote
|
|
* - postmaster@example.com
|
|
* - root
|
|
* - "Joe on its way Down Under :-\)" <doe@example.com>
|
|
* - "Giant; \"Big\" Box" <sysservices@example.net>
|
|
* - sysservices@example.net <sysservices@example.net> // this is wrong, because @ need to be quoted
|
|
*
|
|
* Invalid addresses, if detected, set host to '.SYNTAX-ERROR.'
|
|
*
|
|
* @param string $address - A string containing addresses
|
|
* @param string $default_host - The default host name
|
|
* @return array of objects. The objects properties are:
|
|
* mailbox - the mailbox name (username)
|
|
* host - the host name
|
|
* personal - the personal name
|
|
* adl - at domain source route
|
|
*/
|
|
function imap_rfc822_parse_adrlist($address, $default_host)
|
|
{
|
|
$addresses = array();
|
|
$pending = '';
|
|
foreach(explode(',', $address) as $part)
|
|
{
|
|
$trimmed = trim(($pending ? $pending.',' : '').$part);
|
|
if ((($trimmed[0]??null) == '"' && substr($trimmed, -1) != '>')||strpos($part, '@')===false)
|
|
{
|
|
$pending .= ($pending ? $pending.',' : '').$part;
|
|
continue;
|
|
}
|
|
$pending = '';
|
|
$matches = $personal = $mailbox = $host = null;
|
|
if (preg_match('/^(.*)<([^>@]+)(@([^>]+))?>$/', $trimmed, $matches))
|
|
{
|
|
$personal = trim($matches[1]);
|
|
$mailbox = $matches[2];
|
|
$host = $matches[4];
|
|
}
|
|
elseif (strpos($trimmed, '@') !== false)
|
|
{
|
|
list($mailbox, $host) = explode('@', $trimmed);
|
|
}
|
|
else
|
|
{
|
|
$mailbox = $trimmed;
|
|
}
|
|
if ($personal[0] == '"' && substr($personal, -1) == '"')
|
|
{
|
|
$personal = str_replace('\\', '', substr($personal, 1, -1));
|
|
}
|
|
if (empty($host)) $host = $default_host;
|
|
|
|
$addresses[] = (object)array_diff(array(
|
|
'mailbox' => $mailbox,
|
|
'host' => $host,
|
|
'personal' => $personal,
|
|
), array(null, ''));
|
|
}
|
|
return $addresses;
|
|
}
|
|
}
|
|
|
|
if (!function_exists('imap_rfc822_write_address'))
|
|
{
|
|
/**
|
|
* Returns a properly formatted email address given the mailbox, host, and personal info
|
|
* @param string $mailbox - The mailbox name, see imap_open() for more information
|
|
* @param string $host - The email host part
|
|
* @param string $personal - The name of the account owner
|
|
* @return string properly formatted email address as defined in » RFC2822.
|
|
*/
|
|
function imap_rfc822_write_address($mailbox, $host, $personal)
|
|
{
|
|
if (is_array($personal)) $personal = implode(' ', $personal);
|
|
|
|
//if (!preg_match('/^[!#$%&\'*+/0-9=?A-Z^_`a-z{|}~-]+$/u', $personal)) // that's how I read the rfc(2)822
|
|
if ($personal && !preg_match('/^[0-9A-Z -]*$/iu', $personal)) // but quoting is never wrong, so quote more then necessary
|
|
{
|
|
$personal = '"'.str_replace(array('\\', '"'),array('\\\\', '\\"'), $personal).'"';
|
|
}
|
|
return ($personal ? $personal.' <' : '').$mailbox.($host ? '@'.$host : '').($personal ? '>' : '');
|
|
}
|
|
}
|
|
|
|
if (!function_exists('imap_mime_header_decode'))
|
|
{
|
|
/**
|
|
* Decodes MIME message header extensions that are non ASCII text (RFC2047)
|
|
*
|
|
* Uses Horde_Mime::decode() and therefore always returns only a single array element!
|
|
*
|
|
* @param string $text
|
|
* @return array with single object with attribute text already in our internal encoding and charset
|
|
* @deprecated use Horde_Mime::decode()
|
|
*/
|
|
function imap_mime_header_decode($text)
|
|
{
|
|
return array((object)array(
|
|
'text' => Horde_Mime::decode($text),
|
|
'charset' => Api\Translation::charset(), // is already in our internal encoding!
|
|
));
|
|
}
|
|
}
|
|
|
|
if (!function_exists('mb_strlen'))
|
|
{
|
|
/**
|
|
* Number of characters in a string
|
|
*
|
|
* @param string $str
|
|
* @return int
|
|
*/
|
|
function mb_strlen($str)
|
|
{
|
|
return strlen($str);
|
|
}
|
|
}
|
|
|
|
if (!function_exists('mb_substr'))
|
|
{
|
|
/**
|
|
* Return part of a string
|
|
*
|
|
* @param string $data
|
|
* @param int $offset
|
|
* @param int $len
|
|
* @return string
|
|
*/
|
|
function mb_substr(&$data, $offset, $len=null)
|
|
{
|
|
return is_null($len) ? substr($data, $offset) : substr($data, $offset, $len);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Format array or other types as (one-line) string, eg. for error_log statements
|
|
*
|
|
* @param mixed $var variable to dump
|
|
* @return string
|
|
*/
|
|
function array2string($var)
|
|
{
|
|
switch (($type = gettype($var)))
|
|
{
|
|
case 'boolean':
|
|
return $var ? 'TRUE' : 'FALSE';
|
|
case 'string':
|
|
return "'$var'";
|
|
case 'integer':
|
|
case 'double':
|
|
case 'resource':
|
|
return $var;
|
|
case 'NULL':
|
|
return 'NULL';
|
|
case 'object':
|
|
case 'array':
|
|
return str_replace(array("\n",' '/*,'Array'*/),'',print_r($var,true));
|
|
}
|
|
return 'UNKNOWN TYPE!';
|
|
}
|
|
|
|
/**
|
|
* Check if a given extension is loaded or load it if possible (requires sometimes disabled or unavailable dl function)
|
|
*
|
|
* @param string $extension
|
|
* @param boolean $throw =false should we throw an exception, if $extension could not be loaded, default false = no
|
|
* @return boolean true if loaded now, false otherwise
|
|
* @throws Api\Exception\AssertionFailed
|
|
*/
|
|
function check_load_extension($extension,$throw=false)
|
|
{
|
|
if (!defined('PHP_SHLIB_PREFIX'))
|
|
{
|
|
define('PHP_SHLIB_PREFIX',PHP_SHLIB_SUFFIX == 'dll' ? 'php_' : '');
|
|
}
|
|
// we check for the existens of 'dl', as multithreaded webservers dont have it and some hosters disable it !!!
|
|
$loaded = extension_loaded($extension) || function_exists('dl') && @dl($dl=PHP_SHLIB_PREFIX.$extension.'.'.PHP_SHLIB_SUFFIX);
|
|
|
|
if (!$loaded && $throw)
|
|
{
|
|
throw new Api\Exception\AssertionFailed("PHP extension '$extension' not loaded AND can NOT be loaded via dl('$dl')!");
|
|
}
|
|
return $loaded;
|
|
}
|
|
|
|
// include deprecated factory methods: CreateObject, ExecMethod, ...
|
|
require_once EGW_SERVER_ROOT.'/api/src/loader/deprecated_factory.php';
|
|
|
|
// include deprecated global functions, if phpgwapi is installed
|
|
if (file_exists(EGW_SERVER_ROOT.'/phpgwapi'))
|
|
{
|
|
include_once EGW_SERVER_ROOT.'/phpgwapi/inc/deprecated_functions.inc.php';
|
|
}
|
|
|
|
/**
|
|
* Return a properly formatted account_id.
|
|
*
|
|
* @author skeeter
|
|
* This function will return a properly formatted account_id. This can take either a name or an account_id as paramters. If a name is provided it will return the associated id.
|
|
* $account_id = get_account_id($accountid);
|
|
* @param int|string $account_id either a name or an id
|
|
* @param int|string $default_id either a name or an id
|
|
* @return int account_id
|
|
*/
|
|
function get_account_id($account_id = '',$default_id = '')
|
|
{
|
|
if (is_int($account_id))
|
|
{
|
|
return $account_id;
|
|
}
|
|
if ($account_id == '')
|
|
{
|
|
if ($default_id == '')
|
|
{
|
|
return $GLOBALS['egw_info']['user']['account_id'] ?? 0;
|
|
}
|
|
elseif (is_string($default_id))
|
|
{
|
|
return Api\Accounts::getInstance()->name2id($default_id);
|
|
}
|
|
return (int)$default_id;
|
|
}
|
|
elseif (is_string($account_id))
|
|
{
|
|
if((int)$account_id && Api\Accounts::getInstance()->exists((int)$account_id))
|
|
{
|
|
return (int)$account_id;
|
|
}
|
|
else
|
|
{
|
|
return Api\Accounts::getInstance()->name2id($account_id);
|
|
}
|
|
}
|
|
}
|
|
|
|
/**
|
|
* print an array or object as pre-formatted html
|
|
*
|
|
* @param mixed $array
|
|
* @param boolean $print =true print or return the content
|
|
* @return string if !$print
|
|
*/
|
|
function _debug_array($array,$print=True)
|
|
{
|
|
$output = '<pre>'.print_r($array,true)."</pre>\n";
|
|
|
|
if ($print)
|
|
{
|
|
echo $output;
|
|
}
|
|
else
|
|
{
|
|
return $output;
|
|
}
|
|
}
|
|
|
|
/**
|
|
* backtrace of the calling functions for php4.3+ else menuaction/scriptname
|
|
*
|
|
* @author RalfBecker-AT-outdoor-training.de
|
|
* @param int $remove =0 number of levels to remove
|
|
* @return string function-names separated by slashes (beginning with the calling function not this one)
|
|
*/
|
|
function function_backtrace($remove=0)
|
|
{
|
|
if (function_exists('debug_backtrace'))
|
|
{
|
|
$backtrace = debug_backtrace();
|
|
//echo "function_backtrace($remove)<pre>".print_r($backtrace,True)."</pre>\n";
|
|
foreach($backtrace as $n => $level)
|
|
{
|
|
if ($remove-- < 0)
|
|
{
|
|
$ret[] = (isset($level['class'])?$level['class'].$level['type']:'').$level['function'].
|
|
($n > 0 && isset($backtrace[$n-1]['line']) ? ':'.$backtrace[$n-1]['line'] : ''). // add line number of call
|
|
(empty($level['class']) && !is_object($level['args'][0]) && $level['function'] != 'unserialize' ?
|
|
'('.substr(str_replace(EGW_SERVER_ROOT,'',(string)$level['args'][0]),0,64).')' : '');
|
|
}
|
|
}
|
|
if (is_array($ret))
|
|
{
|
|
return implode(' / ',$ret);
|
|
}
|
|
}
|
|
return $_GET['menuaction'] ? $_GET['menuaction'] : str_replace(EGW_SERVER_ROOT,'',$_SERVER['SCRIPT_FILENAME']);
|
|
}
|
|
|
|
if (!function_exists('lang') && !defined('NO_LANG')) // setup declares an own version
|
|
{
|
|
/**
|
|
* function to handle multilanguage support
|
|
*
|
|
* @param string $key message in englich with %1, %2, ... placeholders
|
|
* @param string $vars =null multiple values to replace the placeholders
|
|
* @return string translated message with placeholders replaced
|
|
*/
|
|
function lang($key,$vars=null)
|
|
{
|
|
if(!is_array($vars))
|
|
{
|
|
$vars = func_get_args();
|
|
array_shift($vars); // remove $key
|
|
}
|
|
return Api\Translation::translate($key,$vars);
|
|
}
|
|
}
|
|
|
|
require_once __DIR__.'/security.php';
|
|
require_once __DIR__.'/exception.php';
|
|
|
|
/**
|
|
* Public functions to be compatible with the exiting eGW framework
|
|
*/
|
|
if (!function_exists('parse_navbar'))
|
|
{
|
|
/**
|
|
* echo's out the navbar
|
|
*
|
|
* @deprecated use $GLOBALS['egw']->framework->navbar() or $GLOBALS['egw']->framework::render()
|
|
*/
|
|
function parse_navbar()
|
|
{
|
|
echo $GLOBALS['egw']->framework->navbar();
|
|
}
|
|
}
|
|
|
|
if (!function_exists('display_sidebox') &&
|
|
// allow developer TranslationTools scanner to overwrite the function
|
|
($_GET['menuaction'] ?? null) !== 'developer.EGroupware\\Developer\\TranslationTools.scan')
|
|
{
|
|
/**
|
|
* echo's out a sidebox menu
|
|
*
|
|
* @deprecated use $GLOBALS['egw']->framework->sidebox()
|
|
*/
|
|
function display_sidebox($appname,$menu_title,$_file)
|
|
{
|
|
$file = array_map(function($item)
|
|
{
|
|
return is_array($item) ? $item :
|
|
str_replace('preferences.uisettings.index', 'preferences.preferences_settings.index', $item);
|
|
}, $_file);
|
|
$GLOBALS['egw']->framework->sidebox($appname,$menu_title,$file);
|
|
}
|
|
} |