diff --git a/Bugzilla/BugUrl.pm b/Bugzilla/BugUrl.pm index dd0c0a582..1b679bb2c 100644 --- a/Bugzilla/BugUrl.pm +++ b/Bugzilla/BugUrl.pm @@ -16,6 +16,7 @@ use base qw(Bugzilla::Object); use Bugzilla::Util; use Bugzilla::Error; use Bugzilla::Constants; +use Bugzilla::Hook; use Module::Runtime qw(require_module); use URI::QueryParam; @@ -131,8 +132,12 @@ sub should_handle { sub class_for { my ($class, $value) = @_; + my @sub_classes = $class->SUB_CLASSES; + Bugzilla::Hook::process('bug_url_sub_classes', + {sub_classes => \@sub_classes}); + my $uri = URI->new($value); - foreach my $subclass ($class->SUB_CLASSES) { + foreach my $subclass (@sub_classes) { require_module($subclass); return wantarray ? ($subclass, $uri) : $subclass if $subclass->should_handle($uri); diff --git a/Bugzilla/Hook.pm b/Bugzilla/Hook.pm index 07ef07fde..57b22dcbf 100644 --- a/Bugzilla/Hook.pm +++ b/Bugzilla/Hook.pm @@ -533,6 +533,21 @@ The hash of changed fields. C<< $changes->{field} = [old, new] >> =back +=head2 bug_url_sub_classes + +Allows you to add more L sub-classes. + +See the C extension to see how things work. + +Params: + +=over + +=item C - An arrayref of strings which represent L +sub-classes. + +=back + =head2 buglist_columns This happens in L, which determines legal bug diff --git a/extensions/MoreBugUrl/Config.pm b/extensions/MoreBugUrl/Config.pm new file mode 100644 index 000000000..f8175bb4c --- /dev/null +++ b/extensions/MoreBugUrl/Config.pm @@ -0,0 +1,20 @@ +# This Source Code Form is subject to the terms of the Mozilla Public +# License, v. 2.0. If a copy of the MPL was not distributed with this +# file, You can obtain one at http://mozilla.org/MPL/2.0/. +# +# This Source Code Form is "Incompatible With Secondary Licenses", as +# defined by the Mozilla Public License, v. 2.0. + +package Bugzilla::Extension::MoreBugUrl; + +use 5.10.1; +use strict; +use warnings; + +use constant NAME => 'MoreBugUrl'; + +use constant REQUIRED_MODULES => []; + +use constant OPTIONAL_MODULES => []; + +__PACKAGE__->NAME; diff --git a/extensions/MoreBugUrl/Extension.pm b/extensions/MoreBugUrl/Extension.pm new file mode 100644 index 000000000..c55542359 --- /dev/null +++ b/extensions/MoreBugUrl/Extension.pm @@ -0,0 +1,50 @@ +# This Source Code Form is subject to the terms of the Mozilla Public +# License, v. 2.0. If a copy of the MPL was not distributed with this +# file, You can obtain one at http://mozilla.org/MPL/2.0/. +# +# This Source Code Form is "Incompatible With Secondary Licenses", as +# defined by the Mozilla Public License, v. 2.0. + +package Bugzilla::Extension::MoreBugUrl; + +use 5.10.1; +use strict; +use warnings; + +use base qw(Bugzilla::Extension); + +use constant MORE_SUB_CLASSES => qw( + Bugzilla::Extension::MoreBugUrl::BitBucket + Bugzilla::Extension::MoreBugUrl::ReviewBoard + Bugzilla::Extension::MoreBugUrl::RT + Bugzilla::Extension::MoreBugUrl::PHP + Bugzilla::Extension::MoreBugUrl::Redmine + Bugzilla::Extension::MoreBugUrl::Savane + Bugzilla::Extension::MoreBugUrl::WineHQForums +); + +# We need to update the bug_see_also table because ReviewBoard was +# originally under Bugzilla/BugUrl/. +sub install_update_db { + my $dbh = Bugzilla->dbh; + + my $should_rename = $dbh->selectrow_array(q{SELECT 1 FROM bug_see_also + WHERE class = 'Bugzilla::BugUrl::ReviewBoard'} + ); + + if ($should_rename) { + my $sth = $dbh->prepare( + 'UPDATE bug_see_also SET class = ? + WHERE class = ?' + ); + $sth->execute('Bugzilla::Extension::MoreBugUrl::ReviewBoard', + 'Bugzilla::BugUrl::ReviewBoard'); + } +} + +sub bug_url_sub_classes { + my ($self, $args) = @_; + push @{$args->{sub_classes}}, MORE_SUB_CLASSES; +} + +__PACKAGE__->NAME; diff --git a/extensions/MoreBugUrl/lib/BitBucket.pm b/extensions/MoreBugUrl/lib/BitBucket.pm new file mode 100644 index 000000000..bc9f27740 --- /dev/null +++ b/extensions/MoreBugUrl/lib/BitBucket.pm @@ -0,0 +1,40 @@ +# This Source Code Form is subject to the terms of the Mozilla Public +# License, v. 2.0. If a copy of the MPL was not distributed with this +# file, You can obtain one at http://mozilla.org/MPL/2.0/. +# +# This Source Code Form is "Incompatible With Secondary Licenses", as +# defined by the Mozilla Public License, v. 2.0. + +package Bugzilla::Extension::MoreBugUrl::BitBucket; + +use 5.10.1; +use strict; +use warnings; + +use base qw(Bugzilla::BugUrl); + +############################### +#### Methods #### +############################### + +sub should_handle { + my ($class, $uri) = @_; + + # BitBucket issues have the form of + # bitbucket.org/user/project/issue/1234 + return (lc($uri->authority) eq "bitbucket.org" + && $uri->path =~ m|[^/]+/[^/]+/issue/\d+|i) ? 1 : 0; +} + +sub _check_value { + my $class = shift; + + my $uri = $class->SUPER::_check_value(@_); + + my ($path) = $uri->path =~ m|([^/]+/[^/]+/issue/\d+)|i; + $uri = new URI("https://bitbucket.org/$path"); + + return $uri; +} + +1; diff --git a/extensions/MoreBugUrl/lib/PHP.pm b/extensions/MoreBugUrl/lib/PHP.pm new file mode 100644 index 000000000..29fcc662f --- /dev/null +++ b/extensions/MoreBugUrl/lib/PHP.pm @@ -0,0 +1,44 @@ +# This Source Code Form is subject to the terms of the Mozilla Public +# License, v. 2.0. If a copy of the MPL was not distributed with this +# file, You can obtain one at http://mozilla.org/MPL/2.0/. +# +# This Source Code Form is "Incompatible With Secondary Licenses", as +# defined by the Mozilla Public License, v. 2.0. + +package Bugzilla::Extension::MoreBugUrl::PHP; + +use 5.10.1; +use strict; +use warnings; + +use base qw(Bugzilla::BugUrl); + +############################### +#### Methods #### +############################### + +sub should_handle { + my ($class, $uri) = @_; + + # PHP Bug URLs have only one form: + # https://bugs.php.net/bug.php?id=1234 + return (lc($uri->authority) eq 'bugs.php.net' + and $uri->path =~ m|/bug\.php$| + and $uri->query_param('id') =~ /^\d+$/) ? 1 : 0; +} + +sub _check_value { + my $class = shift; + + my $uri = $class->SUPER::_check_value(@_); + + # PHP Bug URLs redirect to HTTPS, so just use the HTTPS scheme. + $uri->scheme('https'); + + # And remove any # part if there is one. + $uri->fragment(undef); + + return $uri; +} + +1; diff --git a/extensions/MoreBugUrl/lib/RT.pm b/extensions/MoreBugUrl/lib/RT.pm new file mode 100644 index 000000000..52aab48d1 --- /dev/null +++ b/extensions/MoreBugUrl/lib/RT.pm @@ -0,0 +1,42 @@ +# This Source Code Form is subject to the terms of the Mozilla Public +# License, v. 2.0. If a copy of the MPL was not distributed with this +# file, You can obtain one at http://mozilla.org/MPL/2.0/. +# +# This Source Code Form is "Incompatible With Secondary Licenses", as +# defined by the Mozilla Public License, v. 2.0. + +package Bugzilla::Extension::MoreBugUrl::RT; + +use 5.10.1; +use strict; +use warnings; + +use base qw(Bugzilla::BugUrl); + +############################### +#### Methods #### +############################### + +sub should_handle { + my ($class, $uri) = @_; + + # RT URLs can look like various things: + # http://example.com/rt/Ticket/Display.html?id=1234 + # https://example.com/Public/Bug/Display.html?id=1234 + return ($uri->path =~ m|/Display\.html$| and $uri->query_param('id') =~ /^\d+$/) + ? 1 + : 0; +} + +sub _check_value { + my $class = shift; + + my $uri = $class->SUPER::_check_value(@_); + + # And remove any # part if there is one. + $uri->fragment(undef); + + return $uri; +} + +1; diff --git a/extensions/MoreBugUrl/lib/Redmine.pm b/extensions/MoreBugUrl/lib/Redmine.pm new file mode 100644 index 000000000..577d08bbb --- /dev/null +++ b/extensions/MoreBugUrl/lib/Redmine.pm @@ -0,0 +1,42 @@ +# This Source Code Form is subject to the terms of the Mozilla Public +# License, v. 2.0. If a copy of the MPL was not distributed with this +# file, You can obtain one at http://mozilla.org/MPL/2.0/. +# +# This Source Code Form is "Incompatible With Secondary Licenses", as +# defined by the Mozilla Public License, v. 2.0. + +package Bugzilla::Extension::MoreBugUrl::Redmine; + +use 5.10.1; +use strict; +use warnings; + +use base qw(Bugzilla::BugUrl); + +############################### +#### Methods #### +############################### + +sub should_handle { + my ($class, $uri) = @_; + return ($uri->path =~ m|/issues/\d+$|) ? 1 : 0; +} + +sub _check_value { + my $class = shift; + + my $uri = $class->SUPER::_check_value(@_); + + # Redmine URLs have only one form: + # http://demo.redmine.com/issues/111 + + # Make sure there are no query parameters. + $uri->query(undef); + + # And remove any # part if there is one. + $uri->fragment(undef); + + return $uri; +} + +1; diff --git a/extensions/MoreBugUrl/lib/ReviewBoard.pm b/extensions/MoreBugUrl/lib/ReviewBoard.pm new file mode 100644 index 000000000..49c904523 --- /dev/null +++ b/extensions/MoreBugUrl/lib/ReviewBoard.pm @@ -0,0 +1,47 @@ +# This Source Code Form is subject to the terms of the Mozilla Public +# License, v. 2.0. If a copy of the MPL was not distributed with this +# file, You can obtain one at http://mozilla.org/MPL/2.0/. +# +# This Source Code Form is "Incompatible With Secondary Licenses", as +# defined by the Mozilla Public License, v. 2.0. + +package Bugzilla::Extension::MoreBugUrl::ReviewBoard; + +use 5.10.1; +use strict; +use warnings; + +use base qw(Bugzilla::BugUrl); + +############################### +#### Methods #### +############################### + +sub should_handle { + my ($class, $uri) = @_; + return ($uri->path =~ m|/r/\d+/?$|) ? 1 : 0; +} + +sub _check_value { + my $class = shift; + + my $uri = $class->SUPER::_check_value(@_); + + # Review Board URLs have only one form (the trailing slash is optional): + # http://reviews.reviewboard.org/r/111/ + + # Make sure there are no query parameters. + $uri->query(undef); + + # And remove any # part if there is one. + $uri->fragment(undef); + + # make sure the trailing slash is present + if ($uri->path !~ m|/$|) { + $uri->path($uri->path . '/'); + } + + return $uri; +} + +1; diff --git a/extensions/MoreBugUrl/lib/Savane.pm b/extensions/MoreBugUrl/lib/Savane.pm new file mode 100644 index 000000000..a0ea2f825 --- /dev/null +++ b/extensions/MoreBugUrl/lib/Savane.pm @@ -0,0 +1,40 @@ +# This Source Code Form is subject to the terms of the Mozilla Public +# License, v. 2.0. If a copy of the MPL was not distributed with this +# file, You can obtain one at http://mozilla.org/MPL/2.0/. +# +# This Source Code Form is "Incompatible With Secondary Licenses", as +# defined by the Mozilla Public License, v. 2.0. + +package Bugzilla::Extension::MoreBugUrl::Savane; + +use 5.10.1; +use strict; +use warnings; + +use base qw(Bugzilla::BugUrl); + +############################### +#### Methods #### +############################### + +sub should_handle { + my ($class, $uri) = @_; + return ($uri->as_string =~ m|/bugs/(index\.php)?\?\d+$|) ? 1 : 0; +} + +sub _check_value { + my $class = shift; + + my $uri = $class->SUPER::_check_value(@_); + + # Savane URLs have only two forms: + # http://gna.org/bugs/index.php?12345 + # http://gna.org/bugs/?12345 + + # And remove any # part if there is one. + $uri->fragment(undef); + + return $uri; +} + +1; diff --git a/extensions/MoreBugUrl/lib/WineHQForums.pm b/extensions/MoreBugUrl/lib/WineHQForums.pm new file mode 100644 index 000000000..274f9e9cf --- /dev/null +++ b/extensions/MoreBugUrl/lib/WineHQForums.pm @@ -0,0 +1,46 @@ +# This Source Code Form is subject to the terms of the Mozilla Public +# License, v. 2.0. If a copy of the MPL was not distributed with this +# file, You can obtain one at http://mozilla.org/MPL/2.0/. +# +# This Source Code Form is "Incompatible With Secondary Licenses", as +# defined by the Mozilla Public License, v. 2.0. + +package Bugzilla::Extension::MoreBugUrl::WineHQForums; + +use 5.10.1; +use strict; +use warnings; + +use base qw(Bugzilla::BugUrl); + +############################### +#### Methods #### +############################### + +sub should_handle { + my ($class, $uri) = @_; + + # WineHQ Forums URLs only have one form: + # http(s)://forum.winehq.org/viewtopic.php?f=1234&t=1234 + return (lc($uri->authority) eq 'forum.winehq.org' + and $uri->path =~ m|^/viewtopic\.php$| + and $uri->query_param('f') =~ /^\d+$/ + and $uri->query_param('t') =~ /^\d+$/) ? 1 : 0; +} + +sub _check_value { + my $class = shift; + + my $uri = $class->SUPER::_check_value(@_); + + # WineHQ Forums HTTP URLs redirect to HTTPS, so just use the HTTPS + # scheme. + $uri->scheme('https'); + + # Remove any # part if there is one. + $uri->fragment(undef); + + return $uri; +} + +1; diff --git a/extensions/MoreBugUrl/template/en/default/hook/global/user-error-bug_url_invalid_tracker.html.tmpl b/extensions/MoreBugUrl/template/en/default/hook/global/user-error-bug_url_invalid_tracker.html.tmpl new file mode 100644 index 000000000..21b25cdcf --- /dev/null +++ b/extensions/MoreBugUrl/template/en/default/hook/global/user-error-bug_url_invalid_tracker.html.tmpl @@ -0,0 +1,15 @@ +[%# This Source Code Form is subject to the terms of the Mozilla Public + # License, v. 2.0. If a copy of the MPL was not distributed with this + # file, You can obtain one at http://mozilla.org/MPL/2.0/. + # + # This Source Code Form is "Incompatible With Secondary Licenses", as + # defined by the Mozilla Public License, v. 2.0. + #%] + +
  • An issue on bitbucket.org.
  • +
  • A Review Board review request.
  • +
  • A ticket in an RT installation.
  • +
  • A b[% %]ug on b[% %]ugs.php.net.
  • +
  • An issue in a Redmine installation.
  • +
  • A b[% %]ug in a Savane installation.
  • +
  • A b[% %]ug related topic on WineHQ forums