Login
[x]
Log in using an account from:
Fedora Account System
Red Hat Associate
Red Hat Customer
Or login using a Red Hat Bugzilla account
Forgot Password
Login:
Hide Forgot
Create an Account
Red Hat Bugzilla – Attachment 295587 Details for
Bug 406111
3.1: Issue Tracker Integration
[?]
New
Simple Search
Advanced Search
My Links
Browse
Requests
Reports
Current State
Search
Tabular reports
Graphical reports
Duplicates
Other Reports
User Changes
Plotly Reports
Bug Status
Bug Severity
Non-Defaults
|
Product Dashboard
Help
Page Help!
Bug Writing Guidelines
What's new
Browser Support Policy
5.0.4.rh83 Release notes
FAQ
Guides index
User guide
Web Services
Contact
Legal
This site requires JavaScript to be enabled to function correctly, please enable it.
[patch]
Issue tracker integration (v3)
issuetracker.patch (text/plain), 71.93 KB, created by
David Lawrence
on 2008-02-22 04:30:13 UTC
(
hide
)
Description:
Issue tracker integration (v3)
Filename:
MIME Type:
Creator:
David Lawrence
Created:
2008-02-22 04:30:13 UTC
Size:
71.93 KB
patch
obsolete
>Index: post_bug.cgi >=================================================================== >RCS file: /cvs/qa/rh_bugzilla_3/post_bug.cgi,v >retrieving revision 1.5 >diff -u -r1.5 post_bug.cgi >--- post_bug.cgi 13 Feb 2008 16:44:32 -0000 1.5 >+++ post_bug.cgi 22 Feb 2008 04:27:52 -0000 >@@ -165,6 +165,10 @@ > )); > # REDHAT EXTENSION END 406151 > >+# REDHAT EXTENSION START 406111 >+Bugzilla::Hook::process('get_bug_fields', { fields => \@bug_fields }); >+# REDHAT EXTENSION END 406111 >+ > my %bug_params; > foreach my $field (@bug_fields) { > $bug_params{$field} = $cgi->param($field); >Index: process_bug.cgi >=================================================================== >RCS file: /cvs/qa/rh_bugzilla_3/process_bug.cgi,v >retrieving revision 1.14 >diff -u -r1.14 process_bug.cgi >--- process_bug.cgi 13 Feb 2008 16:44:32 -0000 1.14 >+++ process_bug.cgi 22 Feb 2008 04:27:52 -0000 >@@ -582,6 +582,11 @@ > # Set and update flags. > Bugzilla::Flag->process($bug, undef, $timestamp, $vars); > >+ # REDHAT EXTENSION START 406111 >+ Bugzilla::Hook::process( 'update_bug_data', >+ { bug => $bug, timestamp => $timestamp, who => Bugzilla->user->id } ); >+ # REDHAT EXTENSION END 406111 >+ > $dbh->bz_commit_transaction(); > > ############### >Index: Bugzilla/Bug.pm >=================================================================== >RCS file: /cvs/qa/rh_bugzilla_3/Bugzilla/Bug.pm,v >retrieving revision 1.23 >diff -u -r1.23 Bug.pm >--- Bugzilla/Bug.pm 21 Feb 2008 16:23:57 -0000 1.23 >+++ Bugzilla/Bug.pm 22 Feb 2008 04:27:55 -0000 >@@ -291,6 +291,10 @@ > return $error_self; > } > >+ # REDHAT EXTENSION START 406111 >+ Bugzilla::Hook::process('get_bug_data', { bug => $self }); >+ # REDHAT EXTENSION END 406111 >+ > return $self; > } > >@@ -367,6 +371,14 @@ > delete $params->{comment}; > delete $params->{commentprivacy}; > >+ my $deleted_hook_params = {}; >+ # REDHAT EXTENSION START 406111 >+ # Remove params that should not be used in insert_create_data >+ # but need to be passed to the create_bug_data hook >+ Bugzilla::Hook::process('delete_insert_params', >+ { params => $params, deleted_params => $deleted_hook_params }); >+ # REDHAT EXTENSION END 406111 >+ > # Set up the keyword cache for bug creation. > my $keywords = $params->{keywords}; > $params->{keywords} = join(', ', sort {lc($a) cmp lc($b)} >@@ -470,6 +482,11 @@ > } > } > >+ # REDHAT EXTENSION START 406111 >+ Bugzilla::Hook::process('create_bug_data', >+ { bug => $bug, params => $params, deleted_params => $deleted_hook_params }); >+ # REDHAT EXTENSION END 406111 >+ > $dbh->bz_commit_transaction(); > > # Because MySQL doesn't support transactions on the longdescs table, >@@ -1632,6 +1649,11 @@ > > sub fields { > my $class = shift; >+ my @extra_fields; >+ >+ # REDHAT EXTENSION START 406111 >+ Bugzilla::Hook::process('get_bug_fields', { fields => \@extra_fields }); >+ # REDHAT EXTENSION END 406111 > > return ( > # Standard Fields >@@ -1653,7 +1675,11 @@ > # Conditional Fields > Bugzilla->params->{'useqacontact'} ? "qa_contact" : (), > # Custom Fields >- Bugzilla->custom_field_names >+ Bugzilla->custom_field_names, >+ >+ # REDHAT EXTENSION START 406111 >+ @extra_fields, >+ # REDHAT EXTENSION END 406111 > ); > } > >@@ -3032,6 +3058,12 @@ > $activity_visible = 1; > } > >+ # REDHAT EXTENSIONS START 406111 >+ Bugzilla::Hook::process('filter_change', >+ { field => $fieldname, added => $added, >+ removed => $removed, visible => \$activity_visible }); >+ # REDHAT EXTENSIONS END 406111 >+ > if ($activity_visible) { > # This gets replaced with a hyperlink in the template. > $field =~ s/^Attachment// if $attachid; >Index: Bugzilla/BugMail.pm >=================================================================== >RCS file: /cvs/qa/rh_bugzilla_3/Bugzilla/BugMail.pm,v >retrieving revision 1.10 >diff -u -r1.10 BugMail.pm >--- Bugzilla/BugMail.pm 15 Feb 2008 16:34:46 -0000 1.10 >+++ Bugzilla/BugMail.pm 22 Feb 2008 04:27:56 -0000 >@@ -533,6 +533,14 @@ > push(@excluded, $user->login); > } > } >+ >+ # REDHAT EXTENSION START 406111 >+ Bugzilla::Hook::process('send_change', >+ { bug => $id, diffs => $diffs, >+ start => $start, end => $end, >+ sent => \@sent, excluded => \@excluded, >+ changer => $changer }); >+ # REDHAT EXTENSION END 406111 > > $dbh->do('UPDATE bugs SET lastdiffed = ? WHERE bug_id = ?', > undef, ($end, $id)); >@@ -635,6 +643,12 @@ > $add_diff = 1; > } > >+ # REDHAT EXTENSIONS START 406111 >+ Bugzilla::Hook::process('filter_change', >+ { field => $diff->{fieldname}, added => $diff->{new}, >+ removed => $diff->{old}, visible => \$add_diff }); >+ # REDHAT EXTENSIONS END 406111 >+ > if ($add_diff) { > if (exists($diff->{'header'}) && > ($diffheader ne $diff->{'header'})) { >Index: Bugzilla/Config/IssueTracker.pm >=================================================================== >RCS file: Bugzilla/Config/IssueTracker.pm >diff -N Bugzilla/Config/IssueTracker.pm >--- /dev/null 1 Jan 1970 00:00:00 -0000 >+++ Bugzilla/Config/IssueTracker.pm 22 Feb 2008 04:27:56 -0000 >@@ -0,0 +1,88 @@ >+# -*- 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 Netscape Communications >+# Corporation. Portions created by Netscape are >+# Copyright (C) 1998 Netscape Communications Corporation. All >+# Rights Reserved. >+# >+# Contributor(s): Terry Weissman <terry@mozilla.org> >+# Dawn Endico <endico@mozilla.org> >+# Dan Mosedale <dmose@mozilla.org> >+# Joe Robins <jmrobins@tgix.com> >+# Jacob Steenhagen <jake@bugzilla.org> >+# J. Paul Reed <preed@sigkill.com> >+# Bradley Baetz <bbaetz@student.usyd.edu.au> >+# Joseph Heenan <joseph@heenan.me.uk> >+# Erik Stambaugh <erik@dasbistro.com> >+# Frédéric Buclin <LpSolit@gmail.com> >+# Dave Lawrence <dkl@redhat.com> >+ >+package Bugzilla::Config::IssueTracker; >+ >+use strict; >+ >+use Bugzilla::Config::Common; >+ >+$Bugzilla::Config::IssueTracker::sortkey = "15"; >+ >+sub get_param_list { >+ my $class = shift; >+ my @param_list = ( >+ { >+ name => 'useissuetracker', >+ type => 'b', >+ default => 1, >+ }, >+ >+ { >+ name => 'issuetracker_download_key', >+ type => 't', >+ default => 'f6f87caf6ac2dc1eb1173257c8a5ef78', >+ }, >+ >+ { >+ name => 'issuetracker_rpc_user', >+ type => 't', >+ default => 'tao@redhat.com', >+ }, >+ >+ { >+ name => 'issuetracker_rpc_password', >+ type => 't', >+ default => '', >+ }, >+ >+ { >+ name => 'issuetracker_rpcserver', >+ type => 't', >+ default => 'https://enterprise.redhat.com/issue-tracker/xmlrpc.server.php', >+ }, >+ >+ { >+ name => 'issuetracker_urlbase', >+ type => 't', >+ default => 'https://enterprise.redhat.com/issue-tracker/?module=issues&action=view&tid=', >+ }, >+ >+ { >+ name => 'issuetracker_user', >+ type => 't', >+ default => 'tao@redhat.com', >+ } ); >+ >+ return @param_list; >+} >+ >+1; >Index: Bugzilla/Template/Plugin/Hook.pm >=================================================================== >RCS file: /cvs/qa/rh_bugzilla_3/Bugzilla/Template/Plugin/Hook.pm,v >retrieving revision 1.1.1.1 >diff -u -r1.1.1.1 Hook.pm >--- Bugzilla/Template/Plugin/Hook.pm 19 Nov 2007 22:11:21 -0000 1.1.1.1 >+++ Bugzilla/Template/Plugin/Hook.pm 22 Feb 2008 04:27:56 -0000 >@@ -49,6 +49,7 @@ > > my $paths = $self->{_CONTEXT}->{LOAD_TEMPLATES}->[0]->paths; > my $template = $self->{_CONTEXT}->stash->{component}->{name}; >+ my $caller = $self->{_CONTEXT}->stash->{component}->{caller}; > my @hooks = (); > > # sanity check: >@@ -56,6 +57,9 @@ > ThrowCodeError('template_invalid', { name => $template}); > } > >+ # If we are in a PROCESS block then get the caller name instead >+ $template = $template =~ m/(.*)\.(.*)\.tmpl/ ? $template : $caller; >+ > # also get extension hook files that live in extensions/: > # parse out the parts of the template name > my ($vol, $subpath, $filename) = File::Spec->splitpath($template); >Index: extensions/issuetracker/version.pl >=================================================================== >RCS file: extensions/issuetracker/version.pl >diff -N extensions/issuetracker/version.pl >--- /dev/null 1 Jan 1970 00:00:00 -0000 >+++ extensions/issuetracker/version.pl 22 Feb 2008 04:27:57 -0000 >@@ -0,0 +1,31 @@ >+# -*- 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 Example WebService Plugin >+# >+# The Initial Developer of the Original Code is Everything Solved, Inc. >+# Portions created by Everything Solved, Inc. are Copyright (C) 2007 >+# Everything Solved, Inc. All Rights Reserved. >+# >+# Contributor(s): Max Kanat-Alexander <mkanat@bugzilla.org> >+ >+# This script does some code to return a version number. However, >+# most plugins will probably just want to return a raw string. >+# To do that, the only contents of the file should be the string >+# on a single line, like: >+# >+# '1.2.3'; >+ >+use strict; >+no warnings qw(void); # Avoid "useless use of a constant in void context" >+use Bugzilla::Constants; >+BUGZILLA_VERSION; >Index: extensions/issuetracker/code/create_bug_data.pl >=================================================================== >RCS file: extensions/issuetracker/code/create_bug_data.pl >diff -N extensions/issuetracker/code/create_bug_data.pl >--- /dev/null 1 Jan 1970 00:00:00 -0000 >+++ extensions/issuetracker/code/create_bug_data.pl 22 Feb 2008 04:27:57 -0000 >@@ -0,0 +1,57 @@ >+# -*- 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 Everything Solved, Inc. >+# Portions created by Everything Solved, Inc. are Copyright (C) 2007 >+# Everything Solved, Inc. All Rights Reserved. >+# >+# Contributor(s): Dave Lawrence <dkl@redhat.com> >+ >+use strict; >+use warnings; >+use Bugzilla; >+use extensions::issuetracker::lib::IssueTrackerList; >+ >+my $bug = Bugzilla->hook_args->{bug}; >+my $params = Bugzilla->hook_args->{params}; >+my $deleted_params = Bugzilla->hook_args->{deleted_params}; >+ >+my $can_see_issuetracker = Bugzilla->params->{useissuetracker} >+ and Bugzilla->user->in_group('issuetracker'); >+my $issuetrackers = $params->{issuetrackers} >+ || $deleted_params->{issuetrackers}; >+ >+if ( $issuetrackers and $can_see_issuetracker ) { >+ my @it_id = split( /[\s,]+/, $issuetrackers ); >+ >+ shift @it_id if $it_id[0] eq ''; >+ return if !@it_id; >+ >+ my $it = new extensions::issuetracker::lib::IssueTrackerList( -no_id => 1 ); >+ >+ foreach my $id (@it_id) { >+ $it->validateIssueID($id); >+ } >+ >+ extensions::issuetracker::lib::IssueTrackerList->new( >+ -bz_id => $bug->{bug_id}, >+ -rawbug => 1, >+ -issues => \@it_id, >+ -rawissue => 1 >+ )->toDB( -who => Bugzilla->user->id ); >+ >+ $bug->{'issuetrackers'} >+ = extensions::issuetracker::lib::IssueTrackerList >+ ->fetchIssueTrackerIDs( $bugref->{bug_id} ); >+} >Index: extensions/issuetracker/code/delete_insert_params.pl >=================================================================== >RCS file: extensions/issuetracker/code/delete_insert_params.pl >diff -N extensions/issuetracker/code/delete_insert_params.pl >--- /dev/null 1 Jan 1970 00:00:00 -0000 >+++ extensions/issuetracker/code/delete_insert_params.pl 22 Feb 2008 04:27:57 -0000 >@@ -0,0 +1,30 @@ >+# -*- 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 Everything Solved, Inc. >+# Portions created by Everything Solved, Inc. are Copyright (C) 2007 >+# Everything Solved, Inc. All Rights Reserved. >+# >+# Contributor(s): Dave Lawrence <dkl@redhat.com> >+ >+use strict; >+use warnings; >+use Bugzilla; >+use extensions::issuetracker::lib::IssueTrackerList; >+ >+my $params = Bugzilla->hook_args->{params}; >+my $deleted_params = Bugzilla->hook_args->{deleted_params}; >+ >+$deleted_params->{issuetrackers} = $params->{issuetrackers}; >+delete $params->{issuetrackers}; >Index: extensions/issuetracker/code/filter_change.pl >=================================================================== >RCS file: extensions/issuetracker/code/filter_change.pl >diff -N extensions/issuetracker/code/filter_change.pl >--- /dev/null 1 Jan 1970 00:00:00 -0000 >+++ extensions/issuetracker/code/filter_change.pl 22 Feb 2008 04:27:57 -0000 >@@ -0,0 +1,35 @@ >+# -*- 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 Everything Solved, Inc. >+# Portions created by Everything Solved, Inc. are Copyright (C) 2007 >+# Everything Solved, Inc. All Rights Reserved. >+# >+# Contributor(s): Dave Lawrence <dkl@redhat.com> >+ >+use strict; >+use warnings; >+use Bugzilla; >+ >+my $field = Bugzilla->hook_args->{field}; >+my $added = Bugzilla->hook_args->{added}; >+my $removed = Bugzilla->hook_args->{removed}; >+my $visible = Bugzilla->hook_args->{visible}; >+ >+my $can_see_issuetracker = Bugzilla->params->{useissuetracker} and Bugzilla->user->in_group('issuetracker'); >+ >+if ($field eq 'issuetracker' and $can_see_issuetracker ) { >+ $$visible = 1; >+} >+ >Index: extensions/issuetracker/code/get_bug_data.pl >=================================================================== >RCS file: extensions/issuetracker/code/get_bug_data.pl >diff -N extensions/issuetracker/code/get_bug_data.pl >--- /dev/null 1 Jan 1970 00:00:00 -0000 >+++ extensions/issuetracker/code/get_bug_data.pl 22 Feb 2008 04:27:57 -0000 >@@ -0,0 +1,40 @@ >+# -*- 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 Everything Solved, Inc. >+# Portions created by Everything Solved, Inc. are Copyright (C) 2007 >+# Everything Solved, Inc. All Rights Reserved. >+# >+# Contributor(s): Dave Lawrence <dkl@redhat.com> >+ >+use strict; >+use warnings; >+use Bugzilla; >+use extensions::issuetracker::lib::IssueTrackerList; >+ >+my $bugref = Bugzilla->hook_args->{bug}; >+ >+# Get IssueTracker ID's >+if ( Bugzilla->params->{useissuetracker} >+ and Bugzilla->user->in_group('issuetracker') ) >+{ >+ $bugref->{'issuetrackers'} >+ = extensions::issuetracker::lib::IssueTrackerList >+ ->fetchIssueTrackerIDs( $bugref->{bug_id} ); >+} >+else { >+ $bugref->{'issuetrackers'} = []; >+} >+ >+1; >Index: extensions/issuetracker/code/get_bug_fields.pl >=================================================================== >RCS file: extensions/issuetracker/code/get_bug_fields.pl >diff -N extensions/issuetracker/code/get_bug_fields.pl >--- /dev/null 1 Jan 1970 00:00:00 -0000 >+++ extensions/issuetracker/code/get_bug_fields.pl 22 Feb 2008 04:27:57 -0000 >@@ -0,0 +1,25 @@ >+# -*- 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 Everything Solved, Inc. >+# Portions created by Everything Solved, Inc. are Copyright (C) 2007 >+# Everything Solved, Inc. All Rights Reserved. >+# >+# Contributor(s): Dave Lawrence <dkl@redhat.com> >+ >+use strict; >+use warnings; >+use Bugzilla; >+my $fields = Bugzilla->hook_args->{fields}; >+push( @$fields, 'issuetrackers' ); >Index: extensions/issuetracker/code/send_change.pl >=================================================================== >RCS file: extensions/issuetracker/code/send_change.pl >diff -N extensions/issuetracker/code/send_change.pl >--- /dev/null 1 Jan 1970 00:00:00 -0000 >+++ extensions/issuetracker/code/send_change.pl 22 Feb 2008 04:27:57 -0000 >@@ -0,0 +1,54 @@ >+# -*- 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 Everything Solved, Inc. >+# Portions created by Everything Solved, Inc. are Copyright (C) 2007 >+# Everything Solved, Inc. All Rights Reserved. >+# >+# Contributor(s): Dave Lawrence <dkl@redhat.com> >+ >+use strict; >+use warnings; >+use Bugzilla; >+use extensions::issuetracker::lib::IssueTrackerList; >+ >+my $bug = Bugzilla->hook_args->{bug}; >+my $diffs = Bugzilla->hook_args->{diffs}; >+my $start = Bugzilla->hook_args->{start}; >+my $end = Bugzilla->hook_args->{end}; >+my $changer = Bugzilla->hook_args->{changer}; >+my $sentlist = Bugzilla->hook_args->{sent}; >+my $excluded = Bugzilla->hook_args->{excluded}; >+ >+my $nocomment = 0; >+ >+# prevents looping of issue tracker changes back to issue tracker again. >+if ( Bugzilla->params->{issuetracker_user} eq $changer ) { >+ >+ # Find out if their are changes we are interested in >+ my %fields = qw(bug_status status); >+ my @diffs = grep $fields{ $_->[6] }, @$diffs; >+ return if !@diffs; >+ $nocomment = 1; >+} >+ >+( my ( $sent, $excl ) >+ = extensions::issuetracker::lib::IssueTrackerList->newFromDB( >+ -bz_id => $bug, >+ -rawbug => 1 >+ )->sendChanges( $diffs, $start, $end, $nocomment ) >+) or return; >+ >+push @$sentlist, 'Issue Tracker id(s) ' . join( ',', @$sent ) if @$sent; >+push @$excluded, 'Issue Tracker id(s) ' . join( ',', @$excl ) if @$excl; >Index: extensions/issuetracker/code/update_bug_data.pl >=================================================================== >RCS file: extensions/issuetracker/code/update_bug_data.pl >diff -N extensions/issuetracker/code/update_bug_data.pl >--- /dev/null 1 Jan 1970 00:00:00 -0000 >+++ extensions/issuetracker/code/update_bug_data.pl 22 Feb 2008 04:27:57 -0000 >@@ -0,0 +1,60 @@ >+# -*- 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 Everything Solved, Inc. >+# Portions created by Everything Solved, Inc. are Copyright (C) 2007 >+# Everything Solved, Inc. All Rights Reserved. >+# >+# Contributor(s): Dave Lawrence <dkl@redhat.com> >+ >+use strict; >+use warnings; >+use Bugzilla; >+use extensions::issuetracker::lib::IssueTrackerList; >+ >+my $bug = Bugzilla->hook_args->{bug}; >+my $who = Bugzilla->hook_args->{who}; >+my $timestamp = Bugzilla->hook_args->{timestamp}; >+my $cgi = Bugzilla->cgi; >+ >+my $can_see_issuetracker = Bugzilla->params->{useissuetracker} >+ and Bugzilla->user->in_group('issuetracker'); >+ >+if ( defined $cgi->param('issuetrackers') and $can_see_issuetracker ) { >+ my @validvalues = split( /[\s,]+/, $cgi->param('issuetrackers') ); >+ >+ # split may produce an empty first element >+ shift @validvalues unless $validvalues[0]; >+ >+ my $issuetrackers = new extensions::issuetracker::lib::IssueTrackerList( >+ -bz_id => $bug->{bug_id}, >+ -rawbug => 1, >+ -issues => \@validvalues >+ ); >+ >+ return undef if not $issuetrackers; >+ >+ my $action = $cgi->param('issuetrackeraction') || "makeexact"; >+ if ( not grep( $action eq $_, qw(add delete makeexact) ) ) { >+ $action = "makeexact"; >+ } >+ >+ # handle changes to associated issue tracker issues >+ $issuetrackers->bz_id( -value => $bug->{bug_id}, -raw => 1 ); >+ $issuetrackers->toDB( >+ -who => $who, >+ -how => $action, >+ -when => $timestamp >+ ); >+} >Index: extensions/issuetracker/lib/IssueTrackerList.pm >=================================================================== >RCS file: extensions/issuetracker/lib/IssueTrackerList.pm >diff -N extensions/issuetracker/lib/IssueTrackerList.pm >--- /dev/null 1 Jan 1970 00:00:00 -0000 >+++ extensions/issuetracker/lib/IssueTrackerList.pm 22 Feb 2008 04:27:58 -0000 >@@ -0,0 +1,1339 @@ >+# -*- 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 Netscape Communications >+# Corporation. Portions created by Netscape are >+# Copyright (C) 1998 Netscape Communications Corporation. All >+# Rights Reserved. >+# >+# Contributor(s): Mike MacKenzie <mmackenz@redhat.com> >+ >+=pod >+ >+=head1 NAME >+ >+Bugzilla::IssueTrackerList - Interface to the Bugzilla bug to issue >+tracker issue mapping. >+ >+=head1 SYNOPSIS >+ >+ # make changes to the issue mapping table >+ $itlist = new Bugzilla::IssueTrackerList(-bz_id => $bugid, -issues => [$it1, $it2]); >+ $itlist->toDB(-who => $myid, -when => $timestamp); >+ >+ >+ # work with the issues for a given bug >+ $itlist = newFromDB Bugzilla::IssueTrackerList(-bz_id => $bugid, -raw => 1); >+ print "List of issues associated with bug $bugid:\n"; >+ foreach my $issue (@($itlist->issues)) { >+ print " ", $issue, "\n"; >+ } >+ >+ # same as above, done with class method instead of an instance >+ $issues = Bugzilla::IssueTrackerList->fetchIssueTrackerIDs($bugid); >+ print "List of issues associated with bug $bugid:\n"; >+ foreach my $issue (@$issues) { >+ <tr> >+ print " ", $issue, "\n"; >+ } >+ >+ # other way around >+ $bugz = Bugzilla::IssueTrackerList->fetchBugzillaIDs($itid); >+ print "List of bugs associated with issue tracker ID $itid:\n"; >+ foreach my $bug (@$bugz) { >+ print " ", $bug, "\n"; >+ } >+ >+ # make the same change to several bugs >+ @buglist = &get_some_bugs(); >+ @issues = &get_some_issues(); >+ $timestamp = &get_a_timestamp(); >+ $change = 'add'; >+ $itlist = new Bugzilla::IssueTrackerList($buglist[0], \@issues); >+ foreach my $bug (@buglist) { >+ $itlist->bz_id($bug); >+ $idlist->toDB(-who => $me, -how => $change, -when => $timestamp); >+ } >+ >+=head1 DESCRIPTION >+ >+This module provides an interface for working with the >+bugzilla-to-issue tracker mapping table. This provides a basic >+linkage between customer support issues in an external issue tracking >+system and bugs in Bugzilla. The nature of this relationship might >+commonly be expected to be that the given issue(s) lead to the >+creation of the bug, and that teh bug identifies a specific code >+change that will address the issue(s), but other relationships are >+possible -- and likely in the real world. This module does not >+describe or circumscribe the nature of the relationship. >+ >+It is assumed that a single issume may be associated with multiple >+bugs and vice versa. >+ >+An object oriented interface is provided as well as some provision for >+functional interaction (actually class methods rather than functions) >+where interacting through an instance is too limiting. >+ >+The instances created by this module assume that you are working from >+the perspective of one particular bug with possible several associated >+issues. Tools are provided for instantiation an object based on new >+data or form data stored in the database. A variety of changes can be >+made to the object and then the results can be applied to the >+database. >+ >+=cut >+ >+############################################################################ >+# Module Initialization >+############################################################################ >+ >+use strict; >+ >+package extensions::issuetracker::lib::IssueTrackerList; >+ >+# This module requires that its caller have said "require CGI.pl" to import >+# relevant functions from that script and its companion globals.pl. >+ >+use fields qw(bz_id issues); >+ >+use Bugzilla; >+use Bugzilla::Error; >+use Bugzilla::Util; >+use XMLRPC::Lite; >+use Data::Dumper; >+ >+# constant for the max number of tries to connect to IT before >+# sending an error email >+use constant MAXTRIES => 3; >+ >+my $dbh = Bugzilla->dbh; >+ >+############################################################################ >+# Functions/Methods >+############################################################################ >+ >+=pod >+ >+=head2 Constructors & Factory Methods >+ >+=over 4 >+ >+=cut >+ >+=pod >+ >+=item C<new> >+ >+Z<> >+ >+ $Bugzilla::IssueTrackerList new(-bz_id => $bz_id, >+ -issues => \@issues, >+ -skip_authorization => $boolean, >+ -rawbug => $boolean2, >+ -rawissue => $boolean3 >+ -no_id => $boolean4) >+ >+Construct and return a new Bugzilla::IssueTrackerList object based on >+values passed in as named parameters to the method. Paramaters are: >+ >+=over 4 >+ >+=item C<-bz_id> >+ >+The ID for the Bugzilla bug that is in view. This is a simple scalar >+and will be validated. This parameter is required, unless C<-no_id> is >+true. >+ >+=item C<-issues> >+ >+An array reference containing the list of issued tracker id's that are >+connected with this bug. The list may contain any number of id's >+including one or none. This may be ommitted in which case the object >+will be initialized as if an empty array reference were given. >+ >+=item C<-skip_authorization> >+ >+A boolean to indicate whether or not to also check whether the current >+user is allowed access to the given bug when the bugzilla ID is being >+checked. If C<-rawbug> is true, this option is irrelvant. >+ >+=item C<-rawbug> >+ >+A boolean, which, if true, will cause the bugzilla ID to be placed in >+the new object without any checks for validity or untainting. Use >+with caution or at least awareness :) >+ >+=item C<-rawissue> >+ >+A boolean, which, if true, will cause the issue IDs to be placed in >+the new object without any checks for validity or untainting. Use >+with caution or at least awareness :) >+ >+=item C<-no_id> >+ >+A boolean, which, if true, will allow the object to be instantiated >+without a Bugzilla ID. A Bugzilla ID will need to be supplied later, >+via C<bz_id()> before C<toDB> can be used. >+ >+=back >+ >+The Bugzilla ID and issue tracker IDs are checked for validity and >+detainted, unless C<-raw> is true, and the Bugzilla ID will be checked >+to see whether the user has authorization to access the bug unless >+C<-raw> or C<-skip_authorization> are true. >+ >+=cut >+ >+sub new { >+ my __PACKAGE__ $self = shift; >+ >+ # initialize object >+ unless ( ref $self ) { >+ $self = fields::new($self); >+ } >+ >+ # get parameters >+ my %param = @_; >+ >+ ### set instance variables >+ unless ( $param{-no_id} ) { >+ >+ # make sure required parameter is present >+ $param{-bz_id} || ThrowCodeError('missing_bug_id'); >+ >+ $param{-rawbug} >+ ? $self->_bz_id( $param{-bz_id} ) >+ : $self->bz_id( >+ -value => $param{-bz_id}, >+ -skip_authorization => $param{-skip_authorization} >+ ); >+ } >+ >+ $param{-rawissue} >+ ? $self->_issues( $param{-issues} || [] ) >+ : $self->issues( -value => $param{-issues} || [] ); >+ ### >+ >+ # return >+ $self; >+} >+ >+=pod >+ >+=item C<newFromDB> >+ >+Z<> >+ >+ $Bugzilla::IssueTrackerList newFromDB(-bz_id => $bz_id, >+ -skip_authorization => $boolean, >+ -raw => $boolean2) >+ >+Instantiates a new Bugzilla::IssueTrackerList object based on the data >+currently in the database. The Bugzilla bug ID is given and the >+associated issue tracker IDs are pulled from the database. This >+method uses named parameters. The parameters are: >+ >+=over 4 >+ >+=item C<-bz_id> >+ >+The ID for the Bugzilla bug that is in view. This is a simple scalar >+and will be validated. This parameter is required. >+ >+=item C<-skip_authorization> >+ >+A boolean to indicate whether or not to also check whether the current >+user is allowed access to the given bug when the bugzilla ID is being >+checked. This is irrelevant if C<-rawbug> is true. >+ >+=item C<-rawbug> >+ >+A boolean, which, if true, will cause the bugzilla ID to be placed in >+the new object without any checks for validity or untainting. Use >+with caution or at least awareness :) >+ >+=item C<-rawissue> >+ >+A boolean, which, if true, will cause the issue IDs to be placed in >+the new object without any checks for validity or untainting. The >+default value for this parameter is true. Set it to a false value >+if you want this validation to occur. >+ >+=back >+ >+=cut >+ >+sub newFromDB { >+ my $class = shift; >+ my %param = @_; >+ >+ # make sure required parameter is present >+ $param{-bz_id} || ThrowCodeError('missing_bug_id'); >+ >+ # get issue tracker IDs from the DB. >+ $param{-issues} = []; >+ foreach my $ref ( @{ $class->fetchIssueTrackerIDs( $param{-bz_id} ) } ) { >+ push( @{ $param{-issues} }, $ref->[0] ); >+ } >+ >+ # don't check the >+ $param{-rawissue} = 1 unless exists $param{-rawissue}; >+ >+ # build and return the new object. >+ $class->new(%param); >+} >+ >+=pod >+ >+=back >+ >+=head2 Instance Methods >+ >+=over 4 >+ >+=cut >+ >+=pod >+ >+=item C<issues> >+ >+Z<> >+ >+ \@issues issues(-value => \@newissues, -raw => $boolean) >+ >+A get/set method. Given no C<-value>, returns an arrary reference >+containing the current set of issue tracker IDs in the object. With a >+C<-value> given, replaces the set of issues associated with the given >+bug and returns the old set. Each issue ID is checked for validity >+unless C<-raw> is set to a true value. >+ >+=cut >+ >+sub issues { >+ my __PACKAGE__ $self = shift; >+ my %param = @_; >+ my $return = $self->{issues}; >+ my $issues = $param{-value}; >+ >+ if ( ref $issues eq 'ARRAY' ) { >+ >+ #do { $self->validateIssueID($_) foreach (@$issues) } unless $param{-raw}; >+ $self->_issues($issues); >+ } >+ elsif ($issues) { >+ ThrowCodeError( >+ 'bad_arg', >+ { argument => '-value', >+ function => 'Bugzilla::IssueTrackerList::issues' >+ } >+ ); >+ } >+ >+ # return >+ $return; >+} >+ >+=pod >+ >+=begin private >+ >+=item C<_issues> >+ >+Z<> >+ >+ void _issues(\@newissues) >+ >+A private method that sets the issues instance variables with a minimum >+of fuss -- no validation or untainting. It also does not check that >+the input parameter is a valid array reference. Do not use this >+outside of this module. Use C<issues(-raw => 1)> instead. >+ >+=end private >+ >+=cut >+ >+sub _issues { >+ my __PACKAGE__ $self = shift; >+ $self->{issues} = $_[0]; # if bz_id was not initialized >+} >+ >+=pod >+ >+=item C<bz_id> >+ >+Z<> >+ >+ $bz_id bz_id(-value => $bz_id, -skip_authorization => $boolean, -raw => $boolean2) >+ >+A get/set method for the Bugzilla bug ID instance variable. With no >+arguments, returns the Bugzilla bug ID. With C<-value> set, attempts >+to set the Bugzilla ID number to this new value, checking that it is a >+real bug ID and that the user has permission to see it. If successful, >+the old bug ID is returned. >+ >+C<-skip_authorization> is an optional boolean; if true, the new Bug ID >+is not checked for whether the current user is authorized to see the >+bug. >+ >+C<-raw> is an optional boolean; if true, the new Bug ID is not checked >+at all. If this is true, C<-skip_authorization> is ignored. >+ >+=cut >+ >+sub bz_id { >+ my __PACKAGE__ $self = shift; >+ my %param = @_; >+ my $return = $self->{bz_id} >+ if $self->{bz_id}; # if bz_id was not initialized >+ >+ if ( $param{-value} ) { >+ Bugzilla::Bug::ValidateBugID( $param{-value}, >+ $param{-skip_authorization} ) >+ unless $param{-raw}; >+ $self->_bz_id( $param{-value} ); >+ } >+ >+ # return >+ $return; >+} >+ >+=pod >+ >+=begin private >+ >+=item C<_bz_id> >+ >+Z<> >+ >+ void _bz_id($bz_id) >+ >+A private method for setting the Bugzilla bug ID with a minimum of >+fuss. Does not check validity or authorization or even that a scalar >+argument is given. Do not use this outside of this module. Use >+C<bz_id(-raw => 1)> instead. >+ >+=end private >+ >+=cut >+ >+sub _bz_id { >+ my __PACKAGE__ $self = shift; >+ $self->{bz_id} = $_[0]; >+} >+ >+# documentation for the Issue Tracker's XML RPC call used below >+# >+# IT.addEvent($struct, $username, $password): Adds an event to an >+# Issue-Tracker ticket >+# >+# Parameters: >+# >+# $struct: Data structure containing the following keys >+# >+# * 'tid': >+# Issue-Tracker Ticket ID that you are sending this event to >+# [string] (REQUIRED) >+# * 'bugzilla_id': >+# The Bugzilla ID that is associated with this IT ticket >+# [string] (REQUIRED) >+# * 'comment' >+# Struct (OPTIONAL) >+# o text [string]: New comment on the bugzilla bug >+# o private [boolean]: Public/Private flag for the comment >+# (defaults to 't') >+# * 'private' >+# Flag ('t'/'f') to make this event private/public [string] >+# (OPTIONAL) (defaults to 't') >+# * 'summary' >+# Array[old string, new string] - Brief description of bug (OPTIONAL) >+# * 'status' >+# Array[old string, new string] - Status of the bug (OPTIONAL) >+# * 'resolution' >+# Array[old string, new string] - If bug is closed, list reason (OPTIONAL) >+# * 'assignedto' >+# Array[old string, new string] - The email address of the >+# person assigned to the bug (OPTIONAL) >+# * 'blocks' >+# Array[old Array, new Array] - List of bug ids that cannot be >+# closed until this bug is closed (OPTIONAL) >+# * 'dependson' >+# Array[old Array, new Array] - List of bug ids that must be >+# closed before this bug is closed (OPTIONAL) >+# * 'notify' >+# String - Comma-separated list of additional email addresses to >+# notify (OPTIONAL) >+# >+# $username Required username for Bugzilla [string] >+# $password Required password for Bugzilla [string] >+ >+=pod >+ >+=item C<sendChanges> >+ >+Z<> >+ >+ (\@sentids,\@skippedids) sendChanges(\@changelist, $start, $end) >+ >+Reports 'interesting' changes that have (presumably) just been applied >+to the bug in the caller to all of the caller's issues via XML-RPC. >+All changes, except new comments, are reported in C<@changelist>, an >+array of arrays. Only the items at indexes 0,2,3,4, and 6 are of interest >+to this method: >+ >+=over >+ >+=item 0 >+ >+The login name of the person making the change >+ >+=item 2 >+ >+The date and time the change was made. Must be in a common >+format, but the exact format is not defined. >+ >+=item 3 >+ >+The old value of the field >+ >+=item 4 >+ >+The new value of the field >+ >+=item 6 >+ >+The name of the field that was changed >+ >+=back >+ >+Only changes to certain fields are reported. The current list of >+'interesting' fields is short_desc, bug_status, resolution, >+assigned_to, blocked, and dependson. >+ >+New comments, that were added between C<start> and C<end> >+date/times, are also reported to the issue tracker, >+ >+C<changelist> is required. The other two arguments are optional. >+ >+The return value is false (undef in scalar context, () in array >+context) if no changes need to be reported -- if there are no issues >+associated with this bug, or none of the reported changes are >+'interesting'. Otherwise, an array of two array refs is returned, the >+first array lists the ids that were successfully notified of changes, >+the second lists ids that were not successfully notified. >+ >+Any fatal errors arising from the XML-RPC system are turned into >+warnings on STDERR. >+ >+All changes in C<changelist> should be within the range of dates >+C<start> and C<end>, so that comments regarding these changes are >+included. This restriction is not enforced by this method, however. >+ >+The peculiar argument structure and behaviors of this method reflect >+the fact that this needs to interact smoothly with >+BugMail::ProcessOneBug(). >+ >+=cut >+ >+my $username = Bugzilla->params->{issuetracker_rpc_user}; >+my $password = Bugzilla->params->{issuetracker_rpc_password}; >+ >+sub _RPCNOERROR; >+sub _RPC; >+ >+sub sendChanges { >+ my ( $self, $diffs, $start, $end, $nocomment ) = @_; >+ my ( %incl, %excl, %diffs, %events ); >+ >+ my $issues = $self->issues; >+ >+ #use Data::Dumper; warn Dumper $diffs; >+ # get the changes and comments we are interested in >+ my %fields = qw( short_desc summary >+ bug_status status >+ priority priority >+ bug_severity severity >+ resolution resolution >+ assigned_to assignedto >+ fixed_in fixedin >+ blocked blocked >+ dependson dependson >+ keywords keywords >+ issuetracker issuetracker >+ flagtypes.name flag); >+ my @diffs = grep $fields{ $_->[7] }, @$diffs; >+ >+ # Do not pass comment if we are only interested in attribute changes >+ my $comments = []; >+ if ( !$nocomment ) { >+ $comments >+ = Bugzilla::Bug::GetComments( $self->{bz_id}, 'oldest_to_newest', >+ $start, $end ); >+ } >+ >+ # Grab list of group ids to pass with event >+ my $bug = new Bugzilla::Bug( $self->{bz_id}, Bugzilla->user->id ); >+ >+ # If current user cannot see bug, load it as bugzilla user so >+ # the message will be transferred anyway >+ my $cant_see = 0; >+ if ( $bug->{error} && $bug->{error} =~ /NotPermitted/i ) { >+ $bug = new Bugzilla::Bug( >+ $self->{bz_id}, >+ Bugzilla->user->login_to_id( >+ Bugzilla->params->{issuetracker_user} >+ ) >+ ); >+ $cant_see = 1; >+ } >+ >+ # Return empty if we still can't see >+ if ( $bug->{error} ) { >+ warn "Error opening bug $self->{bz_id}: $bug->{error}\n"; >+ return ( [], [] ); >+ } >+ >+ my $groupsref = $bug->groups; >+ my $groups = []; >+ foreach my $ref ( @{$groupsref} ) { >+ push( @{$groups}, $ref->{'bit'} ) if $ref->{'ison'}; >+ } >+ >+ # make sure there are interesting changes to report >+ # and there are affected issues to report them to >+ return >+ unless @diffs || @$comments >+ and @$issues || grep $_->[6] eq 'issuetracker', @diffs; >+ >+ # Arrange changes into events based on the time at which changes occurred. >+ # All changes occurring at the same time are assumed to be one event. >+ # Note: performed_by assumes all changes made at the same time are >+ # made by the same person. As long as times include fractional seconds this >+ # should be true 99.9999999% of the time. >+ foreach my $diff (@diffs) { >+ $diffs{ $diff->[3] } = [] if not exists $diffs{ $diff->[3] }; >+ push( @{ $diffs{ $diff->[3] } }, $diff ); >+ } >+ >+ foreach my $time ( sort keys %diffs ) { >+ print STDERR "time: $time\n"; >+ $events{$time} = { >+ bugzilla_id => $self->{bz_id}, >+ performed_by => $diffs{$time}[0][0], >+ groups => $groups, >+ }; >+ foreach my $diff ( @{ $diffs{$time} } ) { >+ $events{$time}{ $fields{ $diff->[7] } } >+ = [ $diff->[4], $diff->[5] ]; >+ } >+ if ( $bug->{'resolution'} eq 'DUPLICATE' ) { >+ $events{$time}{'dup_id'} = $bug->dup_id; >+ } >+ $events{$time}{issuetracker} = $issues; # MUST be after the map above >+ } >+ >+ # add in comments >+ foreach my $comment (@$comments) { >+ my $time = $comment->{'time'}; >+ >+ # create event with basic information if not already created. >+ unless ( exists $events{$time} ) { >+ $events{$time} = { >+ bugzilla_id => $self->{bz_id}, >+ performed_by => $comment->{author}->login, >+ groups => $groups, >+ issuetracker => $issues, >+ }; >+ } >+ $events{$time}{comment} = { >+ text => $comment->{body}, >+ private => $comment->{isprivate} ? 0 : 1 >+ }; >+ } >+ >+ # get the xmlrpc client >+ my $rpc = _RPCNOERROR or return ( [], $issues ); >+ >+ foreach my $evt ( keys %events ) { >+ my $result = eval { callIT_HASHX( 'addEvent', $events{$evt} ) }; >+ >+ print STDERR Dumper($result); >+ >+ # record what happened >+ if ( my $e = $@ ) { >+ mailError( join( ', ', @{ $events{$evt}{'issuetracker'} } ), >+ $e, Dumper( $events{$evt} ) ); >+ $excl{"(Issuetrackers not updated for changes at $evt)"} = 1; >+ next; >+ } >+ foreach my $issue ( keys %{$result} ) { >+ $incl{$issue} = 1 if $result->{$issue}; >+ } >+ foreach my $issue ( @{$issues} ) { >+ $excl{$issue} = 1 if !$result->{$issue}; >+ } >+ } >+ >+ if ($cant_see) { >+ return ( [], [] ); >+ } >+ else { >+ return ( [ keys %incl ], [ keys %excl ] ); >+ } >+} >+ >+=pod >+ >+=item C<toDB> >+ >+Z<> >+ >+ void toDB(-who => $userid, -how => $method, -when => $timestamp) >+ >+Saves the current issue tracker data in the given IssueTrackerList >+object. There are two named parameters: >+ >+=over 4 >+ >+=item C<-who> >+ >+Required. The user id of the person making the change. >+ >+=item C<-how> >+ >+Optional. This value of C<-how> is a scalar determing how the list of >+issue tracker IDs is to affect the database. Three values are >+allowed: >+ >+=over 4 >+ >+=item C<makeexact> >+ >+The default value. Replace the database values for the given Bugzilla >+bug with the values stored in the instance. >+ >+=item C<add> >+ >+Add the issue tracker IDs to those already present in the database for >+this given Bugzilla bug. >+ >+=item C<delete> >+ >+Remove the issue tracker IDs, if they are present in the database for >+this Bugzilla bug. >+ >+=back >+ >+=item C<-when> >+ >+Optional. A timestamp string suitable for passing to >+C<LogActivityEntry()>. Defaults to 'now'. This allows users who have >+to calculate the timestamp for many different database activites >+(e.g., process_bugs.cgi) to use the same timestamp for them all. >+ >+=back >+ >+=cut >+ >+sub toDB { >+ >+ # check and process arguments >+ my $self = shift; >+ my %param = @_; >+ my $who = $param{'-who'} >+ || ThrowCodeError( >+ 'required_arg', >+ { argument => '-who', >+ description => 'user id of the current user', >+ function => __PACKAGE__ . '::toDB', >+ } >+ ); >+ my $how = $param{'-how'} || 'makeexact'; >+ my $when = $param{'-when'} || $dbh->selectrow_array("SELECT NOW()"); >+ >+ my $score = $param{'-score'}; >+ >+ # figure out what to do -- also does more argument checking on $how >+ my ( $to_add, $to_del, $to_update ) = $self->_determineDBChanges($how); >+ my $sql_id = $dbh->quote( $self->{bz_id} ); >+ >+ # remove items >+ if (@$to_del) { >+ $dbh->do( "DELETE FROM bz_it_map " >+ . " WHERE bz_id = $sql_id" >+ . " AND it_id IN (" >+ . join( ',', map( $dbh->quote($_), @$to_del ) ) >+ . ")" ); >+ } >+ >+ # add items >+ foreach my $it_id (@$to_add) { >+ detaint_natural($it_id); >+ my $set_score = defined $score >+ && $score >= 0 ? $score : $self->getScore($it_id); >+ do { $self->validateIssueID($_) foreach (@$to_add) } >+ unless $param{-raw}; >+ $dbh->do( "INSERT INTO bz_it_map (bz_id,it_id,it_score)" >+ . "VALUES ($sql_id," >+ . $dbh->quote($it_id) >+ . ", $set_score)" ); >+ } >+ >+ # update scores if no add or delete action taken >+ if ( !@$to_add && !@$to_del && @$to_update ) { >+ foreach my $it_id (@$to_update) { >+ detaint_natural($it_id); >+ my $set_score = defined $score >+ && $score >= 0 ? $score : $self->getScore($it_id); >+ if ( $set_score >= 0 ) { >+ $dbh->do( "UPDATE bz_it_map SET it_score = $set_score " >+ . "WHERE bz_id = $sql_id AND it_id = " >+ . $dbh->quote($it_id) ); >+ } >+ } >+ } >+ >+ # log ativity >+ Bugzilla::Bug::LogActivityEntry( >+ $self->{bz_id}, 'issuetracker', >+ join( ', ', @$to_del ), >+ join( ', ', @$to_add ), >+ $who, $when, >+ ); >+} >+ >+=pod >+ >+=begin private >+ >+=item C<_determineDBChanges> >+ >+Z<> >+ >+ (\@addlist, \@dellist) _determineDBChanges($how) >+ >+Private helper method for C<toDB> that encapsulates the process of >+determining which issue tracker IDs to add and which to delete. >+C<$how> is the same as C<-how> from C<toDB>. >+ >+=end private >+ >+=cut >+ >+sub _determineDBChanges { >+ my ( $self, $how ) = @_; >+ my ( %new, %old, $to_add, $to_del, $to_update ); >+ >+ if ( $self->issues ) { >+ foreach my $issue ( @{ $self->issues } ) { >+ $new{$issue} = 1; >+ } >+ } >+ >+ #@new{@{$self->issues}} = 1; >+ # get issue tracker IDs from the DB. >+ foreach my $ref ( @{ $self->fetchIssueTrackerIDs( $self->{bz_id} ) } ) { >+ $old{ $ref->[0] } = 1; >+ } >+ >+ #@old{@{$self->fetchIssueTrackerIDs($self->bz_id)}} = 1; >+ >+SWITCH: for ($how) { >+ /^makeexact$/ && do { >+ $to_add = [ grep !exists( $old{$_} ), keys %new ]; >+ $to_del = [ grep !exists( $new{$_} ), keys %old ]; >+ last SWITCH; >+ }; >+ /^add$/ && do { >+ $to_add = [ grep !exists( $old{$_} ), keys %new ]; >+ $to_del = []; >+ last SWITCH; >+ }; >+ /^delete$/ && do { >+ $to_add = []; >+ $to_del = [ grep exists( $new{$_} ), keys %old ]; >+ last SWITCH; >+ }; >+ >+ # DEFAULT: something goofy happened so complain >+ my $error_data = { 'field' => 'issue tracker ID map' }; >+ $error_data->{'action'} = $how if $how; >+ ThrowCodeError( "unknown_update_action", $error_data ); >+ } >+ >+ $to_update = $self->issues; >+ >+ # return >+ ( $to_add, $to_del, $to_update ); >+} >+ >+=pod >+ >+=back >+ >+=head2 Class Methods >+ >+=over 4 >+ >+=cut >+ >+=pod >+ >+=item C<fetchIssueTrackerIDs> >+ >+Z<> >+ >+ \@issues fetchIssueTrackerIDs($bz_id) >+ >+Returns a list of issues (issue tracker IDs) that are related >+to the given Bugzilla bug ID (C<$bz_id>). >+ >+=cut >+ >+sub fetchIssueTrackerIDs { >+ _fromDB( 'it_id', 'bz_id', 'it_score', $_[1] ); >+} >+ >+=pod >+ >+=item C<fetchBugzillaIDs> >+ >+Z<> >+ >+ \@bugs fetchBugzillaIDs($it_id) >+ >+Returns a list of Bugzilla bug IDs that are related to the given >+issue tracker ID (C<$it_id>). >+ >+=cut >+ >+sub fetchBugzillaIDs { >+ _fromDB( 'bz_id', 'it_id', 'it_score', $_[1] ); >+} >+ >+=pod >+ >+=begin private >+ >+=item C<_fromDB> >+ >+Z<> >+ >+ \@ids _fromDB($field1, $field2, $id) >+ >+private function (I<not a method>) for validating >+A private class method that is the guts of the functionality >+advertized in C<fetchBugzillaIDs> and C<fetchIssueTrackerIDs>. >+Returns a list if IDs from the bz_id_map table. The kind of IDs >+returned is determined by C<$field1>, which must be one of the names >+of the columns in the bz_id_map table. The second two arguments limit >+the IDs returned to those whose C<$field2> column is equal to C<$id>. >+Presumably, C<$field2> will not be the same as C<$field1>, but that >+assumption is not enforced. >+ >+=end private >+ >+=cut >+ >+sub _fromDB { >+ my ( $field1, $field2, $field3, $id ) = @_; >+ my $result = []; >+ my $sth = $dbh->prepare( >+ "SELECT $field1, $field3 FROM bz_it_map WHERE $field2 = " >+ . $dbh->quote($id) ); >+ $sth->execute(); >+ while ( my ( $field1, $field3 ) = $sth->fetchrow_array() ) { >+ push @$result, [ $field1, $field3 ]; >+ } >+ >+ # return >+ $result; >+} >+ >+=pod >+ >+=item C<getScore> >+ >+Z<> >+ >+ int getScore($it_id) >+ >+Retrieves current score for IssueTracker ID from IssueTracker database. >+Otherwise defaults to -1 to denote not score yet. >+ >+kbaker: it should use undef to represent "no score yet" >+ >+=cut >+ >+sub getScore { >+ my ( $self, $it_id ) = @_; >+ >+ if ( !detaint_natural($it_id) ) { >+ return -1; >+ } >+ >+ my $result = eval { callIT_HASH( 'getScore', [$it_id] ) }; >+ >+ # record what happened but do not stop >+ if ( my $e = $@ ) { >+ mailError( $it_id, $e ); >+ >+#ThrowCodeError('xmlrpc_error', >+# { action=>'Getting score for issuetracker IDs', message=>"$eval_error" }); >+ return -1; >+ } >+ >+ if ( defined( $result->{$it_id} ) ) { >+ return $result->{$it_id}; >+ } >+ return -1; >+} >+ >+=pod C<mailError> >+ >+ void mailError($it_id, $error) >+ >+Mails Issue Tracker error message to bugzilla-maintainer >+ >+=cut >+ >+sub mailError { >+ my ( $it_id, $error, $extra ) = @_; >+ >+ my $host = eval { require Sys::Hostname; Sys::Hostname::hostname() } >+ || 'undefined'; >+ my $stack = eval { require Carp; Carp::longmess("stack backtrace") } >+ || 'undefined'; >+ my $user >+ = eval { require Bugzilla; Bugzilla->user->identity } || 'undefined'; >+ >+ warn "Error communicating with IssueTracker ID(s): $it_id: $error"; >+ >+ # Send email to bugzilla owner about the problem >+ my $err_msg = "To: " . Bugzilla->params->{maintainer} . "\n"; >+ $err_msg .= "From: bugzilla\@redhat.com\n"; >+ $err_msg >+ .= "Subject: Error communicating with IssueTracker ID(s): $it_id\n\n"; >+ $err_msg .= "Error communicating with IssueTracker ID(s): $it_id\n"; >+ $err_msg .= "Error \$\@: $error\n\n"; >+ $err_msg .= "Host: $host\n"; >+ $err_msg .= "Pid: $$\n"; >+ $err_msg .= "User: $user\n"; >+ $err_msg .= "Remote Address: $ENV{REMOTE_ADDR}\n"; >+ $err_msg .= "Stack Trace:\n$stack\n"; >+ $err_msg .= "Extra Data:\n$extra\n" if $extra; >+ >+ open( SENDMAIL, "|/usr/lib/sendmail -t -i" ) >+ || warn "Can't open sendmail"; >+ print SENDMAIL $err_msg; >+ close SENDMAIL || warn "Can't close sendmail"; >+} >+ >+=pod >+ >+=item C<validateIssueID> >+ >+Z<> >+ >+ void validateIssueID($it_id) >+ >+Validates that a given issue tracker ID (C<$it_id>) corresponds to a >+real issue in the issue tracker and also if it currently does not have >+a bug id associated with it. >+ >+Throws a user error if there is a problem with the input C<$it_id>. >+ >+=cut >+ >+sub validateIssueID { >+ >+ # Check to see actually a valid issue >+ $_[0]->issueIDIsValid( $_[1] ) >+ || ThrowUserError( "invalid_issue_id", { badissue => $_[1] } ); >+ >+ # Check to see if issue already has one or more bugs associated >+ $_[0]->issueHasBug( $_[1] ) >+ && ThrowUserError( "issue_has_bug", { badissue => $_[1] } ); >+} >+ >+=pod >+ >+=item C<issueIDIsValid> >+ >+Z<> >+ >+ $boolean issueIDIsValid($it_id) >+ >+Validates that a given issue tracker ID (C<$it_id>) corresponds to a >+real issue in the issue tracker and is allowed to be linked. >+ >+Returns a true value if the issue ID is valid, false otherwise. >+ >+=cut >+ >+sub issueIDIsValid { >+ my ( undef, $it_id ) = @_; >+ >+ if ( !detaint_natural($it_id) ) { >+ ThrowCodeError( >+ 'xmlrpc_error', >+ { action => "Validating issuetracker IDs", >+ message => >+ "Error: Issue Tracker ID $it_id is not a valid integer." >+ } >+ ); >+ } >+ >+ my $result = eval { callIT( 'issueExists', $it_id ) }; >+ >+ if ( my $e = $@ ) { >+ >+ ThrowCodeError( >+ 'xmlrpc_error', >+ { action => "Validating issuetracker IDs", >+ message => "Error: $e" >+ } >+ ); >+ } >+ >+ return $result; >+} >+ >+=pod >+ >+=item C<issueHasBug> >+ >+Z<> >+ >+ $boolean issueHasBug($it_id) >+ >+Validates that a given issue tracker ID (C<$it_id>) does not >+already have a bug id associated with it. >+ >+Returns a true value if the adding of the issue ID is valid, false otherwise. >+ >+=cut >+ >+sub issueHasBug { >+ my ( undef, $it_id ) = @_; >+ >+ if ( !detaint_natural($it_id) ) { >+ ThrowCodeError( >+ 'xmlrpc_error', >+ { action => "Validating issuetracker IDs", >+ message => >+ "Error: Issue Tracker ID $it_id is not a valid integer." >+ } >+ ); >+ } >+ >+ my $result = eval { callIT_HASH( 'getBugzillaIDs', [$it_id] ) }; >+ >+ if ( my $e = $@ ) { >+ ThrowCodeError( >+ 'xmlrpc_error', >+ { action => "Validating issuetracker IDs", >+ message => "Error: $e" >+ } >+ ); >+ } >+ >+ # If issue has one or more bugs assigned to it, we fail >+ if ( exists $result->{$it_id} and @{ $result->{$it_id} } > 0 ) { >+ return 1; >+ } >+ >+ return 0; >+} >+ >+=item callIT_HASH( $function, @function_params ) >+ >+returns result hash ref on success. >+ >+die's on error. >+ >+=cut >+ >+sub callIT_HASH { >+ my $func = shift; >+ my @func_params = @_; >+ >+ my $result = callIT( $func, @func_params ); >+ if ( not defined $result ) { >+ die "no result returned from $func call to Issue Tracker"; >+ } >+ if ( ref($result) ne 'HASH' ) { >+ die "expected HASH from $func call to Issue Tracker but got: " >+ . Data::Dumper::Dumper($result); >+ } >+ return $result; # success >+} >+ >+=item callIT_HASHX( $function, @function_params ) >+ >+returns result hash ref on success. Handles the case where IT returns >+an empty string sometimes and a HASH other times. The caller of callIT_HASHX >+will always get a hash back. >+ >+die's on error. >+ >+=cut >+ >+sub callIT_HASHX { >+ my $func = shift; >+ my @func_params = @_; >+ >+ my $result = callIT( $func, @func_params ); >+ if ( not defined $result ) { >+ die "no result returned from $func call to Issue Tracker"; >+ } >+ if ( not ref($result) and $result eq '' ) { >+ return {}; >+ } >+ if ( ref($result) ne 'HASH' ) { >+ die "expected HASH from $func call to Issue Tracker but got: " >+ . Data::Dumper::Dumper($result); >+ } >+ return $result; # success >+} >+ >+=item callIT( $function, @function_params ) >+ >+returns result success. >+ >+die's on error. >+ >+=cut >+ >+sub callIT { >+ my $func = shift; >+ my @func_params = @_; >+ >+ my $rpc = _RPC(); >+ >+TRY: >+ >+ for my $try ( 1 .. MAXTRIES ) { >+ my $result = eval { >+ my $call = $rpc->call( "IT.$func", @func_params, $username, >+ $password ); >+ if ( not $call ) { >+ die "IT.$func failure: no call object returned by rpc!!"; >+ } >+ if ( $call->faultstring ) { >+ die "IT.$func failure: " . $call->faultstring; >+ } >+ $call->result; >+ }; >+ >+ my $call_error = $@; >+ >+ if ( !$call_error ) { >+ return $result; >+ } >+ >+ if ( $try == MAXTRIES ) { >+ die $call_error; >+ } >+ else { >+ warn "IT.$func call failed attempt $try with: $call_error"; >+ } >+ >+ sleep 2; >+ } >+ >+ die "callIT failure: should never get here"; >+} >+ >+=pod >+ >+=back >+ >+=head2 Class Variables >+ >+Note: this/these are described as variables, but are implemented as >+functions that take no arguments and return the described value. >+Since they don't care about their arguments, they can be called as >+regular functions, class methods or instance methods. >+ >+=over 4 >+ >+=cut >+ >+=pod >+ >+=item C<XMLRPC::Lite _RPC> >+ >+A client for interacting with the Issue Tracker's XML-RPC server. The >+first time this is called it creates the client object. If the client >+can't be created it will throw a code error. Once created, this is >+the same object as C<_RPCNOERROR>. >+ >+=cut >+ >+my $rpc; >+ >+sub _RPC { >+ >+ # already created >+ return $rpc if $rpc; >+ >+ # create and return new >+ eval { >+ $rpc = new XMLRPC::Lite( >+ proxy => Bugzilla->params->{issuetracker_rpcserver} ); >+ }; >+ >+ ThrowCodeError( 'cannot_create_xmlrpc_client', { message => "$@" } ) >+ if $@; >+ return $rpc; >+} >+ >+=pod >+ >+=item C<XMLRPC::Lite _RPCNOERROR> >+ >+A client for interacting with the Issue Tracker's XML-RPC server. The >+first time this is called it creates the client object. If the client >+can't be created undef will be returned. Once created this is the >+same object as C<_RPC> >+ >+=cut >+ >+# if Bugzilla used real exceptions, this wouldn't be necessary. -mpm >+sub _RPCNOERROR { >+ >+ # already created >+ return $rpc if $rpc; >+ >+ # create and return new >+ eval { >+ $rpc = new XMLRPC::Lite( >+ proxy => Bugzilla->params->{issuetracker_rpcserver} ); >+ }; >+ >+ warn "Can't create XML-RPC client: $@" if $@; >+ return $rpc; >+} >+ >+=pod >+ >+=back >+ >+=head1 SEE ALSO >+ >+L<Bugzilla|Bugzilla> >+ >+=cut >+ >+1; >Index: extensions/issuetracker/template/en/bug/edit-text-field.html.tmpl >=================================================================== >RCS file: extensions/issuetracker/template/en/bug/edit-text-field.html.tmpl >diff -N extensions/issuetracker/template/en/bug/edit-text-field.html.tmpl >--- /dev/null 1 Jan 1970 00:00:00 -0000 >+++ extensions/issuetracker/template/en/bug/edit-text-field.html.tmpl 22 Feb 2008 04:27:58 -0000 >@@ -0,0 +1,23 @@ >+[% IF Param('useissuetracker') AND user.in_group('issuetracker') %] >+ [% issues = [] %] >+ [% FOREACH issue = bug.issuetrackers %] >+ [% issues.push(issue.0) %] >+ [% END %] >+ [% IF issues.size > 0 %] >+ [% issue_string = issues.join(', ') %] >+ [% ELSE %] >+ [% issue_string = " " %] >+ [% END %] >+ <tr> >+ <th>[% field_descs.issuetrackers %]:</th> >+ [% PROCESS input inputname => "issuetrackers" size => "40" colspan => 2 value => issue_string %] >+ </tr><tr> >+ <td></td> >+ <td colspan="2"> >+ [% FOREACH issue = bug.issuetrackers %] >+ <a href="[% Param('issuetracker_urlbase') %][% issue.0 FILTER url_quote %]"> >+ [% issue.0 FILTER html %]</a> ([% issue.1 FILTER html %])[% " " %] >+ [% END %] >+ </tr> >+[% END %] >+ >Index: extensions/issuetracker/template/en/bug/show-multiple-text-field.html.tmpl >=================================================================== >RCS file: extensions/issuetracker/template/en/bug/show-multiple-text-field.html.tmpl >diff -N extensions/issuetracker/template/en/bug/show-multiple-text-field.html.tmpl >--- /dev/null 1 Jan 1970 00:00:00 -0000 >+++ extensions/issuetracker/template/en/bug/show-multiple-text-field.html.tmpl 22 Feb 2008 04:27:58 -0000 >@@ -0,0 +1,13 @@ >+[% IF Param('useissuetracker') AND user.in_group('issuetracker') %] >+ [% issues = [] %] >+ [% FOREACH issue = bug.issuetrackers %] >+ [% issue = "$issue.0 ($issue.1)" FILTER html %] >+ [% issues.push(issue) %] >+ [% END %] >+ [% IF issues.size > 0 %] >+ [% issue_string = issues.join(', ') %] >+ [% ELSE %] >+ [% issue_string = " " %] >+ [% END %] >+ [% PROCESS row cell = "issuetrackers" fullrow = 1 value = issue_string %] >+[% END %] >Index: extensions/issuetracker/template/en/bug/create/create-form.html.tmpl >=================================================================== >RCS file: extensions/issuetracker/template/en/bug/create/create-form.html.tmpl >diff -N extensions/issuetracker/template/en/bug/create/create-form.html.tmpl >--- /dev/null 1 Jan 1970 00:00:00 -0000 >+++ extensions/issuetracker/template/en/bug/create/create-form.html.tmpl 22 Feb 2008 04:27:58 -0000 >@@ -0,0 +1,9 @@ >+[% IF Param('useissuetracker') AND user.in_group('issuetracker') %] >+ <tr> >+ <th>[% field_descs.issuetrackers %]:</th> >+ <td> >+ <input name="issuetrackers" size="60"> >+ </td> >+ </tr> >+[% END %] >+ >Index: extensions/issuetracker/template/en/global/field-descs-end.none.tmpl >=================================================================== >RCS file: extensions/issuetracker/template/en/global/field-descs-end.none.tmpl >diff -N extensions/issuetracker/template/en/global/field-descs-end.none.tmpl >--- /dev/null 1 Jan 1970 00:00:00 -0000 >+++ extensions/issuetracker/template/en/global/field-descs-end.none.tmpl 22 Feb 2008 04:27:58 -0000 >@@ -0,0 +1,2 @@ >+[% field = "issuetrackers" %] >+[% SET field_descs.${field} = "Issue Trackers" %] >Index: template/en/default/admin/params/issuetracker.html.tmpl >=================================================================== >RCS file: template/en/default/admin/params/issuetracker.html.tmpl >diff -N template/en/default/admin/params/issuetracker.html.tmpl >--- /dev/null 1 Jan 1970 00:00:00 -0000 >+++ template/en/default/admin/params/issuetracker.html.tmpl 22 Feb 2008 04:27:58 -0000 >@@ -0,0 +1,43 @@ >+[%# 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 Netscape Communications >+ # Corporation. Portions created by Netscape are >+ # Copyright (C) 1998 Netscape Communications Corporation. All >+ # Rights Reserved. >+ # >+ # Contributor(s): Dave Miller <justdave@bugzilla.org> >+ # Frédéric Buclin <LpSolit@gmail.com> >+ # Marc Schumann <wurblzap@gmail.com> >+ # Dave Lawrence <dkl@redhat.com> >+ #%] >+[% >+ title = "Issue Tracker" >+ desc = "Set up Issue Tracker Integration Parameters" >+%] >+ >+[% param_descs = { >+ useissuetracker => "If this option is on, a field will display that will allow issue tracker id's to be" _ >+ "stored in the database per report. Links will be displayed as well to the issue tracker reports.", >+ >+ issuetracker_urlbase => "The base URL use to build links to items in the issue tracker system", >+ >+ issuetracker_download_key => "Key passed in to automatically auth user when clicking on IssueTracker download link", >+ >+ issuetracker_user => "User that reports changes from Issue Tracker", >+ >+ issuetracker_rpc_user => "User that reports changes from Bugzilla to Issue Tracker over XML-RPC.", >+ >+ issuetracker_rpc_password => "Password for user that reports changes from Bugzilla to Issue Tracker over XML-RPC.", >+ >+ issuetracker_rpcserver => "URL for Issue Tracker XML RPC service" } >+%] >Index: template/en/default/bug/edit.html.tmpl >=================================================================== >RCS file: /cvs/qa/rh_bugzilla_3/template/en/default/bug/edit.html.tmpl,v >retrieving revision 1.10 >diff -u -r1.10 edit.html.tmpl >--- template/en/default/bug/edit.html.tmpl 15 Feb 2008 06:48:08 -0000 1.10 >+++ template/en/default/bug/edit.html.tmpl 22 Feb 2008 04:27:59 -0000 >@@ -163,7 +163,11 @@ > [% PROCESS section_spacer %] > > [% PROCESS section_url_keyword_whiteboard %] >- >+ >+ [%# REDHAT EXTENSION START 406111 %] >+ [% Hook.process("text-field") %] >+ [%# REDHAT EXTENSION END 406111 %] >+ > [% PROCESS section_spacer %] > > [%# *** Dependencies *** %] >@@ -637,7 +641,7 @@ > </tr> > [% END %] > [%# REDHAT EXTENSION END 406151 %] >- >+ > [% IF use_keywords %] > <tr> > <td class="field_label"> >Index: template/en/default/bug/show-multiple.html.tmpl >=================================================================== >RCS file: /cvs/qa/rh_bugzilla_3/template/en/default/bug/show-multiple.html.tmpl,v >retrieving revision 1.2 >diff -u -r1.2 show-multiple.html.tmpl >--- template/en/default/bug/show-multiple.html.tmpl 13 Feb 2008 16:44:32 -0000 1.2 >+++ template/en/default/bug/show-multiple.html.tmpl 22 Feb 2008 04:28:00 -0000 >@@ -190,6 +190,10 @@ > [% PROCESS row cell = "fixed_in" fullrow = 1 %] > [%# REDHAT EXTENSION END 406151 %] > >+ [%# REDHAT EXTENSION START 406111 %] >+ [% Hook.process('text-field') %] >+ [%# REDHAT EXTENSION END 406111 %] >+ > [% USE Bugzilla %] > [% field_counter = 0 %] > [% FOREACH field = Bugzilla.get_fields({ obsolete => 0, custom => 1 }) %] >@@ -309,9 +313,12 @@ > [%###########################################################################%] > > [% BLOCK row %] >+ [%# REDHAT EXTENSION START 406111 %] >+ [% val = value ? value : bug.${cell} %] >+ [%# REDHAT EXTENSION END 406111 %] > <tr> > <th>[% field_descs.${cell} FILTER html %]:</th> >- <td[% " colspan=3" IF fullrow %]>[% bug.${cell} FILTER html %]</td> >+ <td[% " colspan=3" IF fullrow %]>[% val FILTER html %]</td> > [% PROCESS rightcell IF !fullrow %] > </tr> > [% fullrow = 0 %] >Index: template/en/default/bug/create/create.html.tmpl >=================================================================== >RCS file: /cvs/qa/rh_bugzilla_3/template/en/default/bug/create/create.html.tmpl,v >retrieving revision 1.5 >diff -u -r1.5 create.html.tmpl >--- template/en/default/bug/create/create.html.tmpl 15 Feb 2008 06:50:40 -0000 1.5 >+++ template/en/default/bug/create/create.html.tmpl 22 Feb 2008 04:28:00 -0000 >@@ -559,6 +559,12 @@ > [% END %] > [%# REDHAT EXTENSION END 406151 %] > >+ [%# REDHAT EXTENSION START 406111 >+ # Moved up from bottom %] >+ [%# Form controls for entering additional data about the bug being created. %] >+ [% Hook.process("form") %] >+ [%# REDHAT EXTENSION END 406111 %] >+ > [% IF user.in_group('editbugs', product.id) %] > [% IF use_keywords %] > <tr> >@@ -612,9 +618,6 @@ > </tr> > [% END %] > >- [%# Form controls for entering additional data about the bug being created. %] >- [% Hook.process("form") %] >- > <tr> > <th> </th> > <td colspan="3"> >Index: template/en/default/global/code-error.html.tmpl >=================================================================== >RCS file: /cvs/qa/rh_bugzilla_3/template/en/default/global/code-error.html.tmpl,v >retrieving revision 1.3 >diff -u -r1.3 code-error.html.tmpl >--- template/en/default/global/code-error.html.tmpl 28 Jan 2008 04:46:17 -0000 1.3 >+++ template/en/default/global/code-error.html.tmpl 22 Feb 2008 04:28:01 -0000 >@@ -77,6 +77,11 @@ > [% ELSIF error == "bug_error" %] > Trying to retrieve [% terms.bug %] [%+ bug.bug_id FILTER html %] returned > the error [% bug.error FILTER html %]. >+ >+ [%# REDHAT EXTENSION START 406111 %] >+ [% ELSIF error == "cannot_create_xmlrpc_client" %] >+ Cannot create an XML-RPC client: [% message FILTER html %]. >+ [%# REDHAT EXTENSION END 406111 > > [% ELSIF error == "chart_data_not_generated" %] > [% admindocslinks = {'extraconfig.html' => 'Setting up Charting'} %] >Index: template/en/default/global/field-descs.none.tmpl >=================================================================== >RCS file: /cvs/qa/rh_bugzilla_3/template/en/default/global/field-descs.none.tmpl,v >retrieving revision 1.3 >diff -u -r1.3 field-descs.none.tmpl >--- template/en/default/global/field-descs.none.tmpl 15 Feb 2008 07:17:48 -0000 1.3 >+++ template/en/default/global/field-descs.none.tmpl 22 Feb 2008 04:28:01 -0000 >@@ -24,7 +24,7 @@ > > [%# REDHAT EXTENSION START 406151 406371 > # Added devel_whiteboard, qa_whiteboard, internal_whiteboard, fixed_in >- # issuetrackers, itmaxscore, blockedby, dependson, and flags %] >+ # itmaxscore, blockedby, dependson, and flags %] > [% field_descs = { "[Bug creation]" => "[$terms.Bug creation]", > "actual_time" => "Actual Hours" > "alias" => "Alias", >@@ -67,7 +67,6 @@ > "status_whiteboard" => "Status Whiteboard", > "devel_whiteboard" => "Devel Whiteboard", > "qa_whiteboard" => "QA Whiteboard", >- "issuetrackers" => "Issue Trackers", > "itmaxscore" => "IT Max Score", > "dependson" => "Depends On", > "blockedby" => "Blocked By", >Index: template/en/default/global/user-error.html.tmpl >=================================================================== >RCS file: /cvs/qa/rh_bugzilla_3/template/en/default/global/user-error.html.tmpl,v >retrieving revision 1.13 >diff -u -r1.13 user-error.html.tmpl >--- template/en/default/global/user-error.html.tmpl 14 Feb 2008 03:17:47 -0000 1.13 >+++ template/en/default/global/user-error.html.tmpl 22 Feb 2008 04:28:03 -0000 >@@ -868,6 +868,19 @@ > [% title = "Invalid Parameter" %] > The new value for [% name FILTER html %] is invalid: [% err FILTER html %]. > >+ [%# REDHAT EXTENSION START 406111 %] >+ [% ELSIF error == "invalid_issue_id" %] >+ [% title = "Invalid Issue Tracker ID" %] >+ The issue tracker ID, '[% badissue FILTER html %]', is invalid. It must be >+ a positive integer and must be an existing ticket ID in the issue tracker >+ system. >+ >+ [% ELSIF error == "issue_has_bug" %] >+ [% title = "Invalid Issue Tracker ID" %] >+ The issue tracker ID, '[% badissue FILTER html %]', already has a [% terms.bug %] associated >+ with it. >+ [%# REDHAT EXTENSION END 406111 %] >+ > [% ELSIF error == "invalid_product_name" %] > [% title = "Invalid Product Name" %] > The product name '[% product FILTER html %]' is invalid or does not exist.
You cannot view the attachment while viewing its details because your browser does not support IFRAMEs.
View the attachment on a separate page
.
View Attachment As Diff
View Attachment As Raw
Actions:
View
|
Diff
Attachments on
bug 406111
:
295481
|
295565
|
295587
|
295999
|
297255
|
298010
|
298220