From 8b56e2825d7082b5168da6167b85ef66d8e0f042 Mon Sep 17 00:00:00 2001 From: pdontthink Date: Fri, 13 Oct 2006 17:29:53 +0000 Subject: [PATCH] New static plugin hook registration has now been implemented. Looks to work with a handful of plugins, but keep your eyes out and TEST! Seems like this will be a winner. Everyone needs to run conf.pl once and just type 's' to save after updating their CVS trees. git-svn-id: https://svn.code.sf.net/p/squirrelmail/code/trunk/squirrelmail@11912 7612ce4b-ef26-0410-bec9-ea0150e637f0 --- config/conf.pl | 202 +++++++++++++++++++++++++++++++++++++++++-- functions/plugin.php | 31 +++++-- include/init.php | 21 ++--- 3 files changed, 226 insertions(+), 28 deletions(-) diff --git a/config/conf.pl b/config/conf.pl index 0a0a2539..b314e1ff 100755 --- a/config/conf.pl +++ b/config/conf.pl @@ -53,7 +53,7 @@ if ( -e "config.php" ) { print "The file \"config/config.php\" was found, but you don't\n"; print "have rights to read it.\n"; print "\n"; - print "Press any key to continue"; + print "Press enter to continue"; $ctu = ; exit; } @@ -1529,12 +1529,12 @@ sub command_smtp_sitewide_userpass($) { } } else { print "Invalid input. You must set username used for SMTP authentication.\n"; - print "Click any key to continue\n"; + print "Click enter to continue\n"; $tmp = ; } } else { print "Invalid input\n"; - print "Click any key to continue\n"; + print "Click enter to continue\n"; $tmp = ; } } @@ -2081,7 +2081,7 @@ sub command215 { print "Deleting folders will bypass the trash folder and be immediately deleted\n\n"; print "If this is not the correct value for your server,\n"; print "please use option D on the Main Menu to configure your server correctly.\n\n"; - print "Press any key to continue...\n"; + print "Press enter to continue...\n"; $new_delete = ; $delete_folder = 'true'; } else { @@ -4581,6 +4581,9 @@ sub save_data { close CF; print "Data saved in config.php\n"; + + build_plugin_hook_array(); + } else { print "Error saving config.php: $!\n"; } @@ -4986,7 +4989,7 @@ sub check_imap_folder($) { if ($folder_name =~ /[\x80-\xFFFF]/) { print "Folder name contains 8bit characters. Configuration utility requires\n"; print "UTF7-IMAP encoded folder names.\n"; - print "Press any key to continue..."; + print "Press enter to continue..."; my $tmp = ; return 0; } elsif ($folder_name =~ /[&\*\%]/) { @@ -5011,3 +5014,192 @@ sub quote_single($) { $string =~ s/\'/\\'/g; return $string; } + +# parses the setup.php files for all activated plugins and +# builds static plugin hooks array so we don't have to load +# ALL plugins are runtime and build the hook array on every +# page request +# +# hook array is saved in config/plugin_hooks.php +# +# Note the $verbose variable at the top of this routine +# can be set to zero to quiet it down. +# +# NOTE/FIXME: we aren't necessarily interested in writing +# a full-blown PHP parsing engine, so plenty +# of assumptions are included herein about the +# coding of the plugin setup files, and things +# like commented out curly braces or other +# such oddities can break this in a bad way. +# +sub build_plugin_hook_array() { + + $verbose = 1; + + if ($verbose) { + print "\n\n"; + } + + if ( open( HOOKFILE, ">plugin_hooks.php" ) ) { + print HOOKFILE "; + print "\n"; + next; + } + open( FILE, "$setup_file" ); + $inside_init_fxn = 0; + $brace_count = 0; + while ( $line = ) { + + # throw away lines until we get to target function + # + if (!$inside_init_fxn + && $line !~ /^\s*function\s*squirrelmail_plugin_init_/i) { + next; + } + $inside_init_fxn = 1; + + + # throw away lines that are not exactly one "brace set" deep + # + if ($brace_count > 1) { + next; + } + + + # count open braces + # + if ($line =~ /{/) { + $brace_count++; + } + + + # count close braces + # + if ($line =~ /}/) { + $brace_count--; + + # leaving _init() function... + if ($brace_count == 0) { + close(FILE); + next PLUGIN; + } + + } + + + # also not interested in lines that are not + # hook registration points + # + if ($line !~ /^\s*\$squirrelmail_plugin_hooks/i) { + next; + } + + + # if $line does not have an ending semicolon, + # we need to recursively read in subsequent + # lines until we find one + while ( $line !~ /;\s*$/ ) { + $line =~ s/[\n\r]\s*$//; + $line .= ; + } + + + $line =~ s/^\s+//; + $line =~ s/^\$//; + $var = $line; + + $var =~ s/=/EQUALS/; + if ( $var =~ /^([a-z])/i ) { + @options = split ( /\s*EQUALS\s*/, $var ); + $options[1] =~ s/[\n\r]//g; + $options[1] =~ s/[\'\"];\s*$//; + $options[1] =~ s/;$//; + $options[1] =~ s/^[\'\"]//; + # de-escape escaped strings + $options[1] =~ s/\\'/'/g; + $options[1] =~ s/\\\\/\\/g; + + if ( $options[0] =~ /^squirrelmail_plugin_hooks\s*\[\s*['"]([a-z0-9._-]+)['"]\s*\]\s*\[\s*['"]([0-9a-z._-]+)['"]\s*\]/i ) { + $hook_name = $1; + $hooked_plugin_name = $2; +# FIXME: what to do with this? shouldn't ever be necessary, but... +if ($hooked_plugin_name ne $plugins[$ct]) { + print "ummmm, plugin is tring to hook in under different name.... what do we do with this???\n"; +} + +#FIXME: do we want to count the number of hook registrations for each plugin and warn if a plugin doesn't have any? + # hook registration has been found! + if ($verbose) { + print " registering on hook \"" . $hook_name . "\"\n"; + } + $line =~ s/ {2,}/ /g; + print HOOKFILE "\$$line"; + + } + + } + + } + close(FILE); + + } else { + print "\n"; + print "WARNING:\n"; + print "The file \"$setup_file\" was not found.\n"; + print "The plugin \"" . $plugins[$ct]; + print "\" will not be activated until you fix this.\n"; + print "\nPress enter to continue"; + $ctu = ; + print "\n"; + next; + } + + } + + print HOOKFILE "\n\n"; + close(HOOKFILE); +# if ($verbose) { + print "\nDone activating plugins; registration data saved in plugin_hooks.php\n\n"; +# } + + } else { + + print "\n"; + print "WARNING:\n"; + print "The file \"plugin_hooks.php\" was not able to be written to.\n"; + print "No plugins will be activated until you fix this.\n"; + print "\nPress enter to continue"; + $ctu = ; + print "\n"; + + } + +} + diff --git a/functions/plugin.php b/functions/plugin.php index 342d2ac4..2d1528ac 100644 --- a/functions/plugin.php +++ b/functions/plugin.php @@ -21,10 +21,18 @@ function use_plugin ($name) { if (file_exists(SM_PATH . "plugins/$name/setup.php")) { include_once(SM_PATH . "plugins/$name/setup.php"); - $function = "squirrelmail_plugin_init_$name"; - if (function_exists($function)) { - $function(); - } + + /** + * As of SM 1.5.2, plugin hook registration is statically + * accomplished using the configuration utility (config/conf.pl). + * And this code is deprecated (but let's keep it until + * the new registration system is proven). + * + */ + //$function = "squirrelmail_plugin_init_$name"; + //if (function_exists($function)) { + // $function(); + //} } } @@ -40,7 +48,8 @@ function do_hook ($name) { if (isset($squirrelmail_plugin_hooks[$name]) && is_array($squirrelmail_plugin_hooks[$name])) { - foreach ($squirrelmail_plugin_hooks[$name] as $function) { + foreach ($squirrelmail_plugin_hooks[$name] as $plugin_name => $function) { + use_plugin($plugin_name); /* Add something to set correct gettext domain for plugin. */ if (function_exists($function)) { $function($data); @@ -73,7 +82,8 @@ function filter_hook_function($name,$parm=NULL) { if (isset($squirrelmail_plugin_hooks[$name]) && is_array($squirrelmail_plugin_hooks[$name])) { - foreach ($squirrelmail_plugin_hooks[$name] as $function) { + foreach ($squirrelmail_plugin_hooks[$name] as $plugin_name => $function) { + use_plugin($plugin_name); /* Add something to set correct gettext domain for plugin. */ if (function_exists($function)) { $parm = $function($parm); @@ -102,7 +112,8 @@ function do_hook_function($name,$parm=NULL) { if (isset($squirrelmail_plugin_hooks[$name]) && is_array($squirrelmail_plugin_hooks[$name])) { - foreach ($squirrelmail_plugin_hooks[$name] as $function) { + foreach ($squirrelmail_plugin_hooks[$name] as $plugin_name => $function) { + use_plugin($plugin_name); /* Add something to set correct gettext domain for plugin. */ if (function_exists($function)) { $ret = $function($parm); @@ -146,7 +157,8 @@ function concat_hook_function($name,$parm=NULL) { if (isset($squirrelmail_plugin_hooks[$name]) && is_array($squirrelmail_plugin_hooks[$name])) { - foreach ($squirrelmail_plugin_hooks[$name] as $function) { + foreach ($squirrelmail_plugin_hooks[$name] as $plugin_name => $function) { + use_plugin($plugin_name); /* Add something to set correct gettext domain for plugin. */ if (function_exists($function)) { $plugin_ret = $function($parm); @@ -188,7 +200,8 @@ function boolean_hook_function($name,$parm=NULL,$priority=0,$tie=false) { /* Loop over the plugins that registered the hook */ $currentHookName = $name; - foreach ($squirrelmail_plugin_hooks[$name] as $function) { + foreach ($squirrelmail_plugin_hooks[$name] as $plugin_name => $function) { + use_plugin($plugin_name); if (function_exists($function)) { $ret = $function($parm); if ($ret) { diff --git a/include/init.php b/include/init.php index 1db44003..6a0d70e1 100644 --- a/include/init.php +++ b/include/init.php @@ -268,20 +268,13 @@ if (file_exists(SM_PATH . 'plugins/compatibility/functions.php')) include_once(SM_PATH . 'plugins/compatibility/functions.php'); $squirrelmail_plugin_hooks = array(); -/* On init, register all plugins configured for use. */ -if (isset($plugins) && is_array($plugins)) { - // turn on output buffering in order to prevent output of new lines - ob_start(); - foreach ($plugins as $name) { - use_plugin($name); - } - // get output and remove whitespace - $output = trim(ob_get_contents()); - ob_end_clean(); - // if plugins output more than newlines and spacing, stop script execution. - if (!empty($output)) { - die($output); - } +/** + * On init, we no longer need to load all plugin setup files. + * Now, we load the statically generated hook registrations here + * and let the hook calls include only the plugins needed. + */ +if (file_exists(SM_PATH . 'config/plugin_hooks.php')) { + include_once(SM_PATH . 'config/plugin_hooks.php'); } /** -- 2.25.1