summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAlbert Ting <altlist@gmail.com>2015-01-08 18:49:25 +0100
committerDylan William Hardison <dylan@hardison.net>2015-01-13 16:06:54 +0100
commit8762d1e68c4ea2343f445bb4beb46c1ae04586b1 (patch)
treeb26119ae24f924c50ca50a57dbedd2c6780e3d1b
parentcde1c5854904f8989e39a217b1d4f02c9204428e (diff)
downloadbugzilla-8762d1e68c4ea2343f445bb4beb46c1ae04586b1.tar.gz
bugzilla-8762d1e68c4ea2343f445bb4beb46c1ae04586b1.tar.xz
Bug 832095 - Request new buglist/query hooks
-rw-r--r--Bugzilla/Hook.pm182
-rwxr-xr-xbuglist.cgi9
-rw-r--r--extensions/Example/Extension.pm23
-rwxr-xr-xquery.cgi14
4 files changed, 162 insertions, 66 deletions
diff --git a/Bugzilla/Hook.pm b/Bugzilla/Hook.pm
index 430d5af49..5abaabc7c 100644
--- a/Bugzilla/Hook.pm
+++ b/Bugzilla/Hook.pm
@@ -57,11 +57,11 @@ Bugzilla::Hook - Extendable extension hooks for Bugzilla code
=head1 DESCRIPTION
-Bugzilla allows extension modules to drop in and add routines at
+Bugzilla allows extension modules to drop in and add routines at
arbitrary points in Bugzilla code. These points are referred to as
hooks. When a piece of standard Bugzilla code wants to allow an extension
to perform additional functions, it uses Bugzilla::Hook's L</process>
-subroutine to invoke any extension code if installed.
+subroutine to invoke any extension code if installed.
The implementation of extensions is described in L<Bugzilla::Extension>.
@@ -98,7 +98,7 @@ mechanism.
=item C<$name> - The name of the hook to invoke.
-=item C<$args> - A hashref. The named args to pass to the hook.
+=item C<$args> - A hashref. The named args to pass to the hook.
They will be passed as arguments to the hook method in the extension.
=back
@@ -170,13 +170,13 @@ Params:
=item C<modules>
This is a hash--a mapping from login-type "names" to the actual module on
-disk. The keys will be all the values that were passed to
+disk. The keys will be all the values that were passed to
L<Bugzilla::Auth/login> for the C<Login> parameter. The values are the
actual path to the module on disk. (For example, if the key is C<DB>, the
value is F<Bugzilla/Auth/Login/DB.pm>.)
-For your extension, the path will start with
-F<Bugzilla/Extension/Foo/>, where "Foo" is the name of your Extension.
+For your extension, the path will start with
+F<Bugzilla/Extension/Foo/>, where "Foo" is the name of your Extension.
(See the code in the example extension.)
If your login type is in the hash as a key, you should set that key to the
@@ -253,7 +253,7 @@ Params:
=over
-=item C<bug>
+=item C<bug>
The changed bug object, with all fields set to their updated values.
@@ -262,12 +262,12 @@ The changed bug object, with all fields set to their updated values.
A bug object pulled from the database before the fields were set to
their updated values (so it has the old values available for each field).
-=item C<timestamp>
+=item C<timestamp>
The timestamp used for all updates in this transaction, as a SQL date
string.
-=item C<changes>
+=item C<changes>
The hash of changed fields. C<< $changes->{field} = [old, new] >>
@@ -276,9 +276,9 @@ The hash of changed fields. C<< $changes->{field} = [old, new] >>
=head2 bug_check_can_change_field
This hook controls what fields users are allowed to change. You can add code
-here for site-specific policy changes and other customizations.
+here for site-specific policy changes and other customizations.
-This hook is only executed if the field's new and old values differ.
+This hook is only executed if the field's new and old values differ.
Any denies take priority over any allows. So, if another extension denies
a change but yours allows the change, the other extension's deny will
@@ -373,7 +373,7 @@ An arrayref of hashrefs.
You should push a hashref containing two keys (C<match> and C<replace>)
in to this array. C<match> is the regular expression that matches the
text you want to replace, C<replace> is what you want to replace that
-text with. (This gets passed into a regular expression like
+text with. (This gets passed into a regular expression like
C<s/$match/$replace/>.)
Instead of specifying a regular expression for C<replace> you can also
@@ -394,7 +394,7 @@ do so could open a security hole in Bugzilla.
A B<reference> to the exact text that you are parsing.
-Generally you should not modify this yourself. Instead you should be
+Generally you should not modify this yourself. Instead you should be
returning regular expressions using the C<regexes> array.
The text has not been parsed in any way. (So, for example, it is not
@@ -435,7 +435,7 @@ Params:
=over
-=item C<bug>
+=item C<bug>
The changed bug object, with all fields set to their updated values.
@@ -444,12 +444,12 @@ The changed bug object, with all fields set to their updated values.
A bug object pulled from the database before the fields were set to
their updated values (so it has the old values available for each field).
-=item C<timestamp>
+=item C<timestamp>
The timestamp used for all updates in this transaction, as a SQL date
string.
-=item C<changes>
+=item C<changes>
The hash of changed fields. C<< $changes->{field} = [old, new] >>
@@ -509,7 +509,7 @@ Params:
=over
=item C<column_joins> - A hashref containing data to return back to
-L<Bugzilla::Search>. This hashref contains names of the columns as keys and
+L<Bugzilla::Search>. This hashref contains names of the columns as keys and
a hashref about table to join as values. This hashref has the following keys:
=over
@@ -533,11 +533,38 @@ table should be joined with the C<bugs> table. If omitted, LEFT is used.
=back
+=head2 buglist_format
+
+This happens in F<buglist.cgi>, used to change the template variables before
+processing the associated template hook.
+
+Params:
+
+=over
+
+=item C<vars>
+
+This is the entire set of variables that the current template
+can see.
+
+=item C<file>
+
+The name of the template file being processed. This is
+relative to the main template directory for the language (i.e. for
+F<template/en/default/list/list.html.tmpl>, this variable will contain
+C<list/list.html.tmpl>).
+
+=item C<params>
+
+A hashref. The set of named parameters extracted from cgi.
+
+=back
+
=head2 search_operator_field_override
This allows you to modify L<Bugzilla::Search/OPERATOR_FIELD_OVERRIDE>,
which determines the search functions for fields. It allows you to specify
-custom search functionality for certain fields.
+custom search functionality for certain fields.
See L<Bugzilla::Search/OPERATOR_FIELD_OVERRIDE> for reference and see
the code in the example extension.
@@ -599,18 +626,18 @@ instead of as a string.)
This is a hash of L<Bugzilla::User> objects, keyed by id. This is so you can
find out more information about any of the user ids in the C<recipients> hash.
-Every id in the incoming C<recipients> hash will have an object in here.
-(But if you add additional recipients to the C<recipients> hash, you are
+Every id in the incoming C<recipients> hash will have an object in here.
+(But if you add additional recipients to the C<recipients> hash, you are
B<not> required to add them to this hash.)
=item C<diffs>
-This is a list of hashes, each hash representing a change to the bug. Each
-hash has the following members: C<field_name>, C<bug_when>, C<old>, C<new>
-and C<who> (a L<Bugzilla::User>). If appropriate, there will also be
-C<attach_id> or C<comment_id>; if either is present, there will be
-C<isprivate>. See C<_get_diffs> in F<Bugzilla/BugMail.pm> to see exactly how
-it is populated. Warning: the format and existence of the "diffs" parameter
+This is a list of hashes, each hash representing a change to the bug. Each
+hash has the following members: C<field_name>, C<bug_when>, C<old>, C<new>
+and C<who> (a L<Bugzilla::User>). If appropriate, there will also be
+C<attach_id> or C<comment_id>; if either is present, there will be
+C<isprivate>. See C<_get_diffs> in F<Bugzilla/BugMail.pm> to see exactly how
+it is populated. Warning: the format and existence of the "diffs" parameter
is subject to change in future releases of Bugzilla.
=back
@@ -684,7 +711,7 @@ A hashref, where the keys are the "name" of the panel and the value
is the Perl module representing that panel. For example, if
the name is C<Auth>, the value would be C<Bugzilla::Config::Auth>.
-For your extension, the Perl module would start with
+For your extension, the Perl module would start with
C<Bugzilla::Extension::Foo>, where "Foo" is the name of your Extension.
(See the code in the example extension.)
@@ -703,7 +730,7 @@ Params:
=item C<panels>
-A hashref, where the keys are lower-case panel "names" (like C<auth>,
+A hashref, where the keys are lower-case panel "names" (like C<auth>,
C<admin>, etc.) and the values are hashrefs. The hashref contains a
single key, C<params>. C<params> is an arrayref--the return value from
C<get_param_list> for that module. You can modify C<params> and
@@ -838,7 +865,7 @@ Params:
=over
-=item C<group>
+=item C<group>
The new L<Bugzilla::Group> object that was just created.
@@ -846,24 +873,24 @@ The new L<Bugzilla::Group> object that was just created.
=head2 group_end_of_update
-This happens at the end of L<Bugzilla::Group/update>, after all other
+This happens at the end of L<Bugzilla::Group/update>, after all other
changes are made to the database. This occurs inside a database transaction.
Params:
=over
-=item C<group> - The changed L<Bugzilla::Group> object, with all fields set
+=item C<group> - The changed L<Bugzilla::Group> object, with all fields set
to their updated values.
-=item C<changes> - The hash of changed fields.
+=item C<changes> - The hash of changed fields.
C<< $changes->{$field} = [$old, $new] >>
=back
=head2 install_before_final_checks
-Allows execution of custom code before the final checks are done in
+Allows execution of custom code before the final checks are done in
checksetup.pl.
Params:
@@ -884,7 +911,7 @@ time should be printed.
Allows for additional files and directories to be added to the
list of files and directories already managed by checksetup.pl.
You will be able to also set permissions for the files and
-directories using this hook. You can also use this hook to create
+directories using this hook. You can also use this hook to create
appropriate .htaccess files for any directory to secure its contents.
For examples see L<FILESYSTEM> in L<Bugzilla::Install::Filesystem>.
@@ -919,7 +946,7 @@ key's value is the permissions to be set on the directory.
=item C<recurse_dirs>
-Hash reference of directories that will have permissions set for each item inside
+Hash reference of directories that will have permissions set for each item inside
each of the directories, including the directory itself. Each directory key
points to another hash reference containing the following settings.
@@ -953,7 +980,7 @@ empty file.
=item C<htaccess>
Hash reference containing htaccess files to be created. You can set the permissions
-for the htaccess as well as the contents of the file. Each file key points to another
+for the htaccess as well as the contents of the file. Each file key points to another
hash reference containing the following settings.
Params:
@@ -988,7 +1015,7 @@ the L</install_update_db> hook.
=head2 db_schema_abstract_schema
-This allows you to add tables to Bugzilla. Note that we recommend that you
+This allows you to add tables to Bugzilla. Note that we recommend that you
prefix the names of your tables with some word (preferably the name of
your Extension), so that they don't conflict with any future Bugzilla tables.
@@ -999,7 +1026,7 @@ Params:
=over
-=item C<schema> - A hashref, in the format of
+=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.
@@ -1008,18 +1035,18 @@ database when run.
=head2 job_map
-Bugzilla has a system - L<Bugzilla::JobQueue> - for running jobs
-asynchronously, if the administrator has set it up. This hook allows the
-addition of mappings from job names to handler classes, so an extension can
+Bugzilla has a system - L<Bugzilla::JobQueue> - for running jobs
+asynchronously, if the administrator has set it up. This hook allows the
+addition of mappings from job names to handler classes, so an extension can
fire off jobs.
Params:
=over
-=item C<job_map> - The job map hash. Key: the name of the job, as should be
-passed to Bugzilla->job_queue->insert(). Value: the name of the Perl module
-which implements the task (an instance of L<TheSchwartz::Worker>).
+=item C<job_map> - The job map hash. Key: the name of the job, as should be
+passed to Bugzilla->job_queue->insert(). Value: the name of the Perl module
+which implements the task (an instance of L<TheSchwartz::Worker>).
=back
@@ -1045,7 +1072,7 @@ Params:
=item C<class>
-The name of the class that C<create> was called on. You can check this
+The name of the class that C<create> was called on. You can check this
like C<< if ($class->isa('Some::Class')) >> in your code, to perform specific
tasks before C<create> for only certain classes.
@@ -1094,7 +1121,7 @@ limit your changes to only certain subclasses of Bugzilla::Object.
The name of the field being updated in the object.
-=item C<value>
+=item C<value>
The value being set on the object.
@@ -1118,17 +1145,17 @@ Params:
=item C<class>
-The name of the class that this hook is being called on. You can check this
+The name of the class that this hook is being called on. You can check this
like C<< if ($class->isa('Some::Class')) >> in your code, to add new
fields only for certain classes.
=item C<columns>
An arrayref. Add the string names of columns to this array to add new
-values to objects.
+values to objects.
For example, if you add an C<example> column to a particular table
-(using L</install_update_db>), and then push the string C<example> into
+(using L</install_update_db>), and then push the string C<example> into
this array for the object that uses that table, then you can access the
information in that column via C<< $object->{example} >> on all objects
of that type.
@@ -1149,7 +1176,7 @@ Params:
=item C<class>
-The name of the class that C<create> was called on. You can check this
+The name of the class that C<create> was called on. You can check this
like C<< if ($class->isa('Some::Class')) >> in your code, to perform specific
tasks for only certain classes.
@@ -1173,7 +1200,7 @@ Params:
=item C<class>
-The name of the class that C<create> was called on. You can check this
+The name of the class that C<create> was called on. You can check this
like C<< if ($class->isa('Some::Class')) >> in your code, to perform specific
tasks for only certain classes.
@@ -1300,7 +1327,7 @@ Params:
=item C<class>
-The name of the class that C<VALIDATORS> was called on. You can check this
+The name of the class that C<VALIDATORS> was called on. You can check this
like C<< if ($class->isa('Some::Class')) >> in your code, to add
validators only for certain classes.
@@ -1406,7 +1433,7 @@ changes will be rolled back, including the creation of the new product.
(However, note that such rollbacks should not normally be used, as
some databases that Bugzilla supports have very bad rollback performance.
If you want to validate input and throw errors before the Product is created,
-use L</object_end_of_create_validators> instead, or add a validator
+use L</object_end_of_create_validators> instead, or add a validator
using L</object_validators>.)
Params:
@@ -1417,17 +1444,56 @@ Params:
=back
+=head2 query_default_list
+
+This happens in F<query.cgi>, used to include additional cgi params to be
+searched for in order to create the set of default values.
+
+Params:
+
+=over
+
+=item C<list>
+
+The current list of cgi params to search for.
+
+=back
+
+=head2 query_format
+
+This happens in F<query.cgi>, used to to add/modify $vars before
+processing the template. For example, one could supply or modify the
+default values for a custom query format.
+
+Params:
+
+=over
+
+=item C<vars>
+
+This is the entire set of variables that the current template
+can see.
+
+=item C<file>
+
+The name of the template file being processed. This is
+relative to the main template directory for the language (i.e. for
+F<template/en/default/list/list.html.tmpl>, this variable will contain
+C<list/list.html.tmpl>).
+
+=back
+
=head2 quicksearch_map
-This hook allows you to alter the Quicksearch syntax to include e.g. special
+This hook allows you to alter the Quicksearch syntax to include e.g. special
searches for custom fields you have.
Params:
=over
-=item C<map> - a hash where the key is the name you want to use in
-Quicksearch, and the value is the name from the C<fielddefs> table that you
+=item C<map> - a hash where the key is the name you want to use in
+Quicksearch, and the value is the name from the C<fielddefs> table that you
want it to map to. You can modify existing mappings or add new ones.
=back
@@ -1491,7 +1557,7 @@ the template being processed, or to modify the variables that are currently
in the template. It works exactly as though you inserted code to modify
template variables at the top of a template.
-You probably want to restrict this hook to operating only if a certain
+You probably want to restrict this hook to operating only if a certain
file is being processed (which is why you get a C<file> argument
below). Otherwise, modifying the C<vars> argument will affect every single
template in Bugzilla.
@@ -1581,7 +1647,7 @@ Params:
=item C<dispatch>
A hashref where you can specify the names of your modules and which Perl
-module handles the functions for that module. (This is actually sent to
+module handles the functions for that module. (This is actually sent to
L<SOAP::Lite/dispatch_with>. You can see how that's used in F<xmlrpc.cgi>.)
The Perl module name will most likely start with C<Bugzilla::Extension::Foo::>
diff --git a/buglist.cgi b/buglist.cgi
index ee4b34578..2ecb04e0c 100755
--- a/buglist.cgi
+++ b/buglist.cgi
@@ -25,6 +25,7 @@ use Bugzilla::Product;
use Bugzilla::Field;
use Bugzilla::Status;
use Bugzilla::Token;
+use Bugzilla::Hook;
use Date::Parse;
@@ -447,8 +448,8 @@ if (!$params->param('query_format')) {
# Determine the format in which the user would like to receive the output.
# Uses the default format if the user did not specify an output format;
# otherwise validates the user's choice against the list of available formats.
-my $format = $template->get_format("list/list", scalar $cgi->param('format'),
- scalar $cgi->param('ctype'));
+my $format = $template->get_format("list/list", scalar $params->param('format'),
+ scalar $params->param('ctype'));
# Use server push to display a "Please wait..." message for the user while
# executing their query if their browser supports it and they are viewing
@@ -1124,6 +1125,10 @@ $cgi->close_standby_message($contenttype, $disposition, $disp_prefix, $format->{
# Content Generation
################################################################################
+Bugzilla::Hook::process("buglist_format", {'vars' => $vars,
+ 'format' => $format,
+ 'params' => $params});
+
# Generate and return the UI (HTML page) from the appropriate template.
$template->process($format->{'template'}, $vars)
|| ThrowTemplateError($template->error());
diff --git a/extensions/Example/Extension.pm b/extensions/Example/Extension.pm
index af36b107a..0ab5220a7 100644
--- a/extensions/Example/Extension.pm
+++ b/extensions/Example/Extension.pm
@@ -304,6 +304,17 @@ sub buglist_column_joins {
};
}
+sub buglist_format {
+ my ($self, $args) = @_;
+ my $vars = $args->{'vars'};
+ my $format = $args->{'format'};
+ my $params = $args->{'params'};
+
+ if ($format->{'template'} eq "list/list-example.html.tmpl") {
+ $vars->{'example'} = $params->param('example');
+ }
+}
+
sub search_operator_field_override {
my ($self, $args) = @_;
@@ -856,6 +867,18 @@ sub product_end_of_create {
}
}
+sub query_format {
+ my ($self, $args) = @_;
+ my $vars = $args->{'vars'};
+ my $default = $vars->{'default'};
+ my $format = $args->{'format'};
+
+ # change some default values
+ if ($format->{'template'} eq "search/search-example.html.tmpl") {
+ $default->{'example'}[0] = $default->{'example'}[0] || "example";
+ }
+}
+
sub quicksearch_map {
my ($self, $args) = @_;
my $map = $args->{'map'};
diff --git a/query.cgi b/query.cgi
index faf670d23..fab90eb2d 100755
--- a/query.cgi
+++ b/query.cgi
@@ -95,7 +95,7 @@ my $userdefaultquery;
if ($userid) {
$userdefaultquery = $dbh->selectrow_array(
"SELECT query FROM namedqueries " .
- "WHERE userid = ? AND name = ?",
+ "WHERE userid = ? AND name = ?",
undef, ($userid, DEFAULT_QUERY_NAME));
}
@@ -128,7 +128,7 @@ sub PrefillForm {
next if grep { $_ eq $name } @skip;
$foundone = 1;
my @values = $buf->param($name);
-
+
# If the name is a single letter followed by numbers, it's part
# of Custom Search. We store these as an array of hashes.
if ($name =~ /^([[:lower:]])(\d+)$/) {
@@ -158,9 +158,9 @@ if (!PrefillForm($buffer)) {
}
}
-# if using groups for entry, then we don't want people to see products they
+# if using groups for entry, then we don't want people to see products they
# don't have access to. Remove them from the list.
-my @selectable_products = sort {lc($a->name) cmp lc($b->name)}
+my @selectable_products = sort {lc($a->name) cmp lc($b->name)}
@{$user->get_selectable_products};
Bugzilla::Product::preload(\@selectable_products);
$vars->{'product'} = \@selectable_products;
@@ -297,10 +297,12 @@ if (defined($vars->{'format'}) && IsValidQueryType($vars->{'format'})) {
# If we submit back to ourselves (for e.g. boolean charts), we need to
# preserve format information; hence query_format taking priority over
# format.
-my $format = $template->get_format("search/search",
- $vars->{'query_format'} || $vars->{'format'},
+my $format = $template->get_format("search/search",
+ $vars->{'query_format'} || $vars->{'format'},
scalar $cgi->param('ctype'));
+Bugzilla::Hook::process("query_format", {'vars' => $vars, 'format' => $format});
+
print $cgi->header($format->{'ctype'});
$template->process($format->{'template'}, $vars)