summaryrefslogtreecommitdiffstats
path: root/extensions/RequestNagger/Extension.pm
diff options
context:
space:
mode:
Diffstat (limited to 'extensions/RequestNagger/Extension.pm')
-rw-r--r--extensions/RequestNagger/Extension.pm552
1 files changed, 251 insertions, 301 deletions
diff --git a/extensions/RequestNagger/Extension.pm b/extensions/RequestNagger/Extension.pm
index e0f97c9f7..54a11ff5b 100644
--- a/extensions/RequestNagger/Extension.pm
+++ b/extensions/RequestNagger/Extension.pm
@@ -25,241 +25,239 @@ use DateTime;
our $VERSION = '1';
BEGIN {
- *Bugzilla::Flag::age = \&_flag_age;
- *Bugzilla::Flag::deferred = \&_flag_deferred;
- *Bugzilla::Product::nag_interval = \&_product_nag_interval;
+ *Bugzilla::Flag::age = \&_flag_age;
+ *Bugzilla::Flag::deferred = \&_flag_deferred;
+ *Bugzilla::Product::nag_interval = \&_product_nag_interval;
}
sub _flag_age {
- return time_ago(datetime_from($_[0]->modification_date));
+ return time_ago(datetime_from($_[0]->modification_date));
}
sub _flag_deferred {
- my ($self) = @_;
- if (!exists $self->{deferred}) {
- my $dbh = Bugzilla->dbh;
- my ($defer_until) = $dbh->selectrow_array(
- "SELECT defer_until FROM nag_defer WHERE flag_id=?",
- undef,
- $self->id
- );
- $self->{deferred} = $defer_until ? datetime_from($defer_until) : undef;
- }
- return $self->{deferred};
+ my ($self) = @_;
+ if (!exists $self->{deferred}) {
+ my $dbh = Bugzilla->dbh;
+ my ($defer_until)
+ = $dbh->selectrow_array("SELECT defer_until FROM nag_defer WHERE flag_id=?",
+ undef, $self->id);
+ $self->{deferred} = $defer_until ? datetime_from($defer_until) : undef;
+ }
+ return $self->{deferred};
}
sub _product_nag_interval { $_[0]->{nag_interval} }
sub object_columns {
- my ($self, $args) = @_;
- my ($class, $columns) = @$args{qw(class columns)};
- if ($class->isa('Bugzilla::Product')) {
- push @$columns, 'nag_interval';
- }
+ my ($self, $args) = @_;
+ my ($class, $columns) = @$args{qw(class columns)};
+ if ($class->isa('Bugzilla::Product')) {
+ push @$columns, 'nag_interval';
+ }
}
sub object_update_columns {
- my ($self, $args) = @_;
- my ($object, $columns) = @$args{qw(object columns)};
- if ($object->isa('Bugzilla::Product')) {
- push @$columns, 'nag_interval';
- }
+ my ($self, $args) = @_;
+ my ($object, $columns) = @$args{qw(object columns)};
+ if ($object->isa('Bugzilla::Product')) {
+ push @$columns, 'nag_interval';
+ }
}
sub object_before_create {
- my ($self, $args) = @_;
- my ($class, $params) = @$args{qw(class params)};
- return unless $class->isa('Bugzilla::Product');
- my $input = Bugzilla->input_params;
- if (exists $input->{nag_interval}) {
- my $interval = _check_nag_interval($input->{nag_interval});
- $params->{nag_interval} = $interval;
- }
+ my ($self, $args) = @_;
+ my ($class, $params) = @$args{qw(class params)};
+ return unless $class->isa('Bugzilla::Product');
+ my $input = Bugzilla->input_params;
+ if (exists $input->{nag_interval}) {
+ my $interval = _check_nag_interval($input->{nag_interval});
+ $params->{nag_interval} = $interval;
+ }
}
sub object_end_of_set_all {
- my ($self, $args) = @_;
- my ($object, $params) = @$args{qw(object params)};
- return unless $object->isa('Bugzilla::Product');
- my $input = Bugzilla->input_params;
- if (exists $input->{nag_interval}) {
- my $interval = _check_nag_interval($input->{nag_interval});
- $object->set('nag_interval', $interval);
- }
+ my ($self, $args) = @_;
+ my ($object, $params) = @$args{qw(object params)};
+ return unless $object->isa('Bugzilla::Product');
+ my $input = Bugzilla->input_params;
+ if (exists $input->{nag_interval}) {
+ my $interval = _check_nag_interval($input->{nag_interval});
+ $object->set('nag_interval', $interval);
+ }
}
sub _check_nag_interval {
- my ($value) = @_;
- detaint_natural($value)
- || ThrowUserError('invalid_parameter', { name => 'request reminding interval', err => 'must be numeric' });
- return $value < 0 ? 0 : $value * 24;
+ my ($value) = @_;
+ detaint_natural($value)
+ || ThrowUserError('invalid_parameter',
+ {name => 'request reminding interval', err => 'must be numeric'});
+ return $value < 0 ? 0 : $value * 24;
}
sub page_before_template {
- my ($self, $args) = @_;
- my ($vars, $page) = @$args{qw(vars page_id)};
- return unless $page eq 'request_defer.html';
-
- my $user = Bugzilla->login(LOGIN_REQUIRED);
- my $input = Bugzilla->input_params;
-
- # load flag
- my $flag_id = scalar($input->{flag})
- || ThrowUserError('request_nagging_flag_invalid');
- detaint_natural($flag_id)
- || ThrowUserError('request_nagging_flag_invalid');
- my $flag = Bugzilla::Flag->new({ id => $flag_id, cache => 1 })
- || ThrowUserError('request_nagging_flag_invalid');
-
- # you can only defer flags directed at you
- $user->can_see_bug($flag->bug->id)
- || ThrowUserError("bug_access_denied", { bug_id => $flag->bug->id });
- $flag->status eq '?'
- || ThrowUserError('request_nagging_flag_set');
- $flag->requestee
- || ThrowUserError('request_nagging_flag_wind');
- $flag->requestee->id == $user->id
- || ThrowUserError('request_nagging_flag_not_owned');
-
- my $date = DateTime->now()->truncate(to => 'day');
- my $defer_until;
- if ($input->{'defer-until'}
- && $input->{'defer-until'} =~ /^(\d\d\d\d)-(\d\d)-(\d\d)$/)
- {
- $defer_until = DateTime->new(year => $1, month => $2, day => $3);
- if ($defer_until > $date->clone->add(days => 7)) {
- $defer_until = undef;
- }
+ my ($self, $args) = @_;
+ my ($vars, $page) = @$args{qw(vars page_id)};
+ return unless $page eq 'request_defer.html';
+
+ my $user = Bugzilla->login(LOGIN_REQUIRED);
+ my $input = Bugzilla->input_params;
+
+ # load flag
+ my $flag_id
+ = scalar($input->{flag}) || ThrowUserError('request_nagging_flag_invalid');
+ detaint_natural($flag_id) || ThrowUserError('request_nagging_flag_invalid');
+ my $flag = Bugzilla::Flag->new({id => $flag_id, cache => 1})
+ || ThrowUserError('request_nagging_flag_invalid');
+
+ # you can only defer flags directed at you
+ $user->can_see_bug($flag->bug->id)
+ || ThrowUserError("bug_access_denied", {bug_id => $flag->bug->id});
+ $flag->status eq '?' || ThrowUserError('request_nagging_flag_set');
+ $flag->requestee || ThrowUserError('request_nagging_flag_wind');
+ $flag->requestee->id == $user->id
+ || ThrowUserError('request_nagging_flag_not_owned');
+
+ my $date = DateTime->now()->truncate(to => 'day');
+ my $defer_until;
+ if ( $input->{'defer-until'}
+ && $input->{'defer-until'} =~ /^(\d\d\d\d)-(\d\d)-(\d\d)$/)
+ {
+ $defer_until = DateTime->new(year => $1, month => $2, day => $3);
+ if ($defer_until > $date->clone->add(days => 7)) {
+ $defer_until = undef;
}
-
- if ($input->{save} && $defer_until) {
- $self->_defer_until($flag_id, $defer_until);
- $vars->{saved} = "1";
- $vars->{defer_until} = $defer_until;
- }
- else {
- my @dates;
- foreach my $i (1..7) {
- $date->add(days => 1);
- unshift @dates, { days => $i, date => $date->clone };
- }
- $vars->{defer_until} = \@dates;
+ }
+
+ if ($input->{save} && $defer_until) {
+ $self->_defer_until($flag_id, $defer_until);
+ $vars->{saved} = "1";
+ $vars->{defer_until} = $defer_until;
+ }
+ else {
+ my @dates;
+ foreach my $i (1 .. 7) {
+ $date->add(days => 1);
+ unshift @dates, {days => $i, date => $date->clone};
}
+ $vars->{defer_until} = \@dates;
+ }
- $vars->{flag} = $flag;
+ $vars->{flag} = $flag;
}
sub _defer_until {
- my ($self, $flag_id, $defer_until) = @_;
- my $dbh = Bugzilla->dbh;
-
- $dbh->bz_start_transaction();
-
- my ($defer_id) = $dbh->selectrow_array("SELECT id FROM nag_defer WHERE flag_id=?", undef, $flag_id);
- if ($defer_id) {
- $dbh->do("UPDATE nag_defer SET defer_until=? WHERE id=?", undef, $defer_until->ymd, $flag_id);
- } else {
- $dbh->do("INSERT INTO nag_defer(flag_id, defer_until) VALUES (?, ?)", undef, $flag_id, $defer_until->ymd);
- }
-
- $dbh->bz_commit_transaction();
+ my ($self, $flag_id, $defer_until) = @_;
+ my $dbh = Bugzilla->dbh;
+
+ $dbh->bz_start_transaction();
+
+ my ($defer_id)
+ = $dbh->selectrow_array("SELECT id FROM nag_defer WHERE flag_id=?",
+ undef, $flag_id);
+ if ($defer_id) {
+ $dbh->do("UPDATE nag_defer SET defer_until=? WHERE id=?",
+ undef, $defer_until->ymd, $flag_id);
+ }
+ else {
+ $dbh->do("INSERT INTO nag_defer(flag_id, defer_until) VALUES (?, ?)",
+ undef, $flag_id, $defer_until->ymd);
+ }
+
+ $dbh->bz_commit_transaction();
}
sub object_end_of_update {
- my ($self, $args) = @_;
- if ($args->{object}->isa("Bugzilla::Flag") && exists $args->{changes}) {
- # any change to the flag (setting, clearing, or retargetting) will clear the deferals
- my $flag = $args->{object};
- Bugzilla->dbh->do("DELETE FROM nag_defer WHERE flag_id=?", undef, $flag->id);
- }
+ my ($self, $args) = @_;
+ if ($args->{object}->isa("Bugzilla::Flag") && exists $args->{changes}) {
+
+# any change to the flag (setting, clearing, or retargetting) will clear the deferals
+ my $flag = $args->{object};
+ Bugzilla->dbh->do("DELETE FROM nag_defer WHERE flag_id=?", undef, $flag->id);
+ }
}
sub user_preferences {
- my ($self, $args) = @_;
- my $tab = $args->{'current_tab'};
- return unless $tab eq 'request_nagging';
-
- my $save = $args->{'save_changes'};
- my $vars = $args->{'vars'};
- my $user = Bugzilla->user;
- my $dbh = Bugzilla->dbh;
-
- my %watching =
- map { $_ => 1 }
- @{ $dbh->selectcol_arrayref(
- "SELECT profiles.login_name
+ my ($self, $args) = @_;
+ my $tab = $args->{'current_tab'};
+ return unless $tab eq 'request_nagging';
+
+ my $save = $args->{'save_changes'};
+ my $vars = $args->{'vars'};
+ my $user = Bugzilla->user;
+ my $dbh = Bugzilla->dbh;
+
+ my %watching = map { $_ => 1 } @{
+ $dbh->selectcol_arrayref(
+ "SELECT profiles.login_name
FROM nag_watch
INNER JOIN profiles ON nag_watch.nagged_id = profiles.userid
WHERE nag_watch.watcher_id = ?
- ORDER BY profiles.login_name",
- undef,
- $user->id
- ) };
-
- my $nag_settings = Bugzilla::Extension::RequestNagger::Settings->new($user->id);
-
- if ($save) {
- my $input = Bugzilla->input_params;
- Bugzilla::User::match_field({ 'add_watching' => {'type' => 'multi'} });
-
- $dbh->bz_start_transaction();
-
- # user preference
- if (my $value = $input->{request_nagging}) {
- my $settings = $user->settings;
- my $setting = new Bugzilla::User::Setting('request_nagging');
- if ($value eq 'default') {
- $settings->{request_nagging}->reset_to_default;
- }
- else {
- $setting->validate_value($value);
- $settings->{request_nagging}->set($value);
- }
- }
-
- # watching
- if ($input->{remove_watched_users}) {
- my $del_watching = ref($input->{del_watching}) ? $input->{del_watching} : [ $input->{del_watching} ];
- foreach my $login (@$del_watching) {
- my $u = Bugzilla::User->new({ name => $login, cache => 1 })
- || next;
- next unless exists $watching{$u->login};
- $dbh->do(
- "DELETE FROM nag_watch WHERE watcher_id=? AND nagged_id=?",
- undef,
- $user->id, $u->id
- );
- delete $watching{$u->login};
- }
- }
- if ($input->{add_watching}) {
- my $add_watching = ref($input->{add_watching}) ? $input->{add_watching} : [ $input->{add_watching} ];
- foreach my $login (@$add_watching) {
- my $u = Bugzilla::User->new({ name => $login, cache => 1 })
- || next;
- next if exists $watching{$u->login};
- $dbh->do(
- "INSERT INTO nag_watch(watcher_id, nagged_id) VALUES(?, ?)",
- undef,
- $user->id, $u->id
- );
- $watching{$u->login} = 1;
- }
- }
-
- # watching settings
- foreach my $field (Bugzilla::Extension::RequestNagger::Settings::FIELDS()) {
- $nag_settings->set($field, $input->{$field});
- }
-
- $dbh->bz_commit_transaction();
+ ORDER BY profiles.login_name", undef, $user->id
+ )
+ };
+
+ my $nag_settings = Bugzilla::Extension::RequestNagger::Settings->new($user->id);
+
+ if ($save) {
+ my $input = Bugzilla->input_params;
+ Bugzilla::User::match_field({'add_watching' => {'type' => 'multi'}});
+
+ $dbh->bz_start_transaction();
+
+ # user preference
+ if (my $value = $input->{request_nagging}) {
+ my $settings = $user->settings;
+ my $setting = new Bugzilla::User::Setting('request_nagging');
+ if ($value eq 'default') {
+ $settings->{request_nagging}->reset_to_default;
+ }
+ else {
+ $setting->validate_value($value);
+ $settings->{request_nagging}->set($value);
+ }
}
- $vars->{watching} = [ sort keys %watching ];
- $vars->{settings} = $nag_settings;
+ # watching
+ if ($input->{remove_watched_users}) {
+ my $del_watching
+ = ref($input->{del_watching})
+ ? $input->{del_watching}
+ : [$input->{del_watching}];
+ foreach my $login (@$del_watching) {
+ my $u = Bugzilla::User->new({name => $login, cache => 1}) || next;
+ next unless exists $watching{$u->login};
+ $dbh->do("DELETE FROM nag_watch WHERE watcher_id=? AND nagged_id=?",
+ undef, $user->id, $u->id);
+ delete $watching{$u->login};
+ }
+ }
+ if ($input->{add_watching}) {
+ my $add_watching
+ = ref($input->{add_watching})
+ ? $input->{add_watching}
+ : [$input->{add_watching}];
+ foreach my $login (@$add_watching) {
+ my $u = Bugzilla::User->new({name => $login, cache => 1}) || next;
+ next if exists $watching{$u->login};
+ $dbh->do("INSERT INTO nag_watch(watcher_id, nagged_id) VALUES(?, ?)",
+ undef, $user->id, $u->id);
+ $watching{$u->login} = 1;
+ }
+ }
+
+ # watching settings
+ foreach my $field (Bugzilla::Extension::RequestNagger::Settings::FIELDS()) {
+ $nag_settings->set($field, $input->{$field});
+ }
- my $handled = $args->{'handled'};
- $$handled = 1;
+ $dbh->bz_commit_transaction();
+ }
+
+ $vars->{watching} = [sort keys %watching];
+ $vars->{settings} = $nag_settings;
+
+ my $handled = $args->{'handled'};
+ $$handled = 1;
}
#
@@ -267,125 +265,77 @@ sub user_preferences {
#
sub db_schema_abstract_schema {
- my ($self, $args) = @_;
- $args->{'schema'}->{'nag_watch'} = {
- FIELDS => [
- id => {
- TYPE => 'MEDIUMSERIAL',
- NOTNULL => 1,
- PRIMARYKEY => 1,
- },
- nagged_id => {
- TYPE => 'INT3',
- NOTNULL => 1,
- REFERENCES => {
- TABLE => 'profiles',
- COLUMN => 'userid',
- DELETE => 'CASCADE',
- }
- },
- watcher_id => {
- TYPE => 'INT3',
- NOTNULL => 1,
- REFERENCES => {
- TABLE => 'profiles',
- COLUMN => 'userid',
- DELETE => 'CASCADE',
- }
- },
- ],
- INDEXES => [
- nag_watch_idx => {
- FIELDS => [ 'nagged_id', 'watcher_id' ],
- TYPE => 'UNIQUE',
- },
- ],
- };
- $args->{'schema'}->{'nag_defer'} = {
- FIELDS => [
- id => {
- TYPE => 'MEDIUMSERIAL',
- NOTNULL => 1,
- PRIMARYKEY => 1,
- },
- flag_id => {
- TYPE => 'INT3',
- NOTNULL => 1,
- REFERENCES => {
- TABLE => 'flags',
- COLUMN => 'id',
- DELETE => 'CASCADE',
- }
- },
- defer_until => {
- TYPE => 'DATETIME',
- NOTNULL => 1,
- },
- ],
- INDEXES => [
- nag_defer_idx => {
- FIELDS => [ 'flag_id' ],
- TYPE => 'UNIQUE',
- },
- ],
- };
- $args->{'schema'}->{'nag_settings'} = {
- FIELDS => [
- id => {
- TYPE => 'MEDIUMSERIAL',
- NOTNULL => 1,
- PRIMARYKEY => 1,
- },
- user_id => {
- TYPE => 'INT3',
- NOTNULL => 1,
- REFERENCES => {
- TABLE => 'profiles',
- COLUMN => 'userid',
- DELETE => 'CASCADE',
- }
- },
- setting_name => {
- TYPE => 'VARCHAR(16)',
- NOTNULL => 1,
- },
- setting_value => {
- TYPE => 'VARCHAR(16)',
- NOTNULL => 1,
- },
- ],
- INDEXES => [
- nag_setting_idx => {
- FIELDS => [ 'user_id', 'setting_name' ],
- TYPE => 'UNIQUE',
- },
- ],
- };
+ my ($self, $args) = @_;
+ $args->{'schema'}->{'nag_watch'} = {
+ FIELDS => [
+ id => {TYPE => 'MEDIUMSERIAL', NOTNULL => 1, PRIMARYKEY => 1,},
+ nagged_id => {
+ TYPE => 'INT3',
+ NOTNULL => 1,
+ REFERENCES => {TABLE => 'profiles', COLUMN => 'userid', DELETE => 'CASCADE',}
+ },
+ watcher_id => {
+ TYPE => 'INT3',
+ NOTNULL => 1,
+ REFERENCES => {TABLE => 'profiles', COLUMN => 'userid', DELETE => 'CASCADE',}
+ },
+ ],
+ INDEXES => [
+ nag_watch_idx => {FIELDS => ['nagged_id', 'watcher_id'], TYPE => 'UNIQUE',},
+ ],
+ };
+ $args->{'schema'}->{'nag_defer'} = {
+ FIELDS => [
+ id => {TYPE => 'MEDIUMSERIAL', NOTNULL => 1, PRIMARYKEY => 1,},
+ flag_id => {
+ TYPE => 'INT3',
+ NOTNULL => 1,
+ REFERENCES => {TABLE => 'flags', COLUMN => 'id', DELETE => 'CASCADE',}
+ },
+ defer_until => {TYPE => 'DATETIME', NOTNULL => 1,},
+ ],
+ INDEXES => [nag_defer_idx => {FIELDS => ['flag_id'], TYPE => 'UNIQUE',},],
+ };
+ $args->{'schema'}->{'nag_settings'} = {
+ FIELDS => [
+ id => {TYPE => 'MEDIUMSERIAL', NOTNULL => 1, PRIMARYKEY => 1,},
+ user_id => {
+ TYPE => 'INT3',
+ NOTNULL => 1,
+ REFERENCES => {TABLE => 'profiles', COLUMN => 'userid', DELETE => 'CASCADE',}
+ },
+ setting_name => {TYPE => 'VARCHAR(16)', NOTNULL => 1,},
+ setting_value => {TYPE => 'VARCHAR(16)', NOTNULL => 1,},
+ ],
+ INDEXES => [
+ nag_setting_idx => {FIELDS => ['user_id', 'setting_name'], TYPE => 'UNIQUE',},
+ ],
+ };
}
sub install_update_db {
- my $dbh = Bugzilla->dbh;
- $dbh->bz_add_column('products', 'nag_interval', { TYPE => 'INT2', NOTNULL => 1, DEFAULT => 7 * 24 });
+ my $dbh = Bugzilla->dbh;
+ $dbh->bz_add_column('products', 'nag_interval',
+ {TYPE => 'INT2', NOTNULL => 1, DEFAULT => 7 * 24});
}
sub install_filesystem {
- my ($self, $args) = @_;
- my $files = $args->{'files'};
- my $extensions_dir = bz_locations()->{'extensionsdir'};
- my $script_name = $extensions_dir . "/" . __PACKAGE__->NAME . "/bin/send-request-nags.pl";
- $files->{$script_name} = {
- perms => Bugzilla::Install::Filesystem::WS_EXECUTE
- };
+ my ($self, $args) = @_;
+ my $files = $args->{'files'};
+ my $extensions_dir = bz_locations()->{'extensionsdir'};
+ my $script_name
+ = $extensions_dir . "/" . __PACKAGE__->NAME . "/bin/send-request-nags.pl";
+ $files->{$script_name} = {perms => Bugzilla::Install::Filesystem::WS_EXECUTE};
}
sub install_before_final_checks {
- my ($self, $args) = @_;
- add_setting({
- name => 'request_nagging',
- options => ['on', 'off'],
- default => 'on',
- category => 'Reviews and Needinfo'
- });
+ my ($self, $args) = @_;
+ add_setting({
+ name => 'request_nagging',
+ options => ['on', 'off'],
+ default => 'on',
+ category => 'Reviews and Needinfo'
+ });
}
__PACKAGE__->NAME;