summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authormkanat%bugzilla.org <>2006-09-08 08:41:32 +0200
committermkanat%bugzilla.org <>2006-09-08 08:41:32 +0200
commit460eb160b7d524b38fe7ea340922521c333282d7 (patch)
tree47c5486a0876cdab4871b605c15787719153b3c6
parent666dd28a656b6893c96e837517e5ee65e19e1447 (diff)
downloadbugzilla-460eb160b7d524b38fe7ea340922521c333282d7.tar.gz
bugzilla-460eb160b7d524b38fe7ea340922521c333282d7.tar.xz
Bug 350217: Extensions need to be able to update Bugzilla's DB schema
Patch By Max Kanat-Alexander <mkanat@bugzilla.org> r=ghendricks, a=myk
-rw-r--r--Bugzilla.pm11
-rw-r--r--Bugzilla/DB/Schema.pm11
-rw-r--r--Bugzilla/Hook.pm100
-rw-r--r--Bugzilla/Install/DB.pm3
-rwxr-xr-xenter_bug.cgi2
5 files changed, 116 insertions, 11 deletions
diff --git a/Bugzilla.pm b/Bugzilla.pm
index 0fb223e9e..24e93edc7 100644
--- a/Bugzilla.pm
+++ b/Bugzilla.pm
@@ -343,6 +343,12 @@ sub custom_field_names {
@{Bugzilla::Field->match({ custom=>1, obsolete=>0 })});
}
+sub hook_args {
+ my ($class, $args) = @_;
+ $class->request_cache->{hook_args} = $args if $args;
+ return $class->request_cache->{hook_args};
+}
+
sub request_cache {
if ($ENV{MOD_PERL}) {
require Apache2::RequestUtil;
@@ -556,4 +562,9 @@ The current Parameters of Bugzilla, as a hashref. If C<data/params>
does not exist, then we return an empty hashref. If C<data/params>
is unreadable or is not valid perl, we C<die>.
+=item C<hook_args>
+
+If you are running inside a code hook (see L<Bugzilla::Hook>) this
+is how you get the arguments passed to the hook.
+
=back
diff --git a/Bugzilla/DB/Schema.pm b/Bugzilla/DB/Schema.pm
index ea25a125a..4c270e68c 100644
--- a/Bugzilla/DB/Schema.pm
+++ b/Bugzilla/DB/Schema.pm
@@ -35,9 +35,11 @@ package Bugzilla::DB::Schema;
use strict;
use Bugzilla::Error;
+use Bugzilla::Hook;
use Bugzilla::Util;
use Bugzilla::Constants;
+use Hash::Util qw(lock_value unlock_hash lock_keys unlock_keys);
use Safe;
# Historical, needed for SCHEMA_VERSION = '1.00'
use Storable qw(dclone freeze thaw);
@@ -1168,6 +1170,15 @@ sub _initialize {
$abstract_schema ||= ABSTRACT_SCHEMA;
+ # Let extensions add tables, but make sure they can't modify existing
+ # tables. If we don't lock/unlock keys, lock_value complains.
+ lock_keys(%$abstract_schema);
+ lock_value(%$abstract_schema, $_) foreach (keys %$abstract_schema);
+ unlock_keys(%$abstract_schema);
+ Bugzilla::Hook::process('db_schema-abstract_schema',
+ { schema => $abstract_schema });
+ unlock_hash(%$abstract_schema);
+
$self->{schema} = dclone($abstract_schema);
# While ABSTRACT_SCHEMA cannot be modified,
# $self->{abstract_schema} can be. So, we dclone it to prevent
diff --git a/Bugzilla/Hook.pm b/Bugzilla/Hook.pm
index 8ce1482c1..be4a70077 100644
--- a/Bugzilla/Hook.pm
+++ b/Bugzilla/Hook.pm
@@ -29,8 +29,7 @@ use Bugzilla::Error;
use strict;
sub process {
- my $name = shift;
- trick_taint($name);
+ my ($name, $args) = @_;
# get a list of all extensions
my @extensions = glob(bz_locations()->{'extensionsdir'} . "/*");
@@ -43,6 +42,7 @@ sub process {
# worry about, so we can safely detaint them:
trick_taint($extension);
if (-e $extension.'/code/'.$name.'.pl') {
+ Bugzilla->hook_args($args);
do($extension.'/code/'.$name.'.pl');
ThrowCodeError('extension_invalid', {
name => $name, extension => $extension }) if $@;
@@ -61,26 +61,106 @@ Bugzilla::Hook - Extendible extension hooks for Bugzilla code
=head1 SYNOPSIS
- use Bugzilla::Hook;
+ use Bugzilla::Hook;
- Bugzilla::Hook::process("hookname");
+ Bugzilla::Hook::process("hookname", { arg => $value, arg2 => $value2 });
=head1 DESCRIPTION
Bugzilla allows extension modules to drop in and add routines at
arbitrary points in Bugzilla code. These points are refered to as
hooks. When a piece of standard Bugzilla code wants to allow an extension
-to perform additional functions, it uses Bugzilla::Hook's process()
+to perform additional functions, it uses Bugzilla::Hook's L</process>
subroutine to invoke any extension code if installed.
-=over 4
+=head2 How Hooks Work
+
+When a hook named C<HOOK_NAME> is run, Bugzilla will attempt to invoke any
+source files named F<extensions/*/code/HOOK_NAME.pl>.
+
+So, for example, if your extension is called "testopia", and you
+want to have code run during the L</install-update_db> hook, you
+would have a file called F<extensions/testopia/code/install-update_db.pl>
+that contained perl code to run during that hook.
+
+=head2 Arguments Passed to Hooks
+
+Some L<hooks|/HOOKS> have params that are passed to them.
+
+These params are accessible through L<Bugzilla/hook_args>.
+That returns a hashref. Very frequently, if you want your
+hook to do anything, you have to modify these variables.
+
+=head1 SUBROUTINES
+
+=over
=item C<process>
-Invoke any code hooks with a matching name from any installed extensions.
-When this subroutine is called with hook name foo, Bugzilla will attempt
-to invoke any source files in C<bugzilla/extension/EXTENSION_NAME/code/foo.pl>.
+=over
+
+=item B<Description>
+
+Invoke any code hooks with a matching name from any installed extensions.
+
See C<customization.xml> in the Bugzilla Guide for more information on
-Bugzilla's extension mechanism.
+Bugzilla's extension mechanism.
+
+=item B<Params>
+
+=over
+
+=item C<$name> - The name of the hook to invoke.
+
+=item C<$args> - A hashref. The named args to pass to the hook.
+They will be accessible to the hook via L<Bugzilla/hook_args>.
+
+=back
+
+=item B<Returns> (nothing)
+
+=back
+
+=back
+
+=head1 HOOKS
+
+This describes what hooks exist in Bugzilla currently.
+
+=head2 enter_bug-entrydefaultvars
+
+This happens right before the template is loaded on enter_bug.cgi.
+
+Params:
+
+=over
+
+=item C<vars> - A hashref. The variables that will be passed into the template.
+
+=back
+
+=head2 install-update_db
+
+This happens at the very end of all the tables being updated
+during an installation or upgrade. If you need to modify your custom
+schema, do it here. No params are passed.
+
+=head2 db_schema-abstract_schema
+
+This allows you to add tables to Bugzilla. Note that we recommend that you
+prefix the names of your tables with some word, so that they don't conflict
+with any future Bugzilla tables.
+
+If you wish to add new I<columns> to existing Bugzilla tables, do that
+in L</install-update_db>.
+
+Params:
+
+=over
+
+=item C<schema> - A hashref, in the format of
+L<Bugzilla::DB::Schema/ABSTRACT_SCHEMA>. Add new hash keys to make new table
+definitions. F<checksetup.pl> will automatically add these tables to the
+database when run.
=back
diff --git a/Bugzilla/Install/DB.pm b/Bugzilla/Install/DB.pm
index d7918f6ac..e4e4e97fe 100644
--- a/Bugzilla/Install/DB.pm
+++ b/Bugzilla/Install/DB.pm
@@ -23,6 +23,7 @@ use strict;
use Bugzilla::Bug qw(is_open_state);
use Bugzilla::Constants;
+use Bugzilla::Hook;
use Bugzilla::Util;
use Bugzilla::Series;
@@ -490,6 +491,8 @@ sub update_table_definitions {
################################################################
# New --TABLE-- changes should go *** A B O V E *** this point #
################################################################
+
+ Bugzilla::Hook::process('install-update_db');
}
# Subroutines should be ordered in the order that they are called.
diff --git a/enter_bug.cgi b/enter_bug.cgi
index a138d5edf..62abdcd81 100755
--- a/enter_bug.cgi
+++ b/enter_bug.cgi
@@ -547,7 +547,7 @@ foreach my $row (@$grouplist) {
$vars->{'group'} = \@groups;
-Bugzilla::Hook::process("enter_bug-entrydefaultvars");
+Bugzilla::Hook::process("enter_bug-entrydefaultvars", { vars => $vars });
$vars->{'default'} = \%default;