diff options
Diffstat (limited to 'Bugzilla/BugUrl.pm')
-rw-r--r-- | Bugzilla/BugUrl.pm | 228 |
1 files changed, 112 insertions, 116 deletions
diff --git a/Bugzilla/BugUrl.pm b/Bugzilla/BugUrl.pm index a824d286d..e6c68416c 100644 --- a/Bugzilla/BugUrl.pm +++ b/Bugzilla/BugUrl.pm @@ -27,55 +27,56 @@ use URI::QueryParam; use constant DB_TABLE => 'bug_see_also'; use constant NAME_FIELD => 'value'; use constant LIST_ORDER => 'id'; + # See Also is tracked in bugs_activity. use constant AUDIT_CREATES => 0; use constant AUDIT_UPDATES => 0; use constant AUDIT_REMOVES => 0; use constant DB_COLUMNS => qw( - id - bug_id - value - class + id + bug_id + value + class ); # This must be strings with the names of the validations, # instead of coderefs, because subclasses override these # validators with their own. use constant VALIDATORS => { - value => '_check_value', - bug_id => '_check_bug_id', - class => \&_check_class, + value => '_check_value', + bug_id => '_check_bug_id', + class => \&_check_class, }; # This is the order we go through all of subclasses and # pick the first one that should handle the url. New # subclasses should be added at the end of the list. use constant SUB_CLASSES => qw( - Bugzilla::BugUrl::Bugzilla::Local - Bugzilla::BugUrl::Bugzilla - Bugzilla::BugUrl::Launchpad - Bugzilla::BugUrl::Google - Bugzilla::BugUrl::Chromium - Bugzilla::BugUrl::Edge - Bugzilla::BugUrl::Debian - Bugzilla::BugUrl::JIRA - Bugzilla::BugUrl::Trac - Bugzilla::BugUrl::MantisBT - Bugzilla::BugUrl::SourceForge - Bugzilla::BugUrl::GitHub - Bugzilla::BugUrl::MozSupport - Bugzilla::BugUrl::Aha - Bugzilla::BugUrl::WebCompat - Bugzilla::BugUrl::ServiceNow - Bugzilla::BugUrl::Splat + Bugzilla::BugUrl::Bugzilla::Local + Bugzilla::BugUrl::Bugzilla + Bugzilla::BugUrl::Launchpad + Bugzilla::BugUrl::Google + Bugzilla::BugUrl::Chromium + Bugzilla::BugUrl::Edge + Bugzilla::BugUrl::Debian + Bugzilla::BugUrl::JIRA + Bugzilla::BugUrl::Trac + Bugzilla::BugUrl::MantisBT + Bugzilla::BugUrl::SourceForge + Bugzilla::BugUrl::GitHub + Bugzilla::BugUrl::MozSupport + Bugzilla::BugUrl::Aha + Bugzilla::BugUrl::WebCompat + Bugzilla::BugUrl::ServiceNow + Bugzilla::BugUrl::Splat ); ############################### #### Accessors ###### ############################### -sub class { return $_[0]->{class} } +sub class { return $_[0]->{class} } sub bug_id { return $_[0]->{bug_id} } ############################### @@ -83,125 +84,120 @@ sub bug_id { return $_[0]->{bug_id} } ############################### sub new { - my $class = shift; - my $param = shift; - - if (ref $param) { - my $bug_id = $param->{bug_id}; - my $name = $param->{name} || $param->{value}; - if (!defined $bug_id) { - ThrowCodeError('bad_arg', - { argument => 'bug_id', - function => "${class}::new" }); - } - if (!defined $name) { - ThrowCodeError('bad_arg', - { argument => 'name', - function => "${class}::new" }); - } - - my $condition = 'bug_id = ? AND value = ?'; - my @values = ($bug_id, $name); - $param = { condition => $condition, values => \@values }; + my $class = shift; + my $param = shift; + + if (ref $param) { + my $bug_id = $param->{bug_id}; + my $name = $param->{name} || $param->{value}; + if (!defined $bug_id) { + ThrowCodeError('bad_arg', {argument => 'bug_id', function => "${class}::new"}); + } + if (!defined $name) { + ThrowCodeError('bad_arg', {argument => 'name', function => "${class}::new"}); } - unshift @_, $param; - return $class->SUPER::new(@_); + my $condition = 'bug_id = ? AND value = ?'; + my @values = ($bug_id, $name); + $param = {condition => $condition, values => \@values}; + } + + unshift @_, $param; + return $class->SUPER::new(@_); } sub _do_list_select { - my $class = shift; - my $objects = $class->SUPER::_do_list_select(@_); + my $class = shift; + my $objects = $class->SUPER::_do_list_select(@_); - foreach my $object (@$objects) { - require_module($object->class); - bless $object, $object->class; - } + foreach my $object (@$objects) { + require_module($object->class); + bless $object, $object->class; + } - return $objects + return $objects; } # This is an abstract method. It must be overridden # in every subclass. sub should_handle { - my ($class, $input) = @_; - ThrowCodeError('unknown_method', - { method => "${class}::should_handle" }); + my ($class, $input) = @_; + ThrowCodeError('unknown_method', {method => "${class}::should_handle"}); } sub class_for { - my ($class, $value) = @_; + my ($class, $value) = @_; - my $uri = URI->new($value); - foreach my $subclass ($class->SUB_CLASSES) { - require_module($subclass); - return wantarray ? ($subclass, $uri) : $subclass - if $subclass->should_handle($uri); - } + my $uri = URI->new($value); + foreach my $subclass ($class->SUB_CLASSES) { + require_module($subclass); + return wantarray ? ($subclass, $uri) : $subclass + if $subclass->should_handle($uri); + } - ThrowUserError('bug_url_invalid', { url => $value, - reason => 'show_bug' }); + ThrowUserError('bug_url_invalid', {url => $value, reason => 'show_bug'}); } sub _check_class { - my ($class, $subclass) = @_; - require_module($subclass); - return $subclass; + my ($class, $subclass) = @_; + require_module($subclass); + return $subclass; } sub _check_bug_id { - my ($class, $bug_id) = @_; + my ($class, $bug_id) = @_; - my $bug; - if (blessed $bug_id) { - # We got a bug object passed in, use it - $bug = $bug_id; - $bug->check_is_visible; - } - else { - # We got a bug id passed in, check it and get the bug object - $bug = Bugzilla::Bug->check({ id => $bug_id }); - } + my $bug; + if (blessed $bug_id) { - return $bug->id; + # We got a bug object passed in, use it + $bug = $bug_id; + $bug->check_is_visible; + } + else { + # We got a bug id passed in, check it and get the bug object + $bug = Bugzilla::Bug->check({id => $bug_id}); + } + + return $bug->id; } sub _check_value { - my ($class, $uri) = @_; - - my $value = $uri->as_string; - - if (!$value) { - ThrowCodeError('param_required', - { function => 'add_see_also', param => '$value' }); - } - - # We assume that the URL is an HTTP URL if there is no (something):// - # in front. - if (!$uri->scheme) { - # This works better than setting $uri->scheme('http'), because - # that creates URLs like "http:domain.com" and doesn't properly - # differentiate the path from the domain. - $uri = new URI("http://$value"); - } - elsif ($uri->scheme ne 'http' && $uri->scheme ne 'https') { - ThrowUserError('bug_url_invalid', { url => $value, reason => 'http' }); - } - - # This stops the following edge cases from being accepted: - # * show_bug.cgi?id=1 - # * /show_bug.cgi?id=1 - # * http:///show_bug.cgi?id=1 - if (!$uri->authority or $uri->path !~ m{/}) { - ThrowUserError('bug_url_invalid', - { url => $value, reason => 'path_only' }); - } - - if (length($uri->path) > MAX_BUG_URL_LENGTH) { - ThrowUserError('bug_url_too_long', { url => $uri->path }); - } - - return $uri; + my ($class, $uri) = @_; + + my $value = $uri->as_string; + + if (!$value) { + ThrowCodeError('param_required', + {function => 'add_see_also', param => '$value'}); + } + + # We assume that the URL is an HTTP URL if there is no (something):// + # in front. + if (!$uri->scheme) { + + # This works better than setting $uri->scheme('http'), because + # that creates URLs like "http:domain.com" and doesn't properly + # differentiate the path from the domain. + $uri = new URI("http://$value"); + } + elsif ($uri->scheme ne 'http' && $uri->scheme ne 'https') { + ThrowUserError('bug_url_invalid', {url => $value, reason => 'http'}); + } + + # This stops the following edge cases from being accepted: + # * show_bug.cgi?id=1 + # * /show_bug.cgi?id=1 + # * http:///show_bug.cgi?id=1 + if (!$uri->authority or $uri->path !~ m{/}) { + ThrowUserError('bug_url_invalid', {url => $value, reason => 'path_only'}); + } + + if (length($uri->path) > MAX_BUG_URL_LENGTH) { + ThrowUserError('bug_url_too_long', {url => $uri->path}); + } + + return $uri; } 1; |