#!/usr/bin/perl -wT # -*- Mode: perl; indent-tabs-mode: nil -*- # # The contents of this file are subject to the Mozilla Public # 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 Terry Weissman. # Portions created by Terry Weissman are # Copyright (C) 2000 Terry Weissman. All # Rights Reserved. # # Contributor(s): Terry Weissman use strict; use lib "."; require "CGI.pl"; use Bugzilla::Constants; use Bugzilla::Config qw(:DEFAULT $datadir); use Bugzilla::User; my $cgi = Bugzilla->cgi; my $dbh = Bugzilla->dbh; use vars qw($template $vars); sub Validate ($$) { my ($name, $description) = @_; if ($name eq "") { ThrowUserError("keyword_blank_name"); } if ($name =~ /[\s,]/) { ThrowUserError("keyword_invalid_name"); } if ($description eq "") { ThrowUserError("keyword_blank_description"); } } sub ValidateKeyID { my $id = shift; $id = trim($id || 0); detaint_natural($id) || ThrowCodeError('invalid_keyword_id'); return $id; } # # Preliminary checks: # Bugzilla->login(LOGIN_REQUIRED); print Bugzilla->cgi->header(); UserInGroup("editkeywords") || ThrowUserError("auth_failure", {group => "editkeywords", action => "edit", object => "keywords"}); my $action = trim($cgi->param('action') || ''); $vars->{'action'} = $action; if ($action eq "") { my @keywords; SendSQL("SELECT keyworddefs.id, keyworddefs.name, keyworddefs.description, COUNT(keywords.bug_id) FROM keyworddefs LEFT JOIN keywords ON keyworddefs.id = keywords.keywordid " . $dbh->sql_group_by('keyworddefs.id', 'keyworddefs.name, keyworddefs.description') . " ORDER BY keyworddefs.name"); while (MoreSQLData()) { my ($id, $name, $description, $bugs) = FetchSQLData(); my $keyword = {}; $keyword->{'id'} = $id; $keyword->{'name'} = $name; $keyword->{'description'} = $description; $keyword->{'bug_count'} = $bugs; push(@keywords, $keyword); } print Bugzilla->cgi->header(); $vars->{'keywords'} = \@keywords; $template->process("admin/keywords/list.html.tmpl", $vars) || ThrowTemplateError($template->error()); exit; } if ($action eq 'add') { print Bugzilla->cgi->header(); $template->process("admin/keywords/create.html.tmpl", $vars) || ThrowTemplateError($template->error()); exit; } # # action='new' -> add keyword entered in the 'action=add' screen # if ($action eq 'new') { # Cleanups and valididy checks my $name = trim($cgi->param('name') || ''); my $description = trim($cgi->param('description') || ''); Validate($name, $description); SendSQL("SELECT id FROM keyworddefs WHERE name = " . SqlQuote($name)); if (FetchOneColumn()) { $vars->{'name'} = $name; ThrowUserError("keyword_already_exists", $vars); } # Pick an unused number. Be sure to recycle numbers that may have been # deleted in the past. This code is potentially slow, but it happens # rarely enough, and there really aren't ever going to be that many # keywords anyway. SendSQL("SELECT id FROM keyworddefs ORDER BY id"); my $newid = 1; while (MoreSQLData()) { my $oldid = FetchOneColumn(); if ($oldid > $newid) { last; } $newid = $oldid + 1; } # Add the new keyword. SendSQL("INSERT INTO keyworddefs (id, name, description) VALUES ($newid, " . SqlQuote($name) . "," . SqlQuote($description) . ")"); # Make versioncache flush unlink "$datadir/versioncache"; print Bugzilla->cgi->header(); $vars->{'name'} = $name; $template->process("admin/keywords/created.html.tmpl", $vars) || ThrowTemplateError($template->error()); exit; } # # action='edit' -> present the edit keywords from # # (next action would be 'update') # if ($action eq 'edit') { my $id = ValidateKeyID(scalar $cgi->param('id')); # get data of keyword SendSQL("SELECT name,description FROM keyworddefs WHERE id=$id"); my ($name, $description) = FetchSQLData(); if (!$name) { $vars->{'id'} = $id; ThrowCodeError("invalid_keyword_id", $vars); } SendSQL("SELECT count(*) FROM keywords WHERE keywordid = $id"); my $bugs = ''; $bugs = FetchOneColumn() if MoreSQLData(); $vars->{'keyword_id'} = $id; $vars->{'name'} = $name; $vars->{'description'} = $description; $vars->{'bug_count'} = $bugs; print Bugzilla->cgi->header(); $template->process("admin/keywords/edit.html.tmpl", $vars) || ThrowTemplateError($template->error()); exit; } # # action='update' -> update the keyword # if ($action eq 'update') { my $id = ValidateKeyID(scalar $cgi->param('id')); my $name = trim($cgi->param('name') || ''); my $description = trim($cgi->param('description') || ''); Validate($name, $description); SendSQL("SELECT id FROM keyworddefs WHERE name = " . SqlQuote($name)); my $tmp = FetchOneColumn(); if ($tmp && $tmp != $id) { $vars->{'name'} = $name; ThrowUserError("keyword_already_exists", $vars); } SendSQL("UPDATE keyworddefs SET name = " . SqlQuote($name) . ", description = " . SqlQuote($description) . " WHERE id = $id"); # Make versioncache flush unlink "$datadir/versioncache"; print Bugzilla->cgi->header(); $vars->{'name'} = $name; $template->process("admin/keywords/rebuild-cache.html.tmpl", $vars) || ThrowTemplateError($template->error()); exit; } if ($action eq 'delete') { my $id = ValidateKeyID(scalar $cgi->param('id')); SendSQL("SELECT name FROM keyworddefs WHERE id=$id"); my $name = FetchOneColumn(); if (!$cgi->param('reallydelete')) { SendSQL("SELECT count(*) FROM keywords WHERE keywordid = $id"); my $bugs = FetchOneColumn(); if ($bugs) { $vars->{'bug_count'} = $bugs; $vars->{'keyword_id'} = $id; $vars->{'name'} = $name; print Bugzilla->cgi->header(); $template->process("admin/keywords/confirm-delete.html.tmpl", $vars) || ThrowTemplateError($template->error()); exit; } } SendSQL("DELETE FROM keywords WHERE keywordid = $id"); SendSQL("DELETE FROM keyworddefs WHERE id = $id"); # Make versioncache flush unlink "$datadir/versioncache"; print Bugzilla->cgi->header(); $vars->{'name'} = $name; $template->process("admin/keywords/rebuild-cache.html.tmpl", $vars) || ThrowTemplateError($template->error()); exit; } ThrowCodeError("action_unrecognized", $vars);