Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
bugzilla
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
etersoft
bugzilla
Commits
5d516a6a
Commit
5d516a6a
authored
Nov 10, 2009
by
mkanat%bugzilla.org
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Bug 472217: Create a Bugzilla::Comment object and eliminate GetComments
Patch by Max Kanat-Alexander <mkanat@bugzilla.org> r=LpSolit, a=LpSolit
parent
88a69f20
Hide whitespace changes
Inline
Side-by-side
Showing
17 changed files
with
326 additions
and
226 deletions
+326
-226
Bug.pm
Bugzilla/Bug.pm
+37
-78
BugMail.pm
Bugzilla/BugMail.pm
+3
-36
Comment.pm
Bugzilla/Comment.pm
+173
-0
Template.pm
Bugzilla/Template.pm
+1
-1
User.pm
Bugzilla/User.pm
+1
-1
Util.pm
Bugzilla/Util.pm
+50
-33
Bug.pm
Bugzilla/WebService/Bug.pm
+17
-23
email_in.pl
email_in.pl
+1
-1
enter_bug.cgi
enter_bug.cgi
+5
-6
post_bug.cgi
post_bug.cgi
+4
-4
process_bug.cgi
process_bug.cgi
+1
-2
comments.html.tmpl
template/en/default/bug/comments.html.tmpl
+7
-13
edit.html.tmpl
template/en/default/bug/edit.html.tmpl
+2
-2
format_comment.txt.tmpl
template/en/default/bug/format_comment.txt.tmpl
+16
-17
show-multiple.html.tmpl
template/en/default/bug/show-multiple.html.tmpl
+1
-1
show.xml.tmpl
template/en/default/bug/show.xml.tmpl
+6
-7
newchangedmail.txt.tmpl
template/en/default/email/newchangedmail.txt.tmpl
+1
-1
No files found.
Bugzilla/Bug.pm
View file @
5d516a6a
...
@@ -46,6 +46,7 @@ use Bugzilla::Product;
...
@@ -46,6 +46,7 @@ use Bugzilla::Product;
use
Bugzilla::
Component
;
use
Bugzilla::
Component
;
use
Bugzilla::
Group
;
use
Bugzilla::
Group
;
use
Bugzilla::
Status
;
use
Bugzilla::
Status
;
use
Bugzilla::
Comment
;
use
List::
Util
qw(min)
;
use
List::
Util
qw(min)
;
use
Storable
qw(dclone)
;
use
Storable
qw(dclone)
;
...
@@ -1835,12 +1836,12 @@ sub set_cclist_accessible { $_[0]->set('cclist_accessible', $_[1]); }
...
@@ -1835,12 +1836,12 @@ sub set_cclist_accessible { $_[0]->set('cclist_accessible', $_[1]); }
sub
set_comment_is_private
{
sub
set_comment_is_private
{
my
(
$self
,
$comment_id
,
$isprivate
)
=
@_
;
my
(
$self
,
$comment_id
,
$isprivate
)
=
@_
;
return
unless
Bugzilla
->
user
->
is_insider
;
return
unless
Bugzilla
->
user
->
is_insider
;
my
(
$comment
)
=
grep
(
$comment_id
eq
$_
->
{
id
},
@
{
$self
->
longdescs
});
my
(
$comment
)
=
grep
(
$comment_id
==
$_
->
id
,
@
{
$self
->
comments
});
ThrowUserError
(
'comment_invalid_isprivate'
,
{
id
=>
$comment_id
})
ThrowUserError
(
'comment_invalid_isprivate'
,
{
id
=>
$comment_id
})
if
!
$comment
;
if
!
$comment
;
$isprivate
=
$isprivate
?
1
:
0
;
$isprivate
=
$isprivate
?
1
:
0
;
if
(
$isprivate
!=
$comment
->
{
isprivate
}
)
{
if
(
$isprivate
!=
$comment
->
is_private
)
{
$self
->
{
comment_isprivate
}
||=
{};
$self
->
{
comment_isprivate
}
||=
{};
$self
->
{
comment_isprivate
}
->
{
$comment_id
}
=
$isprivate
;
$self
->
{
comment_isprivate
}
->
{
$comment_id
}
=
$isprivate
;
}
}
...
@@ -2665,12 +2666,38 @@ sub keyword_objects {
...
@@ -2665,12 +2666,38 @@ sub keyword_objects {
return
$self
->
{
'keyword_objects'
};
return
$self
->
{
'keyword_objects'
};
}
}
sub
longdescs
{
sub
comments
{
my
(
$self
)
=
@_
;
my
(
$self
,
$params
)
=
@_
;
return
$self
->
{
'longdescs'
}
if
exists
$self
->
{
'longdescs'
};
return
[]
if
$self
->
{
'error'
};
return
[]
if
$self
->
{
'error'
};
$self
->
{
'longdescs'
}
=
GetComments
(
$self
->
{
bug_id
});
$params
||=
{};
return
$self
->
{
'longdescs'
};
if
(
!
defined
$self
->
{
'comments'
})
{
$self
->
{
'comments'
}
=
Bugzilla::
Comment
->
match
({
bug_id
=>
$self
->
id
});
my
$count
=
0
;
foreach
my
$comment
(
@
{
$self
->
{
'comments'
}
})
{
$comment
->
{
count
}
=
$count
++
;
}
}
my
@comments
=
@
{
$self
->
{
'comments'
}
};
my
$order
=
$params
->
{
order
}
||
Bugzilla
->
user
->
settings
->
{
'comment_sort_order'
}
->
{
'value'
};
if
(
$order
ne
'oldest_to_newest'
)
{
@comments
=
reverse
@comments
;
if
(
$order
eq
'newest_to_oldest_desc_first'
)
{
unshift
(
@comments
,
pop
@comments
);
}
}
if
(
$params
->
{
after
})
{
my
$from
=
datetime_from
(
$params
->
{
after
});
@comments
=
grep
{
datetime_from
(
$_
->
creation_ts
)
>
$from
}
@comments
;
}
if
(
$params
->
{
to
})
{
my
$to
=
datetime_from
(
$params
->
{
to
});
@comments
=
grep
{
datetime_from
(
$_
->
creation_ts
)
<=
$to
}
@comments
;
}
return
\
@comments
;
}
}
sub
milestoneurl
{
sub
milestoneurl
{
...
@@ -2955,7 +2982,7 @@ sub update_comment {
...
@@ -2955,7 +2982,7 @@ sub update_comment {
||
ThrowCodeError
(
'bad_arg'
,
{
argument
=>
'comment_id'
,
function
=>
'update_comment'
});
||
ThrowCodeError
(
'bad_arg'
,
{
argument
=>
'comment_id'
,
function
=>
'update_comment'
});
# The comment ID must belong to this bug.
# The comment ID must belong to this bug.
my
@current_comment_obj
=
grep
{
$_
->
{
'id'
}
==
$comment_id
}
@
{
$self
->
longdesc
s
};
my
@current_comment_obj
=
grep
{
$_
->
id
==
$comment_id
}
@
{
$self
->
comment
s
};
scalar
(
@current_comment_obj
)
scalar
(
@current_comment_obj
)
||
ThrowCodeError
(
'bad_arg'
,
{
argument
=>
'comment_id'
,
function
=>
'update_comment'
});
||
ThrowCodeError
(
'bad_arg'
,
{
argument
=>
'comment_id'
,
function
=>
'update_comment'
});
...
@@ -2972,7 +2999,7 @@ sub update_comment {
...
@@ -2972,7 +2999,7 @@ sub update_comment {
$self
->
_sync_fulltext
();
$self
->
_sync_fulltext
();
# Update the comment object with this new text.
# Update the comment object with this new text.
$current_comment_obj
[
0
]
->
{
'
body
'
}
=
$new_comment
;
$current_comment_obj
[
0
]
->
{
'
thetext
'
}
=
$new_comment
;
}
}
# Represents which fields from the bugs table are handled by process_bug.cgi.
# Represents which fields from the bugs table are handled by process_bug.cgi.
...
@@ -3032,74 +3059,6 @@ sub ValidateTime {
...
@@ -3032,74 +3059,6 @@ sub ValidateTime {
}
}
}
}
sub
GetComments
{
my
(
$id
,
$comment_sort_order
,
$start
,
$end
,
$raw
)
=
@_
;
my
$dbh
=
Bugzilla
->
dbh
;
$comment_sort_order
=
$comment_sort_order
||
Bugzilla
->
user
->
settings
->
{
'comment_sort_order'
}
->
{
'value'
};
my
$sort_order
=
(
$comment_sort_order
eq
"oldest_to_newest"
)
?
'asc'
:
'desc'
;
my
@comments
;
my
@args
=
(
$id
);
my
$query
=
'SELECT longdescs.comment_id AS id, profiles.userid, '
.
$dbh
->
sql_date_format
(
'longdescs.bug_when'
,
'%Y.%m.%d %H:%i:%s'
)
.
' AS time, longdescs.thetext AS body, longdescs.work_time,
isprivate, already_wrapped, type, extra_data
FROM longdescs
INNER JOIN profiles
ON profiles.userid = longdescs.who
WHERE longdescs.bug_id = ?'
;
if
(
$start
)
{
$query
.=
' AND longdescs.bug_when > ?'
;
push
(
@args
,
$start
);
}
if
(
$end
)
{
$query
.=
' AND longdescs.bug_when <= ?'
;
push
(
@args
,
$end
);
}
$query
.=
" ORDER BY longdescs.bug_when $sort_order"
;
my
$sth
=
$dbh
->
prepare
(
$query
);
$sth
->
execute
(
@args
);
# Cache the users we look up
my
%
users
;
while
(
my
$comment_ref
=
$sth
->
fetchrow_hashref
())
{
my
%
comment
=
%
$comment_ref
;
$users
{
$comment
{
'userid'
}}
||=
new
Bugzilla::
User
(
$comment
{
'userid'
});
$comment
{
'author'
}
=
$users
{
$comment
{
'userid'
}};
# If raw data is requested, do not format 'special' comments.
$comment
{
'body'
}
=
format_comment
(
\%
comment
)
unless
$raw
;
push
(
@comments
,
\%
comment
);
}
if
(
$comment_sort_order
eq
"newest_to_oldest_desc_first"
)
{
unshift
(
@comments
,
pop
@comments
);
}
return
\
@comments
;
}
# Format language specific comments.
sub
format_comment
{
my
$comment
=
shift
;
my
$template
=
Bugzilla
->
template_inner
;
my
$vars
=
{
comment
=>
$comment
};
my
$body
;
$template
->
process
(
"bug/format_comment.txt.tmpl"
,
$vars
,
\
$body
)
||
ThrowTemplateError
(
$template
->
error
());
$body
=~
s/^X//
;
return
$body
;
}
# Get the activity of a bug, starting from $starttime (if given).
# Get the activity of a bug, starting from $starttime (if given).
# This routine assumes Bugzilla::Bug->check has been previously called.
# This routine assumes Bugzilla::Bug->check has been previously called.
sub
GetBugActivity
{
sub
GetBugActivity
{
...
@@ -3644,7 +3603,7 @@ sub _validate_attribute {
...
@@ -3644,7 +3603,7 @@ sub _validate_attribute {
my
@valid_attributes
=
(
my
@valid_attributes
=
(
# Miscellaneous properties and methods.
# Miscellaneous properties and methods.
qw(error groups product_id component_id
qw(error groups product_id component_id
longdesc
s milestoneurl attachments
comment
s milestoneurl attachments
isopened isunconfirmed
isopened isunconfirmed
flag_types num_attachment_flag_types
flag_types num_attachment_flag_types
show_attachment_flags any_flags_requesteeble)
,
show_attachment_flags any_flags_requesteeble)
,
...
...
Bugzilla/BugMail.pm
View file @
5d516a6a
...
@@ -119,6 +119,7 @@ sub Send {
...
@@ -119,6 +119,7 @@ sub Send {
my
$msg
=
""
;
my
$msg
=
""
;
my
$dbh
=
Bugzilla
->
dbh
;
my
$dbh
=
Bugzilla
->
dbh
;
my
$bug
=
new
Bugzilla::
Bug
(
$id
);
# XXX - These variables below are useless. We could use field object
# XXX - These variables below are useless. We could use field object
# methods directly. But we first have to implement a cache in
# methods directly. But we first have to implement a cache in
...
@@ -356,7 +357,7 @@ sub Send {
...
@@ -356,7 +357,7 @@ sub Send {
}
}
}
}
my
$comments
=
get_comments_by_bug
(
$id
,
$start
,
$end
);
my
$comments
=
$bug
->
comments
({
after
=>
$start
,
to
=>
$end
}
);
###########################################################################
###########################################################################
# Start of email filtering code
# Start of email filtering code
...
@@ -569,7 +570,7 @@ sub sendMail {
...
@@ -569,7 +570,7 @@ sub sendMail {
}
}
if
(
!
$user
->
is_insider
)
{
if
(
!
$user
->
is_insider
)
{
@send_comments
=
grep
{
!
$_
->
{
isprivate
}
}
@send_comments
;
@send_comments
=
grep
{
!
$_
->
is_private
}
@send_comments
;
}
}
if
(
$difftext
eq
""
&&
!
scalar
(
@send_comments
)
&&
!
$isnew
)
{
if
(
$difftext
eq
""
&&
!
scalar
(
@send_comments
)
&&
!
$isnew
)
{
...
@@ -650,38 +651,4 @@ sub sendMail {
...
@@ -650,38 +651,4 @@ sub sendMail {
return
1
;
return
1
;
}
}
# Get bug comments for the given period.
sub
get_comments_by_bug
{
my
(
$id
,
$start
,
$end
)
=
@_
;
my
$dbh
=
Bugzilla
->
dbh
;
my
$result
=
""
;
my
$count
=
0
;
# $start will be undef for new bugs, and defined for pre-existing bugs.
if
(
$start
)
{
# If $start is not NULL, obtain the count-index
# of this comment for the leading "Comment #xxx" line.
$count
=
$dbh
->
selectrow_array
(
'SELECT COUNT(*) FROM longdescs
WHERE bug_id = ? AND bug_when <= ?'
,
undef
,
(
$id
,
$start
));
}
my
$raw
=
1
;
# Do not format comments which are not of type CMT_NORMAL.
my
$comments
=
Bugzilla::Bug::
GetComments
(
$id
,
"oldest_to_newest"
,
$start
,
$end
,
$raw
);
my
$attach_base
=
correct_urlbase
()
.
'attachment.cgi?id='
;
foreach
my
$comment
(
@$comments
)
{
$comment
->
{
count
}
=
$count
++
;
# If an attachment was created, then add an URL. (Note: the 'g'lobal
# replace should work with comments with multiple attachments.)
if
(
$comment
->
{
body
}
=~
/Created an attachment \(/
)
{
$comment
->
{
body
}
=~
s/(Created an attachment \(id=([0-9]+)\))/$1\n --> \($attach_base$2\)/g
;
}
$comment
->
{
body
}
=
$comment
->
{
'already_wrapped'
}
?
$comment
->
{
body
}
:
wrap_comment
(
$comment
->
{
body
});
}
return
$comments
;
}
1
;
1
;
Bugzilla/Comment.pm
0 → 100644
View file @
5d516a6a
# -*- 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 James Robson.
# Portions created by James Robson are Copyright (c) 2009 James Robson.
# All rights reserved.
#
# Contributor(s): James Robson <arbingersys@gmail.com>
use
strict
;
package
Bugzilla::
Comment
;
use
base
qw(Bugzilla::Object)
;
use
Bugzilla::
Constants
;
use
Bugzilla::
Error
;
use
Bugzilla::
Util
;
###############################
#### Initialization ####
###############################
use
constant
DB_COLUMNS
=>
qw(
comment_id
bug_id
who
bug_when
work_time
thetext
isprivate
already_wrapped
type
extra_data
)
;
use
constant
DB_TABLE
=>
'longdescs'
;
use
constant
ID_FIELD
=>
'comment_id'
;
use
constant
LIST_ORDER
=>
'bug_when'
;
###############################
#### Accessors ######
###############################
sub
already_wrapped
{
return
$_
[
0
]
->
{
'already_wrapped'
};
}
sub
body
{
return
$_
[
0
]
->
{
'thetext'
};
}
sub
bug_id
{
return
$_
[
0
]
->
{
'bug_id'
};
}
sub
creation_ts
{
return
$_
[
0
]
->
{
'bug_when'
};
}
sub
is_private
{
return
$_
[
0
]
->
{
'isprivate'
};
}
sub
work_time
{
return
$_
[
0
]
->
{
'work_time'
};
}
sub
author
{
my
$self
=
shift
;
$self
->
{
'author'
}
||=
new
Bugzilla::
User
(
$self
->
{
'who'
});
return
$self
->
{
'author'
};
}
sub
body_full
{
my
(
$self
,
$params
)
=
@_
;
$params
||=
{};
my
$template
=
Bugzilla
->
template_inner
;
my
$body
;
$template
->
process
(
"bug/format_comment.txt.tmpl"
,
{
comment
=>
$self
,
%
$params
},
\
$body
)
||
ThrowTemplateError
(
$template
->
error
());
$body
=~
s/^X//
;
if
(
$params
->
{
wrap
}
and
!
$self
->
already_wrapped
)
{
$body
=
wrap_comment
(
$body
);
}
return
$body
;
}
1
;
__END__
=head1 NAME
Bugzilla::Comment - A Comment for a given bug
=head1 SYNOPSIS
use Bugzilla::Comment;
my $comment = Bugzilla::Comment->new($comment_id);
my $comments = Bugzilla::Comment->new_from_list($comment_ids);
=head1 DESCRIPTION
Bugzilla::Comment represents a comment attached to a bug.
This implements all standard C<Bugzilla::Object> methods. See
L<Bugzilla::Object> for more details.
=head2 Accessors
=over
=item C<bug_id>
C<int> The ID of the bug to which the comment belongs.
=item C<creation_ts>
C<string> The comment creation timestamp.
=item C<body>
C<string> The body without any special additional text.
=item C<work_time>
C<string> Time spent as related to this comment.
=item C<is_private>
C<boolean> Comment is marked as private
=item C<already_wrapped>
If this comment is stored in the database word-wrapped, this will be C<1>.
C<0> otherwise.
=item C<author>
L<Bugzilla::User> who created the comment.
=item C<body_full>
=over
=item B<Description>
C<string> Body of the comment, including any special text (such as
"this bug was marked as a duplicate of...").
=item B<Params>
=over
=item C<is_bugmail>
C<boolean>. C<1> if this comment should be formatted specifically for
bugmail.
=item C<wrap>
C<boolean>. C<1> if the comment should be returned word-wrapped.
=back
=item B<Returns>
A string, the full text of the comment as it would be displayed to an end-user.
=back
=back
=cut
Bugzilla/Template.pm
View file @
5d516a6a
...
@@ -170,7 +170,7 @@ sub quoteUrls {
...
@@ -170,7 +170,7 @@ sub quoteUrls {
# If the comment is already wrapped, we should ignore newlines when
# If the comment is already wrapped, we should ignore newlines when
# looking for matching regexps. Else we should take them into account.
# looking for matching regexps. Else we should take them into account.
my
$s
=
(
$comment
&&
$comment
->
{
already_wrapped
}
)
my
$s
=
(
$comment
&&
$comment
->
already_wrapped
)
?
qr/\s/
:
qr/[[:blank:]]/
;
?
qr/\s/
:
qr/[[:blank:]]/
;
# However, note that adding the title (for buglinks) can affect things
# However, note that adding the title (for buglinks) can affect things
...
...
Bugzilla/User.pm
View file @
5d516a6a
...
@@ -1390,7 +1390,7 @@ sub wants_bug_mail {
...
@@ -1390,7 +1390,7 @@ sub wants_bug_mail {
my
$self
=
shift
;
my
$self
=
shift
;
my
(
$bug_id
,
$relationship
,
$fieldDiffs
,
$comments
,
$dependencyText
,
my
(
$bug_id
,
$relationship
,
$fieldDiffs
,
$comments
,
$dependencyText
,
$changer
,
$bug_is_new
)
=
@_
;
$changer
,
$bug_is_new
)
=
@_
;
my
$comments_concatenated
=
join
(
"\n"
,
map
{
$_
->
{
body
}
}
(
@$comments
)
);
my
$comments_concatenated
=
join
(
"\n"
,
map
{
$_
->
body
}
@$comments
);
# Make a list of the events which have happened during this bug change,
# Make a list of the events which have happened during this bug change,
# from the point of view of this user.
# from the point of view of this user.
...
...
Bugzilla/Util.pm
View file @
5d516a6a
...
@@ -40,7 +40,7 @@ use base qw(Exporter);
...
@@ -40,7 +40,7 @@ use base qw(Exporter);
diff_arrays
diff_arrays
trim wrap_hard wrap_comment find_wrap_point
trim wrap_hard wrap_comment find_wrap_point
format_time format_time_decimal validate_date
format_time format_time_decimal validate_date
validate_time
validate_time
datetime_from
file_mod_time is_7bit_clean
file_mod_time is_7bit_clean
bz_crypt generate_random_password
bz_crypt generate_random_password
validate_email_syntax clean_text
validate_email_syntax clean_text
...
@@ -396,7 +396,9 @@ sub format_time {
...
@@ -396,7 +396,9 @@ sub format_time {
# If $format is undefined, try to guess the correct date format.
# If $format is undefined, try to guess the correct date format.
if
(
!
defined
(
$format
))
{
if
(
!
defined
(
$format
))
{
if
(
$date
=~
m/^(\d{4})[-\.](\d{2})[-\.](\d{2}) (\d{2}):(\d{2})(:(\d{2}))?$/
)
{
if
(
!
ref
$date
&&
$date
=~
/^(\d{4})[-\.](\d{2})[-\.](\d{2}) (\d{2}):(\d{2})(:(\d{2}))?$/
)
{
my
$sec
=
$7
;
my
$sec
=
$7
;
if
(
defined
$sec
)
{
if
(
defined
$sec
)
{
$format
=
"%Y-%m-%d %T %Z"
;
$format
=
"%Y-%m-%d %T %Z"
;
...
@@ -409,44 +411,49 @@ sub format_time {
...
@@ -409,44 +411,49 @@ sub format_time {
}
}
}
}
# strptime($date) returns an empty array if $date has an invalid date format.
my
$dt
=
ref
$date
?
$date
:
datetime_from
(
$date
,
$timezone
);
$date
=
defined
$dt
?
$dt
->
strftime
(
$format
)
:
''
;
return
trim
(
$date
);
}
sub
datetime_from
{
my
(
$date
,
$timezone
)
=
@_
;
# strptime($date) returns an empty array if $date has an invalid
# date format.
my
@time
=
strptime
(
$date
);
my
@time
=
strptime
(
$date
);
unless
(
scalar
@time
)
{
unless
(
scalar
@time
)
{
# If an unknown timezone is passed (such as MSK, for Moskow), strptime() is
# If an unknown timezone is passed (such as MSK, for Moskow),
# unable to parse the date. We try again, but we first remove the timezone.
# strptime() is unable to parse the date. We try again, but we first
# remove the timezone.
$date
=~
s/\s+\S+$//
;
$date
=~
s/\s+\S+$//
;
@time
=
strptime
(
$date
);
@time
=
strptime
(
$date
);
}
}
if
(
scalar
@time
)
{
return
undef
if
!
@time
;
# Fix a bug in strptime() where seconds can be undefined in some cases.
$time
[
0
]
||=
0
;
# strptime() counts years from 1900, and months from 0 (January).
# We have to fix both values.
# strptime() counts years from 1900, and months from 0 (January).
my
$dt
=
DateTime
->
new
({
# We have to fix both values.
year
=>
$time
[
5
]
+
1900
,
my
$dt
=
DateTime
->
new
({
year
=>
1900
+
$time
[
5
],
month
=>
$time
[
4
]
+
1
,
month
=>
++
$time
[
4
],
day
=>
$time
[
3
],
day
=>
$time
[
3
],
hour
=>
$time
[
2
],
hour
=>
$time
[
2
],
minute
=>
$time
[
1
],
minute
=>
$time
[
1
],
# DateTime doesn't like fractional seconds.
# DateTime doesn't like fractional seconds.
# Also, sometimes seconds are undef.
second
=>
int
(
$time
[
0
]),
second
=>
int
(
$time
[
0
]
||
0
),
# If importing, use the specified timezone, otherwise
# If a timezone was specified, use it. Otherwise, use the
# use the timezone specified by the server.
# local timezone.
time_zone
=>
Bugzilla
->
local_timezone
->
offset_as_string
(
$time
[
6
])
time_zone
=>
Bugzilla
->
local_timezone
->
offset_as_string
(
$time
[
6
])
||
Bugzilla
->
local_timezone
});
||
Bugzilla
->
local_timezone
,
});
# Now display the date using the given timezone,
# or the user's timezone if none is given.
# Now display the date using the given timezone,
$dt
->
set_time_zone
(
$timezone
||
Bugzilla
->
user
->
timezone
);
# or the user's timezone if none is given.
$date
=
$dt
->
strftime
(
$format
);
$dt
->
set_time_zone
(
$timezone
||
Bugzilla
->
user
->
timezone
);
}
return
$dt
;
else
{
# Don't let invalid (time) strings to be passed to templates!
$date
=
''
;
}
return
trim
(
$date
);
}
}
sub
format_time_decimal
{
sub
format_time_decimal
{
...
@@ -641,6 +648,7 @@ Bugzilla::Util - Generic utility functions for bugzilla
...
@@ -641,6 +648,7 @@ Bugzilla::Util - Generic utility functions for bugzilla
# Functions for formatting time
# Functions for formatting time
format_time($time);
format_time($time);
datetime_from($time, $timezone);
# Functions for dealing with files
# Functions for dealing with files
$time = file_mod_time($filename);
$time = file_mod_time($filename);
...
@@ -894,6 +902,15 @@ This routine is mainly called from templates to filter dates, see
...
@@ -894,6 +902,15 @@ This routine is mainly called from templates to filter dates, see
Returns a number with 2 digit precision, unless the last digit is a 0. Then it
Returns a number with 2 digit precision, unless the last digit is a 0. Then it
returns only 1 digit precision.
returns only 1 digit precision.
=item C<datetime_from($time, $timezone)>
Returns a DateTime object given a date string. If the string is not in some
valid date format that C<strptime> understands, we return C<undef>.
You can optionally specify a timezone for the returned date. If not
specified, defaults to the currently-logged-in user's timezone, or
the Bugzilla server's local timezone if there isn't a logged-in user.
=back
=back
...
...
Bugzilla/WebService/Bug.pm
View file @
5d516a6a
...
@@ -23,6 +23,7 @@ package Bugzilla::WebService::Bug;
...
@@ -23,6 +23,7 @@ package Bugzilla::WebService::Bug;
use
strict
;
use
strict
;
use
base
qw(Bugzilla::WebService)
;
use
base
qw(Bugzilla::WebService)
;
use
Bugzilla::
Comment
;
use
Bugzilla::
Constants
;
use
Bugzilla::
Constants
;
use
Bugzilla::
Error
;
use
Bugzilla::
Error
;
use
Bugzilla::
Field
;
use
Bugzilla::
Field
;
...
@@ -95,12 +96,12 @@ sub comments {
...
@@ -95,12 +96,12 @@ sub comments {
foreach
my
$bug_id
(
@$bug_ids
)
{
foreach
my
$bug_id
(
@$bug_ids
)
{
my
$bug
=
Bugzilla::
Bug
->
check
(
$bug_id
);
my
$bug
=
Bugzilla::
Bug
->
check
(
$bug_id
);
# We want the API to always return comments in the same order.
# We want the API to always return comments in the same order.
my
$comments
=
Bugzilla::Bug::
GetComments
(
$bug
->
id
,
'oldest_to_newest'
,
$params
->
{
new_since
});
my
$comments
=
$bug
->
comments
({
order
=>
'oldest_to_newest'
,
after
=>
$params
->
{
new_since
}
});
my
@result
;
my
@result
;
foreach
my
$comment
(
@$comments
)
{
foreach
my
$comment
(
@$comments
)
{
next
if
$comment
->
{
isprivate
}
&&
!
$user
->
is_insider
;
next
if
$comment
->
is_private
&&
!
$user
->
is_insider
;
$comment
->
{
bug_id
}
=
$bug
->
id
;
push
(
@result
,
$self
->
_translate_comment
(
$comment
,
$params
));
push
(
@result
,
$self
->
_translate_comment
(
$comment
,
$params
));
}
}
$bugs
{
$bug
->
id
}{
'comments'
}
=
\
@result
;
$bugs
{
$bug
->
id
}{
'comments'
}
=
\
@result
;
...
@@ -109,15 +110,10 @@ sub comments {
...
@@ -109,15 +110,10 @@ sub comments {
my
%
comments
;
my
%
comments
;
if
(
scalar
@$comment_ids
)
{
if
(
scalar
@$comment_ids
)
{
my
@ids
=
map
{
trim
(
$_
)
}
@$comment_ids
;
my
@ids
=
map
{
trim
(
$_
)
}
@$comment_ids
;
my
@sql_ids
=
map
{
$dbh
->
quote
(
$_
)
}
@ids
;
my
$comment_data
=
Bugzilla::
Comment
->
new_from_list
(
\
@ids
);
my
$comment_data
=
$dbh
->
selectall_arrayref
(
'SELECT comment_id AS id, bug_id, who, bug_when AS time,
isprivate, thetext AS body, type, extra_data
FROM longdescs WHERE '
.
$dbh
->
sql_in
(
'comment_id'
,
\
@sql_ids
),
{
Slice
=>
{}});
# See if we were passed any invalid comment ids.
# See if we were passed any invalid comment ids.
my
%
got_ids
=
map
{
$_
->
{
id
}
=>
1
}
@$comment_data
;
my
%
got_ids
=
map
{
$_
->
id
=>
1
}
@$comment_data
;
foreach
my
$comment_id
(
@ids
)
{
foreach
my
$comment_id
(
@ids
)
{
if
(
!
$got_ids
{
$comment_id
})
{
if
(
!
$got_ids
{
$comment_id
})
{
ThrowUserError
(
'comment_id_invalid'
,
{
id
=>
$comment_id
});
ThrowUserError
(
'comment_id_invalid'
,
{
id
=>
$comment_id
});
...
@@ -125,16 +121,14 @@ sub comments {
...
@@ -125,16 +121,14 @@ sub comments {
}
}
# Now make sure that we can see all the associated bugs.
# Now make sure that we can see all the associated bugs.
my
%
got_bug_ids
=
map
{
$_
->
{
bug_id
}
=>
1
}
@$comment_data
;
my
%
got_bug_ids
=
map
{
$_
->
bug_id
=>
1
}
@$comment_data
;
Bugzilla::
Bug
->
check
(
$_
)
foreach
(
keys
%
got_bug_ids
);
Bugzilla::
Bug
->
check
(
$_
)
foreach
(
keys
%
got_bug_ids
);
foreach
my
$comment
(
@$comment_data
)
{
foreach
my
$comment
(
@$comment_data
)
{
if
(
$comment
->
{
isprivate
}
&&
!
$user
->
is_insider
)
{
if
(
$comment
->
is_private
&&
!
$user
->
is_insider
)
{
ThrowUserError
(
'comment_is_private'
,
{
id
=>
$comment
->
{
id
}
});
ThrowUserError
(
'comment_is_private'
,
{
id
=>
$comment
->
id
});
}
}
$comment
->
{
author
}
=
new
Bugzilla::
User
(
$comment
->
{
who
});
$comments
{
$comment
->
id
}
=
$comment
->
{
body
}
=
Bugzilla::Bug::
format_comment
(
$comment
);
$comments
{
$comment
->
{
id
}}
=
$self
->
_translate_comment
(
$comment
,
$params
);
$self
->
_translate_comment
(
$comment
,
$params
);
}
}
}
}
...
@@ -146,12 +140,12 @@ sub comments {
...
@@ -146,12 +140,12 @@ sub comments {
sub
_translate_comment
{
sub
_translate_comment
{
my
(
$self
,
$comment
,
$filters
)
=
@_
;
my
(
$self
,
$comment
,
$filters
)
=
@_
;
return
filter
$filters
,
{
return
filter
$filters
,
{
id
=>
$self
->
type
(
'int'
,
$comment
->
{
id
}
),
id
=>
$self
->
type
(
'int'
,
$comment
->
id
),
bug_id
=>
$self
->
type
(
'int'
,
$comment
->
{
bug_id
}
),
bug_id
=>
$self
->
type
(
'int'
,
$comment
->
bug_id
),
author
=>
$self
->
type
(
'string'
,
$comment
->
{
author
}
->
login
),
author
=>
$self
->
type
(
'string'
,
$comment
->
author
->
login
),
time
=>
$self
->
type
(
'dateTime'
,
$comment
->
{
'time'
}
),
time
=>
$self
->
type
(
'dateTime'
,
$comment
->
creation_ts
),
is_private
=>
$self
->
type
(
'boolean'
,
$comment
->
{
isprivate
}
),
is_private
=>
$self
->
type
(
'boolean'
,
$comment
->
is_private
),
text
=>
$self
->
type
(
'string'
,
$comment
->
{
body
}
),
text
=>
$self
->
type
(
'string'
,
$comment
->
body_full
),
};
};
}
}
...
...
email_in.pl
View file @
5d516a6a
...
@@ -204,7 +204,7 @@ sub process_bug {
...
@@ -204,7 +204,7 @@ sub process_bug {
foreach
my
$field
(
keys
%
fields
)
{
foreach
my
$field
(
keys
%
fields
)
{
$cgi
->
param
(
-
name
=>
$field
,
-
value
=>
$fields
{
$field
});
$cgi
->
param
(
-
name
=>
$field
,
-
value
=>
$fields
{
$field
});
}
}
$cgi
->
param
(
'longdesclength'
,
scalar
$bug
->
longdescs
);
$cgi
->
param
(
'longdesclength'
,
scalar
@
{
$bug
->
comments
}
);
$cgi
->
param
(
'token'
,
issue_hash_token
([
$bug
->
id
,
$bug
->
delta_ts
]));
$cgi
->
param
(
'token'
,
issue_hash_token
([
$bug
->
id
,
$bug
->
delta_ts
]));
require
'process_bug.cgi'
;
require
'process_bug.cgi'
;
...
...
enter_bug.cgi
View file @
5d516a6a
...
@@ -434,17 +434,16 @@ if ($cloned_bug_id) {
...
@@ -434,17 +434,16 @@ if ($cloned_bug_id) {
# We need to ensure that we respect the 'insider' status of
# We need to ensure that we respect the 'insider' status of
# the first comment, if it has one. Either way, make a note
# the first comment, if it has one. Either way, make a note
# that this bug was cloned from another bug.
# that this bug was cloned from another bug.
# We cannot use $cloned_bug->longdescs because this method
my
$bug_desc
=
$cloned_bug
->
comments
({
order
=>
'oldest_to_newest'
})
->
[
0
];
# depends on the "comment_sort_order" user pref, and we
my
$isprivate
=
$bug_desc
->
is_private
;
# really want the first comment of the bug.
my
$bug_desc
=
Bugzilla::Bug::
GetComments
(
$cloned_bug_id
,
'oldest_to_newest'
);
my
$isprivate
=
$bug_desc
->
[
0
]
->
{
'isprivate'
};
$vars
->
{
'comment'
}
=
""
;
$vars
->
{
'comment'
}
=
""
;
$vars
->
{
'commentprivacy'
}
=
0
;
$vars
->
{
'commentprivacy'
}
=
0
;
if
(
!
$isprivate
||
Bugzilla
->
user
->
is_insider
)
{
if
(
!
$isprivate
||
Bugzilla
->
user
->
is_insider
)
{
$vars
->
{
'comment'
}
=
$bug_desc
->
[
0
]
->
{
'body'
};
# We use "body" to avoid any format_comment text, which would be
# pointless to clone.
$vars
->
{
'comment'
}
=
$bug_desc
->
body
;
$vars
->
{
'commentprivacy'
}
=
$isprivate
;
$vars
->
{
'commentprivacy'
}
=
$isprivate
;
}
}
...
...
post_bug.cgi
View file @
5d516a6a
...
@@ -229,13 +229,13 @@ if (defined($cgi->upload('data')) || $cgi->param('attachurl')) {
...
@@ -229,13 +229,13 @@ if (defined($cgi->upload('data')) || $cgi->param('attachurl')) {
# expects to find this exact string.
# expects to find this exact string.
my
$new_comment
=
"Created an attachment (id="
.
$attachment
->
id
.
")\n"
.
my
$new_comment
=
"Created an attachment (id="
.
$attachment
->
id
.
")\n"
.
$attachment
->
description
.
"\n"
;
$attachment
->
description
.
"\n"
;
# We can use $bug->
longdesc
s here because we are sure that the bug
# We can use $bug->
comment
s here because we are sure that the bug
# description is of type CMT_NORMAL. No need to include it if it's
# description is of type CMT_NORMAL. No need to include it if it's
# empty, though.
# empty, though.
if
(
$bug
->
longdescs
->
[
0
]
->
{
'body'
}
!~
/^\s+$/
)
{
if
(
$bug
->
comments
->
[
0
]
->
body
!~
/^\s+$/
)
{
$new_comment
.=
"\n"
.
$bug
->
longdescs
->
[
0
]
->
{
'body'
}
;
$new_comment
.=
"\n"
.
$bug
->
comments
->
[
0
]
->
body
;
}
}
$bug
->
update_comment
(
$bug
->
longdescs
->
[
0
]
->
{
'id'
}
,
$new_comment
);
$bug
->
update_comment
(
$bug
->
comments
->
[
0
]
->
id
,
$new_comment
);
}
}
else
{
else
{
$vars
->
{
'message'
}
=
'attachment_creation_failed'
;
$vars
->
{
'message'
}
=
'attachment_creation_failed'
;
...
...
process_bug.cgi
View file @
5d516a6a
...
@@ -168,8 +168,7 @@ if (defined $cgi->param('delta_ts')
...
@@ -168,8 +168,7 @@ if (defined $cgi->param('delta_ts')
$vars
->
{
'start_at'
}
=
$cgi
->
param
(
'longdesclength'
);
$vars
->
{
'start_at'
}
=
$cgi
->
param
(
'longdesclength'
);
# Always sort midair collision comments oldest to newest,
# Always sort midair collision comments oldest to newest,
# regardless of the user's personal preference.
# regardless of the user's personal preference.
$vars
->
{
'comments'
}
=
Bugzilla::Bug::
GetComments
(
$first_bug
->
id
,
$vars
->
{
'comments'
}
=
$first_bug
->
comments
({
order
=>
"oldest_to_newest"
});
"oldest_to_newest"
);
$vars
->
{
'bug'
}
=
$first_bug
;
$vars
->
{
'bug'
}
=
$first_bug
;
# The token contains the old delta_ts. We need a new one.
# The token contains the old delta_ts. We need a new one.
$cgi
->
param
(
'token'
,
issue_hash_token
([
$first_bug
->
id
,
$first_bug
->
delta_ts
]));
$cgi
->
param
(
'token'
,
issue_hash_token
([
$first_bug
->
id
,
$first_bug
->
delta_ts
]));
...
...
template/en/default/bug/comments.html.tmpl
View file @
5d516a6a
...
@@ -94,7 +94,6 @@
...
@@ -94,7 +94,6 @@
[% DEFAULT start_at = 0 mode = "show" %]
[% DEFAULT start_at = 0 mode = "show" %]
[% isinsider = Param("insidergroup") && user.in_group(Param("insidergroup")) %]
[% sort_order = user.settings.comment_sort_order.value %]
[% sort_order = user.settings.comment_sort_order.value %]
[%# NOTE: (start_at > 0) means we came here from a midair collision,
[%# NOTE: (start_at > 0) means we came here from a midair collision,
...
@@ -145,8 +144,9 @@
...
@@ -145,8 +144,9 @@
[%############################################################################%]
[%############################################################################%]
[% BLOCK a_comment %]
[% BLOCK a_comment %]
[% IF NOT comment.isprivate || isinsider %]
[% RETURN IF comment.is_private AND ! user.is_insider %]
<div class="bz_comment[% " bz_private" IF comment.isprivate %]
<div class="bz_comment[% " bz_private" IF comment.is_private %]
[% " bz_comment_hilite" IF marks.$count %]
[% " bz_comment_hilite" IF marks.$count %]
[% " bz_first_comment" IF count == description %]">
[% " bz_first_comment" IF count == description %]">
[% IF count == description %]
[% IF count == description %]
...
@@ -168,7 +168,7 @@
...
@@ -168,7 +168,7 @@
</span>
</span>
[% END %]
[% END %]
[% IF mode == "edit" &&
is
insider %]
[% IF mode == "edit" &&
user.is_
insider %]
<div class="bz_private_checkbox">
<div class="bz_private_checkbox">
<input type="hidden" value="1"
<input type="hidden" value="1"
name="defined_isprivate_[% comment.id %]">
name="defined_isprivate_[% comment.id %]">
...
@@ -176,7 +176,7 @@
...
@@ -176,7 +176,7 @@
name="isprivate_[% comment.id %]" value="1"
name="isprivate_[% comment.id %]" value="1"
id="isprivate_[% comment.id %]"
id="isprivate_[% comment.id %]"
onClick="updateCommentPrivacy(this, [% count %])"
onClick="updateCommentPrivacy(this, [% count %])"
[% " checked=\"checked\"" IF comment.isprivate %]>
[% " checked=\"checked\"" IF comment.is
_
private %]>
<label for="isprivate_[% comment.id %]">Private</label>
<label for="isprivate_[% comment.id %]">Private</label>
</div>
</div>
[% END %]
[% END %]
...
@@ -201,7 +201,7 @@
...
@@ -201,7 +201,7 @@
</span>
</span>
<span class="bz_comment_time">
<span class="bz_comment_time">
[%+ comment.
time
FILTER time %]
[%+ comment.
creation_ts
FILTER time %]
</span>
</span>
</div>
</div>
...
@@ -215,15 +215,9 @@
...
@@ -215,15 +215,9 @@
[%# Don't indent the <pre> block, since then the spaces are displayed in the
[%# Don't indent the <pre> block, since then the spaces are displayed in the
# generated HTML
# generated HTML
#%]
#%]
[% IF comment.already_wrapped %]
[% wrapped_comment = comment.body %]
[% ELSE %]
[% wrapped_comment = comment.body FILTER wrap_comment %]
[% END %]
<pre class="bz_comment_text"
<pre class="bz_comment_text"
[% ' id="comment_text_' _ count _ '"' IF mode == "edit" %]>
[% ' id="comment_text_' _ count _ '"' IF mode == "edit" %]>
[%-
wrapped_comment
FILTER quoteUrls(bug, comment) -%]
[%-
comment.body_full({ wrap => 1 })
FILTER quoteUrls(bug, comment) -%]
</pre>
</pre>
</div>
</div>
[% END %]
[% END %]
[% END %]
template/en/default/bug/edit.html.tmpl
View file @
5d516a6a
...
@@ -142,7 +142,7 @@
...
@@ -142,7 +142,7 @@
<form name="changeform" method="post" action="process_bug.cgi">
<form name="changeform" method="post" action="process_bug.cgi">
<input type="hidden" name="delta_ts" value="[% bug.delta_ts %]">
<input type="hidden" name="delta_ts" value="[% bug.delta_ts %]">
<input type="hidden" name="longdesclength" value="[% bug.
longdesc
s.size %]">
<input type="hidden" name="longdesclength" value="[% bug.
comment
s.size %]">
<input type="hidden" name="id" value="[% bug.bug_id %]">
<input type="hidden" name="id" value="[% bug.bug_id %]">
<input type="hidden" name="token" value="[% issue_hash_token([bug.id, bug.delta_ts]) FILTER html %]">
<input type="hidden" name="token" value="[% issue_hash_token([bug.id, bug.delta_ts]) FILTER html %]">
...
@@ -287,7 +287,7 @@
...
@@ -287,7 +287,7 @@
<hr>
<hr>
<div id="comments">
<div id="comments">
[% PROCESS bug/comments.html.tmpl
[% PROCESS bug/comments.html.tmpl
comments = bug.
longdesc
s
comments = bug.
comment
s
mode = user.id ? "edit" : "show"
mode = user.id ? "edit" : "show"
%]
%]
</div>
</div>
...
...
template/en/default/bug/format_comment.txt.tmpl
View file @
5d516a6a
...
@@ -23,23 +23,23 @@
...
@@ -23,23 +23,23 @@
#%]
#%]
[%# INTERFACE:
[%# INTERFACE:
# comment: A hash containing comment information.
# comment: A Bugzilla::Comment object.
# count: The comment number (on the bug it belongs to)
# is_bugmail: boolean; True if this comment is going into a plain-text
# author: The Bugzilla::User object of the comment's
# bugmail.
# author
# time: The time at which the comment has been
# committed
# body: The comment text
# type: One of the CMT_* constants (not given if none
# applies)
# extra_data: Extra data (type specific)
# already_wrapped: Determines whether the comment is pre-wrapped
#%]
#%]
[% PROCESS 'global/field-descs.none.tmpl' %]
[%# Please don't use field-descs here. It can slow down Bugzilla. %]
[% PROCESS 'global/variables.none.tmpl' %]
[% SET comment_body = comment.body %]
[% IF is_bugmail %]
[% comment_body = comment_body.replace( '(Created an attachment \(id=([0-9]+)\))',
'$1' _ "\n" _ ' --> (' _ urlbase
_ 'attachment.cgi?id=$2)' ) %]
[% END %]
[% IF comment.type == constants.CMT_DUPE_OF %]
[% IF comment.type == constants.CMT_DUPE_OF %]
X[% comment
.
body %]
X[% comment
_
body %]
*** This [% terms.bug %] has been marked as a duplicate of [% terms.bug %] [%+ comment.extra_data %] ***
*** This [% terms.bug %] has been marked as a duplicate of [% terms.bug %] [%+ comment.extra_data %] ***
[% ELSIF comment.type == constants.CMT_HAS_DUPE %]
[% ELSIF comment.type == constants.CMT_HAS_DUPE %]
...
@@ -47,14 +47,13 @@ X[% comment.body %]
...
@@ -47,14 +47,13 @@ X[% comment.body %]
[% ELSIF comment.type == constants.CMT_POPULAR_VOTES %]
[% ELSIF comment.type == constants.CMT_POPULAR_VOTES %]
*** This [% terms.bug %] has been confirmed by popular vote. ***
*** This [% terms.bug %] has been confirmed by popular vote. ***
[% ELSIF comment.type == constants.CMT_MOVED_TO %]
[% ELSIF comment.type == constants.CMT_MOVED_TO %]
X[% comment
.
body %]
X[% comment
_
body %]
[%+ terms.Bug %] moved to [% Param("move-to-url") %].
[%+ terms.Bug %] moved to [% Param("move-to-url") %].
If the move succeeded, [% comment.extra_data %] will receive a mail containing
If the move succeeded, [% comment.extra_data %] will receive a mail containing
the number of the new [% terms.bug %] in the other database.
the number of the new [% terms.bug %] in the other database.
If all went well, please mark this [% terms.bug %]
If all went well, please paste in a link to the new [% terms.bug %].
[%+ display_value("bug_status", 'VERIFIED') %], and paste in a link to the new [% terms.bug %].
Otherwise, reopen this [% terms.bug %].
Otherwise, reopen this [% terms.bug %].
[% ELSE %]
[% ELSE %]
X[% comment
.
body %]
X[% comment
_
body %]
[% END %]
[% END %]
template/en/default/bug/show-multiple.html.tmpl
View file @
5d516a6a
...
@@ -289,7 +289,7 @@
...
@@ -289,7 +289,7 @@
<br>
<br>
[% PROCESS bug/comments.html.tmpl
[% PROCESS bug/comments.html.tmpl
comments = bug.
longdesc
s %]
comments = bug.
comment
s %]
[% END %]
[% END %]
...
...
template/en/default/bug/show.xml.tmpl
View file @
5d516a6a
...
@@ -65,16 +65,16 @@
...
@@ -65,16 +65,16 @@
[% PROCESS section_flags obj => bug %]
[% PROCESS section_flags obj => bug %]
[% IF displayfields.long_desc %]
[% IF displayfields.long_desc %]
[% FOREACH c = bug.
longdesc
s %]
[% FOREACH c = bug.
comment
s %]
[% NEXT IF c.isprivate && !user.in_group(Param("insidergroup")) %]
[% NEXT IF c.is
_
private && !user.in_group(Param("insidergroup")) %]
<long_desc isprivate="[% c.isprivate FILTER xml %]">
<long_desc isprivate="[% c.is
_
private FILTER xml %]">
<commentid>[% c.id FILTER xml %]</commentid>
<commentid>[% c.id FILTER xml %]</commentid>
<who name="[% c.author.name FILTER xml %]">[% c.author.email FILTER email FILTER xml %]</who>
<who name="[% c.author.name FILTER xml %]">[% c.author.email FILTER email FILTER xml %]</who>
<bug_when>[% c.
time
FILTER time("%Y-%m-%d %T %z") FILTER xml %]</bug_when>
<bug_when>[% c.
creation_ts
FILTER time("%Y-%m-%d %T %z") FILTER xml %]</bug_when>
[% IF user.in_group(Param('timetrackinggroup')) && (c.work_time - 0 != 0) %]
[% IF user.in_group(Param('timetrackinggroup')) && (c.work_time - 0 != 0) %]
<work_time>[% PROCESS formattimeunit time_unit = c.work_time FILTER xml %]</work_time>
<work_time>[% PROCESS formattimeunit time_unit = c.work_time FILTER xml %]</work_time>
[% END %]
[% END %]
<thetext>[% c.body FILTER xml %]</thetext>
<thetext>[% c.body
_full
FILTER xml %]</thetext>
</long_desc>
</long_desc>
[% END %]
[% END %]
[% END %]
[% END %]
...
@@ -151,4 +151,4 @@
...
@@ -151,4 +151,4 @@
[% END %]
[% END %]
/>
/>
[% END %]
[% END %]
[% END %]
[% END %]
\ No newline at end of file
template/en/default/email/newchangedmail.txt.tmpl
View file @
5d516a6a
...
@@ -50,7 +50,7 @@ X-Bugzilla-Changed-Fields: [% changedfields %]
...
@@ -50,7 +50,7 @@ X-Bugzilla-Changed-Fields: [% changedfields %]
[%- IF comment.count %]
[%- IF comment.count %]
--- Comment #[% comment.count %] from [% comment.author.identity %] [%+ comment.time FILTER time %] ---
--- Comment #[% comment.count %] from [% comment.author.identity %] [%+ comment.time FILTER time %] ---
[% END %]
[% END %]
[%+
FILTER remove('^X') %][% PROCESS bug/format_comment.txt.tmpl %][% END
%]
[%+
comment.body_full({ is_bugmail => 1, wrap => 1 })
%]
[% END %]
[% END %]
-- [%# Protect the trailing space of the signature marker %]
-- [%# Protect the trailing space of the signature marker %]
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment