function sqm_array_merge($a, $b, $concat_strings = true) { $ret = array(); if (is_array($a)) { $ret = $a; } else { if (is_string($a) && is_string($b) && $concat_strings) { return $a . $b; } $ret[] = $a; } if (is_array($b)) { foreach ($b as $key => $value) { if (isset($ret[$key])) { $ret[$key] = sqm_array_merge($ret[$key], $value, $concat_strings); } else { $ret[$key] = $value; } } } else { $ret[] = $b; } return $ret; }
/** * This function executes a hook that allows for an arbitrary * return value from each plugin that will be merged into one * array (or one string if all return values are strings) and * returned to the core hook location. * * Note that unlike PHP's array_merge function, matching array keys * will not overwrite each other, instead, values under such keys * will be concatenated if they are both strings, or merged if they * are arrays (in the same (non-overwrite) manner recursively). * * Plugins returning non-arrays (strings, objects, etc) will have * their output added to the end of the ultimate return array, * unless ALL values returned are strings, in which case one string * with all returned strings concatenated together is returned * (unless $force_array is TRUE). * * If any plugin on this hook wants to modify the $args * plugin parameter, it simply has to use call-by-reference * syntax in the hook function that it has registered for the * current hook. Note that this is in addition to (entirely * independent of) the return value for this hook. * * @param string $name Name of hook being executed * @param mixed &$args A single value or an array of arguments * that are to be passed to all plugins * operating off the hook being called. * Note that this argument is passed by * reference thus it is liable to be * changed after the hook completes. * @param boolean $force_array When TRUE, guarantees the return * value will ALWAYS be an array, * (simple strings will be forced * into a one-element array). * When FALSE, behavior is as * described above (OPTIONAL; * default behavior is to return * mixed - array or string). * * @return mixed the merged return arrays or strings of each * plugin on this hook. * */ function concat_hook_function($name, &$args, $force_array = FALSE) { global $squirrelmail_plugin_hooks, $currentHookName; $currentHookName = $name; $ret = ''; if (isset($squirrelmail_plugin_hooks[$name]) && is_array($squirrelmail_plugin_hooks[$name])) { foreach ($squirrelmail_plugin_hooks[$name] as $plugin_name => $function) { use_plugin($plugin_name); if (function_exists($function)) { $plugin_ret = $function($args); if (!empty($plugin_ret)) { $ret = sqm_array_merge($ret, $plugin_ret); } // each plugin can call additional hooks, so need // to make sure the current hook name is accurate // again after each plugin has finished // $currentHookName = $name; } } } if ($force_array && is_string($ret)) { $ret = array($ret); } $currentHookName = ''; return $ret; }