7dbda95f283d85d46e8b26e6ac578fb280695862
6 * This file provides the framework for a plugin architecture.
8 * Documentation on how to write plugins might show up some time.
10 * @copyright © 1999-2007 The SquirrelMail Project Team
11 * @license http://opensource.org/licenses/gpl-license.php GNU Public License
13 * @package squirrelmail
17 * This function adds a plugin.
18 * @param string $name Internal plugin name (ie. delete_move_next)
21 function use_plugin ($name) {
22 if (file_exists(SM_PATH
. "plugins/$name/setup.php")) {
23 include_once(SM_PATH
. "plugins/$name/setup.php");
26 * As of SM 1.5.2, plugin hook registration is statically
27 * accomplished using the configuration utility (config/conf.pl).
28 * And this code is deprecated (but let's keep it until
29 * the new registration system is proven).
32 //$function = "squirrelmail_plugin_init_$name";
33 //if (function_exists($function)) {
40 * This function executes a plugin hook.
42 * It includes an arbitrary return value that is managed by
43 * all plugins on the same hook and returned to the core hook
46 * The desired format of the return value should be defined
47 * by the context in which the hook is called.
49 * Note that the master return value for this hook is passed
50 * to each plugin after the main argument(s) value/array as a
51 * convenience only - to show what the current return value is
52 * even though it is liable to be changed by other plugins.
54 * If any plugin on this hook wants to modify the $args
55 * plugin parameter, it simply has to use call-by-reference
56 * syntax in the hook function that it has registered for the
57 * current hook. Note that this is in addition to (entirely
58 * independent of) the return value for this hook.
60 * @param string $name Name of hook being executed
61 * @param mixed $args A single value or an array of arguments
62 * that are to be passed to all plugins
63 * operating off the hook being called.
64 * Note that this argument is passed by
65 * reference thus it is liable to be
66 * changed after the hook completes.
68 * @return mixed The return value that is managed by the plugins
69 * on the current hook.
72 function do_hook($name, &$args) {
74 global $squirrelmail_plugin_hooks, $currentHookName;
75 $currentHookName = $name;
78 if (isset($squirrelmail_plugin_hooks[$name])
79 && is_array($squirrelmail_plugin_hooks[$name])) {
80 foreach ($squirrelmail_plugin_hooks[$name] as $plugin_name => $function) {
81 use_plugin($plugin_name);
82 if (function_exists($function)) {
83 $ret = $function($args, $ret);
85 // each plugin can call additional hooks, so need
86 // to make sure the current hook name is accurate
87 // again after each plugin has finished
89 $currentHookName = $name;
94 $currentHookName = '';
100 * This function executes a hook that allows for an arbitrary
101 * return value from each plugin that will be merged into one
102 * array (or one string if all return values are strings) and
103 * returned to the core hook location.
105 * Note that unlike PHP's array_merge function, matching array keys
106 * will not overwrite each other, instead, values under such keys
107 * will be concatenated if they are both strings, or merged if they
108 * are arrays (in the same (non-overwrite) manner recursively).
110 * Plugins returning non-arrays (strings, objects, etc) will have
111 * their output added to the end of the ultimate return array,
112 * unless ALL values returned are strings, in which case one string
113 * with all returned strings concatenated together is returned
114 * (unless $force_array is TRUE).
116 * If any plugin on this hook wants to modify the $args
117 * plugin parameter, it simply has to use call-by-reference
118 * syntax in the hook function that it has registered for the
119 * current hook. Note that this is in addition to (entirely
120 * independent of) the return value for this hook.
122 * @param string $name Name of hook being executed
123 * @param mixed $args A single value or an array of arguments
124 * that are to be passed to all plugins
125 * operating off the hook being called.
126 * Note that this argument is passed by
127 * reference thus it is liable to be
128 * changed after the hook completes.
129 * @param boolean $force_array When TRUE, guarantees the return
130 * value will ALWAYS be an array,
131 * (simple strings will be forced
132 * into a one-element array).
133 * When FALSE, behavior is as
134 * described above (OPTIONAL;
135 * default behavior is to return
136 * mixed - array or string).
138 * @return mixed the merged return arrays or strings of each
139 * plugin on this hook.
142 function concat_hook_function($name, &$args, $force_array=FALSE) {
144 global $squirrelmail_plugin_hooks, $currentHookName;
145 $currentHookName = $name;
148 if (isset($squirrelmail_plugin_hooks[$name])
149 && is_array($squirrelmail_plugin_hooks[$name])) {
150 foreach ($squirrelmail_plugin_hooks[$name] as $plugin_name => $function) {
151 use_plugin($plugin_name);
152 if (function_exists($function)) {
153 $plugin_ret = $function($args);
154 if (!empty($plugin_ret)) {
155 $ret = sqm_array_merge($ret, $plugin_ret);
158 // each plugin can call additional hooks, so need
159 // to make sure the current hook name is accurate
160 // again after each plugin has finished
162 $currentHookName = $name;
167 if ($force_array && is_string($ret)) {
171 $currentHookName = '';
177 * This function is used for hooks which are to return true or
178 * false. If $priority is > 0, any one or more trues will override
179 * any falses. If $priority < 0, then one or more falses will
180 * override any trues.
181 * Priority 0 means majority rules. Ties will be broken with $tie
183 * If any plugin on this hook wants to modify the $args
184 * plugin parameter, it simply has to use call-by-reference
185 * syntax in the hook function that it has registered for the
186 * current hook. Note that this is in addition to (entirely
187 * independent of) the return value for this hook.
189 * @param string $name The hook name
190 * @param mixed $args A single value or an array of arguments
191 * that are to be passed to all plugins
192 * operating off the hook being called.
193 * Note that this argument is passed by
194 * reference thus it is liable to be
195 * changed after the hook completes.
196 * @param int $priority See explanation above
197 * @param boolean $tie See explanation above
199 * @return boolean The result of the function
202 function boolean_hook_function($name, &$args, $priority=0, $tie=false) {
204 global $squirrelmail_plugin_hooks, $currentHookName;
209 if (isset($squirrelmail_plugin_hooks[$name]) &&
210 is_array($squirrelmail_plugin_hooks[$name])) {
212 /* Loop over the plugins that registered the hook */
213 $currentHookName = $name;
214 foreach ($squirrelmail_plugin_hooks[$name] as $plugin_name => $function) {
215 use_plugin($plugin_name);
216 if (function_exists($function)) {
217 $ret = $function($args);
224 // each plugin can call additional hooks, so need
225 // to make sure the current hook name is accurate
226 // again after each plugin has finished
228 $currentHookName = $name;
231 $currentHookName = '';
233 /* Examine the aftermath and assign the return value appropriately */
234 if (($priority > 0) && ($yea)) {
236 } elseif (($priority < 0) && ($nay)) {
238 } elseif ($yea > $nay) {
240 } elseif ($nay > $yea) {
243 // There's a tie, no action needed.
247 // If the code gets here, there was a problem - no hooks, etc.
253 * Do not use, use checkForJavascript() instead.
255 * This function checks whether the user's USER_AGENT is known to
256 * be broken. If so, returns true and the plugin is invisible to the
258 * *** THIS IS A TEST FOR JAVASCRIPT SUPPORT ***
260 * @return bool whether this browser properly supports JavaScript
261 * @deprecated use checkForJavascript() since 1.5.1
264 return !checkForJavascript();
268 * Check if plugin is enabled
269 * @param string $plugin_name plugin name
273 function is_plugin_enabled($plugin_name) {
277 * check if variable is empty. if var is not set, php empty
278 * returns true without error notice.
280 * then check if it is an array
282 if (empty($plugins) ||
! is_array($plugins))
285 if ( in_array($plugin_name,$plugins) ) {
293 * Get a plugin's version.
295 * Determines and returns a plugin's version.
297 * By default, the desired plugin must be currently
298 * activated, and if it is not, this function will
299 * return FALSE. By overriding the default value
300 * of $force_inclusion, this function will attempt
301 * to grab versioning information from the given
302 * plugin even if it is not activated (plugin still
303 * has to be unpackaged and set in place in the
304 * plugins directory). Use with care - some plugins
305 * might break SquirrelMail when this is used.
307 * By turning on the $do_parse argument, the version
308 * string will be parsed by SquirrelMail into a
309 * SquirrelMail-compatible version string (such as
310 * "1.2.3") if it is not already.
312 * Note that this assumes plugin versioning is
313 * consistently applied in the same fashion that
314 * SquirrelMail versions are, with the exception that
315 * an applicable SquirrelMail version may be appended
316 * to the version number (which will be ignored herein).
317 * That is, plugin version number schemes are expected
318 * in the following format: 1.2.3, or 1.2.3-1.4.0.
320 * Any characters after the third version number
321 * indicating things such as beta or release candidate
322 * versions are discarded, so formats such as the
323 * following will also work, although extra information
324 * about beta versions can possibly confuse the desired
325 * results of the version check: 1.2.3-beta4, 1.2.3.RC2,
330 * @param string plugin_name name of the plugin to
331 * check; must precisely
334 * @param bool force_inclusion try to get version info
335 * for plugins not activated?
337 * @param bool do_parse return the plugin version
338 * in SquirrelMail-compatible
339 * format (default FALSE)
341 * @return mixed The plugin version string if found, otherwise,
342 * boolean FALSE is returned indicating that no
343 * version information could be found for the plugin.
346 function get_plugin_version($plugin_name, $force_inclusion = FALSE, $do_parse = FALSE)
349 $info_function = $plugin_name . '_info';
350 $version_function = $plugin_name . '_version';
351 $plugin_info = array();
352 $plugin_version = FALSE;
355 // first attempt to find the plugin info function, wherein
356 // the plugin version should be available
358 if (function_exists($info_function))
359 $plugin_info = $info_function();
360 else if ($force_inclusion
361 && file_exists(SM_PATH
. 'plugins/' . $plugin_name . '/setup.php'))
364 /* --- Old code, keeping just in case... problem with it is, for example,
365 if it is used, but later we are checking if the same plugin is
366 activated (because it SHOULD be), this code having run will possibly
367 create a false positive.
368 include_once(SM_PATH . 'plugins/' . $plugin_name . '/setup.php');
369 if (function_exists($info_function))
370 $plugin_info = $info_function();
373 // so what we need to do is process this plugin without
374 // it polluting our environment
376 // we *could* just use the above code, which is more of a
377 // sure thing than some regular expressions, and then test
378 // the contents of the $plugins array to see if this plugin
379 // is actually activated, and that might be good enough, but
380 // for now, we'll use the following approach, because of two
381 // concerns: other plugins and other templates might force
382 // the inclusion of a plugin (which SHOULD also add it to
383 // the $plugins array, but am not 100% sure at this time (FIXME)),
384 // and because the regexps below should work just fine with
385 // any resonably formatted plugin setup file.
387 // read the target plugin's setup.php file into a string,
388 // then use a regular expression to try to find the version...
389 // this of course can break if plugin authors do funny things
390 // with their file formatting
393 $file_contents = file(SM_PATH
. 'plugins/' . $plugin_name . '/setup.php');
394 foreach ($file_contents as $line)
395 $setup_file .= $line;
398 // this regexp grabs a version number from a standard
399 // <plugin>_info() function
401 if (preg_match('/[\'"]version[\'"]\s*=>\s*[\'"](.+?)[\'"]/is', $setup_file, $matches))
402 $plugin_info = array('version' => $matches[1]);
405 // this regexp grabs a version number from a standard
406 // (deprecated) <plugin>_version() function
408 else if (preg_match('/function\s+.*?' . $plugin_name . '_version.*?\(.*?\).*?\{.*?return\s+[\'"](.+?)[\'"]/is', $setup_file, $matches))
409 $plugin_info = array('version' => $matches[1]);
412 if (!empty($plugin_info['version']))
413 $plugin_version = $plugin_info['version'];
416 // otherwise, look for older version function
418 if (!$plugin_version && function_exists($version_function))
419 $plugin_version = $version_function();
422 if ($plugin_version && $do_parse)
425 // massage version number into something we understand
427 // the first regexp strips everything and anything that follows
428 // the first occurance of a non-digit (or non decimal point), so
429 // beware that putting letters in the middle of a version string
430 // will effectively truncate the version string right there (but
431 // this also just helps remove the SquirrelMail version part off
432 // of versions such as "1.2.3-1.4.4")
434 // the second regexp just strips out non-digits/non-decimal points
435 // (and might be redundant(?))
437 // the regexps are wrapped in a trim that makes sure the version
438 // does not start or end with a decimal point
440 $plugin_version = trim(preg_replace(array('/[^0-9.]+.*$/', '/[^0-9.]/'),
441 '', $plugin_version),
446 return $plugin_version;
451 * Check a plugin's version.
453 * Returns TRUE if the given plugin is installed,
454 * activated and is at minimum version $a.$b.$c.
455 * If any one of those conditions fails, FALSE
456 * will be returned (careful of plugins that are
457 * sufficiently versioned but are not activated).
459 * By overriding the default value of $force_inclusion,
460 * this function will attempt to grab versioning
461 * information from the given plugin even if it
462 * is not activated (the plugin still has to be
463 * unpackaged and set in place in the plugins
464 * directory). Use with care - some plugins
465 * might break SquirrelMail when this is used.
467 * Note that this function assumes plugin
468 * versioning is consistently applied in the same
469 * fashion that SquirrelMail versions are, with the
470 * exception that an applicable SquirrelMail
471 * version may be appended to the version number
472 * (which will be ignored herein). That is, plugin
473 * version number schemes are expected in the following
474 * format: 1.2.3, or 1.2.3-1.4.0.
476 * Any characters after the third number indicating
477 * things such as beta or release candidate versions
478 * are discarded, so formats such as the following
479 * will also work, although extra information about
480 * beta versions can possibly confuse the desired results
481 * of the version check: 1.2.3-beta4, 1.2.3.RC2, and so forth.
485 * @param string plugin_name Name of the plugin to
486 * check; must precisely
489 * @param int a Major version number
490 * @param int b Minor version number
491 * @param int c Release number
492 * @param bool force_inclusion Try to get version info
493 * for plugins not activated?
499 function check_plugin_version($plugin_name,
500 $a = 0, $b = 0, $c = 0,
501 $force_inclusion = FALSE)
504 $plugin_version = get_plugin_version($plugin_name, $force_inclusion, TRUE);
505 if (!$plugin_version) return FALSE;
508 // split the version string into sections delimited by
509 // decimal points, and make sure we have three sections
511 $plugin_version = explode('.', $plugin_version);
512 if (!isset($plugin_version[0])) $plugin_version[0] = 0;
513 if (!isset($plugin_version[1])) $plugin_version[1] = 0;
514 if (!isset($plugin_version[2])) $plugin_version[2] = 0;
515 // sm_print_r($plugin_version);
518 // now test the version number
520 if ($plugin_version[0] < $a ||
521 ($plugin_version[0] == $a && $plugin_version[1] < $b) ||
522 ($plugin_version[0] == $a && $plugin_version[1] == $b && $plugin_version[2] < $c))
531 * Get a certain plugin requirement.
533 * Attempts to find the given plugin requirement value
534 * in the given plugin's informational array, and returns
535 * it or NULL if it was not found.
537 * Some plugins have different values for the same
538 * requirement depending on the SquirrelMail version,
539 * and this function is smart enough to take that into
542 * By default, the desired plugin must be currently
543 * activated, and if it is not, this function will
544 * return NULL. By overriding the default value
545 * of $force_inclusion, this function will attempt
546 * to grab requirement information from the given
547 * plugin even if it is not activated (plugin still
548 * has to be unpackaged and set in place in the
549 * plugins directory). Use with care - some plugins
550 * might break SquirrelMail when this is used.
554 * @param string plugin_name Name of the plugin to
555 * check; must precisely
558 * @param string requirement The desired requirement name
559 * @param bool force_inclusion Try to get requirement info
560 * for plugins not activated?
563 * @return mixed NULL is returned if the plugin could not be
564 * found or does not include the given requirement,
565 * otherwise the value of the requirement is returned,
566 * whatever that may be (varies per requirement type).
569 function get_plugin_requirement($plugin_name, $requirement,
570 $force_inclusion = FALSE)
573 $info_function = $plugin_name . '_info';
574 $plugin_info = array();
575 $requirement_value = NULL;
578 // first attempt to find the plugin info function, wherein
579 // the plugin requirements should be available
581 if (function_exists($info_function))
582 $plugin_info = $info_function();
583 else if ($force_inclusion
584 && file_exists(SM_PATH
. 'plugins/' . $plugin_name . '/setup.php'))
587 /* --- Old code, keeping just in case... problem with it is, for example,
588 if it is used, but later we are checking if the same plugin is
589 activated (because it SHOULD be), this code having run will possibly
590 create a false positive.
591 include_once(SM_PATH . 'plugins/' . $plugin_name . '/setup.php');
592 if (function_exists($info_function))
593 $plugin_info = $info_function();
596 // so what we need to do is process this plugin without
597 // it polluting our environment
599 // we *could* just use the above code, which is more of a
600 // sure thing than a regular expression, and then test
601 // the contents of the $plugins array to see if this plugin
602 // is actually activated, and that might be good enough, but
603 // for now, we'll use the following approach, because of two
604 // concerns: other plugins and other templates might force
605 // the inclusion of a plugin (which SHOULD also add it to
606 // the $plugins array, but am not 100% sure at this time (FIXME)),
607 // and because the regexp below should work just fine with
608 // any resonably formatted plugin setup file.
610 // read the target plugin's setup.php file into a string,
611 // then use a regular expression to try to find the needed
612 // requirement information...
613 // this of course can break if plugin authors do funny things
614 // with their file formatting
617 $file_contents = file(SM_PATH
. 'plugins/' . $plugin_name . '/setup.php');
618 foreach ($file_contents as $line)
619 $setup_file .= $line;
622 // this regexp grabs the full plugin info array from a standard
623 // <plugin>_info() function... determining the end of the info
624 // array can fail, but if authors end the array with ");\n"
625 // (without quotes), then it should work well, especially because
626 // newlines shouldn't be found inside the array after any ");"
629 if (preg_match('/function\s+.*?' . $plugin_name . '_info.*?\(.*?\).*?\{.*?(array.+?\)\s*;)\s*' . "\n" . '/is', $setup_file, $matches))
630 eval('$plugin_info = ' . $matches[1]);
635 // attempt to get the requirement from the "global" scope
636 // of the plugin information array
638 if (isset($plugin_info[$requirement])
639 && !is_null($plugin_info[$requirement]))
640 $requirement_value = $plugin_info[$requirement];
643 // now, if there is a series of per-version requirements,
646 if (!empty($plugin_info['per_version_requirements'])
647 && is_array($plugin_info['per_version_requirements']))
650 // iterate through requirements, where keys are version
651 // numbers -- tricky part is knowing the difference between
652 // more than one version for which the current SM installation
653 // passes the check_sm_version() test... we want the highest one
655 $requirement_value_override = NULL;
656 $highest_version_array = array();
657 foreach ($plugin_info['per_version_requirements'] as $version => $requirement_overrides)
660 $version_array = explode('.', $version);
661 if (sizeof($version_array) != 3) continue;
663 $a = $version_array[0];
664 $b = $version_array[1];
665 $c = $version_array[2];
667 if (check_sm_version($a, $b, $c)
668 && isset($requirement_overrides[$requirement])
669 && !is_null($requirement_overrides[$requirement]))
672 if (empty($highest_version_array)
673 ||
$highest_version_array[0] < $a
674 ||
($highest_version_array[0] == $a
675 && $highest_version_array[1] < $b)
676 ||
($highest_version_array[0] == $a
677 && $highest_version_array[1] == $b
678 && $highest_version_array[2] < $c))
680 $highest_version_array = $version_array;
681 $requirement_value_override = $requirement_overrides[$requirement];
688 // now grab override if one is available
690 if (!is_null($requirement_value_override))
691 $requirement_value = $requirement_value_override;
695 return $requirement_value;
700 * Get a plugin's other plugin dependencies.
702 * Determines and returns all the other plugins
703 * that a given plugin requires, as well as the
704 * minimum version numbers of the required plugins
705 * and whether or not they need to be activated.
707 * By default, the desired plugin must be currently
708 * activated, and if it is not, this function will
709 * return FALSE. By overriding the default value
710 * of $force_inclusion, this function will attempt
711 * to grab dependency information from the given
712 * plugin even if it is not activated (plugin still
713 * has to be unpackaged and set in place in the
714 * plugins directory). Use with care - some plugins
715 * might break SquirrelMail when this is used.
717 * By turning on the $do_parse argument (it is on by
718 * default), the version string for each required
719 * plugin will be parsed by SquirrelMail into a
720 * SquirrelMail-compatible version string (such as
721 * "1.2.3") if it is not already. See notes about
722 * version formatting under the get_plugin_version()
723 * function documentation.
727 * @param string plugin_name name of the plugin to
728 * check; must precisely
731 * @param bool force_inclusion try to get version info
732 * for plugins not activated?
734 * @param bool do_parse return the version numbers
735 * for required plugins in
736 * SquirrelMail-compatible
737 * format (default FALSE)
739 * @return mixed Boolean FALSE is returned if the plugin
740 * could not be found or does not indicate
741 * whether it has other plugin dependencies,
742 * otherwise an array is returned where keys
743 * are the names of required plugin dependencies,
744 * and values are arrays again, where at least
745 * the following keys (and corresponding values)
746 * will be available: 'version' - value is the
747 * minimum version required for that plugin (the
748 * format of which might vary per the value of
749 * $do_parse), 'activate' - value is boolean:
750 * TRUE indicates that the plugin must also be
751 * activated, FALSE means that it only needs to
752 * be present, but does not need to be activated.
753 * Note that the return value might be an empty
754 * array, indicating that the plugin has no
758 function get_plugin_dependencies($plugin_name, $force_inclusion = FALSE,
762 $plugin_dependencies = get_plugin_requirement($plugin_name,
767 // not an array of requirements? wrong format, just return FALSE
769 if (!is_array($plugin_dependencies))
773 // make sure everything is in order...
775 if (!empty($plugin_dependencies))
778 $new_plugin_dependencies = array();
779 foreach ($plugin_dependencies as $plugin_name => $plugin_requirements)
782 // if $plugin_requirements isn't an array, this is old-style,
783 // where only the version number was given...
785 if (is_string($plugin_requirements))
786 $plugin_requirements = array('version' => $plugin_requirements,
787 'activate' => FALSE);
790 // trap badly formatted requirements arrays that don't have
793 if (!is_array($plugin_requirements)
794 ||
!isset($plugin_requirements['version']))
796 if (!isset($plugin_requirements['activate']))
797 $plugin_requirements['activate'] = FALSE;
800 // parse version into something we understand?
805 // massage version number into something we understand
807 // the first regexp strips everything and anything that follows
808 // the first occurance of a non-digit (or non decimal point), so
809 // beware that putting letters in the middle of a version string
810 // will effectively truncate the version string right there (but
811 // this also just helps remove the SquirrelMail version part off
812 // of versions such as "1.2.3-1.4.4")
814 // the second regexp just strips out non-digits/non-decimal points
815 // (and might be redundant(?))
817 // the regexps are wrapped in a trim that makes sure the version
818 // does not start or end with a decimal point
820 $plugin_requirements['version']
821 = trim(preg_replace(array('/[^0-9.]+.*$/', '/[^0-9.]/'),
822 '', $plugin_requirements['version']),
827 $new_plugin_dependencies[$plugin_name] = $plugin_requirements;
831 $plugin_dependencies = $new_plugin_dependencies;
835 return $plugin_dependencies;
840 * Check a plugin's other plugin dependencies.
842 * Determines whether or not all of the given
843 * plugin's required plugins are installed and
844 * up to the proper version, and if they are
845 * activated if required.
847 * By default, the desired plugin must be currently
848 * activated, and if it is not, this function will
849 * return FALSE. By overriding the default value
850 * of $force_inclusion, this function will attempt
851 * to grab dependency information from the given
852 * plugin even if it is not activated (plugin still
853 * has to be unpackaged and set in place in the
854 * plugins directory). Use with care - some plugins
855 * might break SquirrelMail when this is used.
857 * NOTE that if a plugin does not report whether or
858 * not it has other plugin dependencies, this function
859 * will return TRUE, although that is possibly incorrect
864 * @param string plugin_name name of the plugin to
865 * check; must precisely
868 * @param bool force_inclusion try to get version info
869 * for plugins not activated?
872 * @return mixed Boolean TRUE if all of the plugin's
873 * required plugins are correctly installed,
874 * otherwise an array of the required plugins
875 * that are either not installed or not up to
876 * the minimum required version. The array is
877 * keyed by plugin name where values are arrays
878 * again, where at least the following keys (and
879 * corresponding values) will be available:
880 * 'version' - value is the minimum version
881 * required for that plugin (in printable, non-
882 * parsed format), 'activate' - value is boolean:
883 * TRUE indicates that the plugin must also be
884 * activated, FALSE means that it only needs to
885 * be present, but does not need to be activated.
888 function check_plugin_dependencies($plugin_name, $force_inclusion = FALSE)
891 $dependencies = get_plugin_dependencies($plugin_name, $force_inclusion);
892 if (!$dependencies) return TRUE;
893 $missing_or_bad = array();
895 foreach ($dependencies as $depend_name => $depend_requirements)
897 $version = preg_split('/\./', $depend_requirements['version'], 3);
898 $version[0] = intval($version[0]);
899 $version[1] = intval($version[1]);
900 $version[2] = intval($version[2]);
902 $force_dependency_inclusion = !$depend_requirements['activate'];
904 if (!check_plugin_version($depend_name, $version[0], $version[1],
905 $version[2], $force_dependency_inclusion))
906 $missing_or_bad[$depend_name] = $depend_requirements;
909 if (empty($missing_or_bad)) return TRUE;
912 // get non-parsed required versions
914 $non_parsed_dependencies = get_plugin_dependencies($plugin_name,
917 $return_array = array();
918 foreach ($missing_or_bad as $depend_name => $ignore)
919 $return_array[$depend_name] = $non_parsed_dependencies[$depend_name];
921 return $return_array;