+ function demo_handle_zip_attachment(&$Args)
+ {
+ include_once(SM_PATH . 'plugins/demo/functions.php');
+ demo_handle_zip_attachment_do($Args);
+ }
+
+And the demo_handle_zip_attachment_do() function in the
+plugins/demo/functions.php file would typically (but not necessarily)
+display a custom link:
+
+ function demo_handle_zip_attachment_do(&$Args)
+ {
+ $Args[1]['demo']['href'] = SM_PATH . 'plugins/demo/zip_handler.php?'
+ . 'passed_id=' . $Args[3] . '&mailbox=' . $Args[4]
+ . '&passed_ent_id=' . $Args[5];
+ $Args[1]['demo']['text'] = 'show zip contents';
+ }
+
+The file plugins/demo/zip_handler.php can now do whatever it needs with the
+attachment (note that this will hand information about how to retrieve the
+source message from the IMAP server as GET varibles).
+
+
+(*) Options
+-----------
+Before you start adding user preferences to your plugin, please take a moment
+to think about it: in some cases, more options may not be a good thing.
+Having too many options can be confusing. Thinking from the user's
+perspective, will the proposed options actually be used? Will users
+understand what these options are for?
+
+There are two ways to add options for your plugin. When you only have a few
+options that don't merit an entirely new preferences page, you can incorporate
+them into an existing section of SquirrelMail preferences (Personal
+Information, Display Preferences, Message Highlighting, Folder Preferences or
+Index Order). Or, if you have an extensive number of settings or for some
+reason need a separate page for the user to interact with, you can create your
+own preferences page.
+
+
+Integrating Your Options Into Existing SquirrelMail Preferences Pages
+---------------------------------------------------------------------
+
+There are two ways to accomplish the integration of your plugin's settings
+into another preferences page. The first method is to add the HTML code
+for your options directly to the preferences page of your choice. Although
+currently very popular, this method will soon be deprecated, so avoid it
+if you can. That said, here is how it works. :) Look for any of the hooks
+named as "options_<pref page>_inside", where <pref page> is "display",
+"personal", etc. For this example, we'll use "options_display_inside" and,
+as above, "demo" as our plugin name:
+
+ 1. In setup.php in the squirrelmail_plugin_init_demo() function:
+
+ $squirrelmail_plugin_hooks['options_display_inside']['demo']
+ = 'demo_show_options';
+
+ Note that there are also hooks such as "options_display_bottom",
+ however, they place your options at the bottom of the preferences
+ page, which is usually not desirable (mostly because they also
+ come AFTER the HTML FORM tag is already closed). It is possible
+ to use these hooks if you want to create your own FORM with custom
+ submission logic.
+
+ 2. Assuming the function demo_show_options() calls another function
+ elsewhere called demo_show_options_do(), that function should have
+ output similar to this (note that you will be inserting code into
+ a table that is already defined with two columns, so please be sure
+ to keep this framework in your plugin):
+
+ ------cut here-------
+ <tr>
+ <td>
+ OPTION_NAME
+ </td>
+ <td>
+ OPTION_INPUT
+ </td>
+ </tr>
+ ------cut here-------
+
+ Of course, you can place any text where OPTION_NAME is and any input
+ tags where OPTION_INPUT is.
+
+ 3. You will want to use the "options_<pref page>_save" hook (in this case,
+ "options_display_save") to save the user's settings after they have
+ pressed the "Submit" button. Again, back in setup.php in the
+ squirrelmail_plugin_init_demo() function:
+
+ $squirrelmail_plugin_hooks['options_display_save']['demo']
+ = 'demo_save_options';
+
+ 4. Assuming the function demo_save_options() calls another function
+ elsewhere called demo_save_options_do(), that function should put
+ the user's settings into permanent storage (see the preferences
+ section below for more information). This example assumes that
+ in the preferences page, the INPUT tag's NAME attribute was set
+ to "demo_option":
+
+ global $data_dir, $username;
+ sqgetGlobalVar('demo_option', $demo_option);
+ setPref($data_dir, $username, 'demo_option', $demo_option);
+
+
+The second way to add options to one of the SquirrelMail preferences page is
+to use one of the "optpage_loadhook_<pref page>" hooks. The sent_subfolders
+plugin has an excellent example of this method. Briefly, this way of adding
+options consists of adding some plugin-specific information to a predefined
+data structure which SquirrelMail then uses to build the HTML input forms
+for you. This is the preferred method of building options lists going forward.
+
+ 1. We'll use the "optpage_loadhook_display" hook to add a new group of
+ options to the display preferences page. In setup.php in the
+ squirrelmail_plugin_init_demo() function:
+
+ $squirrelmail_plugin_hooks['optpage_loadhook_display']['demo']
+ = 'demo_options';
+
+ 2. Assuming the function demo_options() calls another function elsewhere
+ called demo_options_do(), that function needs to add a new key to two
+ arrays, $optpage_data['grps'] and $optpage_data['vals']. The value
+ associated with that key should simply be a section heading for your
+ plugin on the preferences page for the $optpage_data['grps'] array,
+ and yet another array with all of your plugin's options for the
+ $optpage_data['vals'] array. The options are built as arrays (yes,
+ that's four levels of nested arrays) that specify attributes that are
+ used by SquirrelMail to build your HTML input tags automatically.
+ This example includes just one input element, a SELECT (drop-down)
+ list:
+
+ global $optpage_data;
+ $optpage_data['grps']['DEMO_PLUGIN'] = 'Demo Options';
+ $optionValues = array();
+ $optionValues[] = array(
+ 'name' => 'plugin_demo_favorite_color',
+ 'caption' => 'Please Choose Your Favorite Color',
+ 'type' => SMOPT_TYPE_STRLIST,
+ 'refresh' => SMOPT_REFRESH_ALL,
+ 'posvals' => array(0 => 'red',
+ 1 => 'blue',
+ 2 => 'green',
+ 3 => 'orange'),
+ 'save' => 'save_plugin_demo_favorite_color'
+ );
+ $optpage_data['vals']['DEMO_PLUGIN'] = $optionValues;
+
+ The array that you use to specify each plugin option has the following
+ possible attributes:
+
+ name The name of this setting, which is used not only for
+ the INPUT tag name, but also for the name of this
+ setting in the user's preferences
+ caption The text that prefaces this setting on the preferences
+ page
+ trailing_text Text that follows a text input or select list input on
+ the preferences page (useful for indicating units,
+ meanings of special values, etc.)
+ type The type of INPUT element, which should be one of:
+ SMOPT_TYPE_STRING String/text input
+ SMOPT_TYPE_STRLIST Select list input
+ SMOPT_TYPE_TEXTAREA Text area input
+ SMOPT_TYPE_INTEGER Integer input
+ SMOPT_TYPE_FLOAT Floating point number input
+ SMOPT_TYPE_BOOLEAN Boolean (yes/no radio buttons)
+ input
+ SMOPT_TYPE_HIDDEN Hidden input (not actually
+ shown on preferences page)
+ SMOPT_TYPE_COMMENT Text is shown (specified by the
+ 'comment' attribute), but no
+ user input is needed
+ SMOPT_TYPE_FLDRLIST Select list of IMAP folders
+ refresh Indicates if a link should be shown to refresh part or
+ all of the window (optional). Possible values are:
+ SMOPT_REFRESH_NONE No refresh link is shown
+ SMOPT_REFRESH_FOLDERLIST Link is shown to refresh
+ only the folder list
+ SMOPT_REFRESH_ALL Link is shown to refresh
+ the entire window
+ initial_value The value that should initially be placed in this
+ INPUT element
+ posvals For select lists, this should be an associative array,
+ where each key is an actual input value and the
+ corresponding value is what is displayed to the user
+ for that list item in the drop-down list
+ value Specify the default/preselected value for this option
+ input
+ save You may indicate that special functionality needs to be
+ used instead of just saving this setting by giving the
+ name of a function to call when this value would
+ otherwise just be saved in the user's preferences
+ size Specifies the size of certain input items (typically
+ textual inputs). Possible values are:
+ SMOPT_SIZE_TINY
+ SMOPT_SIZE_SMALL
+ SMOPT_SIZE_MEDIUM
+ SMOPT_SIZE_LARGE
+ SMOPT_SIZE_HUGE
+ SMOPT_SIZE_NORMAL
+ comment For SMOPT_TYPE_COMMENT type options, this is the text
+ displayed to the user
+ script This is where you may add any additional javascript
+ or other code to the user input
+ post_script You may specify some script (usually Javascript) that
+ will be placed after (outside of) the INPUT tag.
+
+ Note that you do not have to create a whole new section on the options
+ page if you merely want to add a simple input item or two to an options
+ section that already exists. For example, the Display Options page has
+ these groups:
+
+ 0 - General Display Options
+ 1 - Mailbox Display Options
+ 2 - Message Display and Composition
+
+ To add our previous input drop-down to the Mailbox Display Options,
+ we would not have to create our own group; just add it to group
+ number one:
+
+ global $optpage_data;
+ $optpage_data['vals'][1][] = array(
+ 'name' => 'plugin_demo_favorite_color',
+ 'caption' => 'Please Choose Your Favorite Color',
+ 'type' => SMOPT_TYPE_STRLIST,
+ 'refresh' => SMOPT_REFRESH_ALL,
+ 'posvals' => array(0 => 'red',
+ 1 => 'blue',
+ 2 => 'green',
+ 3 => 'orange'),
+ 'save' => 'save_plugin_demo_favorite_color'
+ );
+
+ 3. If you indicated a 'save' attribute for any of your options, you must
+ create that function (you'll only need to do this if you need to do
+ some special processing for one of your settings). The function gets
+ one parameter, which is an object with mostly the same attributes you
+ defined when you made the option above... the 'new_value' (and possibly
+ 'value', which is the current value for this setting) is the most useful
+ attribute in this context:
+
+ function save_plugin_demo_favorite_color($option)
+ {
+ // if user chose orange, make note that they are really dumb
+ if ($option->new_value == 3)
+ {
+ // more code here as needed
+ }
+
+ // don't even save this setting if user chose green (old
+ // setting will remain)
+ if ($option->new_value == 2)
+ return;
+
+ // for all other colors, save as normal
+ save_option($option);
+ }
+
+
+Creating Your Own Preferences Page
+----------------------------------
+
+It is also possible to create your own preferences page for a plugin. This
+is particularly useful when your plugin has numerous options or needs to
+offer special interaction with the user (for things such as changing password,
+etc.). Here is an outline of how to do so (again, using the "demo" plugin
+name):
+
+ 1. Add a new listing to the main Options page. Older versions of
+ SquirrelMail offered a hook called "options_link_and_description"
+ although its use is deprecated (and it is harder to use in that
+ it requires you to write your own HTML to add the option). Instead,
+ you should always use the "optpage_register_block" hook where you
+ create a simple array that lets SquirrelMail build the HTML
+ to add the plugin options entry automatically. In setup.php in the
+ squirrelmail_plugin_init_demo() function:
+
+ $squirrelmail_plugin_hooks['optpage_register_block']['demo']
+ = 'demo_options_block';
+
+ 2. Assuming the function demo_options_block() calls another function
+ elsewhere called demo_options_block_do(), that function only needs
+ to create a simple array and add it to the $optpage_blocks array:
+
+ global $optpage_blocks;
+ $optpage_blocks[] = array(
+ 'name' => 'Favorite Color Settings',
+ 'url' => SM_PATH . 'plugins/demo/options.php',
+ 'desc' => 'Change your favorite color & find new exciting colors',
+ 'js' => FALSE
+ );
+
+ The array should have four elements:
+ name The title of the plugin's options as it will be displayed on
+ the Options page
+ url The URI that points to your plugin's custom preferences page
+ desc A description of what the preferences page offers the user,
+ displayed on the Options page below the title
+ js Indicates if this option page requires the client browser
+ to be Javascript-capable. Should be TRUE or FALSE.
+
+ 3. There are two different ways to create the actual preferences page
+ itself. One is to simply write all of your own HTML and other
+ interactive functionality, while the other is to define some data
+ structures that allow SquirrelMail to build your user inputs and save
+ your data automatically.
+
+ Building your own page is wide open, and for ideas, you should look at
+ any of the plugins that currently have their own preferences pages. If
+ you do this, make sure to read step number 4 below for information on
+ saving settings. In order to maintain security, consistant look and
+ feel, internationalization support and overall integrity, there are just
+ a few things you should always do in this case: define the SM_PATH
+ constant, include the file include/validate.php (see the section about
+ including other files above) and make a call to place the standard page
+ heading at the top of your preferences page. The top of your PHP file
+ might look something like this:
+
+ define('SM_PATH', '../../');
+ include_once(SM_PATH . 'include/validate.php');
+ global $color;
+ displayPageHeader($color, 'None');
+
+ From here you are on your own, although you are encouraged to do things
+ such as use the $color array to keep your HTML correctly themed, etc.
+
+ If you want SquirrelMail to build your preferences page for you,
+ creating input forms and automatically saving users' settings, then
+ you should change the 'url' attribute in the options block you created
+ in step number 2 above to read as follows:
+
+ 'url' => SM_PATH . 'src/options.php?optpage=plugin_demo',
+
+ Now, you will need to use the "optpage_set_loadinfo" hook to tell
+ SquirrelMail about your new preferences page. In setup.php in the
+ squirrelmail_plugin_init_demo() function:
+
+ $squirrelmail_plugin_hooks['optpage_set_loadinfo']['demo']
+ = 'demo_optpage_loadinfo';
+
+ Assuming the function demo_optpage_loadinfo() calls another function
+ elsewhere called demo_optpage_loadinfo_do(), that function needs to
+ define values for four variables (make sure you test to see that it
+ is your plugin that is being called by checking the GET variable you
+ added to the url just above):
+
+ global $optpage, $optpage_name, $optpage_file,
+ $optpage_loader, $optpage_loadhook;
+ if ($optpage == 'plugin_demo')
+ {
+ $optpage_name = "Favorite Color Preferences";
+ $optpage_file = SM_PATH . 'plugins/demo/options.php';
+ $optpage_loader = 'load_optpage_data_demo';
+ $optpage_loadhook = 'optpage_loadhook_demo';
+ }
+
+ Now you are ready to build all of your options. In the file you
+ indicated for the variable $optpage_file above, you'll need to create
+ a function named the same as the value you used for $optpage_loader
+ above. In this example, the file plugins/demo/options.php should
+ have at least this function in it:
+
+ function load_optpage_data_demo()
+ {
+ $optpage_data = array();
+ $optpage_data['grps']['DEMO_PLUGIN'] = 'Demo Options';
+ $optionValues = array();
+ $optionValues[] = array(
+ 'name' => 'plugin_demo_favorite_color',
+ 'caption' => 'Please Choose Your Favorite Color',
+ 'type' => SMOPT_TYPE_STRLIST,
+ 'refresh' => SMOPT_REFRESH_ALL,
+ 'posvals' => array(0 => 'red',
+ 1 => 'blue',
+ 2 => 'green',
+ 3 => 'orange'),
+ 'save' => 'save_plugin_demo_favorite_color'
+ );
+ $optpage_data['vals']['DEMO_PLUGIN'] = $optionValues;
+ return $optpage_data;
+ }
+
+ For a detailed description of how you build these options, please read
+ step number 2 for the second method of adding options to an existing
+ preferences page above. Notice that the only difference here is in the
+ very first and last lines of this function where you are actually
+ creating and returning the options array instead of just adding onto it.
+
+ That's all there is to it - SquirrelMail will create a preferences page
+ titled as you indicated for $optpage_name above, and other plugins
+ can even add extra options to this new preferences page. To do so,
+ they should use the hook name you specified for $optpage_loadhook above
+ and use the second method for adding option settings to existing
+ preferences pages described above.
+
+ 4. Saving your options settings: if you used the second method in step
+ number 3 above, your settings will be saved automatically (or you can
+ define special functions to save special settings such as the
+ save_plugin_demo_favorite_color() function in the example described
+ above) and there is probably no need to follow this step. If you
+ created your own preferences page from scratch, you'll need to follow
+ this step. First, you need to register your plugin against the
+ "options_save" hook. In setup.php in the squirrelmail_plugin_init_demo()
+ function:
+
+ $squirrelmail_plugin_hooks['options_save']['demo']
+ = 'demo_save_options';
+
+ Assuming the function demo_save_options() calls another function
+ elsewhere called demo_save_options_do(), that function needs to grab
+ all of your POST and/or GET settings values and save them in the user's
+ preferences (for more about preferences, see that section below). Since
+ this is a generic hook called for all custom preferences pages, you
+ should always set "optpage" as a POST or GET variable with a string that
+ uniquely identifies your plugin:
+
+ <input type="hidden" name="optpage" value="plugin_demo" />
+
+ Now in your demo_save_options_do() function, do something like this:
+
+ global $username, $data_dir, $optpage, $favorite_color;
+ if ($optpage == 'plugin_demo')
+ {
+ sqgetGlobalVar('favorite_color', $favorite_color, SQ_FORM);
+ setPref($data_dir, $username, 'favorite_color', $favorite_color);
+ }
+
+ Note that $favorite_color may not need to be globalized, although
+ experience has shown that some versions of PHP don't behave as expected
+ unless you do so. Even when you use SquirrelMail's built-in preferences
+ page generation functionality, you may still use this hook, although
+ there should be no need to do so. If you need to do some complex
+ validation routines, note that it might be better to do so in the file
+ you specified as the "$optpage_file" (in our example, that was the
+ plugins/demo/options.php file), since at this point, you can still
+ redisplay your preferences page. You could put code similar to this
+ in the plugins/demp/options.php file (note that there is no function;
+ this code needs to be executed at include time):
+
+ global $optmode;
+ if ($optmode == 'submit')
+ {
+ // do something here such as validation, etc
+ if (you want to redisplay your preferences page)
+ $optmode = '';
+ }
+
+
+Preferences
+-----------
+
+Saving and retrieving user preferences is very easy in SquirrelMail.
+SquirrelMail supports preference storage in files or in a database
+backend, however, the code you need to write to manipulate preferences
+is the same in both cases.
+
+Setting preferences:
+
+ Setting preferences is done for you if you use the built-in facilities
+ for automatic options construction and presentation (see above). If
+ you need to manually set preferences, however, all you need to do is:
+
+ global $data_dir, $username;
+ setPref($data_dir, $username, 'pref_name', $pref_value);
+
+ Where "pref_name" is the key under which the value will be stored
+ and "pref_value" is a variable that should contain the actual
+ preference value to be stored.
+
+Loading preferences:
+
+ There are two approaches to retrieving plugin (or any other) preferences.
+ You can grab individual preferences one at a time or you can add your
+ plugin's preferences to the routine that loads up user preferences at
+ the beginning of each page request. If you do the latter, making sure
+ to place your preference variables into the global scope, they will be
+ immediately available in all other plugin code. To retrieve a single
+ preference value at any time, do this:
+
+ global $data_dir, $username;
+ $pref_value = getPref($data_dir, $username, 'pref_name', 'default value');
+
+ Where "pref_name" is the preference you are retrieving, "default_value"
+ is what will be returned if the preference is not found for this user,
+ and, of course, "pref_value" is the variable that will get the actual
+ preference value.
+
+ To have all your preferences loaded at once when each page request is
+ made, you'll need to register a function against the "loading_prefs" hook.
+ For our "demo" plugin, in setup.php in the squirrelmail_plugin_init_demo()
+ function:
+
+ $squirrelmail_plugin_hooks['loading_prefs']['demo']
+ = 'demo_load_prefs';
+
+ Assuming the function demo_load_prefs() calls another function
+ elsewhere called demo_load_prefs_do(), that function just needs to
+ pull out any all all preferences you'll be needing elsewhere:
+
+ global $data_dir, $username, $pref_value;
+ $pref_value = getPref($data_dir, $username, 'pref_name', 'default value');
+
+ Remember to globalize each preference, or this code is useless.
+
+
+Internationalization
+--------------------
+
+Although this document may only be available in English, we sure hope that you
+are thinking about making your plugin useful to the thousands of non-English
+speaking SquirrelMail users out there! It is almost rude not to do so, and
+it isn't much trouble, either. This document will only describe how you can
+accomplish the internationalization of a plugin. For more general information
+about PHP and SquirrelMail translation facilities, see:
+
+http://www.squirrelmail.org/wiki/wiki.php?LanguageTranslation
+
+The unofficial way to internationalize a plugin is to put all plugin output
+into the proper format but to rely on the SquirrelMail translation facilities
+for all the rest. If the plugin were really to get translated, you'd need
+to make sure that all output strings for your plugin are either added to or
+already exist in the main SquirrelMail locale files.
+
+The better way to make sure your plugin is translated is to create your own
+locale files and what is called a "gettext domain" (see the link above for
+more information).