diff options
Diffstat (limited to 'extensions/Mageia/Extension.pm')
-rw-r--r-- | extensions/Mageia/Extension.pm | 200 |
1 files changed, 200 insertions, 0 deletions
diff --git a/extensions/Mageia/Extension.pm b/extensions/Mageia/Extension.pm new file mode 100644 index 000000000..c2f8466e7 --- /dev/null +++ b/extensions/Mageia/Extension.pm @@ -0,0 +1,200 @@ +# 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::Mageia; + +use 5.16.0; +use strict; +use warnings; + +use parent qw(Bugzilla::Extension); + +use Bugzilla::Constants qw(EVT_CC REL_GLOBAL_WATCHER); +use Bugzilla::Bug qw(LogActivityEntry); +use Bugzilla::Field qw(get_field_id); +use Bugzilla::User qw(); +use Bugzilla::User::Setting qw(add_setting); +use Bugzilla::Extension::Mageia::Util qw(compare_datetimes sync_ldap_groups_check); + +use Email::Address; + +# Let's match the Bugzilla version it's written for. +our $VERSION = '5.0'; + +# sysadmin-bugs@ml.mageia.org user ID = 175. +use constant SYSADMIN_USER_ID => 175; + +use constant MGA_SETTINGS => { + mga_inline_history => { options => ['on', 'off'], default => 'on' }, +}; + +sub bug_end_of_create_validators { + my ($self, $args) = @_; + + # If a user enters 'validated_update' or 'validated_backport' as keyword, + # automatically CC sysadmin-bugs@ml.mageia.org. + my $keywords = $args->{params}->{keywords}; + + if (grep { $_->name =~ /^validated_(?:update|backport)$/ } @$keywords) { + my $cc_list = $args->{params}->{cc}; + if (!grep { $_ == SYSADMIN_USER_ID } @$cc_list) { + push(@$cc_list, SYSADMIN_USER_ID); + } + } +} + +sub bug_end_of_update { + my ($self, $args) = @_; + my $bug = $args->{bug}; + my $dbh = Bugzilla->dbh; + my $user = Bugzilla->user; + + my $new_keywords_str; + # Call exists to avoid autovivification of $args->{changes} if it does not exist. + # Else $bug->update() always sees the bug as being edited. + if (exists $args->{changes} && exists $args->{changes}->{keywords}) { + $new_keywords_str = $args->{changes}->{keywords}->[1]; + } + + # If a user enters 'validated_update' or 'validated_backport' as keyword, + # automatically CC sysadmin-bugs@ml.mageia.org. + if ($new_keywords_str) { + my @new_keywords = split(/[,\s]+/, $new_keywords_str); + if (grep { $_ =~ /^validated_(?:update|backport)$/ } @new_keywords + and !grep { $_->id == SYSADMIN_USER_ID } @{$bug->cc_users}) + { + # Safer to clear the cache and let Bugzilla regenerate them if needed. + delete $bug->{cc_users}; + delete $bug->{cc}; + $dbh->do('INSERT INTO cc (bug_id, who) VALUES (?, ?)', + undef, ($bug->id, SYSADMIN_USER_ID)); + + # We also have to update the bug history to reflect this change. + my $changed_cc = $args->{changes}->{cc}; + my $sysadmin_login = Bugzilla::User->new(SYSADMIN_USER_ID)->login; + + if ($changed_cc->[1]) { + $changed_cc->[1] .= ", $sysadmin_login"; + } + else { + $changed_cc->[1] = $sysadmin_login; + } + + my $field_id = get_field_id('cc'); + $dbh->do('DELETE FROM bugs_activity + WHERE bug_id = ? AND bug_when = ? AND fieldid = ?', + undef, ($bug->id, $args->{timestamp}, $field_id)); + + LogActivityEntry($bug->id, 'cc', $changed_cc->[0] // '', $changed_cc->[1], + $user->id, $args->{timestamp}); + } + } +} + +sub bug_format_comment { + my ($self, $args) = @_; + my $regexes = $args->{'regexes'}; + # The Mageia DB was initially using SQL_ASCII as encoding (which means "no encoding"). + # The move to UTF8 caused some characters to be badly decoded, which we fix here. + # Convert "é" into "é". + push(@$regexes, { match => qr/\xc3\xa9/, replace => "\xe9" }); +} + +sub enter_bug_entrydefaultvars { + my ($self, $vars) = @_; + my $cgi = Bugzilla->cgi; + + # By default, users should get the guided form when reporting a new bug. + # Pass &normal=1 to the URL to get the official bug form. + my $format = $cgi->param('normal') ? '' : 'guided'; + $cgi->param('format', $format); +} + +sub install_before_final_checks { + # A hook in Bugzilla::Install::SETTINGS() would be much cleaner. :( + my %settings = %{MGA_SETTINGS()}; + foreach my $setting (keys %settings) { + add_setting($setting, $settings{$setting}->{options}, $settings{$setting}->{default}); + } +} + +sub mailer_before_send { + my ($self, $args) = @_; + my $email = $args->{email}; + + # Include the changer's name in the "From:" field. + if (my $changer = $email->header('X-Bugzilla-Who')) { + $changer = Bugzilla::User->new({ name => $changer }); + return unless $changer; + my $address = Email::Address->new($changer->name, $email->header('From')); + $email->header_str_set('From' => $address->format); + } +} + +sub sanitycheck_check { + my ($self, $args) = @_; + &{$args->{status}}('ldap_check_group_membership'); + sync_ldap_groups_check($args->{status}); +} + +sub sanitycheck_repair { + my ($self, $args) = @_; + if (Bugzilla->cgi->param('sync_ldap_groups')) { + &{$args->{status}}('ldap_repair_start'); + sync_ldap_groups_check($args->{status}, 1); + &{$args->{status}}('ldap_repair_end'); + } +} + +sub template_before_process { + my ($self, $args) = @_; + _inline_history($args) if $args->{file} eq 'bug/comments.html.tmpl'; +} + +sub _inline_history { + my $args = shift; + my $user = Bugzilla->user; + return if $user->setting('mga_inline_history') eq 'off'; + # Only display the bug history in chronological order. + return if $user->setting('comment_sort_order') ne 'oldest_to_newest'; + + my $bug = $args->{vars}->{bug}; + my ($history) = $bug->get_activity(); + # Filter private comments that the user is not allowed to see. + my @comments = grep { !$_->is_private || $user->is_insider || $user->id == $_->author->id } @{ $bug->comments }; + my %h_times = map { $_->{when} => $_ } @$history; + my %c_times = map { $_->creation_ts => $_ } @comments; + my @all_times = sort { compare_datetimes($a, $b) } (keys %c_times, keys %h_times); + my $curr_comment; + + foreach my $time (@all_times) { + if ($c_times{$time}) { + $curr_comment = $c_times{$time}; + $curr_comment->{inline_history} //= []; + } + if (my $activity = $h_times{$time}) { + # If we have no visible comment to attach the activity to, then ignore it. + # This can happen if the initial comment (comment 0) is private. + next unless $curr_comment; + $activity->{after} = compare_datetimes($time, $curr_comment->creation_ts); + $activity->{who} = new Bugzilla::User({ name => $activity->{who}, cache => 1 }); + push(@{ $curr_comment->{inline_history} }, $activity); + } + } +} + +sub user_wants_mail { + my ($self, $args) = @_; + return unless $args->{relationship} == REL_GLOBAL_WATCHER; + + my $wants_mail = $args->{wants_mail}; + my @events = @{ $args->{events} }; + # Do not email global watchers if the single change is about the CC list. + $$wants_mail = (scalar(@events) == 1 && $events[0] == EVT_CC) ? 0 : 1; +} + +__PACKAGE__->NAME; |