POD/Bugzilla::Extension

From Wiki4Intranet
Jump to: navigation, search

NAME

Bugzilla::Extension - core of Bugzilla4Intranet Extension engine, backwards-compatible with old pre-3.6 Bugzilla extension engine.

USAGE

Extension engine was refactored by Bugzilla authors in 3.6. Their new version was incompatible with old extensions, had some restrictions and was just VERY inconvenient to use. So, in Bugzilla4Intranet 3.6, I've created my own extension engine.

Directory layout

All Bugzilla extensions must go into 'extensions' subdirectory. The basic directory layout for an extension is as follows:

 extensions/
   <name>/
     <name>.pl   ---   Main extension file
     disabled    ---   Extension disabled if this file is present
     code/       ---   Directory with old-style (pre-3.6) hooks
       <hook_name>.pl
     lib/        ---   Extension library directory (with *.pm modules)
     template/   ---   Directory with extension templates and template hooks
       en/
         default/
           <template_path>/
             <template_filename>.tmpl
           hook/
             <template_path>/
               <template_filename>-<hook_name>.tmpl

Extension main

Main extension file sets extension version, required and optional Perl modules, and can also set code hooks. It can be omitted if hooks are set using files (see below), and there is no need for required_modules and optional_modules.

The file typically looks like:

use strict;
use Bugzilla;
use Bugzilla::Extension;
 
my $REQUIRED_MODULES = [];
my $OPTIONAL_MODULES = [
    {
        package => 'Spreadsheet-ParseExcel',
        module  => 'Spreadsheet::ParseExcel',
        version => '0.54',
        feature => 'Import of binary Excel files (*.xls)',
    },
];
 
required_modules('<extension name>', $REQUIRED_MODULES);
optional_modules('<extension name>', $OPTIONAL_MODULES);
extension_version('<extension name>', '1.02');
 
set_hook('<extension name>', '<hook name>', 'ExtensionPackage::sub_name');
add_hook('<extension name>', '<hook name>', 'ExtensionPackage::other_sub_name');
# other hooks...
 
1;
__END__

Note that main file must not 'use ExtensionPackage', just because the extension library directory can be unknown at this point. Specify the package name in a string, and it will be loaded automatically.

Hooks

A hook is a place in the code into which other code parts can be inserted. In Bugzilla, there are code hooks and template hooks. Extensions should use hooks for extending the functionality. The best is if you use predefined hooks, but you can also add your own and publish the patch which adds this hooks somewhere on http://wiki.4intra.net/.

Hook functions always get arguments through single hashref parameter ($args). Their return value is always a boolean value: when it's TRUE, other hooks (set after this) are also called. When a hook returns FALSE, hook processing is stopped.

set_hook($extension, $hook_name, $callable) resets $extension's $hook_name to $callable. add_hook(...) does not reset, but adds an additional hook with the same name. Try to use set_hook() as much as you can, because it allows for correct run-time extension reloading support.

Code hooks can be also set using single files inside the extension code directory, just as it was before Bugzilla 3.6. Such files must 'use Bugzilla' and get arguments through 'Bugzilla->hook_args'. They also don't need to return anything - Bugzilla thinks that they always "return true".

You can get the list of all available hooks using grep on Bugzilla code:

    grep -r Bugzilla::Hook::process *.cgi *.pl *.pm Bugzilla/ extensions/

You can also see the list of documented hooks in Bugzilla::Hook.

Template hooks

Template hooks are just evaluated in the place of corresponding hook call.

You can get the list of all available template hooks using grep:

    grep -r Hook.process template/ extensions/

METHODS FOR EXTENSIONS

First of all, add

use Bugzilla::Extension;

to the top of your extension's main file to use these methods.

$arrayref = required_modules([$new_arrayref]) / optional_modules()

Getters/setters for REQUIRED_MODULES and OPTIONAL_MODULES. Perl modules specified here are checked by checksetup.pl during installation. If some of required modules are missing, the installation is aborted. If some of optional modules are missing, there is a warning.

The format of this arrayref is:

[ {
    package => 'Text-CSV',
    module  => 'Text::CSV',
    version => '1.06',
    feature => 'CSV Importing of test cases'
  }, ... ]

$version = extension_version([$new_version])

Getter/setter for extension version.

$dir = extension_code_dir([$new_code_dir])

Getter/setter for extension code directory, i.e. directory which contains individual hook .pl files, as it was old Bugzillas (< 3.6).

Default value for code directory is "extensions/<name>/code/".

$dir = extension_template_dir([$new_template_dir])

Getter/setter for extension template directory. Templates from this directory will override Bugzilla's built-in ones.

Default value for template directory is "extensions/<name>/template/".

METHODS FOR BUGZILLA (INTERNAL USAGE)

@list = Bugzilla::Extension::available()

List all available extension names

@list = Bugzilla::Extension::loaded()

List all loaded extensions

$hashref = Bugzilla::Extension::extension_info()

Get extension information hashref

Bugzilla::Extension::load_all()

Loads all enabled extensions installed into Bugzilla.

Bugzilla::Extension::load($name)

Load one extension named $name.

SEE ALSO

Bugzilla::Hook