summaryrefslogtreecommitdiffstats
path: root/extensions/FlagDefaultRequestee
diff options
context:
space:
mode:
Diffstat (limited to 'extensions/FlagDefaultRequestee')
-rw-r--r--extensions/FlagDefaultRequestee/Config.pm17
-rw-r--r--extensions/FlagDefaultRequestee/Extension.pm173
-rw-r--r--extensions/FlagDefaultRequestee/lib/Constants.pm25
-rw-r--r--extensions/FlagDefaultRequestee/template/en/default/flag/default_requestees.html.tmpl105
-rw-r--r--extensions/FlagDefaultRequestee/template/en/default/hook/admin/flag-type/edit-rows.html.tmpl21
-rw-r--r--extensions/FlagDefaultRequestee/template/en/default/hook/attachment/create-end.html.tmpl9
-rw-r--r--extensions/FlagDefaultRequestee/template/en/default/hook/attachment/edit-end.html.tmpl9
-rw-r--r--extensions/FlagDefaultRequestee/template/en/default/hook/bug/create/create-form.html.tmpl9
-rw-r--r--extensions/FlagDefaultRequestee/template/en/default/hook/bug/edit-after_custom_fields.html.tmpl9
-rw-r--r--extensions/FlagDefaultRequestee/template/en/default/hook/global/messages-flag_type_updated_fields.html.tmpl15
-rw-r--r--extensions/FlagDefaultRequestee/template/en/default/hook/global/user-error-errors.html.tmpl13
11 files changed, 405 insertions, 0 deletions
diff --git a/extensions/FlagDefaultRequestee/Config.pm b/extensions/FlagDefaultRequestee/Config.pm
new file mode 100644
index 000000000..70c5ca33a
--- /dev/null
+++ b/extensions/FlagDefaultRequestee/Config.pm
@@ -0,0 +1,17 @@
+# 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::FlagDefaultRequestee;
+
+use strict;
+
+use constant NAME => 'FlagDefaultRequestee';
+
+use constant REQUIRED_MODULES => [];
+use constant OPTIONAL_MODULES => [];
+
+__PACKAGE__->NAME;
diff --git a/extensions/FlagDefaultRequestee/Extension.pm b/extensions/FlagDefaultRequestee/Extension.pm
new file mode 100644
index 000000000..958a1bb85
--- /dev/null
+++ b/extensions/FlagDefaultRequestee/Extension.pm
@@ -0,0 +1,173 @@
+# 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::FlagDefaultRequestee;
+
+use strict;
+use base qw(Bugzilla::Extension);
+
+use Bugzilla::Error;
+use Bugzilla::FlagType;
+use Bugzilla::User;
+use Bugzilla::Util 'trim';
+
+use Bugzilla::Extension::FlagDefaultRequestee::Constants;
+
+our $VERSION = '1';
+
+################
+# Installation #
+################
+
+sub install_update_db {
+ my $dbh = Bugzilla->dbh;
+ $dbh->bz_add_column('flagtypes', 'default_requestee', {
+ TYPE => 'INT3',
+ NOTNULL => 0,
+ REFERENCES => { TABLE => 'profiles',
+ COLUMN => 'userid',
+ DELETE => 'SET NULL' }
+ });
+}
+
+#############
+# Templates #
+#############
+
+sub template_before_process {
+ my ($self, $args) = @_;
+ return unless Bugzilla->user->id;
+ my ($vars, $file) = @$args{qw(vars file)};
+ return unless grep { $_ eq $file } FLAGTYPE_TEMPLATES;
+
+ my $flag_types = [];
+ if (exists $vars->{bug} || exists $vars->{attachment}) {
+ my $bug;
+ if (exists $vars->{bug}) {
+ $bug = $vars->{'bug'};
+ } elsif (exists $vars->{'attachment'}) {
+ $bug = $vars->{'attachment'}->{bug};
+ }
+
+ $flag_types = Bugzilla::FlagType::match({
+ 'target_type' => ($file =~ /^bug/ ? 'bug' : 'attachment'),
+ 'product_id' => $bug->product_id,
+ 'component_id' => $bug->component_id,
+ 'bug_id' => $bug->id,
+ 'active_or_has_flags' => $bug->id,
+ });
+
+ $vars->{flag_currently_requested} ||= {};
+ foreach my $type (@$flag_types) {
+ my $flags = Bugzilla::Flag->match({
+ type_id => $type->id,
+ bug_id => $bug->id,
+ status => '?'
+ });
+ map { $vars->{flag_currently_requested}->{$_->id} = 1 } @$flags;
+ }
+ }
+ elsif ($file =~ /^bug\/create/ && exists $vars->{product}) {
+ my $bug_flags = $vars->{product}->flag_types->{bug};
+ my $attachment_flags = $vars->{product}->flag_types->{attachment};
+ $flag_types = [ map { $_ } (@$bug_flags, @$attachment_flags) ];
+ }
+
+ return if !@$flag_types;
+
+ $vars->{flag_default_requestees} ||= {};
+ foreach my $type (@$flag_types) {
+ next if !$type->default_requestee;
+ $vars->{flag_default_requestees}->{$type->id} = $type->default_requestee->login;
+ }
+}
+
+##################
+# Object Methods #
+##################
+
+BEGIN {
+ *Bugzilla::FlagType::default_requestee = \&_default_requestee;
+}
+
+sub object_columns {
+ my ($self, $args) = @_;
+ my ($class, $columns) = @$args{qw(class columns)};
+ if ($class->isa('Bugzilla::FlagType')) {
+ push(@$columns, 'default_requestee');
+ }
+}
+
+sub object_update_columns {
+ my ($self, $args) = @_;
+ my $object = $args->{object};
+ return unless $object->isa('Bugzilla::FlagType');
+
+ my $columns = $args->{columns};
+ push(@$columns, 'default_requestee');
+
+ # editflagtypes.cgi doesn't call set_all, so we have to do this here
+ my $input = Bugzilla->input_params;
+ $object->set('default_requestee', $input->{default_requestee})
+ if exists $input->{default_requestee};
+}
+
+sub object_validators {
+ my ($self, $args) = @_;
+ my $class = $args->{class};
+ return unless $class->isa('Bugzilla::FlagType');
+
+ my $validators = $args->{validators};
+ $validators->{default_requestee} = \&_check_default_requestee;
+}
+
+sub object_before_create {
+ my ($self, $args) = @_;
+ my $class = $args->{class};
+ return unless $class->isa('Bugzilla::FlagType');
+
+ my $params = $args->{params};
+ my $input = Bugzilla->input_params;
+ $params->{default_requestee} = $input->{default_requestee}
+ if exists $params->{default_requestee};
+}
+
+sub object_end_of_update {
+ my ($self, $args) = @_;
+ my $object = $args->{object};
+ return unless $object->isa('Bugzilla::FlagType');
+
+ my $old_object = $args->{old_object};
+ my $changes = $args->{changes};
+ my $old_id = $old_object->default_requestee
+ ? $old_object->default_requestee->id
+ : 0;
+ my $new_id = $object->default_requestee
+ ? $object->default_requestee->id
+ : 0;
+ return if $old_id == $new_id;
+
+ $changes->{default_requestee} = [ $old_id, $new_id ];
+}
+
+sub _check_default_requestee {
+ my ($self, $value, $field) = @_;
+ $value = trim($value // '');
+ return undef if $value eq '';
+ ThrowUserError("flag_default_requestee_review")
+ if $self->name eq 'review';
+ return Bugzilla::User->check($value)->id;
+}
+
+sub _default_requestee {
+ my ($self) = @_;
+ return $self->{default_requestee}
+ ? Bugzilla::User->new({ id => $self->{default_requestee}, cache => 1 })
+ : undef;
+}
+
+__PACKAGE__->NAME;
diff --git a/extensions/FlagDefaultRequestee/lib/Constants.pm b/extensions/FlagDefaultRequestee/lib/Constants.pm
new file mode 100644
index 000000000..467028423
--- /dev/null
+++ b/extensions/FlagDefaultRequestee/lib/Constants.pm
@@ -0,0 +1,25 @@
+# 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::FlagDefaultRequestee::Constants;
+
+use strict;
+
+use base qw(Exporter);
+
+our @EXPORT = qw(
+ FLAGTYPE_TEMPLATES
+);
+
+use constant FLAGTYPE_TEMPLATES => (
+ "attachment/edit.html.tmpl",
+ "attachment/createformcontents.html.tmpl",
+ "bug/edit.html.tmpl",
+ "bug/create/create.html.tmpl"
+);
+
+1;
diff --git a/extensions/FlagDefaultRequestee/template/en/default/flag/default_requestees.html.tmpl b/extensions/FlagDefaultRequestee/template/en/default/flag/default_requestees.html.tmpl
new file mode 100644
index 000000000..db728c168
--- /dev/null
+++ b/extensions/FlagDefaultRequestee/template/en/default/flag/default_requestees.html.tmpl
@@ -0,0 +1,105 @@
+[%# 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.
+ #%]
+
+[% IF flag_default_requestees.keys.size %]
+ <script type="text/javascript">
+ var currently_requested = new Array();
+ var default_requestees = new Array();
+ [% FOREACH id = flag_currently_requested.keys %]
+ currently_requested.push('[% id FILTER js %]');
+ [% END %]
+ [% FOREACH id = flag_default_requestees.keys %]
+ default_requestees['id_[% id FILTER js %]'] = '[% flag_default_requestees.$id FILTER js %]';
+ [% END %]
+
+ function fdrSetDefaultRequestee(field, default_requestee) {
+ field.value = default_requestee;
+ field.focus();
+ field.select();
+ }
+
+ function fdrOnChange(ev) {
+ var parts = ev.target.id.split('-');
+ var flag = parts[0];
+ var id = parts[1];
+ var state = ev.target.value;
+ var requestee_field;
+
+ if (flag.search(/_type/) == -1) {
+ for (var i = 0; i < currently_requested.length; i++) {
+ if (id == currently_requested[i]) {
+ return;
+ }
+ }
+ requestee_field = YAHOO.util.Dom.get('requestee-' + id);
+ parts = ev.target.className.split('-');
+ id = parts[1];
+ }
+ else {
+ requestee_field = YAHOO.util.Dom.get('requestee_type-' + id);
+ }
+ if (!requestee_field) return;
+
+ var current_requestee = requestee_field.value;
+ var default_requestee = default_requestees['id_' + id];
+ if (!default_requestee) return;
+
+ if (state == '?' && !current_requestee && default_requestee) {
+ fdrSetDefaultRequestee(requestee_field, default_requestees['id_' + id]);
+ }
+ else if (state == '?' && current_requestee != default_requestee) {
+ fdrShowDefaultLink(requestee_field, id);
+ }
+ }
+
+ YAHOO.util.Event.onDOMReady(function() {
+ var selects = YAHOO.util.Dom.getElementsByClassName('flag_select');
+ for (var i = 0; i < selects.length; i++) {
+ YAHOO.util.Event.on(selects[i], 'change', fdrOnChange);
+ }
+
+ for (var i = 0; i < currently_requested.length; i++) {
+ var flag_id = currently_requested[i];
+ var flag_field = YAHOO.util.Dom.get('flag-' + flag_id);
+ var requestee_field = YAHOO.util.Dom.get('requestee-' + flag_id);
+ if (!requestee_field) continue;
+ var parts = flag_field.className.split('-');
+ var type_id = parts[1];
+ var current_requestee = requestee_field.value;
+ var default_requestee = default_requestees['id_' + type_id];
+ if (!default_requestee) continue;
+ if (current_requestee != default_requestee) {
+ fdrShowDefaultLink(requestee_field, type_id, flag_id);
+ }
+ }
+ });
+
+ function fdrHideDefaultLink (flag_id) {
+ YAHOO.util.Dom.addClass('default_requestee_' + flag_id, 'bz_default_hidden');
+ }
+
+ function fdrShowDefaultLink (requestee_field, type_id, flag_id) {
+ var default_requestee = default_requestees['id_' + type_id];
+
+ var default_link = document.createElement('a');
+ YAHOO.util.Dom.setAttribute(default_link, 'href', 'javascript:void(0)');
+ default_link.appendChild(document.createTextNode('default requestee'));
+ YAHOO.util.Event.addListener(default_link, 'click', function() {
+ fdrSetDefaultRequestee(requestee_field, default_requestee);
+ fdrHideDefaultLink(flag_id);
+ });
+
+ var default_span = document.createElement('span');
+ YAHOO.util.Dom.setAttribute(default_span, 'id', 'default_requestee_' + flag_id);
+ default_span.appendChild(document.createTextNode("\u00a0("));
+ default_span.appendChild(default_link);
+ default_span.appendChild(document.createTextNode(')'));
+ requestee_field.parentNode.parentNode.appendChild(default_span);
+ }
+ </script>
+[% END %]
diff --git a/extensions/FlagDefaultRequestee/template/en/default/hook/admin/flag-type/edit-rows.html.tmpl b/extensions/FlagDefaultRequestee/template/en/default/hook/admin/flag-type/edit-rows.html.tmpl
new file mode 100644
index 000000000..edefca370
--- /dev/null
+++ b/extensions/FlagDefaultRequestee/template/en/default/hook/admin/flag-type/edit-rows.html.tmpl
@@ -0,0 +1,21 @@
+[%# 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.
+ #%]
+
+<tr>
+ <th>Default Requestee:</th>
+ <td>
+ If flag is specifically requestable, this user will be entered in the
+ requestee field by default unless the user changes it.<br>
+ [% INCLUDE global/userselect.html.tmpl
+ name => 'default_requestee'
+ id => 'default_requestee'
+ value => type.default_requestee.login
+ classes => ['requestee']
+ %]
+ </td>
+</tr>
diff --git a/extensions/FlagDefaultRequestee/template/en/default/hook/attachment/create-end.html.tmpl b/extensions/FlagDefaultRequestee/template/en/default/hook/attachment/create-end.html.tmpl
new file mode 100644
index 000000000..20b2526d0
--- /dev/null
+++ b/extensions/FlagDefaultRequestee/template/en/default/hook/attachment/create-end.html.tmpl
@@ -0,0 +1,9 @@
+[%# 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.
+ #%]
+
+[% INCLUDE flag/default_requestees.html.tmpl %]
diff --git a/extensions/FlagDefaultRequestee/template/en/default/hook/attachment/edit-end.html.tmpl b/extensions/FlagDefaultRequestee/template/en/default/hook/attachment/edit-end.html.tmpl
new file mode 100644
index 000000000..20b2526d0
--- /dev/null
+++ b/extensions/FlagDefaultRequestee/template/en/default/hook/attachment/edit-end.html.tmpl
@@ -0,0 +1,9 @@
+[%# 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.
+ #%]
+
+[% INCLUDE flag/default_requestees.html.tmpl %]
diff --git a/extensions/FlagDefaultRequestee/template/en/default/hook/bug/create/create-form.html.tmpl b/extensions/FlagDefaultRequestee/template/en/default/hook/bug/create/create-form.html.tmpl
new file mode 100644
index 000000000..20b2526d0
--- /dev/null
+++ b/extensions/FlagDefaultRequestee/template/en/default/hook/bug/create/create-form.html.tmpl
@@ -0,0 +1,9 @@
+[%# 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.
+ #%]
+
+[% INCLUDE flag/default_requestees.html.tmpl %]
diff --git a/extensions/FlagDefaultRequestee/template/en/default/hook/bug/edit-after_custom_fields.html.tmpl b/extensions/FlagDefaultRequestee/template/en/default/hook/bug/edit-after_custom_fields.html.tmpl
new file mode 100644
index 000000000..20b2526d0
--- /dev/null
+++ b/extensions/FlagDefaultRequestee/template/en/default/hook/bug/edit-after_custom_fields.html.tmpl
@@ -0,0 +1,9 @@
+[%# 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.
+ #%]
+
+[% INCLUDE flag/default_requestees.html.tmpl %]
diff --git a/extensions/FlagDefaultRequestee/template/en/default/hook/global/messages-flag_type_updated_fields.html.tmpl b/extensions/FlagDefaultRequestee/template/en/default/hook/global/messages-flag_type_updated_fields.html.tmpl
new file mode 100644
index 000000000..478718d3c
--- /dev/null
+++ b/extensions/FlagDefaultRequestee/template/en/default/hook/global/messages-flag_type_updated_fields.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.
+ #%]
+
+[% IF changes.default_requestee.defined %]
+ [% IF flagtype.default_requestee %]
+ <li>Default requestee updated to '[% flagtype.default_requestee.login FILTER html %]'</li>
+ [% ELSE %]
+ <li>Default requestee deleted</li>
+ [% END %]
+[% END %]
diff --git a/extensions/FlagDefaultRequestee/template/en/default/hook/global/user-error-errors.html.tmpl b/extensions/FlagDefaultRequestee/template/en/default/hook/global/user-error-errors.html.tmpl
new file mode 100644
index 000000000..3fbd0458c
--- /dev/null
+++ b/extensions/FlagDefaultRequestee/template/en/default/hook/global/user-error-errors.html.tmpl
@@ -0,0 +1,13 @@
+[%# 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.
+ #%]
+
+[% IF error == "flag_default_requestee_review" %]
+ [% title = "Review flag not supported" %]
+ You cannot use the 'Default Requestee' field for the review flag.
+ Instead set the 'Suggested Reviewers' on the Product or Component edit forms.
+[% END %]