Mostly remove bug_status hardcode, fix some more SQL queries for new schema
parent
e1b83084a1
commit
08136a9c69
|
@ -2855,7 +2855,7 @@ sub statuses_available
|
||||||
}
|
}
|
||||||
|
|
||||||
# *Only* users with (product-specific) "canconfirm" privs can confirm bugs.
|
# *Only* users with (product-specific) "canconfirm" privs can confirm bugs.
|
||||||
if (!$self->status->is_confirmed && !$user->in_group('canconfirm', $self->product_id))
|
if (!$self->status->is_confirmed && !Bugzilla->user->in_group('canconfirm', $self->product_id))
|
||||||
{
|
{
|
||||||
@statuses = grep { !$_->is_confirmed } @statuses;
|
@statuses = grep { !$_->is_confirmed } @statuses;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1431,7 +1431,7 @@ Bugzilla::DB - Database access routines, using L<DBI>
|
||||||
# prepare a query using DB methods
|
# prepare a query using DB methods
|
||||||
my $sth = $dbh->prepare("SELECT " .
|
my $sth = $dbh->prepare("SELECT " .
|
||||||
$dbh->sql_date_format("creation_ts", "%Y%m%d") .
|
$dbh->sql_date_format("creation_ts", "%Y%m%d") .
|
||||||
" FROM bugs WHERE bug_status != 'RESOLVED' " .
|
" FROM bugs WHERE bug_status != 4 " .
|
||||||
$dbh->sql_limit(1));
|
$dbh->sql_limit(1));
|
||||||
|
|
||||||
# Execute the query
|
# Execute the query
|
||||||
|
|
|
@ -157,17 +157,6 @@ sub update
|
||||||
if (exists $changes->{$self->NAME_FIELD})
|
if (exists $changes->{$self->NAME_FIELD})
|
||||||
{
|
{
|
||||||
my ($old, $new) = @{ $changes->{$self->NAME_FIELD} };
|
my ($old, $new) = @{ $changes->{$self->NAME_FIELD} };
|
||||||
if ($self->field->type != FIELD_TYPE_MULTI_SELECT)
|
|
||||||
{
|
|
||||||
$self->field->{has_activity} = 1;
|
|
||||||
$dbh->do(
|
|
||||||
"INSERT INTO bugs_activity (bug_id, who, bug_when, fieldid, added, removed)".
|
|
||||||
" SELECT bug_id, ?, NOW(), ?, ?, ? FROM bugs WHERE $fname = ?", undef,
|
|
||||||
Bugzilla->user->id, $self->field->id, $new, $old, $old
|
|
||||||
);
|
|
||||||
$dbh->do("UPDATE bugs SET $fname = ?, lastdiffed = NOW() WHERE $fname = ?",
|
|
||||||
undef, $new, $old);
|
|
||||||
}
|
|
||||||
if ($old_self->is_default)
|
if ($old_self->is_default)
|
||||||
{
|
{
|
||||||
my $param = $self->DEFAULT_MAP->{$self->field->name};
|
my $param = $self->DEFAULT_MAP->{$self->field->name};
|
||||||
|
|
|
@ -715,6 +715,12 @@ WHERE description LIKE\'%[CC:%\'');
|
||||||
$dbh->bz_add_fk('bugs', $_->name, { TABLE => 'bugs', COLUMN => 'bug_id' });
|
$dbh->bz_add_fk('bugs', $_->name, { TABLE => 'bugs', COLUMN => 'bug_id' });
|
||||||
}
|
}
|
||||||
|
|
||||||
|
# Add is_assigned and is_confirmed columns to bug_status table
|
||||||
|
$dbh->bz_add_column('bug_status', is_assigned => {TYPE => 'BOOLEAN', NOTNULL => 1, DEFAULT => 'TRUE'});
|
||||||
|
$dbh->bz_add_column('bug_status', is_confirmed => {TYPE => 'BOOLEAN', NOTNULL => 1, DEFAULT => 'TRUE'});
|
||||||
|
$dbh->do('UPDATE bug_status SET is_assigned=0 WHERE NOT value=?', undef, 'ASSIGNED');
|
||||||
|
$dbh->do('UPDATE bug_status SET is_confirmed=0 WHERE value=?', undef, 'UNCONFIRMED');
|
||||||
|
|
||||||
################################################################
|
################################################################
|
||||||
# New --TABLE-- changes should go *** A B O V E *** this point #
|
# New --TABLE-- changes should go *** A B O V E *** this point #
|
||||||
################################################################
|
################################################################
|
||||||
|
|
|
@ -128,30 +128,8 @@ sub update
|
||||||
my $dbh = Bugzilla->dbh;
|
my $dbh = Bugzilla->dbh;
|
||||||
$dbh->bz_start_transaction();
|
$dbh->bz_start_transaction();
|
||||||
|
|
||||||
# Not Bugzilla::Field::Choice! It will overwrite other products' bug values
|
|
||||||
my ($changes, $old_self) = Bugzilla::Object::update($self, @_);
|
my ($changes, $old_self) = Bugzilla::Object::update($self, @_);
|
||||||
|
|
||||||
if (exists $changes->{value})
|
|
||||||
{
|
|
||||||
# Record activity
|
|
||||||
$self->field->{has_activity} = 1;
|
|
||||||
$dbh->do(
|
|
||||||
'INSERT INTO bugs_activity (bug_id, who, bug_when, fieldid, added, removed)'.
|
|
||||||
' SELECT bug_id, ?, NOW(), ?, ?, ? FROM bugs WHERE target_milestone = ? AND product_id = ?', undef,
|
|
||||||
Bugzilla->user->id, $self->field->id, $self->name, $changes->{value}->[0], $changes->{value}->[0], $self->product_id
|
|
||||||
);
|
|
||||||
# The milestone value is stored in the bugs table instead of its ID.
|
|
||||||
$dbh->do(
|
|
||||||
'UPDATE bugs SET target_milestone = ?, lastdiffed = NOW() WHERE target_milestone = ? AND product_id = ?',
|
|
||||||
undef, $self->name, $changes->{value}->[0], $self->product_id
|
|
||||||
);
|
|
||||||
# The default milestone also stores the value instead of the ID.
|
|
||||||
$dbh->do(
|
|
||||||
'UPDATE products SET defaultmilestone = ? WHERE id = ? AND defaultmilestone = ?',
|
|
||||||
undef, $self->name, $self->product_id, $changes->{value}->[0]
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
# Fill visibility values
|
# Fill visibility values
|
||||||
$self->set_visibility_values([ $self->product_id ]);
|
$self->set_visibility_values([ $self->product_id ]);
|
||||||
|
|
||||||
|
@ -162,36 +140,41 @@ sub update
|
||||||
return $changes;
|
return $changes;
|
||||||
}
|
}
|
||||||
|
|
||||||
sub remove_from_db {
|
sub remove_from_db
|
||||||
|
{
|
||||||
my $self = shift;
|
my $self = shift;
|
||||||
my $dbh = Bugzilla->dbh;
|
my $dbh = Bugzilla->dbh;
|
||||||
|
|
||||||
# The default milestone cannot be deleted.
|
# The default milestone cannot be deleted.
|
||||||
if ($self->name eq $self->product->default_milestone) {
|
if ($self->id eq $self->product->default_milestone)
|
||||||
|
{
|
||||||
ThrowUserError('milestone_is_default', { milestone => $self });
|
ThrowUserError('milestone_is_default', { milestone => $self });
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($self->bug_count) {
|
if ($self->bug_count)
|
||||||
|
{
|
||||||
# We don't want to delete bugs when deleting a milestone.
|
# We don't want to delete bugs when deleting a milestone.
|
||||||
# Bugs concerned are reassigned to the default milestone.
|
# Bugs concerned are reassigned to the default milestone.
|
||||||
my $bug_ids =
|
my $bug_ids = $dbh->selectcol_arrayref(
|
||||||
$dbh->selectcol_arrayref('SELECT bug_id FROM bugs
|
'SELECT bug_id FROM bugs WHERE product_id = ? AND target_milestone = ?',
|
||||||
WHERE product_id = ? AND target_milestone = ?',
|
undef, ($self->product->id, $self->id)
|
||||||
undef, ($self->product->id, $self->name));
|
);
|
||||||
|
|
||||||
my $timestamp = $dbh->selectrow_array('SELECT NOW()');
|
my $timestamp = $dbh->selectrow_array('SELECT NOW()');
|
||||||
|
|
||||||
$dbh->do('UPDATE bugs SET target_milestone = ?, delta_ts = ?
|
$dbh->do(
|
||||||
WHERE ' . $dbh->sql_in('bug_id', $bug_ids),
|
'UPDATE bugs SET target_milestone = ?, delta_ts = ? WHERE ' . $dbh->sql_in('bug_id', $bug_ids),
|
||||||
undef, ($self->product->default_milestone, $timestamp));
|
undef, ($self->product->default_milestone, $timestamp)
|
||||||
|
);
|
||||||
|
|
||||||
require Bugzilla::Bug;
|
require Bugzilla::Bug;
|
||||||
import Bugzilla::Bug qw(LogActivityEntry);
|
my $def = Bugzilla::Milestone->new($self->product->default_milestone);
|
||||||
foreach my $bug_id (@$bug_ids) {
|
foreach my $bug_id (@$bug_ids)
|
||||||
LogActivityEntry($bug_id, 'target_milestone',
|
{
|
||||||
$self->name,
|
Bugzilla::Bug::LogActivityEntry(
|
||||||
$self->product->default_milestone,
|
$bug_id, 'target_milestone', $self->name,
|
||||||
Bugzilla->user->id, $timestamp);
|
$def && $def->name, Bugzilla->user->id, $timestamp
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -249,17 +232,19 @@ sub _check_product {
|
||||||
sub set_name { $_[0]->set('value', $_[1]); }
|
sub set_name { $_[0]->set('value', $_[1]); }
|
||||||
sub set_sortkey { $_[0]->set('sortkey', $_[1]); }
|
sub set_sortkey { $_[0]->set('sortkey', $_[1]); }
|
||||||
|
|
||||||
sub bug_count {
|
sub bug_count
|
||||||
|
{
|
||||||
my $self = shift;
|
my $self = shift;
|
||||||
my $dbh = Bugzilla->dbh;
|
my $dbh = Bugzilla->dbh;
|
||||||
|
|
||||||
if (!defined $self->{'bug_count'}) {
|
if (!defined $self->{bug_count})
|
||||||
$self->{'bug_count'} = $dbh->selectrow_array(q{
|
{
|
||||||
SELECT COUNT(*) FROM bugs
|
$self->{bug_count} = $dbh->selectrow_array(
|
||||||
WHERE product_id = ? AND target_milestone = ?},
|
"SELECT COUNT(*) FROM bugs WHERE product_id = ? AND target_milestone = ?",
|
||||||
undef, $self->product_id, $self->name) || 0;
|
undef, $self->product_id, $self->id
|
||||||
|
) || 0;
|
||||||
}
|
}
|
||||||
return $self->{'bug_count'};
|
return $self->{bug_count};
|
||||||
}
|
}
|
||||||
|
|
||||||
################################
|
################################
|
||||||
|
|
|
@ -1,5 +1,3 @@
|
||||||
# -*- Mode: perl; indent-tabs-mode: nil -*-
|
|
||||||
#
|
|
||||||
# The contents of this file are subject to the Mozilla Public
|
# The contents of this file are subject to the Mozilla Public
|
||||||
# License Version 1.1 (the "License"); you may not use this file
|
# License Version 1.1 (the "License"); you may not use this file
|
||||||
# except in compliance with the License. You may obtain a copy of
|
# except in compliance with the License. You may obtain a copy of
|
||||||
|
@ -17,6 +15,8 @@
|
||||||
# Andreas Franke <afranke@mathweb.org>
|
# Andreas Franke <afranke@mathweb.org>
|
||||||
# Stephen Lee <slee@uk.bnsmc.com>
|
# Stephen Lee <slee@uk.bnsmc.com>
|
||||||
# Marc Schumann <wurblzap@gmail.com>
|
# Marc Schumann <wurblzap@gmail.com>
|
||||||
|
#
|
||||||
|
# Refactoring by Vitaliy Filippov <vitalif@mail.ru>
|
||||||
|
|
||||||
package Bugzilla::Search::Quicksearch;
|
package Bugzilla::Search::Quicksearch;
|
||||||
|
|
||||||
|
|
|
@ -45,10 +45,15 @@ use constant SPECIAL_STATUS_WORKFLOW_ACTIONS => qw(
|
||||||
use constant DB_TABLE => 'bug_status';
|
use constant DB_TABLE => 'bug_status';
|
||||||
use constant FIELD_NAME => 'bug_status';
|
use constant FIELD_NAME => 'bug_status';
|
||||||
|
|
||||||
# This has all the standard Bugzilla::Field::Choice columns plus "is_open"
|
# This has all the standard Bugzilla::Field::Choice columns plus some new ones
|
||||||
sub DB_COLUMNS
|
sub DB_COLUMNS
|
||||||
{
|
{
|
||||||
return ($_[0]->SUPER::DB_COLUMNS, 'is_open');
|
return ($_[0]->SUPER::DB_COLUMNS, qw(is_open is_assigned is_confirmed));
|
||||||
|
}
|
||||||
|
|
||||||
|
sub UPDATE_COLUMNS
|
||||||
|
{
|
||||||
|
return ($_[0]->SUPER::UPDATE_COLUMNS, qw(is_open is_assigned is_confirmed));
|
||||||
}
|
}
|
||||||
|
|
||||||
sub VALIDATORS
|
sub VALIDATORS
|
||||||
|
@ -56,6 +61,8 @@ sub VALIDATORS
|
||||||
my $invocant = shift;
|
my $invocant = shift;
|
||||||
my $validators = $invocant->SUPER::VALIDATORS;
|
my $validators = $invocant->SUPER::VALIDATORS;
|
||||||
$validators->{is_open} = \&Bugzilla::Object::check_boolean;
|
$validators->{is_open} = \&Bugzilla::Object::check_boolean;
|
||||||
|
$validators->{is_assigned} = \&Bugzilla::Object::check_boolean;
|
||||||
|
$validators->{is_confirmed} = \&Bugzilla::Object::check_boolean;
|
||||||
$validators->{value} = \&_check_value;
|
$validators->{value} = \&_check_value;
|
||||||
return $validators;
|
return $validators;
|
||||||
}
|
}
|
||||||
|
@ -91,15 +98,13 @@ sub remove_from_db
|
||||||
|
|
||||||
sub is_active { return $_[0]->{isactive}; }
|
sub is_active { return $_[0]->{isactive}; }
|
||||||
sub is_open { return $_[0]->{is_open}; }
|
sub is_open { return $_[0]->{is_open}; }
|
||||||
|
sub is_assigned { return $_[0]->{is_assigned}; }
|
||||||
|
sub is_confirmed { return $_[0]->{is_confirmed}; }
|
||||||
|
|
||||||
sub is_static
|
sub is_static
|
||||||
{
|
{
|
||||||
my $self = shift;
|
my $self = shift;
|
||||||
if ($self->name eq 'UNCONFIRMED' || $self->name eq Bugzilla->params->{duplicate_or_move_bug_status})
|
return $self->name eq Bugzilla->params->{duplicate_or_move_bug_status} ? 1 : 0;
|
||||||
{
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
##############
|
##############
|
||||||
|
|
|
@ -936,8 +936,7 @@ sub create {
|
||||||
'user' => sub { return Bugzilla->user; },
|
'user' => sub { return Bugzilla->user; },
|
||||||
|
|
||||||
# Currenly active language
|
# Currenly active language
|
||||||
# XXX Eventually this should probably be replaced with something
|
# FIXME Eventually this should probably be replaced with something like Bugzilla->language.
|
||||||
# like Bugzilla->language.
|
|
||||||
'current_language' => sub {
|
'current_language' => sub {
|
||||||
my ($language) = include_languages();
|
my ($language) = include_languages();
|
||||||
return $language;
|
return $language;
|
||||||
|
|
|
@ -1549,17 +1549,19 @@ sub wants_bug_mail {
|
||||||
$wants_mail &= $self->wants_mail([EVT_CHANGED_BY_ME], $relationship);
|
$wants_mail &= $self->wants_mail([EVT_CHANGED_BY_ME], $relationship);
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($wants_mail) {
|
if ($wants_mail)
|
||||||
|
{
|
||||||
my $dbh = Bugzilla->dbh;
|
my $dbh = Bugzilla->dbh;
|
||||||
# We don't create a Bug object from the bug_id here because we only
|
# We don't create a Bug object from the bug_id here because we only
|
||||||
# need one piece of information, and doing so (as of 2004-11-23) slows
|
# need one piece of information, and doing so (as of 2004-11-23) slows
|
||||||
# down bugmail sending by a factor of 2. If Bug creation was more
|
# down bugmail sending by a factor of 2. If Bug creation was more
|
||||||
# lazy, this might not be so bad.
|
# lazy, this might not be so bad.
|
||||||
my $bug_status = $dbh->selectrow_array('SELECT bug_status
|
# FIXME: db abstraction?... or cache this value?...
|
||||||
FROM bugs WHERE bug_id = ?',
|
my ($is_confirmed) = $dbh->selectrow_array(
|
||||||
undef, $bug_id);
|
'SELECT bs.is_confirmed FROM bugs b, bug_status bs WHERE b.bug_id=? AND bs.id=b.bug_status', undef, $bug_id
|
||||||
|
);
|
||||||
if ($bug_status eq "UNCONFIRMED") {
|
if (!$is_confirmed)
|
||||||
|
{
|
||||||
$wants_mail &= $self->wants_mail([EVT_UNCONFIRMED], $relationship);
|
$wants_mail &= $self->wants_mail([EVT_UNCONFIRMED], $relationship);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -115,17 +115,18 @@ sub run_create_validators {
|
||||||
return $params;
|
return $params;
|
||||||
}
|
}
|
||||||
|
|
||||||
sub bug_count {
|
sub bug_count
|
||||||
|
{
|
||||||
my $self = shift;
|
my $self = shift;
|
||||||
my $dbh = Bugzilla->dbh;
|
my $dbh = Bugzilla->dbh;
|
||||||
|
if (!defined $self->{bug_count})
|
||||||
if (!defined $self->{'bug_count'}) {
|
{
|
||||||
$self->{'bug_count'} = $dbh->selectrow_array(qq{
|
$self->{bug_count} = $dbh->selectrow_array(
|
||||||
SELECT COUNT(*) FROM bugs
|
"SELECT COUNT(*) FROM bugs WHERE product_id = ? AND version = ?",
|
||||||
WHERE product_id = ? AND version = ?}, undef,
|
undef, ($self->product_id, $self->id)
|
||||||
($self->product_id, $self->name)) || 0;
|
) || 0;
|
||||||
}
|
}
|
||||||
return $self->{'bug_count'};
|
return $self->{bug_count};
|
||||||
}
|
}
|
||||||
|
|
||||||
sub create
|
sub create
|
||||||
|
@ -149,25 +150,8 @@ sub update
|
||||||
my $dbh = Bugzilla->dbh;
|
my $dbh = Bugzilla->dbh;
|
||||||
$dbh->bz_start_transaction();
|
$dbh->bz_start_transaction();
|
||||||
|
|
||||||
# Not Bugzilla::Field::Choice! It will overwrite other products' bug values
|
|
||||||
my ($changes, $old_self) = Bugzilla::Object::update($self, @_);
|
my ($changes, $old_self) = Bugzilla::Object::update($self, @_);
|
||||||
|
|
||||||
if (exists $changes->{value})
|
|
||||||
{
|
|
||||||
# Record activity
|
|
||||||
$self->field->{has_activity} = 1;
|
|
||||||
$dbh->do(
|
|
||||||
'INSERT INTO bugs_activity (bug_id, who, bug_when, fieldid, added, removed)'.
|
|
||||||
' SELECT bug_id, ?, NOW(), ?, ?, ? FROM bugs WHERE version = ? AND product_id = ?', undef,
|
|
||||||
Bugzilla->user->id, $self->field->id, $self->name, $old_self->name, $old_self->name, $self->product_id
|
|
||||||
);
|
|
||||||
# Rename version
|
|
||||||
$dbh->do(
|
|
||||||
'UPDATE bugs SET version = ?, lastdiffed = NOW() WHERE version = ? AND product_id = ?',
|
|
||||||
undef, $self->name, $old_self->name, $self->product_id
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
# Fill visibility values
|
# Fill visibility values
|
||||||
$self->set_visibility_values([ $self->product_id ]);
|
$self->set_visibility_values([ $self->product_id ]);
|
||||||
|
|
||||||
|
@ -178,13 +162,13 @@ sub update
|
||||||
return $changes;
|
return $changes;
|
||||||
}
|
}
|
||||||
|
|
||||||
sub remove_from_db {
|
sub remove_from_db
|
||||||
|
{
|
||||||
my $self = shift;
|
my $self = shift;
|
||||||
my $dbh = Bugzilla->dbh;
|
my $dbh = Bugzilla->dbh;
|
||||||
|
# The version cannot be removed if there are bugs associated with it.
|
||||||
# The version cannot be removed if there are bugs
|
if ($self->bug_count)
|
||||||
# associated with it.
|
{
|
||||||
if ($self->bug_count) {
|
|
||||||
ThrowUserError("version_has_bugs", { nb => $self->bug_count });
|
ThrowUserError("version_has_bugs", { nb => $self->bug_count });
|
||||||
}
|
}
|
||||||
# Remove visibility values
|
# Remove visibility values
|
||||||
|
|
|
@ -1184,7 +1184,9 @@ $vars->{columns} = $columns;
|
||||||
$vars->{displaycolumns} = \@displaycolumns;
|
$vars->{displaycolumns} = \@displaycolumns;
|
||||||
|
|
||||||
$vars->{openstates} = [BUG_STATE_OPEN];
|
$vars->{openstates} = [BUG_STATE_OPEN];
|
||||||
$vars->{closedstates} = [map {$_->name} closed_bug_statuses()];
|
# used by list.ics.tmpl
|
||||||
|
$vars->{assignedstates} = [ map { $_->name } grep { $_->is_active && $_->is_assigned } Bugzilla::Status->get_all ];
|
||||||
|
$vars->{closedstates} = [ map { $_->name } closed_bug_statuses() ];
|
||||||
|
|
||||||
# The iCal file needs priorities ordered from 1 to 9 (highest to lowest)
|
# The iCal file needs priorities ordered from 1 to 9 (highest to lowest)
|
||||||
# If there are more than 9 values, just make all the lower ones 9
|
# If there are more than 9 values, just make all the lower ones 9
|
||||||
|
|
|
@ -118,9 +118,9 @@ my @resolutions = @{$fields->{'resolution'}};
|
||||||
my (%bug_status, %bug_resolution, %removed);
|
my (%bug_status, %bug_resolution, %removed);
|
||||||
if ($regenerate) {
|
if ($regenerate) {
|
||||||
%bug_resolution = @{ $dbh->selectcol_arrayref(
|
%bug_resolution = @{ $dbh->selectcol_arrayref(
|
||||||
'SELECT bug_id, resolution FROM bugs', {Columns=>[1,2]}) };
|
'SELECT bug_id, resolution.value FROM bugs LEFT JOIN resolution ON resolution.id=bugs.resolution', {Columns=>[1,2]}) };
|
||||||
%bug_status = @{ $dbh->selectcol_arrayref(
|
%bug_status = @{ $dbh->selectcol_arrayref(
|
||||||
'SELECT bug_id, bug_status FROM bugs', {Columns=>[1,2]}) };
|
'SELECT bug_id, bug_status.value FROM bugs LEFT JOIN bug_status ON bug_status.id=bugs.bug_status', {Columns=>[1,2]}) };
|
||||||
|
|
||||||
my $removed_sth = $dbh->prepare(
|
my $removed_sth = $dbh->prepare(
|
||||||
q{SELECT bugs_activity.bug_id, bugs_activity.removed,}
|
q{SELECT bugs_activity.bug_id, bugs_activity.removed,}
|
||||||
|
@ -209,8 +209,8 @@ sub collect_stats {
|
||||||
|
|
||||||
# Now collect current data.
|
# Now collect current data.
|
||||||
my @row = (today());
|
my @row = (today());
|
||||||
my $status_sql = q{SELECT COUNT(*) FROM bugs WHERE bug_status = ?};
|
my $status_sql = q{SELECT COUNT(*) FROM bugs, bug_status WHERE bugs.bug_status=bug_status.id AND bug_status.value = ?};
|
||||||
my $reso_sql = q{SELECT COUNT(*) FROM bugs WHERE resolution = ?};
|
my $reso_sql = q{SELECT COUNT(*) FROM bugs, resolution WHERE bugs.resolution=resolution.id AND resolution.value = ?};
|
||||||
|
|
||||||
if ($product ne '-All-') {
|
if ($product ne '-All-') {
|
||||||
$status_sql .= q{ AND product_id = ?};
|
$status_sql .= q{ AND product_id = ?};
|
||||||
|
|
|
@ -180,10 +180,11 @@ my %since_dups = @{$dbh->selectcol_arrayref(
|
||||||
"SELECT dupe_of, COUNT(dupe)
|
"SELECT dupe_of, COUNT(dupe)
|
||||||
FROM duplicates INNER JOIN bugs_activity
|
FROM duplicates INNER JOIN bugs_activity
|
||||||
ON bugs_activity.bug_id = duplicates.dupe
|
ON bugs_activity.bug_id = duplicates.dupe
|
||||||
WHERE added = 'DUPLICATE' AND fieldid = ?
|
WHERE added = ? AND fieldid = ?
|
||||||
AND bug_when >= LOCALTIMESTAMP(0) - "
|
AND bug_when >= LOCALTIMESTAMP(0) - "
|
||||||
. $dbh->sql_interval('?', 'DAY') .
|
. $dbh->sql_interval('?', 'DAY') .
|
||||||
" GROUP BY dupe_of", {Columns=>[1,2]},
|
" GROUP BY dupe_of", {Columns=>[1,2]},
|
||||||
|
Bugzilla->params->{duplicate_resolution},
|
||||||
$reso_field_id, $changedsince)};
|
$reso_field_id, $changedsince)};
|
||||||
add_indirect_dups(\%since_dups, \%dupe_relation);
|
add_indirect_dups(\%since_dups, \%dupe_relation);
|
||||||
|
|
||||||
|
|
|
@ -311,6 +311,7 @@ if ($action eq 'update') {
|
||||||
$vars->{'classification'} = new Bugzilla::Classification($product->classification_id);
|
$vars->{'classification'} = new Bugzilla::Classification($product->classification_id);
|
||||||
}
|
}
|
||||||
$vars->{'product'} = $product;
|
$vars->{'product'} = $product;
|
||||||
|
$vars->{unconfirmed_states} = [ map { $_->name } grep { !$_->is_confirmed } Bugzilla::Status->get_all ];
|
||||||
$vars->{'changes'} = $changes;
|
$vars->{'changes'} = $changes;
|
||||||
|
|
||||||
$template->process("admin/products/updated.html.tmpl", $vars)
|
$template->process("admin/products/updated.html.tmpl", $vars)
|
||||||
|
|
|
@ -212,20 +212,17 @@ if ($action eq 'update')
|
||||||
{
|
{
|
||||||
check_token_data($token, 'edit_field_value');
|
check_token_data($token, 'edit_field_value');
|
||||||
$vars->{value_old} = $value->name;
|
$vars->{value_old} = $value->name;
|
||||||
if ($value->can('set_timetracking'))
|
for ($value->UPDATE_COLUMNS)
|
||||||
{
|
{
|
||||||
$value->set_timetracking($ARGS->{timetracking} ? 1 : 0);
|
if ($_ ne 'isactive' && $_ ne $value->NAME_FIELD || !$value->is_static && !$value->is_default)
|
||||||
}
|
|
||||||
$value->set_sortkey($ARGS->{sortkey});
|
|
||||||
if (!($value->is_static || $value->is_default))
|
|
||||||
{
|
|
||||||
$value->set_is_active($ARGS->{is_active});
|
|
||||||
$value->set_name($ARGS->{value_new});
|
|
||||||
if ($value->field->value_field)
|
|
||||||
{
|
{
|
||||||
$vars->{changes}->{visibility_values} = $value->set_visibility_values($ARGS->{visibility_value_id});
|
$value->set($_, $ARGS->{$_ eq $value->NAME_FIELD ? 'value_new' : $_});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (!($value->is_static || $value->is_default) && $value->field->value_field)
|
||||||
|
{
|
||||||
|
$vars->{changes}->{visibility_values} = $value->set_visibility_values($ARGS->{visibility_value_id});
|
||||||
|
}
|
||||||
delete_token($token);
|
delete_token($token);
|
||||||
$vars->{changes} = $value->update;
|
$vars->{changes} = $value->update;
|
||||||
$vars->{message} = 'field_value_updated';
|
$vars->{message} = 'field_value_updated';
|
||||||
|
|
|
@ -85,7 +85,7 @@ elsif ($action eq 'update') {
|
||||||
|
|
||||||
# Part 1: Initial bug statuses.
|
# Part 1: Initial bug statuses.
|
||||||
foreach my $new (@$statuses) {
|
foreach my $new (@$statuses) {
|
||||||
if (($new->is_open || $new->name eq 'RESOLVED') && $cgi->param('w_0_' . $new->id)) {
|
if (($new->is_open || $new->name eq Bugzilla->params->{duplicate_or_move_bug_status}) && $cgi->param('w_0_' . $new->id)) {
|
||||||
$sth_insert->execute(undef, $new->id)
|
$sth_insert->execute(undef, $new->id)
|
||||||
unless defined $workflow->{0}->{$new->id};
|
unless defined $workflow->{0}->{$new->id};
|
||||||
}
|
}
|
||||||
|
|
|
@ -645,12 +645,12 @@ my $initial_statuses = Bugzilla::Status->can_change_to();
|
||||||
|
|
||||||
# Exclude closed states from the UI, even if the workflow allows them.
|
# Exclude closed states from the UI, even if the workflow allows them.
|
||||||
# The back-end code will still accept them, though.
|
# The back-end code will still accept them, though.
|
||||||
@$initial_statuses = grep { $_->name eq 'RESOLVED' || $_->is_open } @$initial_statuses;
|
@$initial_statuses = grep { $_->name eq Bugzilla->params->{duplicate_or_move_bug_status} || $_->is_open } @$initial_statuses;
|
||||||
|
|
||||||
if (!$product->allows_unconfirmed)
|
if (!$product->allows_unconfirmed)
|
||||||
{
|
{
|
||||||
# UNCONFIRMED is illegal if allows_unconfirmed is false.
|
# UNCONFIRMED is illegal if allows_unconfirmed is false.
|
||||||
@$initial_statuses = grep { $_->name ne 'UNCONFIRMED' } @$initial_statuses;
|
@$initial_statuses = grep { $_->is_confirmed } @$initial_statuses;
|
||||||
}
|
}
|
||||||
scalar(@$initial_statuses) || ThrowUserError('no_initial_bug_status');
|
scalar(@$initial_statuses) || ThrowUserError('no_initial_bug_status');
|
||||||
|
|
||||||
|
@ -658,7 +658,8 @@ scalar(@$initial_statuses) || ThrowUserError('no_initial_bug_status');
|
||||||
unless ($has_editbugs || $has_canconfirm)
|
unless ($has_editbugs || $has_canconfirm)
|
||||||
{
|
{
|
||||||
# ... use UNCONFIRMED if available, else use the first status of the list.
|
# ... use UNCONFIRMED if available, else use the first status of the list.
|
||||||
my $bug_status = (grep { $_->name eq 'UNCONFIRMED' } @$initial_statuses) ? 'UNCONFIRMED' : $initial_statuses->[0];
|
my ($bug_status) = grep { !$_->is_confirmed } @$initial_statuses;
|
||||||
|
$bug_status ||= $initial_statuses->[0];
|
||||||
@$initial_statuses = ($bug_status);
|
@$initial_statuses = ($bug_status);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -919,7 +919,7 @@ sub process_bug {
|
||||||
# entry in the dup table. Since we can't tell the bug ID of bugs
|
# entry in the dup table. Since we can't tell the bug ID of bugs
|
||||||
# that might not yet be in the database we have no way of populating
|
# that might not yet be in the database we have no way of populating
|
||||||
# this table. Change the resolution instead.
|
# this table. Change the resolution instead.
|
||||||
if ( $valid_res && ( $bug_fields{'resolution'} eq "DUPLICATE" ) ) {
|
if ( $valid_res && ( $bug_fields{'resolution'} eq 'DUPLICATE' ) ) {
|
||||||
$resolution = "MOVED";
|
$resolution = "MOVED";
|
||||||
$err .= "This bug was marked DUPLICATE in the database ";
|
$err .= "This bug was marked DUPLICATE in the database ";
|
||||||
$err .= "it was moved from.\n Changing resolution to \"MOVED\"\n";
|
$err .= "it was moved from.\n Changing resolution to \"MOVED\"\n";
|
||||||
|
@ -928,7 +928,7 @@ sub process_bug {
|
||||||
# If there is at least 1 initial bug status different from UNCO, use it,
|
# If there is at least 1 initial bug status different from UNCO, use it,
|
||||||
# else use the open bug status with the lowest sortkey (different from UNCO).
|
# else use the open bug status with the lowest sortkey (different from UNCO).
|
||||||
my @bug_statuses = @{Bugzilla::Status->can_change_to()};
|
my @bug_statuses = @{Bugzilla::Status->can_change_to()};
|
||||||
@bug_statuses = grep { $_->name ne 'UNCONFIRMED' } @bug_statuses;
|
@bug_statuses = grep { $_->is_confirmed } @bug_statuses;
|
||||||
|
|
||||||
my $initial_status;
|
my $initial_status;
|
||||||
if (scalar(@bug_statuses)) {
|
if (scalar(@bug_statuses)) {
|
||||||
|
@ -937,7 +937,7 @@ sub process_bug {
|
||||||
else {
|
else {
|
||||||
@bug_statuses = Bugzilla::Status->get_all();
|
@bug_statuses = Bugzilla::Status->get_all();
|
||||||
# Exclude UNCO and inactive bug statuses.
|
# Exclude UNCO and inactive bug statuses.
|
||||||
@bug_statuses = grep { $_->is_active && $_->name ne 'UNCONFIRMED'} @bug_statuses;
|
@bug_statuses = grep { $_->is_active && $_->is_confirmed } @bug_statuses;
|
||||||
my @open_statuses = grep { $_->is_open } @bug_statuses;
|
my @open_statuses = grep { $_->is_open } @bug_statuses;
|
||||||
if (scalar(@open_statuses)) {
|
if (scalar(@open_statuses)) {
|
||||||
$initial_status = $open_statuses[0]->name;
|
$initial_status = $open_statuses[0]->name;
|
||||||
|
@ -961,6 +961,7 @@ sub process_bug {
|
||||||
$status = $initial_status;
|
$status = $initial_status;
|
||||||
}
|
}
|
||||||
else{
|
else{
|
||||||
|
# FIXME Remove bug_status==UNCONFIRMED hardcode
|
||||||
$status = "UNCONFIRMED";
|
$status = "UNCONFIRMED";
|
||||||
}
|
}
|
||||||
if ($status ne $bug_fields{'bug_status'}){
|
if ($status ne $bug_fields{'bug_status'}){
|
||||||
|
@ -970,6 +971,7 @@ sub process_bug {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if($everconfirmed){
|
if($everconfirmed){
|
||||||
|
# FIXME Remove bug_status==UNCONFIRMED hardcode
|
||||||
if($status eq "UNCONFIRMED"){
|
if($status eq "UNCONFIRMED"){
|
||||||
$err .= "Bug Status was UNCONFIRMED but everconfirmed was true\n";
|
$err .= "Bug Status was UNCONFIRMED but everconfirmed was true\n";
|
||||||
$err .= " Setting status to $initial_status\n";
|
$err .= " Setting status to $initial_status\n";
|
||||||
|
@ -978,6 +980,7 @@ sub process_bug {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else{ # $everconfirmed is false
|
else{ # $everconfirmed is false
|
||||||
|
# FIXME Remove bug_status==UNCONFIRMED hardcode
|
||||||
if($status ne "UNCONFIRMED"){
|
if($status ne "UNCONFIRMED"){
|
||||||
$err .= "Bug Status was $status but everconfirmed was false\n";
|
$err .= "Bug Status was $status but everconfirmed was false\n";
|
||||||
$err .= " Setting status to UNCONFIRMED\n";
|
$err .= " Setting status to UNCONFIRMED\n";
|
||||||
|
|
|
@ -226,6 +226,7 @@ if ($cgi->param('repair_creation_date')) {
|
||||||
if ($cgi->param('repair_everconfirmed')) {
|
if ($cgi->param('repair_everconfirmed')) {
|
||||||
Status('everconfirmed_start');
|
Status('everconfirmed_start');
|
||||||
|
|
||||||
|
# FIXME Remove bug_status==UNCONFIRMED hardcode
|
||||||
my @confirmed_open_states = grep {$_ ne 'UNCONFIRMED'} BUG_STATE_OPEN;
|
my @confirmed_open_states = grep {$_ ne 'UNCONFIRMED'} BUG_STATE_OPEN;
|
||||||
my $confirmed_open_states = join(', ', map {$dbh->quote($_)} @confirmed_open_states);
|
my $confirmed_open_states = join(', ', map {$dbh->quote($_)} @confirmed_open_states);
|
||||||
|
|
||||||
|
|
|
@ -1,25 +1,7 @@
|
||||||
#!/usr/bin/perl -wT
|
#!/usr/bin/perl -wT
|
||||||
# -*- Mode: perl; indent-tabs-mode: nil -*-
|
# (Rewritten) Bug dependency graph display
|
||||||
#
|
# License: Dual-license GPL 3.0+ or MPL 1.1+
|
||||||
# The contents of this file are subject to the Mozilla Public
|
# Author(s): Vitaliy Filippov <vitalif@mail.ru>
|
||||||
# License Version 1.1 (the "License"); you may not use this file
|
|
||||||
# except in compliance with the License. You may obtain a copy of
|
|
||||||
# the License at http://www.mozilla.org/MPL/
|
|
||||||
#
|
|
||||||
# Software distributed under the License is distributed on an "AS
|
|
||||||
# IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
|
|
||||||
# implied. See the License for the specific language governing
|
|
||||||
# rights and limitations under the License.
|
|
||||||
#
|
|
||||||
# The Original Code is the Bugzilla Bug Tracking System.
|
|
||||||
#
|
|
||||||
# The Initial Developer of the Original Code is Netscape Communications
|
|
||||||
# Corporation. Portions created by Netscape are
|
|
||||||
# Copyright (C) 1998 Netscape Communications Corporation. All
|
|
||||||
# Rights Reserved.
|
|
||||||
#
|
|
||||||
# Contributor(s): Terry Weissman <terry@mozilla.org>
|
|
||||||
# Gervase Markham <gerv@gerv.net>
|
|
||||||
|
|
||||||
use utf8;
|
use utf8;
|
||||||
use strict;
|
use strict;
|
||||||
|
@ -44,7 +26,8 @@ my $vars = {};
|
||||||
|
|
||||||
# Check params
|
# Check params
|
||||||
my $display = $cgi->param('display') || 'tree';
|
my $display = $cgi->param('display') || 'tree';
|
||||||
if (!defined $cgi->param('id') && $display ne 'doall') {
|
if (!defined $cgi->param('id') && $display ne 'doall')
|
||||||
|
{
|
||||||
ThrowCodeError("missing_bug_id");
|
ThrowCodeError("missing_bug_id");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -376,24 +359,28 @@ sub GetNodes
|
||||||
my $nodes = {};
|
my $nodes = {};
|
||||||
my $bugtitles = {};
|
my $bugtitles = {};
|
||||||
# Retrieve bug information from the database
|
# Retrieve bug information from the database
|
||||||
|
# FIXME: Use Bugzilla::Search for this query
|
||||||
my $rows = Bugzilla->dbh->selectall_arrayref(
|
my $rows = Bugzilla->dbh->selectall_arrayref(
|
||||||
"SELECT
|
"SELECT
|
||||||
t1.bug_id,
|
t1.bug_id,
|
||||||
t1.bug_status,
|
bs.value bug_status,
|
||||||
t1.resolution,
|
res.value resolution,
|
||||||
t1.short_desc,
|
t1.short_desc,
|
||||||
t1.estimated_time,
|
t1.estimated_time,
|
||||||
SUM(t3.work_time) AS work_time,
|
SUM(t3.work_time) AS work_time,
|
||||||
t1.assigned_to,
|
t1.assigned_to,
|
||||||
t2.login_name AS assigned_to_login,
|
t2.login_name AS assigned_to_login,
|
||||||
t4.name AS product,
|
p.name AS product,
|
||||||
t5.name AS component,
|
c.name AS component,
|
||||||
t1.bug_severity
|
sev.value bug_severity
|
||||||
FROM bugs AS t1
|
FROM bugs AS t1
|
||||||
|
LEFT JOIN bug_status AS bs ON bs.id=t1.bug_status
|
||||||
|
LEFT JOIN resolution AS res ON res.id=t1.resolution
|
||||||
|
LEFT JOIN bug_severity AS sev ON sev.id=t1.bug_severity
|
||||||
LEFT JOIN profiles AS t2 ON t2.userid=t1.assigned_to
|
LEFT JOIN profiles AS t2 ON t2.userid=t1.assigned_to
|
||||||
LEFT JOIN longdescs AS t3 ON t3.bug_id=t1.bug_id AND t3.work_time > 0
|
LEFT JOIN longdescs AS t3 ON t3.bug_id=t1.bug_id AND t3.work_time > 0
|
||||||
LEFT JOIN products AS t4 ON t4.id=t1.product_id
|
LEFT JOIN products AS p ON p.id=t1.product_id
|
||||||
LEFT JOIN components AS t5 ON t5.id=t1.component_id
|
LEFT JOIN components AS c ON c.id=t1.component_id
|
||||||
WHERE t1.bug_id IN (".join(",", ("?") x scalar keys %$seen).")
|
WHERE t1.bug_id IN (".join(",", ("?") x scalar keys %$seen).")
|
||||||
GROUP BY t1.bug_id", {Slice=>{}}, keys %$seen) || {};
|
GROUP BY t1.bug_id", {Slice=>{}}, keys %$seen) || {};
|
||||||
foreach my $row (@$rows)
|
foreach my $row (@$rows)
|
||||||
|
@ -523,7 +510,8 @@ sub CleanupOldDots
|
||||||
# symlinks), this can't escape to delete anything it shouldn't
|
# symlinks), this can't escape to delete anything it shouldn't
|
||||||
# (unless someone moves the location of $webdotdir, of course)
|
# (unless someone moves the location of $webdotdir, of course)
|
||||||
trick_taint($f);
|
trick_taint($f);
|
||||||
if (file_mod_time($f) < $since) {
|
if (file_mod_time($f) < $since)
|
||||||
|
{
|
||||||
unlink $f;
|
unlink $f;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -533,6 +521,7 @@ sub GetColorByState
|
||||||
{
|
{
|
||||||
my ($state, $base) = (@_);
|
my ($state, $base) = (@_);
|
||||||
$base = $base ? 0 : 0x40;
|
$base = $base ? 0 : 0x40;
|
||||||
|
# FIXME Remove bug_status hardcode
|
||||||
my %colorbystate = (
|
my %colorbystate = (
|
||||||
UNCONFIRMED => 'ffffff',
|
UNCONFIRMED => 'ffffff',
|
||||||
NEW => 'ff8000',
|
NEW => 'ff8000',
|
||||||
|
|
|
@ -94,6 +94,7 @@ td.bz_total {
|
||||||
.bz_buglist .bz_dependson_column { width: 8%; white-space: normal; }
|
.bz_buglist .bz_dependson_column { width: 8%; white-space: normal; }
|
||||||
|
|
||||||
/* Bug states - duplicated here for external stylesheet usage */
|
/* Bug states - duplicated here for external stylesheet usage */
|
||||||
|
/* FIXME: remove bug_status hardcode */
|
||||||
.bz_st_UNCONFIRMED, .bz_UNCONFIRMED td.first-child a { font-style: italic; }
|
.bz_st_UNCONFIRMED, .bz_UNCONFIRMED td.first-child a { font-style: italic; }
|
||||||
.bz_st_RESOLVED, .bz_RESOLVED td.first-child a { text-decoration: line-through; }
|
.bz_st_RESOLVED, .bz_RESOLVED td.first-child a { text-decoration: line-through; }
|
||||||
.bz_st_VERIFIED, .bz_VERIFIED td.first-child a { text-decoration: line-through; border: 1px dashed #2f6fab; margin: 0 -1px; color: black; background-color: #f9f9f9; line-height: 1.1em; }
|
.bz_st_VERIFIED, .bz_VERIFIED td.first-child a { text-decoration: line-through; border: 1px dashed #2f6fab; margin: 0 -1px; color: black; background-color: #f9f9f9; line-height: 1.1em; }
|
||||||
|
|
|
@ -504,6 +504,7 @@ form#Create .comment {
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Bug states */
|
/* Bug states */
|
||||||
|
/* FIXME remove bug_status hardcode */
|
||||||
.bz_st_UNCONFIRMED, .bz_UNCONFIRMED td.first-child a { font-style: italic; }
|
.bz_st_UNCONFIRMED, .bz_UNCONFIRMED td.first-child a { font-style: italic; }
|
||||||
.bz_st_RESOLVED, .bz_RESOLVED td.first-child a { text-decoration: line-through; }
|
.bz_st_RESOLVED, .bz_RESOLVED td.first-child a { text-decoration: line-through; }
|
||||||
.bz_st_VERIFIED, .bz_VERIFIED td.first-child a { text-decoration: line-through; border: 1px dashed #2f6fab; margin: 0 -1px; color: black; background-color: #f9f9f9; line-height: 1.1em; }
|
.bz_st_VERIFIED, .bz_VERIFIED td.first-child a { text-decoration: line-through; border: 1px dashed #2f6fab; margin: 0 -1px; color: black; background-color: #f9f9f9; line-height: 1.1em; }
|
||||||
|
|
|
@ -142,7 +142,7 @@ document.write('<input type="button" value="Disable All Mail" onclick="SetCheckb
|
||||||
|
|
||||||
[% neg_events = [
|
[% neg_events = [
|
||||||
{ id = constants.EVT_UNCONFIRMED,
|
{ id = constants.EVT_UNCONFIRMED,
|
||||||
description = "The $terms.bug is in the UNCONFIRMED state" },
|
description = "The $terms.bug is in the unconfirmed state" },
|
||||||
{ id = constants.EVT_CHANGED_BY_ME,
|
{ id = constants.EVT_CHANGED_BY_ME,
|
||||||
description = "The change was made by me" },
|
description = "The change was made by me" },
|
||||||
] %]
|
] %]
|
||||||
|
|
|
@ -30,7 +30,7 @@
|
||||||
<table border="0" cellpadding="4" cellspacing="0">
|
<table border="0" cellpadding="4" cellspacing="0">
|
||||||
|
|
||||||
<tr>
|
<tr>
|
||||||
<th valign="top" align="right">
|
<th valign="top" align="left">
|
||||||
<label for="value_new">Field Value:</label>
|
<label for="value_new">Field Value:</label>
|
||||||
</th>
|
</th>
|
||||||
<td>
|
<td>
|
||||||
|
@ -46,19 +46,33 @@
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
<th align="right"><label for="sortkey">Sortkey:</label></th>
|
<th align="left"><label for="sortkey">Sortkey:</label></th>
|
||||||
<td><input id="sortkey" size="6" maxlength="6" name="sortkey"
|
<td><input id="sortkey" size="6" maxlength="6" name="sortkey"
|
||||||
value="[%- value.sortkey FILTER html %]" /></td>
|
value="[%- value.sortkey FILTER html %]" /></td>
|
||||||
</tr>
|
</tr>
|
||||||
[% IF field.name == "bug_status" %]
|
[% IF field.name == "bug_status" %]
|
||||||
<tr>
|
<tr>
|
||||||
<th align="right"><label for="is_open">Status Type:</label></th>
|
<th align="left"><label for="is_open">Status Type:</label></th>
|
||||||
<td>[% IF value.is_open %]Open[% ELSE %]Closed[% END %]</td>
|
<td>[% IF value.is_open %]Open[% ELSE %]Closed[% END %]</td>
|
||||||
</tr>
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<th align="left"><label for="is_assigned">Is it an assigned state?</label></th>
|
||||||
|
<td>
|
||||||
|
<input id="is_assigned" name="is_assigned" type="checkbox" value="1"
|
||||||
|
[%+ 'checked="checked"' IF value.is_assigned %] />
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<th align="left"><label for="is_confirmed">Is it a confirmed state?</label></th>
|
||||||
|
<td>
|
||||||
|
<input id="is_confirmed" name="is_confirmed" type="checkbox" value="1"
|
||||||
|
[%+ 'checked="checked"' IF value.is_confirmed %] />
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
[% END %]
|
[% END %]
|
||||||
[% IF field.value_field && !value.is_static %]
|
[% IF field.value_field && !value.is_static %]
|
||||||
<tr>
|
<tr>
|
||||||
<th align="right">
|
<th align="left">
|
||||||
Only appears when [%+ field.value_field.description FILTER html %] is set to:
|
Only appears when [%+ field.value_field.description FILTER html %] is set to:
|
||||||
</th>
|
</th>
|
||||||
<td>
|
<td>
|
||||||
|
@ -79,10 +93,10 @@
|
||||||
</tr>
|
</tr>
|
||||||
[% END %]
|
[% END %]
|
||||||
<tr>
|
<tr>
|
||||||
<th align="right"><label for="is_active">Enabled for [% terms.bugs %]:</label></th>
|
<th align="left"><label for="isactive">Enabled for [% terms.bugs %]:</label></th>
|
||||||
<td>
|
<td>
|
||||||
<input id="is_active" name="is_active" type="checkbox" value="1"
|
<input id="isactive" name="isactive" type="checkbox" value="1"
|
||||||
[%+ 'checked="checked"' IF value.is_active %]
|
[%+ 'checked="checked"' IF value.isactive %]
|
||||||
[%+ 'disabled="disabled"' IF value.is_default OR value.is_static %] />
|
[%+ 'disabled="disabled"' IF value.is_default OR value.is_static %] />
|
||||||
[% IF value.is_default %]
|
[% IF value.is_default %]
|
||||||
This value is selected as default in the parameters for this field. It cannot be disabled.
|
This value is selected as default in the parameters for this field. It cannot be disabled.
|
||||||
|
|
|
@ -49,9 +49,8 @@
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
<th align="right">
|
<th align="right">
|
||||||
<label for="allows_unconfirmed">Enable the
|
<label for="allows_unconfirmed">Enable unconfirmed
|
||||||
UNCONFIRMED status
|
bug state(s) in this product:</label>
|
||||||
in this product:</label>
|
|
||||||
</th>
|
</th>
|
||||||
<td><input type="checkbox" id="allows_unconfirmed" name="allows_unconfirmed"
|
<td><input type="checkbox" id="allows_unconfirmed" name="allows_unconfirmed"
|
||||||
[% ' checked="checked"' IF product.allows_unconfirmed %]
|
[% ' checked="checked"' IF product.allows_unconfirmed %]
|
||||||
|
|
|
@ -104,16 +104,13 @@
|
||||||
[% IF changes.allows_unconfirmed.defined %]
|
[% IF changes.allows_unconfirmed.defined %]
|
||||||
<p>
|
<p>
|
||||||
[% IF product.allows_unconfirmed %]
|
[% IF product.allows_unconfirmed %]
|
||||||
The product now allows the
|
The product now allows unconfirmed states.
|
||||||
UNCONFIRMED status.
|
|
||||||
[% ELSE %]
|
[% ELSE %]
|
||||||
The product no longer allows the
|
The product no longer allows unconfirmed states.
|
||||||
UNCONFIRMED status.
|
|
||||||
Note that any
|
Note that any
|
||||||
<a href="buglist.cgi?product=
|
<a href="buglist.cgi?product=[%- product.name FILTER url_quote %][% FOR s = unconfirmed_states %]&bug_status=[% s | url_quote %][% END %]">
|
||||||
[%- product.name FILTER url_quote %]&bug_status=UNCONFIRMED">
|
[%- terms.bugs %] that currently have unconfirmed states
|
||||||
[%- terms.bugs %] that currently have the
|
</a>
|
||||||
UNCONFIRMED status</a>
|
|
||||||
will remain in that status until they are edited.
|
will remain in that status until they are edited.
|
||||||
[% END %]
|
[% END %]
|
||||||
</p>
|
</p>
|
||||||
|
|
|
@ -30,6 +30,7 @@
|
||||||
//-->
|
//-->
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
[%# FIXME Check if this is correct about 'one of either UNCONFIRMED or REOPENED' %]
|
||||||
<p>
|
<p>
|
||||||
This page allows you to define which status transitions are valid in your workflow.
|
This page allows you to define which status transitions are valid in your workflow.
|
||||||
For compatibility with older versions of [% terms.Bugzilla %], reopening [% terms.abug %]
|
For compatibility with older versions of [% terms.Bugzilla %], reopening [% terms.abug %]
|
||||||
|
@ -66,7 +67,7 @@
|
||||||
</th>
|
</th>
|
||||||
|
|
||||||
[% FOREACH new_status = statuses %]
|
[% FOREACH new_status = statuses %]
|
||||||
[% IF status.id != new_status.id && (status.id || new_status.name == 'RESOLVED' || new_status.is_open) %]
|
[% IF status.id != new_status.id && (status.id || new_status.name == Param('duplicate_or_move_bug_status') || new_status.is_open) %]
|
||||||
[% checked = workflow.${status.id}.${new_status.id}.defined ? 1 : 0 %]
|
[% checked = workflow.${status.id}.${new_status.id}.defined ? 1 : 0 %]
|
||||||
[% mandatory = (status.id && new_status.name == Param("duplicate_or_move_bug_status")) ? 1 : 0 %]
|
[% mandatory = (status.id && new_status.name == Param("duplicate_or_move_bug_status")) ? 1 : 0 %]
|
||||||
<td align="center" class="checkbox-cell[% " checked" IF checked || mandatory %]"
|
<td align="center" class="checkbox-cell[% " checked" IF checked || mandatory %]"
|
||||||
|
|
|
@ -78,11 +78,7 @@
|
||||||
</tr>
|
</tr>
|
||||||
[% END %]
|
[% END %]
|
||||||
|
|
||||||
[% bug_statuses = [] %]
|
[% bug_statuses = bug.statuses_available %]
|
||||||
[% FOREACH bug_status = bug.status.can_change_to %]
|
|
||||||
[% NEXT IF bug_status.name == "UNCONFIRMED" && !bug.product_obj.allows_unconfirmed %]
|
|
||||||
[% bug_statuses.push(bug_status) %]
|
|
||||||
[% END %]
|
|
||||||
[% IF bug_statuses.size %]
|
[% IF bug_statuses.size %]
|
||||||
<tr>
|
<tr>
|
||||||
<th><label for="bug_status">Change bug status to:</label></th>
|
<th><label for="bug_status">Change bug status to:</label></th>
|
||||||
|
@ -95,7 +91,7 @@
|
||||||
[% END %]
|
[% END %]
|
||||||
</select>
|
</select>
|
||||||
[% IF bug.resolution OR bug.check_can_change_field('resolution', bug.resolution, 1) %]
|
[% IF bug.resolution OR bug.check_can_change_field('resolution', bug.resolution, 1) %]
|
||||||
<noscript><br>resolved as </noscript>
|
<noscript><br />resolved as </noscript>
|
||||||
[% END %]
|
[% END %]
|
||||||
|
|
||||||
<span id="resolution_settings">
|
<span id="resolution_settings">
|
||||||
|
@ -107,12 +103,14 @@
|
||||||
%]
|
%]
|
||||||
</span>
|
</span>
|
||||||
<script type="text/javascript">
|
<script type="text/javascript">
|
||||||
|
[%# FIXME Move close_status_array into "js resource data" %]
|
||||||
var close_status_array = [
|
var close_status_array = [
|
||||||
[% FOREACH status = bug.statuses_available %]
|
[% SET i = 0 %]
|
||||||
[% NEXT IF status.is_open %]
|
[% FOREACH status = bug.statuses_available %]
|
||||||
'[% status.name FILTER js %]'[% ',' UNLESS loop.last %]
|
[% NEXT IF status.is_open %]
|
||||||
[% END %]
|
[% ',' IF i; SET i = 1 %]'[% status.name FILTER js %]'
|
||||||
];
|
[% END %]
|
||||||
|
];
|
||||||
function onchange_bug_status()
|
function onchange_bug_status()
|
||||||
{
|
{
|
||||||
showHideStatusItems('[% "is_duplicate" IF bug.dup_id %]', '[% bug.bug_status | js %]');
|
showHideStatusItems('[% "is_duplicate" IF bug.dup_id %]', '[% bug.bug_status | js %]');
|
||||||
|
|
|
@ -44,6 +44,7 @@
|
||||||
|
|
||||||
[% PROCESS global/header.html.tmpl %]
|
[% PROCESS global/header.html.tmpl %]
|
||||||
|
|
||||||
|
[%# FIXME: Remove bug_status hardcode %]
|
||||||
<table cellpadding="2" style="margin-bottom: 16px; border: 1px solid gray; background-color: white">
|
<table cellpadding="2" style="margin-bottom: 16px; border: 1px solid gray; background-color: white">
|
||||||
<tr>
|
<tr>
|
||||||
<td>Bug states:</td>
|
<td>Bug states:</td>
|
||||||
|
|
|
@ -69,10 +69,12 @@
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<script type="text/javascript">
|
<script type="text/javascript">
|
||||||
|
[%# FIXME Move close_status_array into "js resource data" %]
|
||||||
var close_status_array = [
|
var close_status_array = [
|
||||||
|
[% SET i = 0 %]
|
||||||
[% FOREACH status = bug.statuses_available %]
|
[% FOREACH status = bug.statuses_available %]
|
||||||
[% NEXT IF status.is_open %]
|
[% NEXT IF status.is_open %]
|
||||||
'[% status.name FILTER js %]'[% ',' UNLESS loop.last %]
|
[% ',' IF i; SET i = 1 %]'[% status.name FILTER js %]'
|
||||||
[% END %]
|
[% END %]
|
||||||
];
|
];
|
||||||
removeClass('dup_id_discoverable', 'bz_default_hidden');
|
removeClass('dup_id_discoverable', 'bz_default_hidden');
|
||||||
|
@ -84,6 +86,7 @@ function onchange_bug_status()
|
||||||
{
|
{
|
||||||
showHideStatusItems('[% "is_duplicate" IF bug.dup_id %]', '[% bug.bug_status_obj.name | js %]');
|
showHideStatusItems('[% "is_duplicate" IF bug.dup_id %]', '[% bug.bug_status_obj.name | js %]');
|
||||||
var s = document.getElementById('bug_status');
|
var s = document.getElementById('bug_status');
|
||||||
|
[%# FIXME Remove hardcode bug_status==ASSIGNED => assign to self, bug_status==VERIFIED => qa to self %]
|
||||||
if (s.value == "ASSIGNED" && document.changeform.assigned_to.value != "[% user.login %]")
|
if (s.value == "ASSIGNED" && document.changeform.assigned_to.value != "[% user.login %]")
|
||||||
{
|
{
|
||||||
document.changeform.assigned_to.value = "[% user.login %]";
|
document.changeform.assigned_to.value = "[% user.login %]";
|
||||||
|
|
|
@ -448,8 +448,7 @@
|
||||||
|
|
||||||
[% BLOCK error_no_open_bug_status %]
|
[% BLOCK error_no_open_bug_status %]
|
||||||
[% title = "$terms.Bug Cannot Be Confirmed" %]
|
[% title = "$terms.Bug Cannot Be Confirmed" %]
|
||||||
There is no valid transition from
|
There is no valid transition to an open confirmed state.
|
||||||
UNCONFIRMED to an open state.
|
|
||||||
[% END %]
|
[% END %]
|
||||||
|
|
||||||
[% BLOCK error_param_invalid %]
|
[% BLOCK error_param_invalid %]
|
||||||
|
|
|
@ -355,6 +355,13 @@
|
||||||
[% IF changes.isactive %]
|
[% IF changes.isactive %]
|
||||||
<li>It is now [% IF changes.isactive.1 %]enabled[% ELSE %]disabled[% END %] for selection.</li>
|
<li>It is now [% IF changes.isactive.1 %]enabled[% ELSE %]disabled[% END %] for selection.</li>
|
||||||
[% END %]
|
[% END %]
|
||||||
|
[%# For bug_status: %]
|
||||||
|
[% IF changes.is_assigned %]
|
||||||
|
<li>It is now an [% IF changes.is_assigned.1 %]"Assigned" (in-progress)[% ELSE %]normal[% END %] state.</li>
|
||||||
|
[% END %]
|
||||||
|
[% IF changes.is_confirmed %]
|
||||||
|
<li>It is now [% IF changes.is_confirmed.1 %]a confirmed[% ELSE %]an unconfirmed[% END %] state.</li>
|
||||||
|
[% END %]
|
||||||
[% IF changes.visibility_values.defined %]
|
[% IF changes.visibility_values.defined %]
|
||||||
[% IF value.visibility_values.size > 0 %]
|
[% IF value.visibility_values.size > 0 %]
|
||||||
<li>It only appears when
|
<li>It only appears when
|
||||||
|
|
|
@ -404,13 +404,14 @@ document.write(' <input type="button" name="check_all" value="Check All" onclick
|
||||||
<option value="[% dontchange FILTER html %]" selected >[% dontchange FILTER html %]</option>
|
<option value="[% dontchange FILTER html %]" selected >[% dontchange FILTER html %]</option>
|
||||||
[% FOREACH r = resolutions %]
|
[% FOREACH r = resolutions %]
|
||||||
[% NEXT IF !r %]
|
[% NEXT IF !r %]
|
||||||
[% NEXT IF r == "DUPLICATE" || r == "MOVED" %]
|
[% NEXT IF r == Param('duplicate_resolution') || r == "MOVED" %]
|
||||||
<option value="[% r FILTER html %]">[% r FILTER html %]</option>
|
<option value="[% r FILTER html %]">[% r FILTER html %]</option>
|
||||||
[% END %]
|
[% END %]
|
||||||
</select>
|
</select>
|
||||||
</span>
|
</span>
|
||||||
|
|
||||||
<script type="text/javascript">
|
<script type="text/javascript">
|
||||||
|
[%# FIXME Move close_status_array into js resource data %]
|
||||||
var close_status_array = new Array("[% closed_status_array.join('", "') FILTER none %]");
|
var close_status_array = new Array("[% closed_status_array.join('", "') FILTER none %]");
|
||||||
addListener('bug_status', "change", function() { showHideStatusItems('', '') });
|
addListener('bug_status', "change", function() { showHideStatusItems('', '') });
|
||||||
addListener(window, 'load', function() { showHideStatusItems('', '') });
|
addListener(window, 'load', function() { showHideStatusItems('', '') });
|
||||||
|
|
|
@ -80,11 +80,13 @@ END:VCALENDAR
|
||||||
[% END %]
|
[% END %]
|
||||||
[% END %]
|
[% END %]
|
||||||
[% IF NOT status %]
|
[% IF NOT status %]
|
||||||
[% IF bug_status == 'ASSIGNED' %]
|
[% FOREACH state = assignedstates %]
|
||||||
[% status = 'IN-PROGRESS' %]
|
[% IF bug_status == state %]
|
||||||
[% ELSE %]
|
[% status = 'IN-PROGRESS' %]
|
||||||
[% status = 'NEEDS-ACTION' %]
|
[% END %]
|
||||||
[% END %]
|
[% END %]
|
||||||
|
[% IF NOT status %]
|
||||||
|
[% status = 'NEEDS-ACTION' %]
|
||||||
[% END %]
|
[% END %]
|
||||||
[% status FILTER ics('STATUS') %]
|
[% status FILTER ics('STATUS') %]
|
||||||
[% END %]
|
[% END %]
|
||||||
|
|
|
@ -1,6 +1,4 @@
|
||||||
#!/usr/bin/perl -w
|
#!/usr/bin/perl -w
|
||||||
# -*- Mode: perl; indent-tabs-mode: nil -*-
|
|
||||||
#
|
|
||||||
# The contents of this file are subject to the Mozilla Public
|
# The contents of this file are subject to the Mozilla Public
|
||||||
# License Version 1.1 (the "License"); you may not use this file
|
# License Version 1.1 (the "License"); you may not use this file
|
||||||
# except in compliance with the License. You may obtain a copy of
|
# except in compliance with the License. You may obtain a copy of
|
||||||
|
@ -23,9 +21,9 @@
|
||||||
# Frédéric Buclin <LpSolit@gmail.com>
|
# Frédéric Buclin <LpSolit@gmail.com>
|
||||||
|
|
||||||
|
|
||||||
# This is a script suitable for running once a day from a cron job. It
|
# This is a script suitable for running once a day from a cron job. It
|
||||||
# looks at all the bugs, and sends whiny mail to anyone who has a bug
|
# looks at all the bugs, and sends whiny mail to anyone who has a bug
|
||||||
# assigned to them that has status NEW or REOPENED that has not been
|
# assigned to them that has unassigned, but open status that has not been
|
||||||
# touched for more than the number of days specified in the whinedays param.
|
# touched for more than the number of days specified in the whinedays param.
|
||||||
|
|
||||||
use strict;
|
use strict;
|
||||||
|
@ -37,61 +35,63 @@ use Bugzilla::Util;
|
||||||
use Bugzilla::User;
|
use Bugzilla::User;
|
||||||
|
|
||||||
# Whining is disabled if whinedays is zero
|
# Whining is disabled if whinedays is zero
|
||||||
exit unless Bugzilla->params->{'whinedays'} >= 1;
|
exit unless Bugzilla->params->{whinedays} >= 1;
|
||||||
|
|
||||||
my $dbh = Bugzilla->dbh;
|
my $dbh = Bugzilla->dbh;
|
||||||
my $query = q{SELECT bug_id, short_desc, login_name
|
my $query = "SELECT b.bug_id, b.short_desc, p.login_name FROM bugs b".
|
||||||
FROM bugs
|
" INNER JOIN bug_status bs ON bs.id=b.bug_status".
|
||||||
INNER JOIN profiles
|
" INNER JOIN profiles p ON p.userid = b.assigned_to".
|
||||||
ON userid = assigned_to
|
" WHERE bs.is_open AND NOT bs.is_assigned".
|
||||||
WHERE (bug_status = ? OR bug_status = ?)
|
" AND disable_mail = 0 AND " . $dbh->sql_to_days('NOW()') . " - " .
|
||||||
AND disable_mail = 0
|
$dbh->sql_to_days('delta_ts') . " > " . Bugzilla->params->{whinedays} .
|
||||||
AND } . $dbh->sql_to_days('NOW()') . " - " .
|
" ORDER BY bug_id";
|
||||||
$dbh->sql_to_days('delta_ts') . " > " .
|
|
||||||
Bugzilla->params->{'whinedays'} .
|
|
||||||
" ORDER BY bug_id";
|
|
||||||
|
|
||||||
my %bugs;
|
my %bugs;
|
||||||
my %desc;
|
my %desc;
|
||||||
|
|
||||||
# FIXME: Remove status hardcode: NEW | REOPENED == is_open & !ASSIGNED
|
my $slt_bugs = $dbh->selectall_arrayref($query);
|
||||||
my $slt_bugs = $dbh->selectall_arrayref($query, undef, 'NEW', 'REOPENED');
|
|
||||||
|
|
||||||
foreach my $bug (@$slt_bugs) {
|
foreach my $bug (@$slt_bugs)
|
||||||
|
{
|
||||||
my ($id, $desc, $email) = @$bug;
|
my ($id, $desc, $email) = @$bug;
|
||||||
if (!defined $bugs{$email}) {
|
if (!defined $bugs{$email})
|
||||||
|
{
|
||||||
$bugs{$email} = [];
|
$bugs{$email} = [];
|
||||||
}
|
}
|
||||||
if (!defined $desc{$email}) {
|
if (!defined $desc{$email})
|
||||||
|
{
|
||||||
$desc{$email} = [];
|
$desc{$email} = [];
|
||||||
}
|
}
|
||||||
push @{$bugs{$email}}, $id;
|
push @{$bugs{$email}}, $id;
|
||||||
push @{$desc{$email}}, $desc;
|
push @{$desc{$email}}, $desc;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
foreach my $email (sort keys %bugs)
|
||||||
foreach my $email (sort (keys %bugs)) {
|
{
|
||||||
my $user = new Bugzilla::User({name => $email});
|
my $user = new Bugzilla::User({ name => $email });
|
||||||
next if $user->email_disabled;
|
next if $user->email_disabled;
|
||||||
|
|
||||||
my $vars = {'email' => $email};
|
my $vars = {email => $email};
|
||||||
|
|
||||||
my @bugs = ();
|
my @bugs = ();
|
||||||
foreach my $i (@{$bugs{$email}}) {
|
foreach my $i (@{$bugs{$email}})
|
||||||
|
{
|
||||||
my $bug = {};
|
my $bug = {};
|
||||||
$bug->{'summary'} = shift(@{$desc{$email}});
|
$bug->{summary} = shift(@{$desc{$email}});
|
||||||
$bug->{'id'} = $i;
|
$bug->{id} = $i;
|
||||||
push @bugs, $bug;
|
push @bugs, $bug;
|
||||||
}
|
}
|
||||||
$vars->{'bugs'} = \@bugs;
|
$vars->{bugs} = \@bugs;
|
||||||
|
|
||||||
my $msg;
|
my $msg;
|
||||||
my $template = Bugzilla->template_inner($user->settings->{'lang'}->{'value'});
|
my $template = Bugzilla->template_inner($user->settings->{lang}->{value});
|
||||||
$template->process("email/whine.txt.tmpl", $vars, \$msg)
|
$template->process("email/whine.txt.tmpl", $vars, \$msg)
|
||||||
or die($template->error());
|
|| die($template->error);
|
||||||
|
|
||||||
Bugzilla->template_inner("");
|
Bugzilla->template_inner("");
|
||||||
MessageToMTA($msg);
|
MessageToMTA($msg);
|
||||||
|
|
||||||
print "$email " . join(" ", @{$bugs{$email}}) . "\n";
|
print "$email " . join(" ", @{$bugs{$email}}) . "\n";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
exit;
|
||||||
|
|
Loading…
Reference in New Issue