Commit 8ddcf713 authored by Per Cederqvist's avatar Per Cederqvist

Imported Bugzilla 4.0.1.

parent fa943f51
This is a Bazaar control directory.
Do not change any files in this directory.
See http://bazaar-vcs.org/ for more information about Bazaar.
See http://bazaar.canonical.com/ for more information about Bazaar.
No preview for this file type
......@@ -1160,14 +1160,20 @@ sub send_changes {
# If there were changes in dependencies, we need to notify those
# dependencies.
my %notify_deps;
if ($changes->{'bug_status'}) {
my ($old_status, $new_status) = @{ $changes->{'bug_status'} };
# If this bug has changed from opened to closed or vice-versa,
# then all of the bugs we block need to be notified.
if (is_open_state($old_status) ne is_open_state($new_status)) {
$notify_deps{$_} = 1 foreach (@{ $self->blocked });
my $params = { forced => { changer => $user },
type => 'dep',
dep_only => 1 };
foreach my $id (@{ $self->blocked }) {
$params->{id} = $id;
_send_bugmail($params, $vars);
}
}
}
......@@ -1183,8 +1189,7 @@ sub send_changes {
# an error later.
delete $changed_deps{''};
my %all_dep_changes = (%notify_deps, %changed_deps);
foreach my $id (sort { $a <=> $b } (keys %all_dep_changes)) {
foreach my $id (sort { $a <=> $b } (keys %changed_deps)) {
_send_bugmail({ forced => { changer => $user }, type => "dep",
id => $id }, $vars);
}
......@@ -1194,7 +1199,7 @@ sub _send_bugmail {
my ($params, $vars) = @_;
my $results =
Bugzilla::BugMail::Send($params->{'id'}, $params->{'forced'});
Bugzilla::BugMail::Send($params->{'id'}, $params->{'forced'}, $params);
if (Bugzilla->usage_mode == USAGE_MODE_BROWSER) {
my $template = Bugzilla->template;
......
......@@ -109,7 +109,8 @@ sub relationships {
# All the names are email addresses, not userids
# values are scalars, except for cc, which is a list
sub Send {
my ($id, $forced) = (@_);
my ($id, $forced, $params) = (@_);
$params ||= {};
my $dbh = Bugzilla->dbh;
my $bug = new Bugzilla::Bug($id);
......@@ -377,6 +378,11 @@ sub Send {
my @sent;
my @excluded;
# The email client will display the Date: header in the desired timezone,
# so we can always use UTC here.
my $date = $params->{dep_only} ? $end : $bug->delta_ts;
$date = format_time($date, '%a, %d %b %Y %T %z', 'UTC');
foreach my $user_id (keys %recipients) {
my %rels_which_want;
my $sent_mail = 0;
......@@ -428,6 +434,7 @@ sub Send {
bug => $bug,
comments => $comments,
is_new => !$start,
date => $date,
changer => $changer,
watchers => exists $watching{$user_id} ?
$watching{$user_id} : undef,
......@@ -461,6 +468,7 @@ sub sendMail {
my $bug = $params->{bug};
my @send_comments = @{ $params->{comments} };
my $isnew = $params->{is_new};
my $date = $params->{date};
my $changer = $params->{changer};
my $watchingRef = $params->{watchers};
my @diffparts = @{ $params->{diff_parts} };
......@@ -561,6 +569,7 @@ sub sendMail {
my $vars = {
isnew => $isnew,
date => $date,
to_user => $user,
bug => $bug,
changedfields => \@changed_fields,
......
......@@ -197,7 +197,7 @@ use File::Basename;
# CONSTANTS
#
# Bugzilla version
use constant BUGZILLA_VERSION => "4.0";
use constant BUGZILLA_VERSION => "4.0.1";
# These are unique values that are unlikely to match a string or a number,
# to be used in criteria for match() functions and other things. They start
......
......@@ -411,7 +411,7 @@ sub sql_fulltext_search {
@words = map("LOWER($column) LIKE $_", @words);
# search for occurrences of all specified words in the column
return "CASE WHEN (" . join(" AND ", @words) . ") THEN 1 ELSE 0 END";
return join (" AND ", @words), "CASE WHEN (" . join(" AND ", @words) . ") THEN 1 ELSE 0 END";
}
#####################################################################
......@@ -1958,8 +1958,17 @@ Note that both parameters need to be sql-quoted.
=item B<Description>
Returns SQL syntax for performing a full text search for specified text
on a given column.
Returns one or two SQL expressions for performing a full text search for
specified text on a given column.
If one value is returned, it is a numeric expression that indicates
a match with a positive value and a non-match with zero. In this case,
the DB must support casting numeric expresions to booleans.
If the DB does not support casting numeric expresions to booleans, then
the first value is a boolean expression that indicates the presence of
a match, and the second value is a numeric expression that can be
used for ranking.
There is a ANSI SQL version of this method implemented using LIKE operator,
but it's not a real full text search. DB specific modules should override
......
......@@ -478,19 +478,19 @@ sub update_flags {
# This is a new flag.
my $flag = $class->create($new_flag, $timestamp);
$new_flag->{id} = $flag->id;
$class->notify($new_flag, undef, $self);
$class->notify($new_flag, undef, $self, $timestamp);
}
else {
my $changes = $new_flag->update($timestamp);
if (scalar(keys %$changes)) {
$class->notify($new_flag, $old_flags{$new_flag->id}, $self);
$class->notify($new_flag, $old_flags{$new_flag->id}, $self, $timestamp);
}
delete $old_flags{$new_flag->id};
}
}
# These flags have been deleted.
foreach my $old_flag (values %old_flags) {
$class->notify(undef, $old_flag, $self);
$class->notify(undef, $old_flag, $self, $timestamp);
$old_flag->remove_from_db();
}
......@@ -893,7 +893,7 @@ sub extract_flags_from_cgi {
=over
=item C<notify($flag, $bug, $attachment)>
=item C<notify($flag, $old_flag, $object, $timestamp)>
Sends an email notification about a flag being created, fulfilled
or deleted.
......@@ -903,7 +903,7 @@ or deleted.
=cut
sub notify {
my ($class, $flag, $old_flag, $obj) = @_;
my ($class, $flag, $old_flag, $obj, $timestamp) = @_;
my ($bug, $attachment);
if (blessed($obj) && $obj->isa('Bugzilla::Attachment')) {
......@@ -939,6 +939,11 @@ sub notify {
# Is there someone to notify?
return unless ($addressee || $cc_list);
# The email client will display the Date: header in the desired timezone,
# so we can always use UTC here.
$timestamp ||= Bugzilla->dbh->selectrow_array('SELECT LOCALTIMESTAMP(0)');
$timestamp = format_time($timestamp, '%a, %d %b %Y %T %z', 'UTC');
# If the target bug is restricted to one or more groups, then we need
# to make sure we don't send email about it to unauthorized users
# on the request type's CC: list, so we have to trawl the list for users
......@@ -964,10 +969,8 @@ sub notify {
# If there are users in the CC list who don't have an account,
# use the default language for email notifications.
my $default_lang;
my $default_timezone;
if (grep { !$_ } values %recipients) {
$default_lang = Bugzilla::User->new()->settings->{'lang'}->{'value'};
$default_timezone = Bugzilla::User->new()->settings->{'timezone'}->{'value'};
}
foreach my $to (keys %recipients) {
......@@ -975,13 +978,10 @@ sub notify {
# threaded similar to normal bug change emails.
my $thread_user_id = $recipients{$to} ? $recipients{$to}->id : 0;
my $timezone = $recipients{$to} ?
$recipients{$to}->settings->{'timezone'}->{'value'} : $default_timezone;
my $vars = { 'flag' => $flag,
'old_flag' => $old_flag,
'to' => $to,
'timezone' => $timezone,
'date' => $timestamp,
'bug' => $bug,
'attachment' => $attachment,
'threadingmarker' => build_thread_marker($bug->id, $thread_user_id) };
......
......@@ -713,6 +713,99 @@ time should be printed.
=back
=head2 install_filesystem
Allows for additional files and directories to be added to the
list of files and directories already managed by checksetup.pl.
You will be able to also set the permissions for the files and
directories using this hook. You are also able to set or change
permissions for current files and directories using this hook.
You are also able to create appropriate htaccess files for the
any directories to secure its contents. For examples see
L<FILESYSTEM> in L<Bugzilla::Install::Filesystem>.
Params:
=over
=item C<files>
Hash reference of files that are already present when your extension was
installed but need to have specific permissions set. Each file key
points to another hash reference containing the following settings.
Params:
=over
=item C<perms> - Permissions to be set on the file.
=back
=item C<create_dirs>
Hash reference containing the name of each directory that will be created,
pointing at its default permissions.
=item C<non_recurse_dirs>
Hash reference containing directories that we want to set the perms on, but not
recurse through. These are directories not created in checksetup.pl. Each directory
key's value is the permissions to be set on the directory.
=item C<recurse_dirs>
Hash reference of directories that will have permissions set for each item inside
each of the directories, including the directory itself. Each directory key
points to another hash reference containing the following settings.
Params:
=over
=item C<files> - Permissions to be set on any files beneath the directory.
=item C<dirs> - Permissions to be set on the directory itself and any directories
beneath it.
=back
=item C<create_files>
Hash reference of additional files to be created. Each file key points to another
hash reference containing the following settings.
Params:
=over
=item C<perms> - The permissions to be set on the file itself.
=item C<contents> - The contents to be added to the file or leave blank for an
empty file.
=back
=item C<htaccess>
Hash reference containing htaccess files to be created. You can set the permissions
for the htaccess as well as the contents of the file. Each file key points to another
hash reference containing the following settings.
Params:
=over
=item C<perms> - Permissions to be set on the htaccess file.
=item C<contents> - Contents of the htaccess file. It can be set manually or
use L<HT_DEFAULT_DENY> defined in L<Bugzilla::Install::Filesystem> to deny all
by default.
=back
=back
=head2 install_update_db
This happens at the very end of all the tables being updated
......@@ -1069,6 +1162,24 @@ your template.
=back
=head2 post_bug_after_creation
B<DEPRECATED> (Use L</bug_end_of_create> instead.)
This happens after a bug is created and before bug mail is sent
during C<post_bug.cgi>. Note that this only happens during C<post_bug.cgi>,
it doesn't happen during any of the other methods of creating a bug.
Params:
=over
=item C<vars> - The template vars hashref.
=back
=head2 product_confirm_delete
B<DEPRECATED> - Use L</template_before_process> instead.
......
......@@ -54,6 +54,13 @@ use constant REQUIREMENTS => (
package => 'YAML',
version => 0,
},
{
# Many modules on CPAN are now built with Dist::Zilla, which
# unfortunately means they require this version of EU::MM to install.
module => 'ExtUtils::MakeMaker',
package => 'ExtUtils-MakeMaker',
version => '6.31',
},
);
# We need the absolute path of ext_libpath, because CPAN chdirs around
......@@ -63,6 +70,13 @@ use constant REQUIREMENTS => (
# we make it a constant.
use constant BZ_LIB => abs_path(bz_locations()->{ext_libpath});
# These modules are problematic to install with "notest" (sometimes they
# get installed when they shouldn't). So we always test their installation
# and never ignore test failures.
use constant ALWAYS_TEST => qw(
Math::Random::Secure
);
# CPAN requires nearly all of its parameters to be set, or it will start
# asking questions to the user. We want to avoid that, so we have
# defaults here for most of the required parameters we know about, in case
......@@ -152,7 +166,11 @@ sub install_module {
}
print install_string('install_module',
{ module => $name, version => $module->cpan_version }) . "\n";
if ($test) {
if (_always_test($name)) {
CPAN::Shell->install($name);
}
elsif ($test) {
CPAN::Shell->force('install', $name);
}
else {
......@@ -167,6 +185,11 @@ sub install_module {
$CPAN::Config->{makepl_arg} = $original_makepl;
}
sub _always_test {
my ($name) = @_;
return grep(lc($_) eq lc($name), ALWAYS_TEST) ? 1 : 0;
}
sub set_cpan_config {
my $do_global = shift;
my $bzlib = BZ_LIB;
......
......@@ -32,6 +32,7 @@ use Bugzilla::Error;
use Bugzilla::Install::Localconfig;
use Bugzilla::Install::Util qw(install_string);
use Bugzilla::Util;
use Bugzilla::Hook;
use File::Find;
use File::Path;
......@@ -163,6 +164,7 @@ sub FILESYSTEM {
'bugzilla.dtd' => { perms => WS_SERVE },
'mod_perl.pl' => { perms => WS_SERVE },
'robots.txt' => { perms => WS_SERVE },
'.htaccess' => { perms => WS_SERVE },
'contrib/README' => { perms => OWNER_WRITE },
'contrib/*/README' => { perms => OWNER_WRITE },
......@@ -359,6 +361,15 @@ EOT
},
);
Bugzilla::Hook::process('install_filesystem', {
files => \%files,
create_dirs => \%create_dirs,
non_recurse_dirs => \%non_recurse_dirs,
recurse_dirs => \%recurse_dirs,
create_files => \%create_files,
htaccess => \%htaccess,
});
my %all_files = (%create_files, %htaccess, %index_html, %files);
my %all_dirs = (%create_dirs, %non_recurse_dirs);
......
......@@ -221,8 +221,14 @@ sub extension_package_directory {
my ($invocant, $file) = @_;
my $class = ref($invocant) || $invocant;
# $file is set on the first invocation, store the value in the extension's
# package for retrieval on subsequent calls
my $var;
{ no strict 'refs'; $var = \${"${class}::EXTENSION_PACKAGE_DIR"}; }
{
no warnings 'once';
no strict 'refs';
$var = \${"${class}::EXTENSION_PACKAGE_DIR"};
}
if ($file) {
$$var = dirname($file);
}
......
......@@ -1646,7 +1646,7 @@ sub _content_matches {
$rterm2 = $term2 if !$rterm2;
# The term to use in the WHERE clause.
$$term = "$term1 > 0 OR $term2 > 0";
$$term = "$term1 OR $term2";
if ($$t =~ /not/i) {
$$term = "NOT($$term)";
}
......
......@@ -430,9 +430,10 @@ sub _css_link_set {
return \%set;
}
my $user = Bugzilla->user;
my $skin_user_prefs = Bugzilla->user->settings->{skin};
my $cgi_path = bz_locations()->{'cgi_path'};
my $all_skins = $user->settings->{'skin'}->legal_values;
# If the DB is not accessible, user settings are not available.
my $all_skins = $skin_user_prefs ? $skin_user_prefs->legal_values : [];
my %skin_urls;
foreach my $option (@$all_skins) {
next if $option eq 'standard';
......@@ -444,7 +445,7 @@ sub _css_link_set {
}
$set{alternate} = \%skin_urls;
my $skin = $user->settings->{'skin'}->{'value'};
my $skin = $skin_user_prefs->{'value'};
if ($skin ne 'standard' and defined $set{alternate}->{$skin}) {
$set{skin} = delete $set{alternate}->{$skin};
}
......
......@@ -39,6 +39,7 @@ sub legal_values {
# Append 'local' to the list, which will use the timezone
# given by the server.
push(@timezones, 'local');
push(@timezones, 'UTC');
return $self->{'legal_values'} = \@timezones;
}
......
<!ELEMENT bugzilla (bug+)>
<!ATTLIST bugzilla
version CDATA #REQUIRED
urlbase CDATA #REQUIRED
maintainer CDATA #REQUIRED
exporter CDATA #IMPLIED
version CDATA #REQUIRED
urlbase CDATA #REQUIRED
maintainer CDATA #REQUIRED
exporter CDATA #IMPLIED
>
<!ELEMENT bug (bug_id, (alias?, creation_ts, short_desc, delta_ts, reporter_accessible, cclist_accessible, classification_id, classification, product, component, version, rep_platform, op_sys, bug_status, resolution?, dup_id?, bug_file_loc?, status_whiteboard?, keywords*, priority, bug_severity, target_milestone?, dependson*, blocked*, everconfirmed, reporter, assigned_to, qa_contact?, cc*, (estimated_time, remaining_time, actual_time, deadline)?, group*, flag*, long_desc*, attachment*)?)>
<!ELEMENT bug (bug_id, (alias?, creation_ts, short_desc, delta_ts, reporter_accessible,
cclist_accessible, classification_id, classification, product, component,
version, rep_platform, op_sys, bug_status, resolution?, dup_id?, see_also*,
bug_file_loc?, status_whiteboard?, keywords*, priority, bug_severity,
target_milestone?, dependson*, blocked*, everconfirmed, reporter, assigned_to,
cc*, (estimated_time, remaining_time, actual_time, deadline?)?, qa_contact?,
votes?, token?, group*, flag*, long_desc*, attachment*)?)>
<!ATTLIST bug
error (NotFound | NotPermitted | InvalidBugId) #IMPLIED
error (NotFound | NotPermitted | InvalidBugId) #IMPLIED
>
<!ELEMENT bug_id (#PCDATA)>
<!ELEMENT alias (#PCDATA)>
......@@ -23,13 +29,22 @@
<!ELEMENT version (#PCDATA)>
<!ELEMENT rep_platform (#PCDATA)>
<!ELEMENT assigned_to (#PCDATA)>
<!ATTLIST assigned_to
name CDATA #REQUIRED
>
<!ELEMENT delta_ts (#PCDATA)>
<!ELEMENT component (#PCDATA)>
<!ELEMENT reporter (#PCDATA)>
<!ATTLIST reporter
name CDATA #REQUIRED
>
<!ELEMENT target_milestone (#PCDATA)>
<!ELEMENT bug_severity (#PCDATA)>
<!ELEMENT creation_ts (#PCDATA)>
<!ELEMENT qa_contact (#PCDATA)>
<!ATTLIST qa_contact
name CDATA #REQUIRED
>
<!ELEMENT status_whiteboard (#PCDATA)>
<!ELEMENT op_sys (#PCDATA)>
<!ELEMENT resolution (#PCDATA)>
......@@ -41,34 +56,39 @@
<!ELEMENT blocked (#PCDATA)>
<!ELEMENT everconfirmed (#PCDATA)>
<!ELEMENT cc (#PCDATA)>
<!ELEMENT see_also (#PCDATA)>
<!ELEMENT votes (#PCDATA)>
<!ELEMENT token (#PCDATA)>
<!ELEMENT group (#PCDATA)>
<!ATTLIST group
id CDATA #REQUIRED
>
>
<!ELEMENT estimated_time (#PCDATA)>
<!ELEMENT remaining_time (#PCDATA)>
<!ELEMENT actual_time (#PCDATA)>
<!ELEMENT deadline (#PCDATA)>
<!ELEMENT long_desc (who, bug_when, work_time?, thetext)>
<!ELEMENT long_desc (commentid, attachid?, who, bug_when, work_time?, thetext)>
<!ATTLIST long_desc
encoding (base64) #IMPLIED
isprivate (0|1) #IMPLIED
>
isprivate (0|1) #REQUIRED
>
<!ELEMENT commentid (#PCDATA)>
<!ELEMENT who (#PCDATA)>
<!ATTLIST who
name CDATA #REQUIRED
>
<!ELEMENT bug_when (#PCDATA)>
<!ELEMENT work_time (#PCDATA)>
<!ELEMENT thetext (#PCDATA)>
<!ELEMENT attachment (attachid, date, desc, filename?, type?, size?, data?, flag*)>
<!ELEMENT attachment (attachid, date, delta_ts, desc, filename, type, size, attacher, token?, data?, flag*)>
<!ATTLIST attachment
isobsolete (0|1) #IMPLIED
ispatch (0|1) #IMPLIED
isprivate (0|1) #IMPLIED
isurl (0|1) #IMPLIED
isobsolete (0|1) #REQUIRED
ispatch (0|1) #REQUIRED
isprivate (0|1) #REQUIRED
isurl (0|1) #REQUIRED
>
<!ELEMENT attacher (#PCDATA)>
<!ELEMENT attachid (#PCDATA)>
<!ELEMENT date (#PCDATA)>
<!ELEMENT delta_ts (#PCDATA)>
<!ELEMENT desc (#PCDATA)>
<!ELEMENT filename (#PCDATA)>
<!ELEMENT type (#PCDATA)>
......@@ -81,8 +101,8 @@
<!ATTLIST flag
name CDATA #REQUIRED
id CDATA #REQUIRED
type_id CDATA
type_id CDATA #REQUIRED
status CDATA #REQUIRED
setter CDATA #IMPLIED
setter CDATA #REQUIRED
requestee CDATA #IMPLIED
>
......@@ -42,7 +42,7 @@ HOW TO SET UP YOUR OWN XML EDITING ENVIRONMENT:
Trying to set up an XML Docbook editing environment the
first time can be a daunting task.
I use Linux-Mandrake, in part, because it has a fully-functional
I use Mandriva Linux, in part, because it has a fully-functional
XML Docbook editing environment included as part of the
distribution CD's. If you have easier instructions for how to
do this for a particular Linux distribution or platform, please
......@@ -70,9 +70,9 @@ sgml-tools
sgml-common
If you're getting these from RedHat, make sure you get the ones in the
If you're getting these from Red Hat, make sure you get the ones in the
rawhide area. The ones in the 7.2 distribution are too old and don't
include the XML stuff. The packages distrubuted with RedHat 8.0 and 9
include the XML stuff. The packages distrubuted with Red Hat Linux 8.0 and 9
and known to work.
Download "ldp.dsl" from the Resources page on tldp.org. This is the
......@@ -91,7 +91,7 @@ dsssl>
Note the difference is the top one points to the HTML docbook stylesheet,