mantisbt:plugins_overview
Differences
This shows you the differences between two versions of the page.
Both sides previous revisionPrevious revision | Last revisionBoth sides next revision | ||
mantisbt:plugins_overview [2008/02/15 15:33] – daryn | mantisbt:plugins_overview [2008/10/29 04:25] – (old revision restored) 127.0.0.1 | ||
---|---|---|---|
Line 1: | Line 1: | ||
+ | ====== Plugin System Overview ====== | ||
+ | |||
+ | Author: John Reese | ||
+ | |||
+ | Status: Work in Progress | ||
+ | |||
+ | |||
+ | ===== Design Overview ===== | ||
+ | |||
+ | The dynamic plugins system for Mantis is based on a philosophy of simplicity and lightweight design. | ||
+ | |||
+ | ==== Inversion of Control ==== | ||
+ | |||
+ | Rather than having each plugin execute and use the plugin API to set things up, the Mantis plugin manager uses the Inversion of Control design theories. | ||
+ | |||
+ | ===== Event System ==== | ||
+ | |||
+ | Before going in depth with the inner workings of the plugin system, we will give an overview of the event system, which plays a critical role in giving plugins the flexibility and extensibility that they need. A full reference of the core events can be found in the [[plugins_events|Plugin Event Reference]]. | ||
+ | |||
+ | ==== Overview ==== | ||
+ | |||
+ | The Mantis event system requires all events to be ' | ||
+ | |||
+ | ==== Event Types ==== | ||
+ | |||
+ | There are multiple event types defined in the core event system. | ||
+ | |||
+ | === Execute === | ||
+ | |||
+ | This is the most basic event type in Mantis. | ||
+ | |||
+ | === Output === | ||
+ | |||
+ | This type of event is designed specifically for plugins to generate output that will be displayed to the user. The event is passed either a separator string, or an array of prefix, separator, and postfix strings; | ||
+ | |||
+ | === Chain === | ||
+ | |||
+ | This event type is designed to allow plugins to process some input data one after the other, which each callback being passed the output from the callback before it. The parameter passed to the event becomes the input data for the first callback to process, and the return value of the last callback is returned to the event originator. | ||
+ | |||
+ | === Default === | ||
+ | |||
+ | The default event type is designed to be as flexible and generic as possible. | ||
+ | |||
+ | |||
+ | |||
+ | |||
+ | |||
+ | |||
+ | ===== Developing Plugins ===== | ||
+ | |||
+ | The plugin system for Mantis utilizes a class-based hierarchy for plugins, with all plugins deriving from the '' | ||
+ | |||
+ | This section covers the major topics needed to get started with plugin development. | ||
+ | |||
+ | |||
+ | |||
+ | |||
+ | |||
+ | |||
+ | |||
+ | |||
+ | ==== Getting Started ==== | ||
+ | |||
+ | The most important step of getting a plugin to actually //work// with Mantis is properly advertising your plugin to the plugin manager, so that it may discover your plugin and allow the administrator to install it. This is done not only by creating the proper directory structure for your plugin, but by creating the right files with the right classes. | ||
+ | |||
+ | An example plugin with just the basic structure and registration can be seen with the [[plugins_sample# | ||
+ | |||
+ | === Basic Structure === | ||
+ | |||
+ | In order to have a valid plugin, you must choose a succinct, camelcase ' | ||
+ | |||
+ | A barebones plugin named ''' | ||
+ | < | ||
+ | plugins/ | ||
+ | Testing/ | ||
+ | Testing.php | ||
+ | </ | ||
+ | |||
+ | |||
+ | === < | ||
+ | |||
+ | This is the single most essential file for a plugin; | ||
+ | |||
+ | == register() == | ||
+ | |||
+ | This class function must be overridden in order to have a valid extension class (it is marked '' | ||
+ | |||
+ | * '' | ||
+ | * '' | ||
+ | * '' | ||
+ | * '' | ||
+ | * '' | ||
+ | * '' | ||
+ | * '' | ||
+ | * '' | ||
+ | |||
+ | == init() == | ||
+ | |||
+ | Overriding this function allows your plugin to set itself up, include any necessary API's, declare or hook events, etc. Alternatively, | ||
+ | |||
+ | |||
+ | ==== Using the Event System ==== | ||
+ | |||
+ | The event system is what makes Mantis plugins flexible and extensible. | ||
+ | |||
+ | For more detailed information on the event system, see the [[event_system]]. | ||
+ | |||
+ | === Hooking Events === | ||
+ | |||
+ | There are two ways to hook events in your plugins. | ||
+ | |||
+ | == hook() == | ||
+ | |||
+ | The first way is with ' | ||
+ | |||
+ | <code php> | ||
+ | <?php | ||
+ | |||
+ | class ... { | ||
+ | ... | ||
+ | |||
+ | function hook() { | ||
+ | return array( | ||
+ | // single callback per event | ||
+ | ' | ||
+ | |||
+ | // multiple callbacks per event | ||
+ | ' | ||
+ | ); | ||
+ | } | ||
+ | |||
+ | // Callback function | ||
+ | function test( $p_event, $p_params ) {} | ||
+ | } | ||
+ | </ | ||
+ | |||
+ | == plugin_event_hook() == | ||
+ | |||
+ | However, the simplest way for a plugin to hook a individual function to an event is by calling **'' | ||
+ | |||
+ | <code php> | ||
+ | <?php | ||
+ | |||
+ | class ... { | ||
+ | ... | ||
+ | |||
+ | function hook() { | ||
+ | return array( | ||
+ | ' | ||
+ | ); | ||
+ | } | ||
+ | |||
+ | function test( $p_event, $p_params ) { | ||
+ | plugin_event_hook( ' | ||
+ | } | ||
+ | |||
+ | function test2() {} | ||
+ | } | ||
+ | </ | ||
+ | |||
+ | === Declaring Events === | ||
+ | |||
+ | Events must be declared before they can be used, with not only the event name, but the event type, which determines how its callback functions will be handled. | ||
+ | |||
+ | == event_declare( name, type ) == | ||
+ | |||
+ | This function will declare a single event with a given name and type. The only types currently allowed are: | ||
+ | * '' | ||
+ | * '' | ||
+ | * '' | ||
+ | * '' | ||
+ | |||
+ | For example: | ||
+ | <code php> | ||
+ | <?php | ||
+ | event_declare( ' | ||
+ | </ | ||
+ | |||
+ | == event_declare_many( events ) == | ||
+ | |||
+ | This function will declare multiple events at once, taking an array of event name => type pairs. | ||
+ | <code php> | ||
+ | <?php | ||
+ | event_declare_many( array( | ||
+ | ' | ||
+ | ' | ||
+ | ) ); | ||
+ | </ | ||
+ | |||
+ | |||
+ | |||
+ | |||
+ | |||
+ | ==== Language Strings ==== | ||
+ | |||
+ | In order to make plugins more accessible and available to international users, plugins can utilize the benefits of the Mantis language system to consolidate text into separate files for each language, allowing the plugin to be easily translated for different languages. | ||
+ | |||
+ | === Using Strings === | ||
+ | |||
+ | Using international language strings in plugins is just as easy as it is in the core Mantis system. | ||
+ | |||
+ | === Declaring Strings === | ||
+ | |||
+ | If your plugin needs to use language strings that aren't already declared by the core Mantis system, it is very simple to provide the appropriate language files with your plugin. | ||
+ | |||
+ | Drawing on the example plugin used above, the structure should follow this pattern: | ||
+ | < | ||
+ | plugins/ | ||
+ | testing/ | ||
+ | lang/ | ||
+ | strings_english.txt | ||
+ | strings_german.txt | ||
+ | events.php | ||
+ | register.php | ||
+ | </ | ||
+ | |||
+ | The language file itself should follow the same format as standard Mantis language files, a PHP script that declares strings in the following pattern: | ||
+ | < | ||
+ | <?php | ||
+ | $s_plugin_testing_title = " | ||
+ | $s_plugin_testing_manage = " | ||
+ | </ | ||
+ | |||
+ | The above string would then be displayed using something like the following code: | ||
+ | < | ||
+ | <?php | ||
+ | echo lang_get( ' | ||
+ | </ | ||
+ | |||
+ | |||
+ | |||
+ | ==== Configuration ==== | ||
+ | |||
+ | Many plugins will likely have some elements that can or need to be configurable by the site admin or end-user, such as access thresholds or behavioral preferences. | ||
+ | |||
+ | === Default Configurations === | ||
+ | |||
+ | To allow the usage of default configurations for plugins, developers can create a callback method in the plugin' | ||
+ | |||
+ | === General Usage === | ||
+ | |||
+ | To retrieve a plugin configuration value, your plugin can call **'' | ||
+ | |||
+ | ==== Creating Pages ==== | ||
+ | |||
+ | In order to create entirely new features, plugins must be able to create new pages without needing to worry about all of the Mantis core API. For this reason, the Mantis plugin system includes a very simplified method for structuring and linking to plugin pages. | ||
+ | |||
+ | === Structure === | ||
+ | |||
+ | Plugin pages can be named and structured as needed, but they must all be located in the '' | ||
+ | |||
+ | Using the above example plugin as a basis, new pages can be created in the following pattern: | ||
+ | < | ||
+ | plugins/ | ||
+ | testing/ | ||
+ | lang/ | ||
+ | strings_english.txt | ||
+ | strings_german.txt | ||
+ | pages/ | ||
+ | about.php | ||
+ | manage.php | ||
+ | events.php | ||
+ | register.php | ||
+ | </ | ||
+ | |||
+ | === Usage === | ||
+ | |||
+ | Once a page has been created, it can be linked to by using the **'' | ||
+ | |||
+ | === Example Page === | ||
+ | |||
+ | == about.php == | ||
+ | |||
+ | This is an example of a basic display page, which outputs the standard Mantis header and footer, but does nothing else: | ||
+ | < | ||
+ | <?php | ||
+ | html_page_top1( lang_get( ' | ||
+ | html_page_top2(); | ||
+ | |||
+ | # Create a basic href link to the manage.php plugin page | ||
+ | echo 'A href="', | ||
+ | |||
+ | html_page_bottom1( __FILE__ ); | ||
+ | </ | ||
+ | |||
+ | ===== Advanced Plugin Topics ===== | ||
+ | |||
+ | |||
+ | |||
+ | |||
+ | ==== Schema Management ==== | ||
+ | |||
+ | For plugins that need to store information in the database, managing database schema across multiple versions and changes can be difficult, so the Mantis plugin system uses the same type of schema management system as the full application to track and upgrade the database schema for plugins. | ||
+ | |||
+ | === Declaring a Schema === | ||
+ | |||
+ | In the world of Mantis, a database schema is defined by a list of schema changes that are applied sequentially starting from nothing, such as adding tables, adding or modifying columns, etc. The schema history must be linear, and **previous schema entries must not change for the upgrade process to work correctly**. | ||
+ | |||
+ | == plugin_callback_< | ||
+ | |||
+ | This callback function will contain the schema information for a plugin. | ||
+ | |||
+ | == Table Names == | ||
+ | |||
+ | So that plugins will not have conflicting table names and schema entries, the plugin API includes the **'' | ||
+ | |||
+ | === Schema Entries === | ||
+ | |||
+ | All schema entries follow a standard pattern: | ||
+ | < | ||
+ | <?php | ||
+ | $schema[] = array( entryType, entryData ); | ||
+ | </ | ||
+ | |||
+ | '' | ||
+ | |||
+ | //For an example of how schema entries should be used, please see the '' | ||
+ | |||
+ | == Adding/ | ||
+ | |||
+ | < | ||
+ | <?php | ||
+ | $schema[] = array( ' | ||
+ | </ | ||
+ | |||
+ | == Adding a Column == | ||
+ | |||
+ | < | ||
+ | <?php | ||
+ | $schema[] = array( ' | ||
+ | </ | ||
+ | |||
+ | == Altering a Column == | ||
+ | |||
+ | < | ||
+ | <?php | ||
+ | $schema[] = array( ' | ||
+ | </ | ||
+ | |||
+ | == Adding an Index == | ||
+ | |||
+ | < | ||
+ | <?php | ||
+ | $schema[] = array( ' | ||
+ | </ | ||
+ | |||
+ | == Inserting Data == | ||
+ | |||
+ | < | ||
+ | <?php | ||
+ | $schema[] = array( ' | ||
+ | </ | ||
+ | |||
+ | == Dropping a Column == | ||
+ | |||
+ | < | ||
+ | <?php | ||
+ | $schema[] = array( ' | ||
+ | </ | ||
+ | |||
+ | == Dropping a Table == | ||
+ | |||
+ | < | ||
+ | <?php | ||
+ | $schema[] = array( ' | ||
+ | </ | ||
+ | |||
+ | ==== Installation / Upgrade / Uninstallation ==== | ||
+ | |||
+ | In order to allow more advanced plugins the ability to handle the process of installing, upgrading, or uninstalling, | ||
+ | |||
+ | === plugin_callback_< | ||
+ | |||
+ | This callback is executed before the normal plugin installation process has started. | ||
+ | |||
+ | === plugin_callback_< | ||
+ | |||
+ | This callback is executed after the normal schema upgrade process has executed. | ||
+ | |||
+ | === plugin_callback_< | ||
+ | |||
+ | This callback is executed after the normal uninstallation process, and should handle such operations as reverting database schemas, removing unnecessary data, etc. This callback should be used only if Mantis would break when this plugin is uninstalled without any other actions taken, as users may not want to lose data, or be able to re-install the plugin later. | ||
mantisbt/plugins_overview.txt · Last modified: 2011/12/30 10:35 by tandler