summaryrefslogtreecommitdiffstats
path: root/Bugzilla
diff options
context:
space:
mode:
authorMax Kanat-Alexander <mkanat@bugzilla.org>2010-02-11 01:00:32 +0100
committerMax Kanat-Alexander <mkanat@bugzilla.org>2010-02-11 01:00:32 +0100
commitf6fc02e572ba07782a272e8fc8f9f45e13ba4896 (patch)
treef88912a82e4a85661d61716e5f3975ea35ed838b /Bugzilla
parent80477beb472a83f6fa711358372db9edf6209c39 (diff)
downloadbugzilla-f6fc02e572ba07782a272e8fc8f9f45e13ba4896.tar.gz
bugzilla-f6fc02e572ba07782a272e8fc8f9f45e13ba4896.tar.xz
Bug 545524: New Hook: object_validators
r=mkanat, a=mkanat (module owner)
Diffstat (limited to 'Bugzilla')
-rw-r--r--Bugzilla/Bug.pm5
-rw-r--r--Bugzilla/Hook.pm26
-rw-r--r--Bugzilla/Object.pm25
3 files changed, 50 insertions, 6 deletions
diff --git a/Bugzilla/Bug.pm b/Bugzilla/Bug.pm
index 37df30707..336b9cfe1 100644
--- a/Bugzilla/Bug.pm
+++ b/Bugzilla/Bug.pm
@@ -123,8 +123,6 @@ use constant REQUIRED_CREATE_FIELDS => qw(
# There are also other, more complex validators that are called
# from run_create_validators.
sub VALIDATORS {
- my $cache = Bugzilla->request_cache;
- return $cache->{bug_validators} if defined $cache->{bug_validators};
my $validators = {
alias => \&_check_alias,
@@ -167,8 +165,7 @@ sub VALIDATORS {
$validators->{$field->name} = $validator;
}
- $cache->{bug_validators} = $validators;
- return $cache->{bug_validators};
+ return $validators;
};
use constant UPDATE_VALIDATORS => {
diff --git a/Bugzilla/Hook.pm b/Bugzilla/Hook.pm
index 13e435e86..faef9f07d 100644
--- a/Bugzilla/Hook.pm
+++ b/Bugzilla/Hook.pm
@@ -675,6 +675,32 @@ L<Bugzilla::Object/update> returns.
=back
+=head2 object_validators
+
+Allows you to add new items to L<Bugzilla::Object/VALIDATORS> for
+particular classes.
+
+Params:
+
+=over
+
+=item C<class>
+
+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
+
+=item C<validators>
+
+A hashref, where the keys are database columns and the values are subroutine
+references. You can add new validators or modify existing ones. If you modify
+an existing one, you should remember to call the original validator
+inside of your modified validator. (This way, several extensions can all
+modify the same validator.)
+
+=back
+
+
=head2 page_before_template
This is a simple way to add your own pages to Bugzilla. This hooks C<page.cgi>,
diff --git a/Bugzilla/Object.pm b/Bugzilla/Object.pm
index 0bb865ea6..75aa533ca 100644
--- a/Bugzilla/Object.pm
+++ b/Bugzilla/Object.pm
@@ -288,7 +288,7 @@ sub set {
{ object => $self, field => $field,
value => $value });
- my %validators = (%{$self->VALIDATORS}, %{$self->UPDATE_VALIDATORS});
+ my %validators = (%{$self->_get_validators}, %{$self->UPDATE_VALIDATORS});
if (exists $validators{$field}) {
my $validator = $validators{$field};
$value = $self->$validator($value, $field);
@@ -430,7 +430,7 @@ sub check_required_create_fields {
sub run_create_validators {
my ($class, $params) = @_;
- my $validators = $class->VALIDATORS;
+ my $validators = $class->_get_validators;
my %field_values;
# We do the sort just to make sure that validation always
@@ -487,6 +487,27 @@ sub get_all {
sub check_boolean { return $_[1] ? 1 : 0 }
+# For some clases, VALIDATORS takes time to generate, so we cache it. Also,
+# this allows the object_validators hook to only run once per request,
+# instead of every time we call set() on a class of objects.
+#
+# This method is intentionally private and should only be called by
+# Bugzilla::Object.
+sub _get_validators {
+ my $invocant = shift;
+ my $class = ref($invocant) || $invocant;
+ my $cache = Bugzilla->request_cache;
+ my $cache_key = "object_${class}_validators";
+ return $cache->{$cache_key} if $cache->{$cache_key};
+ # We copy this into a hash so that the hook doesn't modify the constant.
+ # (That could be bad in mod_perl.)
+ my %validators = %{ $invocant->VALIDATORS };
+ Bugzilla::Hook::process('object_validators',
+ { class => $class, validators => \%validators });
+ $cache->{$cache_key} = \%validators;
+ return $cache->{$cache_key};
+}
+
1;
__END__