This repository has been archived on 2024-04-08. You can view files and clone it, but cannot push or open issues or pull requests.
phptsmadmin/lib/functions.php
2011-05-25 13:19:08 +10:00

1019 lines
31 KiB
PHP

<?php
// $Header: /cvsroot/phptsmadmin/phpTSMadmin/lib/functions.php,v 1.37 2009/04/19 04:03:05 wurley Exp $
/**
* A collection of common generic functions used throughout the application.
*
* @author Deon George
* @package phpTSMadmin
*/
/**
* @package phpTSMadmin
* @subpackage Functions
*/
define('HTDOCDIR',sprintf('%s/',realpath(LIBDIR.'../htdocs/')));
define('LANGDIR',sprintf('%s/',realpath(LIBDIR.'../locale/')));
define('CONFDIR',sprintf('%s/',realpath(LIBDIR.'../config')));
define('HOOKSDIR',sprintf('%s/',realpath(LIBDIR.'../hooks/')));
define('CSSDIR','css/');
define('IMGDIR','images/');
define('JSDIR','js/');
/**
* Supplimental functions
* This list is a list of supplimental functions that are used throughout
* this application. The order here IS important - so that files that refer to
* functions defined in other files need to be listed after those files.
*/
$app['function_files'] = array(
LIBDIR.'session_functions.php',
# Datasource functions
LIBDIR.'ds.php',
LIBDIR.'tsm_classes.php',
# Functions for rendering the page
LIBDIR.'page.php'
);
if (file_exists(LIBDIR.'functions.custom.php'))
array_push($app['function_files'],LIBDIR.'functions.custom.php');
/**
* Loads class definition
*/
function __autoload($className) {
if (defined('DEBUG_ENABLED') && DEBUG_ENABLED)
debug_log('Call to autoload (%s)',1,__FILE__,__LINE__,__METHOD__,$className);
if (file_exists(HOOKSDIR."classes/$className.php"))
require_once(HOOKSDIR."classes/$className.php");
elseif (file_exists(LIBDIR."$className.php"))
require_once(LIBDIR."$className.php");
elseif (file_exists(LIBDIR."ds_$className.php"))
require_once(LIBDIR."ds_$className.php");
else
system_message(array(
'title'=>_('Generic Error'),
'body'=>sprintf('%s: %s [%s]',
__METHOD__,_('Called to load a class that cant be found'),$className),
'type'=>'error'));
}
/**
* Strips all slashes from the specified array in place (pass by ref).
* @param Array The array to strip slashes from, typically one of
* $_GET, $_POST, or $_COOKIE.
*/
function array_stripslashes(&$array) {
if (DEBUG_ENABLED)
debug_log('Entered with (%s)',1,__FILE__,__LINE__,__METHOD__,$array);
if (is_array($array))
while (list($key) = each($array))
if (is_array($array[$key]) && $key != $array)
array_stripslashes($array[$key]);
else
$array[$key] = stripslashes($array[$key]);
}
/**
* Compatibility Functions
* These functions exist, so that a standard function can be used in new applications, and they
* map to already defined functions in older applications.
*/
/**
* If gettext is not available in PHP, then this will provide compatibility for it.
*/
if (! function_exists('_')) {
function _($msg) {
return $msg;
}
}
/**
* Generic Utility Functions
*/
/**
* Custom error handling function.
* When a PHP error occurs, PHP will call this function rather than printing
* the typical PHP error string. This provides the application the ability to
* format an error message so that it looks better.
* Optionally, it can present a link so that a user can search/submit bugs.
* This function is not to be called directly. It is exclusively for the use of
* PHP internally. If this function is called by PHP from within a context
* where error handling has been disabled (ie, from within a function called
* with "@" prepended), then this function does nothing.
*
* @param int The PHP error number that occurred (ie, E_ERROR, E_WARNING, E_PARSE, etc).
* @param string The PHP error string provided (ie, "Warning index "foo" is undefined)
* @param string The file in which the PHP error ocurred.
* @param int The line number on which the PHP error ocurred
* @see set_error_handler
*/
function app_error_handler($errno,$errstr,$file,$lineno) {
if (defined('DEBUG_ENABLED') && DEBUG_ENABLED)
debug_log('Entered with (%s,%s,%s,%s)',1,__FILE__,__LINE__,__METHOD__,
$errno,$errstr,$file,$lineno);
/**
* error_reporting will be 0 if the error context occurred
* within a function call with '@' preprended (ie, @ldap_bind() );
* So, don't report errors if the caller has specifically
* disabled them with '@'
*/
if (ini_get('error_reporting') == 0 || error_reporting() == 0)
return;
$file = basename($file);
$caller = basename($_SERVER['PHP_SELF']);
$errtype = '';
switch ($errno) {
case E_STRICT: $errtype = 'E_STRICT'; break;
case E_ERROR: $errtype = 'E_ERROR'; break;
case E_WARNING: $errtype = 'E_WARNING'; break;
case E_PARSE: $errtype = 'E_PARSE'; break;
case E_NOTICE: $errtype = 'E_NOTICE'; break;
case E_CORE_ERROR: $errtype = 'E_CORE_ERROR'; break;
case E_CORE_WARNING: $errtype = 'E_CORE_WARNING'; break;
case E_COMPILE_ERROR: $errtype = 'E_COMPILE_ERROR'; break;
case E_COMPILE_WARNING: $errtype = 'E_COMPILE_WARNING'; break;
case E_USER_ERROR: $errtype = 'E_USER_ERROR'; break;
case E_USER_WARNING: $errtype = 'E_USER_WARNING'; break;
case E_USER_NOTICE: $errtype = 'E_USER_NOTICE'; break;
case E_ALL: $errtype = 'E_ALL'; break;
default: $errtype = sprintf('%s: %s',_('Unrecognized error number'),$errno);
}
# Take out extra spaces in error strings.
$errstr = preg_replace('/\s+/',' ',$errstr);
if ($errno == E_NOTICE) {
$body = '<table class="notice">';
$body .= sprintf('<tr><td>%s:</td><td><b>%s</b> (<b>%s</b>)</td></tr>',_('Error'),$errstr,$errtype);
$body .= sprintf('<tr><td>%s:</td><td><b>%s</b> %s <b>%s</b>, %s <b>%s</b></td></tr>',
_('File'),$file,_('line'),$lineno,_('caller'),$caller);
$body .= sprintf('<tr><td>Versions:</td><td>APP: <b>%s</b>, PHP: <b>%s</b>, SAPI: <b>%s</b></td></tr>',
app_version(),phpversion(),php_sapi_name());
$body .= sprintf('<tr><td>Web server:</td><td><b>%s</b></td></tr>',isset($_SERVER['SERVER_SOFTWARE']) ? $_SERVER['SERVER_SOFTWARE'] : 'SCRIPT');
if (function_exists('get_href'))
$body .= sprintf('<tr><td colspan="2"><a href="%s" target="_blank"><center>%s.</center></a></td></tr>',
get_href('search_bug',"&summary_keyword=".rawurlencode($errstr)),
_('Please check and see if this bug has been reported'));
$body .= '</table>';
system_message(array(
'title'=>_('You found a non-fatal application bug!'),
'body'=>$body,
'type'=>'error'));
return;
}
# If this is a more serious error, call the error call.
error(sprintf('%s: %s',$errtype,$errstr),'error',null,true,true);
}
/**
* Returns the application name.
*/
function app_name() {
if (isset($_SESSION[APPCONFIG]))
return $_SESSION[APPCONFIG]->getValue('app','name',false);
else
return 'Application name NOT set';
}
/**
* Returns the application version currently running. The version
* is read from the file named VERSION.
*
* @return string The current version as read from the VERSION file.
*/
function app_version() {
static $CACHE = null;
if ($CACHE)
return $CACHE;
$version_file = realpath(LIBDIR.'../VERSION');
if (! file_exists($version_file))
$CACHE = 'UNKNOWN';
else {
$f = fopen($version_file,'r');
$version = trim(fread($f, filesize($version_file)));
fclose($f);
# We use cvs_prefix, because CVS will translate this on checkout otherwise.
$cvs_prefix = '\$Name:';
$CACHE = preg_replace('/^'.$cvs_prefix.' RELEASE-([0-9_]+)\s*\$$/','$1',$version);
$CACHE = preg_replace('/_/','.',$CACHE);
# Check if we are a CVS copy.
if (preg_match('/^'.$cvs_prefix.'?\s*\$$/',$CACHE))
$CACHE = 'CVS';
# Check if we are special CVS branch
elseif (preg_match('/^'.$cvs_prefix.'?\s*([a-zA-Z]+)?\s*\$$/',$CACHE,$match))
$CACHE = $match[1];
# If return is still the same as version, then the tag is not one we expect.
elseif ($CACHE == $version)
$CACHE = 'UNKNOWN';
}
if (defined('DEBUG_ENABLED') && DEBUG_ENABLED)
debug_log('Entered with (), Returning (%s)',1,__FILE__,__LINE__,__METHOD__,$CACHE);
return $CACHE;
}
/**
* This function will convert the browser two character language into the
* default 5 character language, where the country portion should NOT be
* assumed to be upper case characters of the first two characters.
*/
function auto_lang($lang) {
switch ($lang) {
case 'ja': return 'ja_JP';
case 'cs': return 'cs_CZ';
default: return sprintf('%s_%s',$lang,strtoupper($lang));
}
}
/**
* Makes sure that the config file is properly setup.
*/
function check_config($config_file) {
# Read in config_default.php
require_once LIBDIR.'config_default.php';
# Make sure their PHP version is current enough
if (strcmp(phpversion(),REQUIRED_PHP_VERSION) < 0)
system_message(array(
'title'=>_('Incorrect version of PHP'),
'body'=>sprintf('This application requires PHP version %s or greater.<br /><small>(You are using %s)</small>',
REQUIRED_PHP_VERSION,phpversion()),
'type'=>'error'));
$config = new Config;
if (file_exists(LIBDIR.'config_custom.php') && is_readable(LIBDIR.'config_custom.php'))
include LIBDIR.'config_custom.php';
ob_start();
require $config_file;
$str = '';
if (ob_get_level()) {
$str = ob_get_contents();
ob_end_clean();
}
if ($str) {
$str = strip_tags($str);
$matches = array();
preg_match('/(.*):\s+(.*):.*\s+on line (\d+)/',$str,$matches);
if (isset($matches[1]) && isset($matches[2]) && isset($matches[3])) {
$error_type = $matches[1];
$error = $matches[2];
$line_num = $matches[3];
$file = file($config_file);
$body = '<h3 class="title">Config file ERROR</h3>';
$body .= sprintf('<h3 class="subtitle">%s (%s) on line %s</h3>',$error_type,$error,$line_num);
$body .= '<center>';
$body .= sprintf('Looks like your config file has an ERROR on line %s.<br />',$line_num);
$body .= 'Here is a snippet around that line <br />';
$body .= '<br />'."\n";
$body .= '<div style="text-align: left; font-family: monospace; margin-left: 80px; margin-right: 80px; border: 1px solid black; padding: 10px;">';
for ($i = $line_num-9; $i<$line_num+5; $i++) {
if ($i+1 == $line_num)
$body .= '<div style="color:red;background:#fdd">';
if ($i < 0)
continue;
$body .= sprintf('<b>%s</b>: %s<br />',$i+1,$file[$i]);
if ($i+1 == $line_num)
$body .= '</div>';
}
$body .= '</div>';
$body .= '<br />';
$body .= 'Hint: Sometimes these errors are caused by lines <b>preceding</b> the line reported.';
$body .= '</center>';
$block = new block();
$block->SetBody($body);
$www['page'] = new page();
$www['page']->block_add('body',$block);
$www['page']->display();
die();
}
}
# Process our friendly attributes.
if (isset($friendly_attrs))
$config->getFriendlyAttrs($friendly_attrs);
# Check for server definitions.
if (! isset($servers) || count($servers->GetServerList()) == 0)
error(_('Your config.php is missing Server Definitions. Please see the sample file config/config.php.example.'),'error','index.php',true);
$config->setServers($servers);
# Check the memory limit parameter.
if (ini_get('memory_limit') < $config->getValue('session','memorylimit'))
system_message(array(
'title'=>_('Memory Limit low.'),
'body'=> sprintf('Your php memory limit is low - currently %s, you should increase it to atleast %s. This is normally controlled in /etc/php.ini.',ini_get('memory_limit'),$config->getValue('session','memorylimit')),
'type'=>'error'));
return $config;
}
/**
* Commands available in the control_panel of the page
*
* @return array
*/
function cmd_control_pane($type) {
switch ($type) {
case 'main' :
return array(
'home'=>array(
'title'=>_('Home'),
'link'=>sprintf('href="index.php" title="%s"',_('Home')),
'image'=>sprintf('<img src="%s/home-big.png" alt="%s" />',IMGDIR,_('Home'))),
'purge'=>array(
'title'=>_('Purge caches'),
'link'=>sprintf('href="cmd.php?cmd=purge_cache" onclick="return displayAJ(\'BODY\',\'cmd=purge_cache\',\'%s\');" title="%s"',
_('Clearing cache'),_('Purge caches')),
'image'=>sprintf('<img src="%s/trash-big.png" alt="%s" />',IMGDIR,_('Purge caches'))),
'appearance:hide_debug_info'=>array(
'title'=>_('Show Cache'),
'link'=>sprintf('href="cmd.php?cmd=show_cache" onclick="return displayAJ(\'BODY\',\'cmd=show_cache\',\'%s\');" title="%s"',
_('Loading'),_('Show Cache'),_('Show Cache')),
'image'=>sprintf('<img src="%s/debug-cache.png" alt="%s" />',IMGDIR,_('Show Cache'))),
);
break;
case 'top' :
return array();
break;
}
}
/**
* This function dumps the $variable for debugging purposes
*
* @param string|array Variable to dump
* @param boolean Whether to stop execution or not.
*/
function debug_dump($variable,$die=false,$onlydebugaddr=false) {
if ($onlydebugaddr &&
isset($_SESSION[APPCONFIG]) && $_SESSION[APPCONFIG]->getValue('debug','addr') &&
$_SERVER['HTTP_X_FORWARDED_FOR'] != $_SESSION[APPCONFIG]->getValue('debug','addr') &&
$_SERVER['REMOTE_ADDR'] != $_SESSION[APPCONFIG]->getValue('debug','addr'))
return;
$backtrace = debug_backtrace();
$caller['class'] = isset($backtrace[0]['class']) ? $backtrace[0]['class'] : 'N/A';
$caller['function'] = isset($backtrace[0]['function']) ? $backtrace[0]['function'] : 'N/A';
$caller['file'] = isset($backtrace[0]['file']) ? $backtrace[0]['file'] : 'N/A';
$caller['line'] = isset($backtrace[0]['line']) ? $backtrace[0]['line'] : 'N/A';
$caller['debug'] = $variable;
print '<PRE>';
print_r($caller);
print '</PRE>';
if ($die)
die();
}
/**
* This function generates a backtrace
*
* @param boolean Whether to stop execution or not.
*/
function debug_dump_backtrace($msg='Calling BackTrace',$die=false) {
error($msg,'note',null,$die,true);
}
/**
* Send a debug as a sys message
*/
function debug_sysmsg($msg) {
system_message(array('title'=>_('Debug'),'body'=>$msg,'type'=>'debug'));
}
/**
* Debug Logging to Syslog
*
* The global debug level is turned on in your configuration file by setting:
* <code>
* $config->custom->debug['level'] = 255;
* </code>
* together with atleast one output direction (currently file and syslog are supported).
* <code>
* $config->custom->debug['file'] = '/tmp/app_debug.log';
* $config->custom->debug['syslog'] = true;
* </code>
*
* The debug level is turned into binary, then if the message levels bit is on
* the message will be sent to the debug log. (Thus setting your debug level to 255,
* all bits on, will results in all messages being printed.)
*
* The message level bits are defined here.
* 0( 1) = Entry/Return results from function calls.
* 1( 2) = Configuration Processing
* 2( 4) = Template Processing
* 3( 8) = Schema Processing
* 4( 16) = Server Communication
* 5( 32) = Menu Processing
* 7( 64) = Other non generic messages
* 8(128) = Page Processing
* @param string Message to send to syslog
* @param int Log bit number for this message.
* @see syslog.php
*/
function debug_log($msg,$level=0) {
global $debug_file;
# Temporary, to catch when these are not set in the function arguments.
$file = __FILE__;
$line = __LINE__;
$method = __METHOD__;
# In case we are called before we are fully initialised or if debugging is not set.
if (! isset($_SESSION[APPCONFIG]) || ! ($_SESSION[APPCONFIG]->getValue('debug','file')
|| $_SESSION[APPCONFIG]->getValue('debug','syslog')))
return false;
$debug_level = $_SESSION[APPCONFIG]->getValue('debug','level');
if (! $debug_level || (! ($level & $debug_level)))
return;
$debugaddr = false;
if ($_SESSION[APPCONFIG]->getValue('debug','addr')) {
if (isset($_SERVER['HTTP_X_FORWARDED_FOR']) && $_SERVER['HTTP_X_FORWARDED_FOR'] == $_SESSION[APPCONFIG]->getValue('debug','addr'))
$debugaddr = true;
elseif ($_SERVER['REMOTE_ADDR'] == $_SESSION[APPCONFIG]->getValue('debug','addr'))
$debugaddr = true;
} else $debugaddr = true;
if (! $debugaddr)
return;
# If we are limiting debug to a browser, then check that
$caller = basename( $_SERVER['PHP_SELF'] );
if (func_num_args() > 2) {
$args = func_get_args();
array_shift($args);
array_shift($args);
# This is temporary, until we change all the debug_log statements.
if (is_string($args[0]) && preg_match('/.php$/',$args[0])) {
$file = array_shift($args);
$line = array_shift($args);
$method = array_shift($args);
}
$fargs = array();
foreach ($args as $key) {
if (is_array($key) || is_object($key))
array_push($fargs,serialize($key));
else
array_push($fargs,$key);
}
$msg = vsprintf($msg, array_values($fargs));
}
if (function_exists('stopwatch'))
$timer = stopwatch();
else
$timer = null;
$debug_message = sprintf('[%2.3f] %3s-%s(%04s): %s: %s',$timer,$level,basename($file),$line,$method,substr($msg,0,200));
if ($debug_file || $_SESSION[APPCONFIG]->getValue('debug','file')) {
if (! $debug_file)
$debug_file = fopen($_SESSION[APPCONFIG]->getValue('debug','file'),
$_SESSION[APPCONFIG]->getValue('debug','append') ? 'a' : 'w');
fwrite($debug_file,$debug_message."\n");
}
if ($_SESSION[APPCONFIG]->getValue('debug','syslog'))
syslog_notice($debug_message);
return syslog_notice( sprintf('%s(%s): %s',$caller,$level,$msg) );
}
/**
* Display an error message in the system message panel of the page.
*/
function error($msg,$type='note',$redirect=null,$fatal=false,$backtrace=false) {
global $www;
static $counter;
# Just a check to see that we are called right.
if (! isset($www['page']) && ! $fatal)
die("Function error called incorrectly [$msg]");
# If the error is fatal, we'll need to stop here.
if (! isset($www['page']))
$www['page'] = new page();
if ($fatal)
$www['page']->setsysmsg(array('title'=>_('Error'),'body'=>$msg,'type'=>$type));
else
system_message(array('title'=>_('Error'),'body'=>$msg,'type'=>$type),$redirect);
# Spin loop detection
if ($counter++ > 20) {
debug_dump('Spin loop detection.');
debug_dump(array('msg'=>$msg,'session'=>$_SESSION['sysmsg'],'www'=>$www),1);
}
# Do we have a backtrace to display?
if ($backtrace) {
$backtraceblock = new block();
$backtraceblock->SetTitle('PHP Debug Backtrace');
$body = '<table class="result_table">';
$body .= "\n";
foreach (debug_backtrace() as $error => $line) {
$_SESSION['backtrace'][$error]['file'] = isset($line['file']) ? $line['file'] : 'unknown';
$_SESSION['backtrace'][$error]['line'] = isset($line['line']) ? $line['line'] : 'unknown';
$body .= sprintf('<tr class="hightlight"><td colspan="2"><b><small>%s</small></b></td><td>%s (%s)</td></tr>',
_('File'),isset($line['file']) ? $line['file'] : $last['file'],isset($line['line']) ? $line['line'] : '');
$_SESSION['backtrace'][$error]['function'] = $line['function'];
$body .= sprintf('<tr><td>&nbsp;</td><td><b><small>%s</small></b></td><td><small>%s',
_('Function'),$line['function']);
if (isset($line['args'])) {
$display = strlen(serialize($line['args'])) < 50 ? serialize($line['args']) : substr(serialize($line['args']),0,50).'...<TRUNCATED>';
$_SESSION['backtrace'][$error]['args'] = $line['args'];
if (file_exists(LIBDIR.'../tools/unserialize.php'))
$body .= sprintf('&nbsp;(<a href="%s?index=%s" target="backtrace">%s</a>)',
'../tools/unserialize.php',$error,$display);
else
$body .= sprintf('&nbsp;(%s)',$display);
}
$body .= '</small></td></tr>';
$body .= "\n";
if (isset($line['file']))
$last['file'] = $line['file'];
}
$body .= '</table>';
$body .= "\n";
$backtraceblock->SetBody($body);
$www['page']->block_add('body',$backtraceblock);
}
if ($fatal) {
$www['page']->display(array('menu'=>false));
die();
}
}
/**
* Return the result of a form variable, with optional default
*
* @return The form GET/REQUEST/SESSION/POST variable value or its default
*/
function get_request($attr,$type='POST',$die=false,$default=null) {
switch($type) {
case 'GET':
$value = isset($_GET[$attr]) ? (is_array($_GET[$attr]) ? $_GET[$attr] : rawurldecode($_GET[$attr])) : $default;
break;
case 'REQUEST':
$value = isset($_REQUEST[$attr]) ? (is_array($_REQUEST[$attr]) ? $_REQUEST[$attr] : rawurldecode($_REQUEST[$attr])) : $default;
break;
case 'SESSION':
$value = isset($_SESSION[$attr]) ? (is_array($_SESSION[$attr]) ? $_SESSION[$attr] : rawurldecode($_SESSION[$attr])) : $default;
break;
case 'POST':
default:
$value = isset($_POST[$attr]) ? (is_array($_POST[$attr]) ? $_POST[$attr] : rawurldecode($_POST[$attr])) : $default;
break;
}
if ($die && is_null($value))
system_message(array(
'title'=>_('Generic Error'),
'body'=>sprintf('%s: Called "%s" without "%s" using "%s"',
basename($_SERVER['PHP_SELF']),get_request('cmd','REQUEST'),$attr,$type),
'type'=>'error'),
'index.php');
return $value;
}
/**
* Record a system message.
* This function can be used as an alternative to generate a system message, if page hasnt yet been defined.
*/
function system_message($msg,$redirect=null) {
if (! is_array($msg))
return null;
if (! isset($msg['title']) && ! isset($msg['body']))
return null;
if (! isset($msg['type']))
$msg['type'] = 'info';
if (! isset($_SESSION['sysmsg']) || ! is_array($_SESSION['sysmsg']))
$_SESSION['sysmsg'] = array();
# Try and detect if we are in a redirect loop
if (get_request('redirect','GET') && $msg['type'] != 'debug') {
foreach ($_SESSION['sysmsg'] as $detail) {
if ($msg == $detail && ! isset($detail['special'])) {
debug_dump($_SESSION['sysmsg']);
debug_dump_backtrace('Redirect Loop Detected',true);
}
}
}
array_push($_SESSION['sysmsg'],$msg);
if ($redirect) {
if (preg_match('/\?/',$redirect))
$redirect .= '&';
else
$redirect .= '?';
$redirect .= 'redirect=true';
# Check if we were an ajax request, and only render the ajax message
if (get_request('meth','REQUEST') == 'ajax')
$redirect .= '&meth=ajax';
header("Location: $redirect");
die();
}
}
/**
* Other Functions
*/
/**
* Encryption using blowfish algorithm
*
* @param string Original data
* @param string The secret
* @return string The encrypted result
* @author lem9 (taken from the phpMyAdmin source)
*/
function blowfish_encrypt($data,$secret=null) {
if (DEBUG_ENABLED)
debug_log('Entered with (%s,%s)',1,__FILE__,__LINE__,__METHOD__,
$data,$secret);
# If our secret is null or blank, get the default.
if ($secret === null || ! trim($secret))
$secret = $_SESSION[APPCONFIG]->getValue('session','blowfish');
# If the secret isnt set, then just return the data.
if (! trim($secret))
return $data;
if (file_exists(LIBDIR.'blowfish.php'))
require_once LIBDIR.'blowfish.php';
else
return $data;
$pma_cipher = new Horde_Cipher_blowfish;
$encrypt = '';
for ($i=0; $i<strlen($data); $i+=8) {
$block = substr($data, $i, 8);
if (strlen($block) < 8)
$block = full_str_pad($block,8,"\0", 1);
$encrypt .= $pma_cipher->encryptBlock($block, $secret);
}
return base64_encode($encrypt);
}
/**
* Decryption using blowfish algorithm
*
* @param string Encrypted data
* @param string The secret
* @return string Original data
* @author lem9 (taken from the phpMyAdmin source)
*/
function blowfish_decrypt($encdata,$secret=null) {
if (DEBUG_ENABLED)
debug_log('Entered with (%s,%s)',1,__FILE__,__LINE__,__METHOD__,
$encdata,$secret);
# This cache gives major speed up for stupid callers :)
static $CACHE = array();
if (isset($CACHE[$encdata]))
return $CACHE[$encdata];
# If our secret is null or blank, get the default.
if ($secret === null || ! trim($secret))
$secret = $_SESSION[APPCONFIG]->getValue('session','blowfish');
# If the secret isnt set, then just return the data.
if (! trim($secret))
return $encdata;
if (file_exists(LIBDIR.'blowfish.php'))
require_once LIBDIR.'blowfish.php';
else
return $data;
$pma_cipher = new Horde_Cipher_blowfish;
$decrypt = '';
$data = base64_decode($encdata);
for ($i=0; $i<strlen($data); $i+=8)
$decrypt .= $pma_cipher->decryptBlock(substr($data, $i, 8), $secret);
$return = trim($decrypt);
$CACHE[$encdata] = $return;
return $return;
}
/**
* String padding
*
* @param string Input string
* @param integer Length of the result
* @param string The filling string
* @param integer Padding mode
* @return string The padded string
*/
function full_str_pad($input,$pad_length,$pad_string='',$pad_type=0) {
if (DEBUG_ENABLED)
debug_log('Entered with (%s,%s,%s,%s)',1,__FILE__,__LINE__,__METHOD__,
$input,$pad_length,$pad_string,$pad_type);
$str = '';
$length = $pad_length - strlen($input);
if ($length > 0) { // str_repeat doesn't like negatives
if ($pad_type == STR_PAD_RIGHT) { // STR_PAD_RIGHT == 1
$str = $input.str_repeat($pad_string, $length);
} elseif ($pad_type == STR_PAD_BOTH) { // STR_PAD_BOTH == 2
$str = str_repeat($pad_string, floor($length/2));
$str .= $input;
$str .= str_repeat($pad_string, ceil($length/2));
} else { // defaults to STR_PAD_LEFT == 0
$str = str_repeat($pad_string, $length).$input;
}
} else { // if $length is negative or zero we don't need to do anything
$str = $input;
}
return $str;
}
/**
* Returns the cached array of application server resources.
*
* Note that internally, this function utilizes a two-layer cache,
* one in memory using a static variable for multiple calls within
* the same page load, and one in a session for multiple calls within
* the same user session (spanning multiple page loads).
*
* @return Returns the cached attributed requested,
* or null if there is nothing cached..
*/
function get_cached_item($index,$item,$subitem='null') {
# Set default return
$return = null;
# Check config to make sure session-based caching is enabled.
if ($_SESSION[APPCONFIG]->getValue('cache',$item)) {
global $CACHE;
if (isset($CACHE[$index][$item][$subitem])) {
if (DEBUG_ENABLED)
debug_log('Returning MEMORY cached [%s] (%s)',1,__FILE__,__LINE__,__METHOD__,
$item,$subitem);
$return = $CACHE[$index][$item][$subitem];
} elseif (isset($_SESSION['cache'][$index][$item][$subitem])) {
if (DEBUG_ENABLED)
debug_log('Returning SESSION cached [%s] (%s)',1,__FILE__,__LINE__,__METHOD__,
$item,$subitem);
$return = $_SESSION['cache'][$index][$item][$subitem];
$CACHE[$index][$item][$subitem] = $return;
}
}
if (DEBUG_ENABLED)
debug_log('Entered with (%s,%s,%s), Returning (%s)',1,__FILE__,__LINE__,__METHOD__,
$index,$item,$subitem,$return);
return $return;
}
/**
* Caches the specified $item for the specified $index.
*
* Returns true on success of false on failure.
*/
function set_cached_item($index,$item,$subitem='null',$data) {
if (DEBUG_ENABLED)
debug_log('Entered with (%s,%s,%s,%s)',1,__FILE__,__LINE__,__METHOD__,
$index,$item,$subitem,$data);
# Check config to make sure session-based caching is enabled.
if ($_SESSION[APPCONFIG]->getValue('cache',$item)) {
global $CACHE;
$CACHE[$index][$item][$subitem] = $data;
$_SESSION['cache'][$index][$item][$subitem] = $data;
return true;
} else
return false;
}
/**
* Deletes the cache for a specified $item for the specified $index
*/
function del_cached_item($index,$item,$subitem='null') {
global $CACHE;
if (DEBUG_ENABLED)
debug_log('Entered with (%s,%s,%s)',1,__FILE__,__LINE__,__METHOD__,
$index,$item,$subitem);
# Check config to make sure session-based caching is enabled.
if (isset($_SESSION['cache'][$index][$item][$subitem]))
unset($_SESSION['cache'][$index][$item][$subitem]);
if (isset($CACHE[$index][$item][$subitem]))
unset($CACHE[$index][$item][$subitem]);
}
/**
* Utility wrapper for setting cookies, which takes into consideration
* application configuration values. On success, true is returned. On
* failure, false is returned.
*
* @param string The name of the cookie to set.
* @param string The value of the cookie to set.
* @param int (optional) The duration in seconds of this cookie. If unspecified, $cookie_time is used from config.php
* @param string (optional) The directory value of this cookie (see php.net/setcookie)
* @return boolean
*/
function set_cookie($name,$val,$expire=null,$dir=null) {
# Set default return
$return = false;
if ($expire == null) {
$cookie_time = $_SESSION[APPCONFIG]->getValue('session','cookie_time');
$expire = $cookie_time == 0 ? null : time() + $cookie_time;
}
if ($dir == null)
$dir = dirname($_SERVER['PHP_SELF']);
if (@setcookie($name,$val,$expire,$dir)) {
$_COOKIE[$name] = $val;
$return = true;
}
if (DEBUG_ENABLED)
debug_log('Entered with (%s,%s,%s,%s), Returning (%s)',1,__FILE__,__LINE__,__METHOD__,
$name,$val,$expire,$dir,$return);
return $return;
}
/**
* Get a customized file for a server
* We don't need any caching, because it's done by PHP
*
* @param int The ID of the server
* @param string The requested filename
*
* @return string The customized filename, if exists, or the standard one
*/
function get_custom_file($index,$filename,$path) {
# Set default return
$return = $path.$filename;
$server = $_SESSION[APPCONFIG]->getServer($index);
$custom = $server->getValue('custom','pages_prefix');
if (! is_null($custom) && is_file(realpath($path.$custom.$filename)))
$return = $path.$custom.$filename;
if (DEBUG_ENABLED)
debug_log('Entered with (%s,%s,%s), Returning (%s)',1,__FILE__,__LINE__,__METHOD__,
$index,$filename,$path,$return);
return $return;
}
/**
* Sort a multi dimensional array.
*
* @param array Multi demension array passed by reference
* @param string Comma delimited string of sort keys.
* @param boolean Whether to reverse sort.
* @return array Sorted multi demension array.
*/
function masort(&$data,$sortby,$rev=0) {
if (DEBUG_ENABLED)
debug_log('Entered with (%s,%s,%s)',1,__FILE__,__LINE__,__METHOD__,
$data,$sortby,$rev);
# if the array to sort is null or empty
if (! $data) return;
static $CACHE = array();
if (empty($CACHE[$sortby])) {
$code = "\$c=0;\n";
foreach (explode(',',$sortby) as $key) {
$code .= "if (is_object(\$a) || is_object(\$b)) {\n";
$code .= " if (\$a->$key != \$b->$key)\n";
if ($rev)
$code .= " return (\$a->$key < \$b->$key ? 1 : -1);\n";
else
$code .= " return (\$a->$key > \$b->$key ? 1 : -1);\n";
$code .= "} else {\n";
$code .= "if ((! isset(\$a['$key'])) && (! isset(\$b['$key']))) return 0;\n";
$code .= "if ((! isset(\$a['$key'])) && isset(\$b['$key'])) return -1;\n";
$code .= "if (isset(\$a['$key']) && (! isset(\$b['$key']))) return 1;\n";
$code .= "if (is_numeric(\$a['$key']) && is_numeric(\$b['$key'])) {\n";
$code .= " if (\$a['$key'] != \$b['$key'])\n";
if ($rev)
$code .= " return (\$a['$key'] < \$b['$key'] ? 1 : -1);\n";
else
$code .= " return (\$a['$key'] > \$b['$key'] ? 1 : -1);\n";
$code .= "} else {\n";
if ($rev)
$code .= " if ( (\$c = strcasecmp(\$b['$key'],\$a['$key'])) != 0 ) return \$c;\n";
else
$code .= " if ( (\$c = strcasecmp(\$a['$key'],\$b['$key'])) != 0 ) return \$c;\n";
$code .= "}}\n";
}
$code .= 'return $c;';
$CACHE[$sortby] = create_function('$a, $b',$code);
}
uasort($data,$CACHE[$sortby]);
}
/**
* Is compression enabled for output
*/
function isCompress() {
return (isset($_SESSION[APPCONFIG]) && $_SESSION[APPCONFIG]->getValue('appearance','compress')
&& ! ini_get('zlib.output_compression')
&& eregi('gzip',$_SERVER['HTTP_ACCEPT_ENCODING']));
}
?>