summaryrefslogtreecommitdiffstats
path: root/extensions/ContributorEngagement/Extension.pm
blob: c5ce299665f29d457ff998253fc582dbd8a1cd55 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
# 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::ContributorEngagement;

use 5.10.1;
use strict;
use warnings;

use base qw(Bugzilla::Extension);

use Bugzilla::User;
use Bugzilla::Util qw(format_time);
use Bugzilla::Mailer;
use Bugzilla::Install::Util qw(indicate_progress);

use Bugzilla::Extension::ContributorEngagement::Constants;

our $VERSION = '2.0';

BEGIN {
    *Bugzilla::User::first_patch_reviewed_id = \&_first_patch_reviewed_id;
}

sub _first_patch_reviewed_id { return $_[0]->{'first_patch_reviewed_id'}; }

sub install_update_db {
    my ($self) = @_;
    my $dbh = Bugzilla->dbh;

    if ($dbh->bz_column_info('profiles', 'first_patch_approved_id')) {
        $dbh->bz_drop_column('profiles', 'first_patch_approved_id');
    }
    if (!$dbh->bz_column_info('profiles', 'first_patch_reviewed_id')) {
        $dbh->bz_add_column('profiles', 'first_patch_reviewed_id', { TYPE => 'INT3' });
        _populate_first_reviewed_ids();
     }
}

sub _populate_first_reviewed_ids {
    my $dbh = Bugzilla->dbh;

    my $sth = $dbh->prepare('UPDATE profiles SET first_patch_reviewed_id = ? WHERE userid = ?');
    my $ra = $dbh->selectall_arrayref("SELECT attachments.submitter_id,
                                              attachments.attach_id
                                         FROM attachments
                                              INNER JOIN flags ON attachments.attach_id = flags.attach_id
                                              INNER JOIN flagtypes ON flags.type_id = flagtypes.id
                                        WHERE flagtypes.name LIKE 'review%' AND flags.status = '+'
                                     ORDER BY flags.modification_date");
    my $count = 1;
    my $total = scalar @$ra;
    my %user_seen;
    foreach my $ra_row (@$ra) {
        my ($user_id, $attach_id) = @$ra_row;
        indicate_progress({ current => $count++, total => $total, every => 25 });
        next if $user_seen{$user_id};
        $sth->execute($attach_id, $user_id);
        $user_seen{$user_id} = 1;
    }

    print "done\n";
}

sub object_columns {
    my ($self, $args) = @_;
    my ($class, $columns) = @$args{qw(class columns)};
    if ($class->isa('Bugzilla::User')) {
        my $dbh = Bugzilla->dbh;
        if ($dbh->bz_column_info('profiles', 'first_patch_reviewed_id')) {
            push(@$columns, 'first_patch_reviewed_id');
        }
    }
}

sub flag_end_of_update {
    my ($self, $args) = @_;
    my ($object, $timestamp, $new_flags) = @$args{qw(object timestamp new_flags)};

    if ($object->isa('Bugzilla::Attachment')
        && @$new_flags
        && !$object->attacher->first_patch_reviewed_id
        && grep($_ eq $object->bug->product, ENABLED_PRODUCTS))
    {
        my $attachment = $object;

        foreach my $orig_change (@$new_flags) {
            my $change = $orig_change;
            $change =~ s/^[^:]+://; # get rid of setter
            $change =~ s/\([^\)]+\)$//; # get rid of requestee
            my ($name, $value) = $change =~ /^(.+)(.)$/;

            # Only interested in review flags set to +
            next unless $name =~ /^review/ && $value eq '+';

            _send_mail($attachment, $timestamp);

            Bugzilla->dbh->do("UPDATE profiles SET first_patch_reviewed_id = ? WHERE userid = ?",
                              undef, $attachment->id, $attachment->attacher->id);
            Bugzilla->memcached->clear({ table => 'profiles', id => $attachment->attacher->id });
            last;
        }
    }
}

sub _send_mail {
    my ($attachment, $timestamp) = @_;

    my $vars = {
        date       => format_time($timestamp, '%a, %d %b %Y %T %z', 'UTC'),
        attachment => $attachment,
        from_user  => EMAIL_FROM,
    };

    my $msg;
    my $template = Bugzilla->template_inner($attachment->attacher->setting('lang'));
    $template->process("contributor/email.txt.tmpl", $vars, \$msg)
        || ThrowTemplateError($template->error());

    MessageToMTA($msg);
}

__PACKAGE__->NAME;