summaryrefslogtreecommitdiffstats
path: root/Bugzilla
diff options
context:
space:
mode:
Diffstat (limited to 'Bugzilla')
-rw-r--r--Bugzilla/Chart.pm48
-rw-r--r--Bugzilla/Series.pm104
2 files changed, 68 insertions, 84 deletions
diff --git a/Bugzilla/Chart.pm b/Bugzilla/Chart.pm
index 42827750f..90c1ad16f 100644
--- a/Bugzilla/Chart.pm
+++ b/Bugzilla/Chart.pm
@@ -71,8 +71,8 @@ sub init {
foreach my $series_id ($cgi->param($param)) {
detaint_natural($series_id)
|| &::ThrowCodeError("invalid_series_id");
- push(@{$self->{'lines'}[$1]},
- new Bugzilla::Series($series_id));
+ my $series = new Bugzilla::Series($series_id);
+ push(@{$self->{'lines'}[$1]}, $series) if $series;
}
}
@@ -130,8 +130,10 @@ sub add {
# for inventing something sensible.
foreach my $series_id (@series_ids) {
my $series = new Bugzilla::Series($series_id);
- push(@{$self->{'lines'}}, [$series]);
- push(@{$self->{'labels'}}, "");
+ if ($series) {
+ push(@{$self->{'lines'}}, [$series]);
+ push(@{$self->{'labels'}}, "");
+ }
}
}
@@ -199,6 +201,8 @@ sub readData {
my $self = shift;
my @data;
+ # Note: you get a bad image if getSeriesIDs returns nothing
+ # We need to handle errors better.
my $series_ids = join(",", $self->getSeriesIDs());
# Work out the date boundaries for our data.
@@ -206,7 +210,8 @@ sub readData {
# The date used is the one given if it's in a sensible range; otherwise,
# it's the earliest or latest date in the database as appropriate.
- my $datefrom = $dbh->selectrow_array("SELECT MIN(date) FROM series_data " .
+ my $datefrom = $dbh->selectrow_array("SELECT MIN(series_date) " .
+ "FROM series_data " .
"WHERE series_id IN ($series_ids)");
$datefrom = &::str2time($datefrom);
@@ -214,7 +219,8 @@ sub readData {
$datefrom = $self->{'datefrom'};
}
- my $dateto = $dbh->selectrow_array("SELECT MAX(date) FROM series_data " .
+ my $dateto = $dbh->selectrow_array("SELECT MAX(series_date) " .
+ "FROM series_data " .
"WHERE series_id IN ($series_ids)");
$dateto = &::str2time($dateto);
@@ -223,12 +229,13 @@ sub readData {
}
# Prepare the query which retrieves the data for each series
- my $query = "SELECT TO_DAYS(date) - TO_DAYS(FROM_UNIXTIME($datefrom)), " .
- "value FROM series_data " .
+ my $query = "SELECT TO_DAYS(series_date) - " .
+ " TO_DAYS(FROM_UNIXTIME($datefrom)), " .
+ "series_value FROM series_data " .
"WHERE series_id = ? " .
- "AND date >= FROM_UNIXTIME($datefrom)";
+ "AND series_date >= FROM_UNIXTIME($datefrom)";
if ($dateto) {
- $query .= " AND date <= FROM_UNIXTIME($dateto)";
+ $query .= " AND series_date <= FROM_UNIXTIME($dateto)";
}
my $sth = $dbh->prepare($query);
@@ -296,19 +303,24 @@ sub getSeriesIDs {
sub getVisibleSeries {
my %cats;
+ # List of groups the user is in; use -1 to make sure it's not empty.
+ my $grouplist = join(", ", (-1, values(%{Bugzilla->user->groups})));
+
# Get all visible series
my $dbh = Bugzilla->dbh;
my $serieses = $dbh->selectall_arrayref("SELECT cc1.name, cc2.name, " .
"series.name, series.series_id " .
"FROM series " .
- "LEFT JOIN series_categories AS cc1 " .
- " ON series.category = cc1.category_id " .
- "LEFT JOIN series_categories AS cc2 " .
- " ON series.subcategory = cc2.category_id " .
- "LEFT JOIN user_series_map AS ucm " .
- " ON series.series_id = ucm.series_id " .
- "WHERE ucm.user_id = 0 OR ucm.user_id = $::userid");
-
+ "INNER JOIN series_categories AS cc1 " .
+ " ON series.category = cc1.id " .
+ "INNER JOIN series_categories AS cc2 " .
+ " ON series.subcategory = cc2.id " .
+ "LEFT JOIN category_group_map AS cgm " .
+ " ON series.category = cgm.category_id " .
+ " AND cgm.group_id NOT IN($grouplist) " .
+ "WHERE creator = " . Bugzilla->user->id . " OR " .
+ " cgm.category_id IS NULL " .
+ "GROUP BY series_id");
foreach my $series (@$serieses) {
my ($cat, $subcat, $name, $series_id) = @$series;
$cats{$cat}{$subcat}{$name} = $series_id;
diff --git a/Bugzilla/Series.pm b/Bugzilla/Series.pm
index 4d01a71ca..a4bd6654f 100644
--- a/Bugzilla/Series.pm
+++ b/Bugzilla/Series.pm
@@ -47,6 +47,11 @@ sub new {
my $arg_count = scalar(@_);
+ # new() can return undef if you pass in a series_id and the user doesn't
+ # have sufficient permissions. If you create a new series in this way,
+ # you need to check for an undef return, and act appropriately.
+ my $retval = $self;
+
# There are three ways of creating Series objects. Two (CGI and Parameters)
# are for use when creating a new series. One (Database) is for retrieving
# information on existing series.
@@ -60,7 +65,7 @@ sub new {
else {
# We've been given a series_id, which should represent an existing
# Series.
- $self->initFromDatabase($_[0]);
+ $retval = $self->initFromDatabase($_[0]);
}
}
elsif ($arg_count >= 6 && $arg_count <= 8) {
@@ -73,7 +78,7 @@ sub new {
die("Bad parameters passed in - invalid number of args: $arg_count");
}
- return $self;
+ return $retval;
}
sub initFromDatabase {
@@ -86,23 +91,29 @@ sub initFromDatabase {
my $dbh = Bugzilla->dbh;
my @series = $dbh->selectrow_array("SELECT series.series_id, cc1.name, " .
"cc2.name, series.name, series.creator, series.frequency, " .
- "series.query " .
+ "series.query, series.public " .
"FROM series " .
"LEFT JOIN series_categories AS cc1 " .
- " ON series.category = cc1.category_id " .
+ " ON series.category = cc1.id " .
"LEFT JOIN series_categories AS cc2 " .
- " ON series.subcategory = cc2.category_id " .
- "WHERE series.series_id = $series_id");
+ " ON series.subcategory = cc2.id " .
+ "LEFT JOIN category_group_map AS cgm " .
+ " ON series.category = cgm.category_id " .
+ "LEFT JOIN user_group_map AS ugm " .
+ " ON cgm.group_id = ugm.group_id " .
+ " AND ugm.user_id = " . Bugzilla->user->id .
+ " AND isbless = 0 " .
+ "WHERE series.series_id = $series_id AND " .
+ "(public = 1 OR creator = " . Bugzilla->user->id . " OR " .
+ "(ugm.group_id IS NOT NULL)) " .
+ "GROUP BY series_id");
if (@series) {
- # Note that we calculate $self->{'public'} ourselves instead of passing
- # it as the last parameter in @series; this is because isSubscribed()
- # requires the rest of the object to be set up correctly.
$self->initFromParameters(@series);
- $self->{'public'} = $self->isSubscribed(PUBLIC_USER_ID);
+ return $self;
}
else {
- &::ThrowCodeError("invalid_series_id", { 'series_id' => $series_id });
+ return undef;
}
}
@@ -146,16 +157,20 @@ sub initFromCGI {
$self->{'query'} = $cgi->canonicalise_query("format", "ctype", "action",
"category", "subcategory", "name",
"frequency", "public", "query_format");
+ trick_taint($self->{'query'});
- $self->{'public'} = $cgi->param('public') ? 1 : 0;
+ $self->{'public'} = $cgi->param('public') ? 1 : 0;
+
+ # Change 'admin' here and in series.html.tmpl, or remove the check
+ # completely, if you want to change who can make series public.
+ $self->{'public'} = 0 unless &::UserInGroup('admin');
}
sub writeToDatabase {
my $self = shift;
my $dbh = Bugzilla->dbh;
- $dbh->do("LOCK TABLES series_categories WRITE, series WRITE, " .
- "user_series_map WRITE");
+ $dbh->do("LOCK TABLES series_categories WRITE, series WRITE");
my $category_id = getCategoryID($self->{'category'});
my $subcategory_id = getCategoryID($self->{'subcategory'});
@@ -173,37 +188,28 @@ sub writeToDatabase {
my $dbh = Bugzilla->dbh;
$dbh->do("UPDATE series SET " .
"category = ?, subcategory = ?," .
- "name = ?, frequency = ? " .
+ "name = ?, frequency = ?, public = ? " .
"WHERE series_id = ?", undef,
$category_id, $subcategory_id, $self->{'name'},
- $self->{'frequency'}, $self->{'series_id'});
+ $self->{'frequency'}, $self->{'public'},
+ $self->{'series_id'});
}
else {
# Insert the new series into the series table
$dbh->do("INSERT INTO series (creator, category, subcategory, " .
- "name, frequency, query) VALUES ($self->{'creator'}, " .
+ "name, frequency, query, public) VALUES " .
+ "($self->{'creator'}, " .
"$category_id, $subcategory_id, " .
$dbh->quote($self->{'name'}) . ", $self->{'frequency'}," .
- $dbh->quote($self->{'query'}) . ")");
+ $dbh->quote($self->{'query'}) . ", $self->{'public'})");
# Retrieve series_id
$self->{'series_id'} = $dbh->selectrow_array("SELECT MAX(series_id) " .
"FROM series");
$self->{'series_id'}
|| &::ThrowCodeError("missing_series_id", { 'series' => $self });
-
- # Subscribe creator to the newly-created series.
- $self->subscribe($self->{'creator'});
}
- # Update publicness by changing subscription
- if ($self->{'public'}) {
- $self->subscribe(PUBLIC_USER_ID);
- }
- else {
- $self->unsubscribe(PUBLIC_USER_ID);
- }
-
$dbh->do("UNLOCK TABLES");
}
@@ -236,51 +242,17 @@ sub getCategoryID {
# We are quoting this to put it in the DB, so we can remove taint
trick_taint($category);
- $category_id = $dbh->selectrow_array("SELECT category_id " .
+ $category_id = $dbh->selectrow_array("SELECT id " .
"from series_categories " .
"WHERE name =" . $dbh->quote($category));
- last if $category_id;
+
+ last if defined($category_id);
$dbh->do("INSERT INTO series_categories (name) " .
"VALUES (" . $dbh->quote($category) . ")");
}
return $category_id;
-}
-
-sub subscribe {
- my $self = shift;
- my $userid = shift;
-
- if (!$self->isSubscribed($userid)) {
- # Subscribe current user to series_id
- my $dbh = Bugzilla->dbh;
- $dbh->do("INSERT INTO user_series_map " .
- "VALUES($userid, $self->{'series_id'})");
- }
-}
-
-sub unsubscribe {
- my $self = shift;
- my $userid = shift;
-
- if ($self->isSubscribed($userid)) {
- # Remove current user's subscription to series_id
- my $dbh = Bugzilla->dbh;
- $dbh->do("DELETE FROM user_series_map " .
- "WHERE user_id = $userid AND series_id = $self->{'series_id'}");
- }
-}
-
-sub isSubscribed {
- my $self = shift;
- my $userid = shift;
-
- my $dbh = Bugzilla->dbh;
- my $issubscribed = $dbh->selectrow_array("SELECT 1 FROM user_series_map " .
- "WHERE user_id = $userid " .
- "AND series_id = $self->{'series_id'}");
- return $issubscribed;
}
1;