Viewing file: functions.php (22.31 KB) -rw-r--r-- Select action/file-type: (+) | (+) | (+) | Code (+) | Session (+) | (+) | SDB (+) | (+) | (+) | (+) | (+) | (+) |
<?php
/** * SquirrelMail Compatibility Plugin * Copyright (C) 2004-2007 Paul Lesneiwski <paul@squirrelmail.org> * This program is licensed under GPL. See COPYING for details * */
// change this to TRUE to disable plugin config test functionality // which will increase performance (minimally) // $disable_config_check = FALSE;
// ---------------------------------------
global $compatibility_sm_path, $compatibility_disable_config_check; $compatibility_disable_config_check = $disable_config_check;
// we don't want to do any defining constants ourselves to stay // as non-intrusive as possible, so just our own variable // if (defined('SM_PATH')) $compatibility_sm_path = SM_PATH; else $compatibility_sm_path = '../';
// Some uses of this plugin (such as vlogin) were somehow calling the // functions here before having included the functions in global.php, // resulting in fatal errors when called below. Thus, the need for // the following includes //
// we also need to include the validate file first // thing so we don't lose the ability to display themes, // but we cannot include this file unless we are being // called from a plugin request, thus this if statement // /* if ( strpos(getcwd(), 'plugins') ) { if (file_exists($compatibility_sm_path . 'include/validate.php')) include_once($compatibility_sm_path . 'include/validate.php'); else if (file_exists($compatibility_sm_path . 'src/validate.php')) include_once($compatibility_sm_path . 'src/validate.php'); }
include_once($compatibility_sm_path . 'functions/strings.php');
if (file_exists($compatibility_sm_path . 'functions/global.php')) include_once($compatibility_sm_path . 'functions/global.php'); else if (file_exists($compatibility_sm_path . 'src/global.php')) include_once($compatibility_sm_path . 'src/global.php'); */
// legacy support for previous versions of compatibility plugin // //see below // function compatibility_check_sm_version ($a = '0', $b = '0', $c = '0') // { return check_sm_version($a, $b, $c); } function compatibility_check_php_version ($a = '0', $b = '0', $c = '0') { return check_php_version($a, $b, $c); } function compatibility_sqsession_register ($var, $name) { sqsession_register ($var, $name); } function compatibility_sqsession_unregister ($name) { sqsession_unregister($name); } function compatibility_sqsession_is_active() { sqsession_is_active(); } function compatibility_sqsession_is_registered ($name) { return sqsession_is_registered($name); } function compatibility_sqextractGlobalVar ($name) { global $$name; sqgetGlobalVar($name, $$name); }
// now include everything that current SM version is missing // load_legacy_support();
/** * Checks SquirrelMail version, returns TRUE if SquirrelMail * version is at least a.b.c. * * @param $a int Major version number * @param $b int Minor version number * @param $c int Revision number * * @return boolean TRUE if SquirrelMail version matches at * least a.b.c, FALSE otherwise. * */ function compatibility_check_sm_version ($a = '0', $b = '0', $c = '0') { if (function_exists('check_sm_version')) return check_sm_version($a, $b, $c);
global $version; list($aa, $bb, $cc) = preg_split('/\./', $version, 3);
if(!is_numeric($cc)) list($cc, $info) = explode(' ', $cc, 2);
return ($aa > $a) || (($aa == $a) && ($bb > $b)) || (($aa == $a) && ($bb == $b) && ($cc >= $c)); }
/** * Includes needed files with updated API for legacy * SquirrelMail installations * */ function load_legacy_support() {
global $compatibility_sm_path;
// this array should be updated with every release of SquirrelMail, // along with adding needed directories in the includes for this plugin // // order in this array is significant, please keep newest releases // at top of this list, ordered downward from there... // // these have to be hard-coded since there is no way to know if this // plugin is being used in series 1.2.x, 1.3.x, 1.4.x, 1.5.x, etc. // $compatibility_versions = array( '1.5.2', '1.5.1', '1.5.0', '1.4.10', '1.4.9', '1.4.8', '1.4.7', '1.4.6', '1.4.5', '1.4.4', '1.4.3', '1.4.2', '1.4.1', '1.4.0', // skipping 1.3.x, not supported for now '1.2.11', '1.2.10', '1.2.9', '1.2.8', '1.2.7', // if you are running anything older than this, I feel really, really sorry for you );
$is_first = TRUE; foreach ($compatibility_versions as $version_string) {
$csv_version_string = str_replace('.', ', ', $version_string);
if ($is_first) { eval('if (compatibility_check_sm_version(' . $csv_version_string . ')) return;'); $is_first = FALSE; continue; }
if (eval('if (file_exists($compatibility_sm_path . \'plugins/compatibility/includes/' . $version_string . '/global.php\')) include_once($compatibility_sm_path . \'plugins/compatibility/includes/' . $version_string . '/global.php\'); if (compatibility_check_sm_version(' . $csv_version_string . ')) return TRUE;')) return;
}
}
/** * Allows a plugin to push itself (or another plugin) to the top * or bottom of the plugin order for a certain hook. It also * allows for positioning immediately before or after another * plugin. * * NOTE that this function will only be useful when called from * certain points in the code context, such as from a very early * hook like 'config_override', and may not work reliably for * reordering hooks that are already in execution. * * @param string $plugin_name The name of the plugin to reposition. * @param string $hook_name The name of the hook wherein the * repositioning happens. * @param boolean $before If the repositioning should be at the * top of the plugin list (or before the * $relative_plugin plugin). When FALSE, * repositioning goes to the bottom of * the plugin list or after $relative_plugin * (OPTIONAL; default is TRUE). * @param string $relative_plugin The name of a plugin that the repositioning * should be relative to. If not given, * the target plugin is just moved to the * extreme front or back of the whole plugin * list (OPTIONAL; default not used). * * @return boolean TRUE when repositioning succeeds, FALSE otherwise * (for instance, it might fail if the target plugin * is not already registered on the target hook, or * $relative_plugin is not also found on the target hook). * */ function reposition_plugin_on_hook($plugin_name, $hook_name, $before=TRUE, $relative_plugin='') {
global $squirrelmail_plugin_hooks, $plugins;
// make sure plugin is already registered on the target hook // if (is_array($squirrelmail_plugin_hooks[$hook_name]) && !empty($squirrelmail_plugin_hooks[$hook_name][$plugin_name])) {
// move relative to another plugin? // $relative_plugin_function = FALSE; if (!empty($relative_plugin)) { if (empty($squirrelmail_plugin_hooks[$hook_name][$relative_plugin])) return FALSE;
$relative_plugin_function = $squirrelmail_plugin_hooks[$hook_name][$relative_plugin]; }
// grab target plugin's function callback for this hook // $plugin_function = $squirrelmail_plugin_hooks[$hook_name][$plugin_name];
// reordering an associative array can only be done // by rebuilding by hand as far as I know // $new_hook_array = array(); if ($before && !$relative_plugin_function) $new_hook_array[$plugin_name] = $plugin_function; foreach ($squirrelmail_plugin_hooks[$hook_name] as $plugin => $function) {
if ($plugin == $plugin_name) continue;
// move relative to another plugin? // if ($plugin == $relative_plugin && !empty($relative_plugin)) { if ($before) { $new_hook_array[$plugin_name] = $plugin_function; $new_hook_array[$relative_plugin] = $relative_plugin_function; } else { $new_hook_array[$relative_plugin] = $relative_plugin_function; $new_hook_array[$plugin_name] = $plugin_function; } continue; }
$new_hook_array[$plugin] = $function;
} if (!$before && !$relative_plugin_function) $new_hook_array[$plugin_name] = $plugin_function;
// now replace the plugins for the target hook // $squirrelmail_plugin_hooks[$hook_name] = $new_hook_array;
return TRUE;
}
// plugin not found on target hook // return FALSE;
}
/** * Dynamically enables a plugin to the SquirrelMail environment. * * @param string $plugin_name The name of the plugin to add. * @param mixed $args The current plugin function argument, * which must be exactly as received by * the plugin function that is calling * this code (OPTIONAL; default empty). * @param boolean $dont_execute When adding plugins that are registered * on the same hook that is currently being * executed, the registered function for * the new plugins will be manually run, * however, setting this flag to TRUE will * prevent that from happening (plugins * will be registered, but never executed) * (OPTIONAL; default is FALSE). * */ function add_plugin($plugin_name, $args='', $dont_execute=FALSE) {
global $squirrelmail_plugin_hooks, $plugins;
// changing the hook function array whilst in the // middle of iterating thru it for the same hook // doesn't always work, so we'll see if the hook // currently being executed has had its function // list changed; if so, we will execute the added // hook functions ourselves // $hook_name = get_current_hook_name($args);
// used below for determining if any plugins // were added to currently running hook // if (!empty($hook_name) && !empty($squirrelmail_plugin_hooks[$hook_name]) && is_array($squirrelmail_plugin_hooks[$hook_name])) $original_hook_functions = $squirrelmail_plugin_hooks[$hook_name]; else $original_hook_functions = array();
// add plugin to global plugin array // $plugins[] = $plugin_name;
// enable plugin -- emulate code from use_plugin() function // in SquirrelMail core, because in 1.5.2, it no longer // called "squirrelmail_plugin_init_<plugin_name>", which // NEEDS to be called here. // if (file_exists(SM_PATH . "plugins/$plugin_name/setup.php")) {
include_once(SM_PATH . "plugins/$plugin_name/setup.php");
$function = "squirrelmail_plugin_init_$plugin_name"; if (function_exists($function)) $function();
}
// now get any new plugins for the current hook // and run their hooks // if (!$dont_execute && !empty($hook_name)) {
if (!empty($squirrelmail_plugin_hooks[$hook_name]) && is_array($squirrelmail_plugin_hooks[$hook_name])) $new_hook_functions = array_diff($squirrelmail_plugin_hooks[$hook_name], $original_hook_functions); else $new_hook_functions = array();
foreach ($new_hook_functions as $function) if (function_exists($function)) //FIXME: is $args always how plugins are called, even in 1.4.x? $function($args);
}
}
/** * Dynamically disables a plugin from the SquirrelMail environment. * * @param string $plugin_name The name of the plugin to remove. * */ function remove_plugin($plugin_name) {
global $squirrelmail_plugin_hooks, $plugins;
$plugin_key = array_search($plugin_name, $plugins); if (!is_null($plugin_key) && $plugin_key !== FALSE) { unset($plugins[$plugin_key]); if (is_array($squirrelmail_plugin_hooks)) foreach (array_keys($squirrelmail_plugin_hooks) as $hookName) { unset($squirrelmail_plugin_hooks[$hookName][$plugin_name]); } }
}
/** * Determines what plugin hook is currently executing, * if any, in a SquirrelMail version-independent fashion. * * @param mixed $args The current plugin function argument, * which must be exactly as received by * the plugin function that is calling * this code. * * @return string The name of the currently executing plugin * hook, or an empty string if either no hook * is running or the hook name could not be * determined. * */ function get_current_hook_name($args) {
if (check_sm_version(1, 5, 1)) { global $currentHookName; return $currentHookName; } else { //TODO: should we ALWAYS backtrace instead of assuming that $args[0] is the hook name? if (!empty($args[0]) && is_string($args[0])) return $args[0]; else {
// plugin args not given or didn't have a hook // name in them, so try backtracing instead // $backtrace = debug_backtrace(); foreach ($backtrace as $trace) if ($trace['function'] == 'do_hook' || $trace['function'] == 'do_hook_function' || $trace['function'] == 'concat_hook_function' || $trace['function'] == 'boolean_hook_function') return $trace['args'][0];
// nothing found at all // return '';
} }
}
/** * Load configuration file * * Convenience function for plugins that loads a configuration * file (or files). If the file(s) is(are) not found, an error * is displayed and execution stops (function won't return). * If multiple configuration files are given, ALL of them are * included, if they exist, in the order given. Only one of * them needs to be found to avert triggering an error. * * Non-functional on login_before hook. * * @param string $plugin_name The name of the plugin as * it is known to SquirrelMail, * that is, it is the name * of the plugin directory * @param array $config_files An array of files that will * be included IN THE ORDER that * they are given in the * array. Files should be specified * relative to the calling * plugin's directory, such as: * array('config.php') * or: * array('data/config.php', 'data/admins.php') * It is also possible to give a * full/direct path to a * configuration file by placing * a forward slash at the * beginning of the file: * array('/var/lib/squirrelmail/config/myplugin.conf') * @param boolean $return_errors When true, any errors encountered * will cause this function to return * FALSE; otherwise, errors are * handled herein by showing an error * to the user and exiting (OPTIONAL; * default is FALSE). * * @return mixed If no errors are found, TRUE is returned; if an error * was found and $return_errors is TRUE, FALSE is returned. * If $return_errors is FALSE and an error is found, this * function will never return. * */ function load_config($plugin_name, $config_files, $return_errors=FALSE) {
global $compatibility_sm_path;
// if only one config file given as string, push // into an array just to be nice // if (!is_array($config_files)) $config_files = array($config_files);
// loop through files, attempting to include them // $file_count = 1; foreach ($config_files as $file) {
if (strpos($file, '/') === 0) $plugin_path = $file; else $plugin_path = $compatibility_sm_path . 'plugins/' . $plugin_name . '/' . $file;
// store inclusion results to be checked below // ${'config' . $file_count} = @include_once($plugin_path);
$file_count++; }
// now check to see if we got at least one successful inclusion // $success = FALSE; for ($i = 1; $i < $file_count; $i++) if (${'config' . $i}) { $success = TRUE; break; }
// error... // if (!$success) {
if ($return_errors) return FALSE;
bindtextdomain('compatibility', $compatibility_sm_path . 'locale'); textdomain('compatibility'); $error_msg = _("Administrative error:") . '<br />' . sprintf(_("The plugin %s has not been set up correctly."), '"<strong>' . $plugin_name . '</strong>"') . '<br />' . _("Please read the README or INSTALL files that came with the plugin."); bindtextdomain('squirrelmail', $compatibility_sm_path . 'locale'); textdomain('squirrelmail'); include_once($compatibility_sm_path . 'functions/display_messages.php'); global $color; plain_error_message($error_msg, $color); exit; }
return TRUE;
}
/** * Validate Plugin Setup Utility * * Checks a plugin to see if the user has installed it * correctly by checking for the existence of the given * files (all relative from the plugin's directory) * * @param string $pluginName The name of the plugin as * it is known to SquirrelMail, * that is, it is the name * of the plugin directory. * @param array $configFiles An array of any files that the * user should have set up for * this plugin, for example: * array('config.php') * or: * array('data/config.php', 'data/admins.php') * where all files will be * referenced from the plugin's * main directory. * It is also possible to give a * full/direct path to a * configuration file by placing * a forward slash at the * beginning of the file: * array('/var/lib/squirrelmail/config/myplugin.conf') * @param boolean $return_errors When true, any errors encountered * will cause this function to return * either FALSE or a string describing * the error; otherwise, errors are * handled herein by showing an error * to the user and exiting (OPTIONAL; * default is FALSE). * * @return mixed If no errors are found, TRUE is returned; if an error * was found and $return_errors is TRUE, either FALSE or * a string describing the error is returned. If $return_errors * is FALSE and an error is found, this function will never * return. * */ function check_plugin_setup($pluginName, $configFiles, $return_errors=FALSE) {
global $compatibility_disable_config_check; if ($compatibility_disable_config_check) return;
global $compatibility_sm_path;
// check one at a time... // foreach ($configFiles as $configFile) {
if (strpos($configFile, '/') === 0) $plugin_path = $configFile; else $plugin_path = $compatibility_sm_path . 'plugins/' . $pluginName . '/' . $configFile;
if (!file_exists($plugin_path)) {
//if ($return_errors) return FALSE;
bindtextdomain('compatibility', $compatibility_sm_path . 'locale'); textdomain('compatibility');
if ($return_errors) { $error_msg = sprintf(_("The file %s is missing from plugin %s."), '"<strong>' . $configFile . '</strong>"', '"<strong>' . $pluginName . '</strong>"'); bindtextdomain('squirrelmail', $compatibility_sm_path . 'locale'); textdomain('squirrelmail'); return $error_msg; }
$error_msg = _("Administrative error:") . '<br />' . sprintf(_("The plugin %s has not been set up correctly."), '"<strong>' . $pluginName . '</strong>"') . '<br />' . sprintf(_("The file %s is missing."), '"<strong>' . $configFile . '</strong>"') . '<br />' . _("Please read the README or INSTALL files that came with the plugin."); bindtextdomain('squirrelmail', $compatibility_sm_path . 'locale'); textdomain('squirrelmail'); include_once($compatibility_sm_path . 'functions/display_messages.php'); global $color; plain_error_message($error_msg, $color); exit;
}
}
return TRUE;
}
|